1 | import ApolloClient from 'apollo-client';
|
2 |
|
3 | import {
|
4 | NetworkInterface,
|
5 | Request,
|
6 | } from 'apollo-client/networkInterface';
|
7 |
|
8 | import {
|
9 | GraphQLResult,
|
10 | Document,
|
11 | parse,
|
12 | print,
|
13 | } from 'graphql';
|
14 |
|
15 |
|
16 |
|
17 | function mockNetworkInterface(
|
18 | ...mockedResponses: MockedResponse[]
|
19 | ): NetworkInterface {
|
20 | return new MockNetworkInterface(...mockedResponses);
|
21 | }
|
22 |
|
23 | export interface ParsedRequest {
|
24 | variables?: Object;
|
25 | query?: Document;
|
26 | debugName?: string;
|
27 | }
|
28 |
|
29 | export interface MockedResponse {
|
30 | request: ParsedRequest;
|
31 | result?: GraphQLResult;
|
32 | error?: Error;
|
33 | delay?: number;
|
34 | }
|
35 |
|
36 | export class MockNetworkInterface implements NetworkInterface {
|
37 | private mockedResponsesByKey: { [key: string]: MockedResponse[] } = {};
|
38 |
|
39 | constructor(...mockedResponses: MockedResponse[]) {
|
40 | mockedResponses.forEach((mockedResponse) => {
|
41 | this.addMockedReponse(mockedResponse);
|
42 | });
|
43 | }
|
44 |
|
45 | public addMockedReponse(mockedResponse: MockedResponse) {
|
46 | const key = requestToKey(mockedResponse.request);
|
47 | let mockedResponses = this.mockedResponsesByKey[key];
|
48 | if (!mockedResponses) {
|
49 | mockedResponses = [];
|
50 | this.mockedResponsesByKey[key] = mockedResponses;
|
51 | }
|
52 | mockedResponses.push(mockedResponse);
|
53 | }
|
54 |
|
55 | public query(request: Request) {
|
56 | return new Promise((resolve, reject) => {
|
57 | const parsedRequest: ParsedRequest = {
|
58 | query: parse(request.query),
|
59 | variables: request.variables,
|
60 | debugName: request.debugName,
|
61 | };
|
62 |
|
63 | const key = requestToKey(parsedRequest);
|
64 |
|
65 | if (!this.mockedResponsesByKey[key]) {
|
66 | throw new Error(`No more mocked responses for the query: ${request.query}`);
|
67 | }
|
68 |
|
69 | const { result, error, delay } = this.mockedResponsesByKey[key].shift();
|
70 |
|
71 | if (!result && !error) {
|
72 | throw new Error(`Mocked response should contain either result or error: ${key}`);
|
73 | }
|
74 |
|
75 | setTimeout(() => {
|
76 | if (error) {
|
77 | reject(error);
|
78 | } else {
|
79 | resolve(result);
|
80 | }
|
81 | }, delay ? delay : 0);
|
82 | });
|
83 | }
|
84 | }
|
85 |
|
86 | function requestToKey(request: ParsedRequest): string {
|
87 | const queryString = request.query && print(request.query);
|
88 |
|
89 | return JSON.stringify({
|
90 | variables: request.variables,
|
91 | debugName: request.debugName,
|
92 | query: queryString,
|
93 | });
|
94 | }
|
95 |
|
96 | export function mockClient(...args): ApolloClient {
|
97 | const networkInterface = mockNetworkInterface(...args)
|
98 |
|
99 | return new ApolloClient({
|
100 | networkInterface,
|
101 | });
|
102 | }
|