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