]> git.r.bdr.sh - rbdr/forum/blame - src/stores/posts.test.js
Add tests for actions + pacts for graphql errrors
[rbdr/forum] / src / stores / posts.test.js
CommitLineData
b15225c9
RBR
1import { GraphQLInteraction, Pact, Matchers } from '@pact-foundation/pact';
2import { resolve } from 'path';
3
4import { resolveAfter } from '$/utils/resolve_after';
5
26dfa00e 6const { eachLike, like } = Matchers;
b15225c9
RBR
7
8jest.mock('$/config/config.js');
9
10import { getPost } from './posts';
11
12const internals = {
13 provider: null
14};
15
16describe('Posts store pact', () => {
17
18 beforeAll(async () => {
19
20 internals.provider = new Pact({
21 port: 1234,
22 dir: resolve(process.cwd(), 'pacts'),
23 consumer: 'ForumClient',
24 provider: 'ForumServer',
25 pactfileWriteMode: 'update'
26 });
27
28 await internals.provider.setup();
29 });
30
31 afterEach(() => internals.provider.verify());
32 afterAll(() => internals.provider.finalize());
33
34 describe('When there\'s data', () => {
35
36 describe('GetPost', () => {
37
38 beforeAll(async () => {
39
40 const postQuery = new GraphQLInteraction()
41 .given('there\'s data')
42 .uponReceiving('a request to get a single post')
43 .withRequest({
44 path: '/graphql',
45 method: 'POST'
46 })
47 .withOperation('GetPost')
48 .withQuery(
49 `query GetPost($id: ID!) {
50 post(id: $id) {
51 id
52 text
53 created_at
54 author {
55 id
56 handle
57 __typename
58 }
59 topic {
60 id
61 title
62 __typename
63 }
64 __typename
65 }
66 }`
67 )
68 .withVariables({
5fc4715f 69 id: '8f75eba5-6989-4dd3-b466-e464546ce374'
b15225c9
RBR
70 })
71 .willRespondWith({
72 status: 200,
73 headers: {
74 'Content-Type': 'application/json; charset=utf-8'
75 },
76 body: {
77 data: {
78 post: like({
79 id: like('8f75eba5-6989-4dd3-b466-e464546ce374'),
80 text: like('This is a very pacty post'),
81 created_at: like(1619976194937),
82 author: like({
83 id: like('a805b3de-cac4-451c-a1e6-f078869c9db9'),
84 handle: like('pacts_person')
85 }),
86 topic: like({
87 id: like('5c283ce1-0470-4b98-86f5-1fec9a22c9ac'),
88 title: like('The parent pacts topic')
89 })
90 })
91 }
92 }
93 });
94 return await internals.provider.addInteraction(postQuery);
95 });
96
97 test('it returns the post', async () => {
98
5fc4715f 99 const post = getPost('8f75eba5-6989-4dd3-b466-e464546ce374');
b15225c9
RBR
100 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
101 let response = null;
102 post.subscribe((postValue) => {
103
104 response = postValue;
105 counter();
106 });
107 expect(response.data).toBe(null);
108 expect(response.loading).toBe(true);
109 expect(response.error).toBe(undefined);
110 await resolveAfterTwo;
111 expect(response.data).toEqual({
112 id: '8f75eba5-6989-4dd3-b466-e464546ce374',
113 text: 'This is a very pacty post',
114 created_at: 1619976194937,
115 author: {
116 id: 'a805b3de-cac4-451c-a1e6-f078869c9db9',
117 handle: 'pacts_person'
118 },
119 topic: {
120 id: '5c283ce1-0470-4b98-86f5-1fec9a22c9ac',
121 title: 'The parent pacts topic'
122 }
123 });
124 expect(response.loading).toBe(false);
125 expect(response.error).toBe(undefined);
126 });
127 });
128 });
129
130 describe('When there\'s no data', () => {
131
132 describe('GetPost', () => {
133
134 beforeAll(async () => {
135
136 const postQuery = new GraphQLInteraction()
137 .given('there\'s no data')
138 .uponReceiving('a request to get a single post')
139 .withRequest({
140 path: '/graphql',
141 method: 'POST'
142 })
143 .withOperation('GetPost')
144 .withQuery(
145 `query GetPost($id: ID!) {
146 post(id: $id) {
147 id
148 text
149 created_at
150 author {
151 id
152 handle
153 __typename
154 }
155 topic {
156 id
157 title
158 __typename
159 }
160 __typename
161 }
162 }`
163 )
164 .withVariables({
5fc4715f 165 id: '8f75eba5-6989-4dd3-b466-e464546ce374'
b15225c9
RBR
166 })
167 .willRespondWith({
168 status: 200,
169 headers: {
170 'Content-Type': 'application/json; charset=utf-8'
171 },
172 body: {
173 data: {
174 post: null
175 }
176 }
177 });
178 return await internals.provider.addInteraction(postQuery);
179 });
180
181 test('it returns the post', async () => {
182
5fc4715f 183 const post = getPost('8f75eba5-6989-4dd3-b466-e464546ce374');
b15225c9
RBR
184 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
185 let response = null;
186 post.subscribe((postValue) => {
187
188 response = postValue;
189 counter();
190 });
191 expect(response.data).toBe(null);
192 expect(response.loading).toBe(true);
193 expect(response.error).toBe(undefined);
194 await resolveAfterTwo;
195 expect(response.data).toBe(null);
196 expect(response.loading).toBe(false);
197 expect(response.error).toBe(undefined);
198 });
199 });
200 });
201
26dfa00e 202 describe('When there\'s a server error', () => {
b15225c9
RBR
203
204 describe('GetPost', () => {
205
206 beforeAll(async () => {
207
208 const postQuery = new GraphQLInteraction()
26dfa00e 209 .given('there\'s a server error')
b15225c9
RBR
210 .uponReceiving('a request to get a single post')
211 .withRequest({
212 path: '/graphql',
213 method: 'POST'
214 })
215 .withOperation('GetPost')
216 .withQuery(
217 `query GetPost($id: ID!) {
218 post(id: $id) {
219 id
220 text
221 created_at
222 author {
223 id
224 handle
225 __typename
226 }
227 topic {
228 id
229 title
230 __typename
231 }
232 __typename
233 }
234 }`
235 )
236 .withVariables({
5fc4715f 237 id: '8f75eba5-6989-4dd3-b466-e464546ce374'
b15225c9
RBR
238 })
239 .willRespondWith({
240 status: 500
241 });
242 return await internals.provider.addInteraction(postQuery);
243 });
244
245 test('it returns the error', async () => {
246
5fc4715f 247 const post = getPost('8f75eba5-6989-4dd3-b466-e464546ce374');
b15225c9
RBR
248 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
249 let response = null;
250 post.subscribe((postValue) => {
251
252 response = postValue;
253 counter();
254 });
255 expect(response.data).toBe(null);
256 expect(response.loading).toBe(true);
257 expect(response.error).toBe(undefined);
258 await resolveAfterTwo;
259 expect(response.data).toBe(null);
260 expect(response.loading).toBe(false);
261 expect(response.error).toBeInstanceOf(Error);
262 });
263 });
264 });
26dfa00e
RBR
265
266 describe('When there\'s an error in the response', () => {
267
268 describe('GetPost', () => {
269
270 beforeAll(async () => {
271
272 const postQuery = new GraphQLInteraction()
273 .given('there\'s an error in the response')
274 .uponReceiving('a request to get a single post')
275 .withRequest({
276 path: '/graphql',
277 method: 'POST'
278 })
279 .withOperation('GetPost')
280 .withQuery(
281 `query GetPost($id: ID!) {
282 post(id: $id) {
283 id
284 text
285 created_at
286 author {
287 id
288 handle
289 __typename
290 }
291 topic {
292 id
293 title
294 __typename
295 }
296 __typename
297 }
298 }`
299 )
300 .withVariables({
301 id: '8f75eba5-6989-4dd3-b466-e464546ce374'
302 })
303 .willRespondWith({
304 status: 200,
305 headers: {
306 'Content-Type': 'application/json; charset=utf-8'
307 },
308 body: {
309 errors: eachLike({
310 message: like('An error occurred when fetching the post')
311 })
312 }
313 });
314 return await internals.provider.addInteraction(postQuery);
315 });
316
317 test('it returns the error', async () => {
318
319 const post = getPost('8f75eba5-6989-4dd3-b466-e464546ce374');
320 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
321 let response = null;
322 post.subscribe((postValue) => {
323
324 response = postValue;
325 counter();
326 });
327 expect(response.data).toBe(null);
328 expect(response.loading).toBe(true);
329 expect(response.error).toBe(undefined);
330 await resolveAfterTwo;
331 expect(response.data).toBe(null);
332 expect(response.loading).toBe(false);
333 expect(response.error.graphQLErrors).toEqual(expect.arrayContaining([{
334 message: 'An error occurred when fetching the post'
335 }]));
336 });
337 });
338 });
b15225c9 339});