npm package: @os-team/graphql-test-client
Description: The wrapper of the superagent to make GraphQL queries in tests.
Latest version: 1.2.1

# @os-team/graphql-test-client [![NPM version](https://img.shields.io/npm/v/@os-team/graphql-test-client)](https://yarnpkg.com/package/@os-team/graphql-test-client)

The wrapper of the superagent to make GraphQL queries in tests.

Unlike `apollo-boost` and `apollo-client`, `superagent` saves cookies in the Node.js environment.
This is useful, for example, for testing the authentication flow.

## Usage

Install the package in devDependencies (-D) using the following command:

```
yarn add -D @os-team/graphql-test-client
```

### Example 1. Base request

For example, let's request the sign-in method.

```ts
import GraphQLTestClient from '@os-team/graphql-test-client';

const signInMutation = `
  mutation SignInMutation($input: SignInInput!) {
    signIn(input: $input) {
      ok
    }
  }
`;

it('Should make a request successfully', async () => {
  const input = {
    email: 'name@domain.com',
    password: 'password',
  };

  // Create an instance of GraphQLTestClient
  const client = new GraphQLTestClient({
    url: 'http://localhost:4000/graphql',
  });

  // Make a GraphQL request and pass the variables
  const res = await client.query({
    query: signInMutation,
    variables: { input },
  });

  // Test the response
  assert.equal(res.body.errors, undefined);
  assert.notEqual(res.body.data, undefined);
});
```

Cool, but if you want to request the profile method after that, you must save the cookies. See the next example how you can do it.

### Example 2. Request with cookies

Pass `saveCookies: true` when creating an instance of `GraphQLTestClient`.
Now the GraphQL test client will save cookies after each request.

```ts
import GraphQLTestClient from '@os-team/graphql-test-client';

const signInMutation = `
  mutation SignInMutation($input: SignInInput!) {
    signIn(input: $input) {
      ok
    }
  }
`;

const profileQuery = `
  query profileQuery {
    profile {
      email
      firstName
      lastName
    }
  }
`;

it('Should sign in successfully', async () => {
  const input = {
    email: 'name@domain.com',
    password: 'password',
  };

  // Create an instance of GraphQLTestClient
  const client = new GraphQLTestClient({
    url: 'http://localhost:4000/graphql',
    saveCookies: true,
  });

  // Sign in
  await client.query({
    query: signInMutation,
    variables: { input },
  });

  // Get profile
  const res = await client.query({
    query: profileQuery,
  });

  // Test the response
  assert.equal(res.body.errors, undefined);
  assert.notEqual(res.body.data, undefined);
});
```

### Example 3. Request with file uploads

Sometimes you want to upload files.
Pass the files in the `uploadables` parameter.

```ts
import GraphQLTestClient from '@os-team/graphql-test-client';

const createPostMutation = `
  mutation CreatePostMutation($input: CreatePostInput!) {
    createPost(input: $input) {
      id
      title
      content
      cover
    }
  }
`;

it('Should create a new post', async () => {
  const input = {
    title: 'title',
    content: {},
  };

  // Create an instance of GraphQLTestClient
  const client = new GraphQLTestClient({
    url: 'http://localhost:4000/graphql',
  });

  // Make the request
  const res = await client.query({
    query: createPostMutation,
    variables: { input },
    uploadables: {
      cover: path.resolve(__dirname, './image.jpg'),
    },
  });

  // Test the response
  assert.equal(res.body.errors, undefined);
  assert.notEqual(res.body.data, undefined);
});
```

`GraphQLTestClient` uses the [specification](https://github.com/jaydenseric/graphql-multipart-request-spec) for GraphQL multipart form requests to upload files.
Make sure you implement this spec.

### Example 4. Request with headers

There are 2 ways how you can specify headers:

- Specify unique headers for each request.
- Specify shared headers for all requests.

```ts
import GraphQLTestClient from '@os-team/graphql-test-client';

const createPostMutation = `
  mutation CreatePostMutation($input: CreatePostInput!) {
    createPost(input: $input) {
      id
      title
      content
      cover
    }
  }
`;

it('Should create a new post', async () => {
  const input = {
    title: 'title',
    content: {},
  };

  // Create an instance of GraphQLTestClient
  const client = new GraphQLTestClient({
    url: 'http://localhost:4000/graphql',
    sharedHeaders: {
      Authorization: 'Bearer AUTH_KEY',
    },
  });

  // Make the request
  const res = await client.query({
    query: createPostMutation,
    variables: { input },
    headers: {
      'X-Header': 'Some header',
    },
  });

  // Test the response
  assert.equal(res.body.errors, undefined);
  assert.notEqual(res.body.data, undefined);
});
```

If the same header is used in `sharedHeaders` and `headers`, the latter will rewrite the shared header.

---

Most likely you will use multiple test files (e.g. one test file for testing one API method).
In this case:

1. Create an instance of `GraphQLTestClient` in a separate file and export this variable to use it in any test file.
1. Add the path to this file to [setupFilesAfterEnv](https://jestjs.io/docs/en/configuration#setupfilesafterenv-array). Jest will run this code before each test file in the suite is executed.