Skip to content

Commit

Permalink
setOptions after creation and more specific types
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloSzx committed Dec 6, 2019
1 parent fd62367 commit 2bf265a
Showing 1 changed file with 56 additions and 20 deletions.
76 changes: 56 additions & 20 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
// @flow

import express from 'express';
import httpMocks from 'node-mocks-http';
import { print } from 'graphql';
import { convertNodeHttpToRequest, runHttpQuery } from 'apollo-server-core';

import { ApolloServer } from 'apollo-server-express';
import { DocumentNode } from 'graphql';
import express from 'express';
import { DocumentNode, print } from 'graphql';
import httpMocks, { RequestOptions, ResponseOptions } from 'node-mocks-http';

const mockRequest = (options = {}) =>
const mockRequest = (options: RequestOptions = {}) =>
httpMocks.createRequest({
method: 'POST',
...options
});

const mockResponse = (options = {}) => httpMocks.createResponse(options);
const mockResponse = (options: ResponseOptions = {}) =>
httpMocks.createResponse(options);

type StringOrAst = string | DocumentNode;
type Options = { variables?: object};
export type StringOrAst = string | DocumentNode;
export type Options<T extends object> = { variables?: T };

type TestClientConfig = {
export type TestClientConfig = {
// The ApolloServer instance that will be used for handling the queries you run in your tests.
// Must be an instance of the ApolloServer class from `apollo-server-express` (or a compatible subclass).
apolloServer: ApolloServer;
Expand All @@ -28,15 +27,25 @@ type TestClientConfig = {
// and you want to inject data into that `req` object.
// If you don't pass anything here, we provide a default request mock object for you.
// See https://github.com/howardabrams/node-mocks-http#createrequest for all the default values that are included.
extendMockRequest?: {};
extendMockRequest?: RequestOptions;
// Extends the mocked Response object with additional keys.
// Useful when your apolloServer `context` option is a callback that operates on the passed in `res` key,
// and you want to inject data into that `res` object (such as `res.locals`).
// If you don't pass anything here, we provide a default response mock object for you.
// See https://www.npmjs.com/package/node-mocks-http#createresponse for all the default values that are included.
extendMockResponse?: {};
extendMockResponse?: ResponseOptions;
};

export type TestQuery = <T extends object = {}, V extends object = {}>(
operation: StringOrAst,
{ variables }?: Options<V>
) => Promise<T>;

export type TestSetOptions = (options: {
request?: RequestOptions;
response?: ResponseOptions;
}) => void;

// This function takes in an apollo server instance and returns a function that you can use to run operations
// against your schema, and assert on the results.
//
Expand All @@ -59,17 +68,43 @@ type TestClientConfig = {
// }
// });
// ```
export const createTestClient = ({
export function createTestClient({
apolloServer,
extendMockRequest = {},
extendMockResponse = {}
}: TestClientConfig) => {
}: TestClientConfig) {
const app = express();
apolloServer.applyMiddleware({ app });

const test = async (operation: StringOrAst, {variables}: Options = {}) => {
const req = mockRequest(extendMockRequest);
const res = mockResponse(extendMockResponse);
let mockRequestOptions = extendMockRequest;
let mockResponseOptions = extendMockResponse;

/**
* Set the options after TestClient creation
* Useful when you don't want to create a new instance just for a specific change in the request or response.
* */

const setOptions: TestSetOptions = ({
request,
response
}: {
request?: RequestOptions;
response?: ResponseOptions;
}) => {
if (request) {
mockRequestOptions = request;
}
if (response) {
mockResponseOptions = response;
}
};

const test: TestQuery = async <T extends object = {}, V extends object = {}>(
operation: StringOrAst,
{ variables }: Options<V> = {}
) => {
const req = mockRequest(mockRequestOptions);
const res = mockResponse(mockResponseOptions);

const graphQLOptions = await apolloServer.createGraphQLServerOptions(
req,
Expand All @@ -87,11 +122,12 @@ export const createTestClient = ({
request: convertNodeHttpToRequest(req)
});

return JSON.parse(graphqlResponse);
return JSON.parse(graphqlResponse) as T;
};

return {
query: test,
mutate: test
mutate: test,
setOptions
};
};
}

0 comments on commit 2bf265a

Please sign in to comment.