1 | import gql from 'graphql-tag';
|
2 | import { ApolloLink, execute, Observable } from 'apollo-link';
|
3 |
|
4 | import { print } from 'graphql/language/printer';
|
5 |
|
6 | import { withClientState } from '../';
|
7 |
|
8 |
|
9 | const query = gql`
|
10 | query Test {
|
11 | foo @client {
|
12 | bar
|
13 | }
|
14 | }
|
15 | `;
|
16 |
|
17 | const mixedQuery = gql`
|
18 | query Mixed {
|
19 | foo @client {
|
20 | bar
|
21 | }
|
22 | bar {
|
23 | foo
|
24 | }
|
25 | }
|
26 | `;
|
27 |
|
28 | const resolvers = {
|
29 | Query: {
|
30 | foo: () => ({ bar: true }),
|
31 | },
|
32 | };
|
33 |
|
34 | it('strips out the client directive and does not call other links if no more fields', done => {
|
35 | const nextLink = new ApolloLink(operation => {
|
36 | return done.fail(new Error('should not have called'));
|
37 | });
|
38 |
|
39 | const client = withClientState({ resolvers });
|
40 |
|
41 | execute(client.concat(nextLink), { query }).subscribe(result => {
|
42 | try {
|
43 | expect(result.data).toEqual({ foo: { bar: true } });
|
44 | } catch (error) {
|
45 | done.fail(error);
|
46 | }
|
47 | done();
|
48 | }, done.fail);
|
49 | });
|
50 |
|
51 | it('passes a query on to the next link', done => {
|
52 | const nextLink = new ApolloLink(operation => {
|
53 | try {
|
54 | expect(operation.getContext()).toMatchSnapshot();
|
55 | expect(print(operation.query)).toEqual(
|
56 | print(gql`
|
57 | query Mixed {
|
58 | bar {
|
59 | foo
|
60 | }
|
61 | }
|
62 | `),
|
63 | );
|
64 | } catch (error) {
|
65 | done.fail(error);
|
66 | }
|
67 | return Observable.of({ data: { bar: { foo: true } } });
|
68 | });
|
69 |
|
70 | const client = withClientState({ resolvers });
|
71 |
|
72 | execute(client.concat(nextLink), { query: mixedQuery }).subscribe(
|
73 | () => done(),
|
74 | done.fail,
|
75 | );
|
76 | });
|
77 |
|
78 | it('runs resolvers for client queries', done => {
|
79 | const client = withClientState({
|
80 | resolvers: {
|
81 | Query: {
|
82 | foo: () => ({ bar: true }),
|
83 | },
|
84 | },
|
85 | });
|
86 | execute(client, { query }).subscribe(({ data }) => {
|
87 | try {
|
88 | expect(data).toEqual({ foo: { bar: true } });
|
89 | } catch (error) {
|
90 | done.fail(error);
|
91 | }
|
92 | done();
|
93 | }, done.fail);
|
94 | });
|
95 |
|
96 | it('runs resolvers for missing client queries with server data', done => {
|
97 | const query = gql`
|
98 | query Mixed {
|
99 | foo @client {
|
100 | bar
|
101 | }
|
102 | bar {
|
103 | baz
|
104 | }
|
105 | }
|
106 | `;
|
107 | const sample = new ApolloLink(() =>
|
108 | Observable.of({ data: { bar: { baz: true } } }),
|
109 | );
|
110 | const client = withClientState({ resolvers });
|
111 | execute(client.concat(sample), { query }).subscribe(({ data }) => {
|
112 | try {
|
113 | expect(data).toEqual({ foo: { bar: true }, bar: { baz: true } });
|
114 | } catch (error) {
|
115 | done.fail(error);
|
116 | }
|
117 | done();
|
118 | }, done.fail);
|
119 | });
|
120 |
|
121 | it('runs resolvers for missing client queries with server data including fragments', done => {
|
122 | const query = gql`
|
123 | fragment client on ClientData {
|
124 | bar
|
125 | }
|
126 |
|
127 | query Mixed {
|
128 | foo @client {
|
129 | ...client
|
130 | }
|
131 | bar {
|
132 | baz
|
133 | }
|
134 | }
|
135 | `;
|
136 | const sample = new ApolloLink(() =>
|
137 | Observable.of({ data: { bar: { baz: true } } }),
|
138 | );
|
139 | const client = withClientState({ resolvers });
|
140 | execute(client.concat(sample), { query }).subscribe(({ data }) => {
|
141 | try {
|
142 | expect(data).toEqual({ foo: { bar: true }, bar: { baz: true } });
|
143 | } catch (e) {
|
144 | done.fail(e);
|
145 | }
|
146 | done();
|
147 | }, done.fail);
|
148 | });
|
149 |
|
150 | it('runs resolvers for missing client queries with variables', done => {
|
151 | const query = gql`
|
152 | query WithVariables($id: ID!) {
|
153 | foo @client {
|
154 | bar(id: $id)
|
155 | }
|
156 | }
|
157 | `;
|
158 | const client = withClientState({
|
159 | resolvers: {
|
160 | Query: {
|
161 | foo: () => ({ __typename: 'Foo' }),
|
162 | },
|
163 | Foo: {
|
164 | bar: (data, { id }) => id,
|
165 | },
|
166 | },
|
167 | });
|
168 | execute(client, { query, variables: { id: 1 } }).subscribe(({ data }) => {
|
169 | try {
|
170 | expect(data).toEqual({ foo: { bar: 1 } });
|
171 | } catch (error) {
|
172 | done.fail(error);
|
173 | }
|
174 | done();
|
175 | }, done.fail);
|
176 | });
|
177 |
|
178 | it('passes context to client resolvers', done => {
|
179 | const query = gql`
|
180 | query WithContext {
|
181 | foo @client {
|
182 | bar
|
183 | }
|
184 | }
|
185 | `;
|
186 | const client = withClientState({
|
187 | resolvers: {
|
188 | Query: {
|
189 | foo: () => ({ __typename: 'Foo' }),
|
190 | },
|
191 | Foo: {
|
192 | bar: (data, _, { id }) => id,
|
193 | },
|
194 | },
|
195 | });
|
196 | execute(client, { query, context: { id: 1 } }).subscribe(({ data }) => {
|
197 | try {
|
198 | expect(data).toEqual({ foo: { bar: 1 } });
|
199 | } catch (error) {
|
200 | done.fail(error);
|
201 | }
|
202 | done();
|
203 | }, done.fail);
|
204 | });
|
205 |
|
206 | it('calls resolvers on each request if the prop is a function', done => {
|
207 | const query = gql`
|
208 | query WithContext {
|
209 | foo @client {
|
210 | bar
|
211 | }
|
212 | }
|
213 | `;
|
214 | const resolversSpy = jest.fn();
|
215 | const resolvers = () => {
|
216 | resolversSpy();
|
217 | return {
|
218 | Query: {
|
219 | foo: () => ({ __typename: 'Foo' }),
|
220 | },
|
221 | Foo: {
|
222 | bar: () => 1,
|
223 | },
|
224 | };
|
225 | };
|
226 |
|
227 | const client = withClientState({
|
228 | resolvers,
|
229 | });
|
230 |
|
231 |
|
232 | execute(client, { query }).subscribe(({ data }) => {
|
233 | expect(data).toEqual({ foo: { bar: 1 } });
|
234 |
|
235 |
|
236 | execute(client, { query }).subscribe(({ data }) => {
|
237 | expect(data).toEqual({ foo: { bar: 1 } });
|
238 | expect(resolversSpy).toHaveBeenCalledTimes(2);
|
239 | done();
|
240 | }, done.fail);
|
241 | }, done.fail);
|
242 | });
|