]> git.r.bdr.sh - rbdr/forum/blame - src/lib/stores/topics.test.ts
Start migration to supabase
[rbdr/forum] / src / lib / stores / topics.test.ts
CommitLineData
3435a35c
RBR
1import { GraphQLInteraction, Pact, Matchers } from '@pact-foundation/pact';
2import { resolve } from 'path';
3
a7cf03c1 4import { resolveAfter } from '$lib/utils/resolve_after';
3435a35c
RBR
5
6const { eachLike, like } = Matchers;
7
a7cf03c1 8jest.mock('$lib/config/config.ts');
3435a35c
RBR
9
10import { getTopic } from './topics';
11
12const internals = {
cac85db0 13 provider: null
3435a35c
RBR
14};
15
16describe('Topics store pact', () => {
cac85db0
RBR
17 beforeAll(async () => {
18 internals.provider = new Pact({
19 port: 1234,
20 dir: resolve(process.cwd(), 'pacts'),
21 consumer: 'ForumClient',
22 provider: 'ForumServer',
23 pactfileWriteMode: 'update'
24 });
25
26 await internals.provider.setup();
27 });
28
29 afterEach(() => internals.provider.verify());
30 afterAll(() => internals.provider.finalize());
31
32 describe("When there's data", () => {
33 describe('GetTopic', () => {
34 beforeAll(async () => {
35 const topicQuery = new GraphQLInteraction()
36 .given("there's data")
37 .uponReceiving('a request to get a single topic')
38 .withRequest({
39 path: '/graphql',
40 method: 'POST'
41 })
42 .withOperation('GetTopic')
43 .withQuery(
44 `query GetTopic($id: ID!) {
3435a35c
RBR
45 topic(id: $id) {
46 id
47 title
48 updated_at
49 ttl
50 forum {
51 id
52 glyph
53 label
54 __typename
55 }
56 tags {
57 id
58 weight
59 __typename
60 }
61 posts {
62 id
63 text
64 created_at
65 author {
66 id
67 handle
68 __typename
69 }
70 __typename
71 }
72 __typename
73 }
74 }`
cac85db0
RBR
75 )
76 .withVariables({
77 id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1'
78 })
79 .willRespondWith({
80 status: 200,
81 headers: {
82 'Content-Type': 'application/json; charset=utf-8'
83 },
84 body: {
85 data: {
86 topic: {
87 id: like('0b58959d-d448-4a4e-84b6-35e5ac0028d1'),
88 title: like('The pacty topic of the day'),
89 updated_at: like(1619979888906),
90 ttl: like(3399),
91 forum: {
92 id: like('cucumber'),
93 glyph: like('✽'),
94 label: like('test_forums.cucumber')
95 },
96 tags: eachLike({
97 id: like('skunk'),
98 weight: like(44)
99 }),
100 posts: eachLike({
101 id: like('ed93530e-6f9c-4701-91ef-14f9e0ed3e26'),
102 text: like('The content of this post is very relevant'),
103 created_at: like(1619979889798),
104 author: like({
105 id: like('07fb2ba0-0945-464a-b215-873296710c8c'),
106 handle: like('cucumber_fan92')
107 })
108 })
109 }
110 }
111 }
112 });
113 return await internals.provider.addInteraction(topicQuery);
114 });
115
116 test('it returns the topic', async () => {
117 const topic = getTopic('0b58959d-d448-4a4e-84b6-35e5ac0028d1');
118 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
119 let response = null;
120 topic.subscribe((topicValue) => {
121 response = topicValue;
122 counter();
123 });
124 expect(response.data).toBe(null);
125 expect(response.loading).toBe(true);
126 expect(response.error).toBe(undefined);
127 await resolveAfterTwo;
128 expect(response.data).toEqual({
129 id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1',
130 title: 'The pacty topic of the day',
131 updated_at: 1619979888906,
132 ttl: 3399,
133 forum: {
134 id: 'cucumber',
135 glyph: '✽',
136 label: 'test_forums.cucumber'
137 },
138 tags: [
139 {
140 id: 'skunk',
141 weight: 44
142 }
143 ],
144 posts: [
145 {
146 id: 'ed93530e-6f9c-4701-91ef-14f9e0ed3e26',
147 text: 'The content of this post is very relevant',
148 created_at: 1619979889798,
149 author: {
150 id: '07fb2ba0-0945-464a-b215-873296710c8c',
151 handle: 'cucumber_fan92'
152 }
153 }
154 ]
155 });
156 expect(response.loading).toBe(false);
157 expect(response.error).toBe(undefined);
158 });
159 });
160 });
161
162 describe("When there's no data", () => {
163 describe('GetTopic', () => {
164 beforeAll(async () => {
165 const topicQuery = new GraphQLInteraction()
166 .given("there's no data")
167 .uponReceiving('a request to get a single topic')
168 .withRequest({
169 path: '/graphql',
170 method: 'POST'
171 })
172 .withOperation('GetTopic')
173 .withQuery(
174 `query GetTopic($id: ID!) {
3435a35c
RBR
175 topic(id: $id) {
176 id
177 title
178 updated_at
179 ttl
180 forum {
181 id
182 glyph
183 label
184 __typename
185 }
186 tags {
187 id
188 weight
189 __typename
190 }
191 posts {
192 id
193 text
194 created_at
195 author {
196 id
197 handle
198 __typename
199 }
200 __typename
201 }
202 __typename
203 }
204 }`
cac85db0
RBR
205 )
206 .withVariables({
207 id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1'
208 })
209 .willRespondWith({
210 status: 200,
211 headers: {
212 'Content-Type': 'application/json; charset=utf-8'
213 },
214 body: {
215 data: {
216 topic: null
217 }
218 }
219 });
220 return await internals.provider.addInteraction(topicQuery);
221 });
222
223 test('it returns the topic', async () => {
224 const topic = getTopic('0b58959d-d448-4a4e-84b6-35e5ac0028d1');
225 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
226 let response = null;
227 topic.subscribe((topicValue) => {
228 response = topicValue;
229 counter();
230 });
231 expect(response.data).toBe(null);
232 expect(response.loading).toBe(true);
233 expect(response.error).toBe(undefined);
234 await resolveAfterTwo;
235 expect(response.data).toBe(null);
236 expect(response.loading).toBe(false);
237 expect(response.error).toBe(undefined);
238 });
239 });
240 });
241
242 describe("When there's a server error", () => {
243 describe('GetTopic', () => {
244 beforeAll(async () => {
245 const topicQuery = new GraphQLInteraction()
246 .given("there's a server error")
247 .uponReceiving('a request to get a single topic')
248 .withRequest({
249 path: '/graphql',
250 method: 'POST'
251 })
252 .withOperation('GetTopic')
253 .withQuery(
254 `query GetTopic($id: ID!) {
3435a35c
RBR
255 topic(id: $id) {
256 id
257 title
258 updated_at
259 ttl
260 forum {
261 id
262 glyph
263 label
264 __typename
265 }
266 tags {
267 id
268 weight
269 __typename
270 }
271 posts {
272 id
273 text
274 created_at
275 author {
276 id
277 handle
278 __typename
279 }
280 __typename
281 }
282 __typename
283 }
284 }`
cac85db0
RBR
285 )
286 .withVariables({
287 id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1'
288 })
289 .willRespondWith({
290 status: 500
291 });
292 return await internals.provider.addInteraction(topicQuery);
293 });
294
295 test('it returns the error', async () => {
296 const topic = getTopic('0b58959d-d448-4a4e-84b6-35e5ac0028d1');
297 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
298 let response = null;
299 topic.subscribe((topicValue) => {
300 response = topicValue;
301 counter();
302 });
303 expect(response.data).toBe(null);
304 expect(response.loading).toBe(true);
305 expect(response.error).toBe(undefined);
306 await resolveAfterTwo;
307 expect(response.data).toBe(null);
308 expect(response.loading).toBe(false);
309 expect(response.error).toBeInstanceOf(Error);
310 });
311 });
312 });
313
314 describe("When there's an error in the response", () => {
315 describe('GetTopic', () => {
316 beforeAll(async () => {
317 const topicQuery = new GraphQLInteraction()
318 .given("there's an error in the response")
319 .uponReceiving('a request to get a single topic')
320 .withRequest({
321 path: '/graphql',
322 method: 'POST'
323 })
324 .withOperation('GetTopic')
325 .withQuery(
326 `query GetTopic($id: ID!) {
26dfa00e
RBR
327 topic(id: $id) {
328 id
329 title
330 updated_at
331 ttl
332 forum {
333 id
334 glyph
335 label
336 __typename
337 }
338 tags {
339 id
340 weight
341 __typename
342 }
343 posts {
344 id
345 text
346 created_at
347 author {
348 id
349 handle
350 __typename
351 }
352 __typename
353 }
354 __typename
355 }
356 }`
cac85db0
RBR
357 )
358 .withVariables({
359 id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1'
360 })
361 .willRespondWith({
362 status: 200,
363 headers: {
364 'Content-Type': 'application/json; charset=utf-8'
365 },
366 body: {
367 errors: eachLike({
368 message: like('An error occurred when fetching the topic')
369 })
370 }
371 });
372 return await internals.provider.addInteraction(topicQuery);
373 });
374
375 test('it returns the error', async () => {
376 const topic = getTopic('0b58959d-d448-4a4e-84b6-35e5ac0028d1');
377 const { counter, promise: resolveAfterTwo } = resolveAfter(2);
378 let response = null;
379 topic.subscribe((topicValue) => {
380 response = topicValue;
381 counter();
382 });
383 expect(response.data).toBe(null);
384 expect(response.loading).toBe(true);
385 expect(response.error).toBe(undefined);
386 await resolveAfterTwo;
387 expect(response.data).toBe(null);
388 expect(response.loading).toBe(false);
389 expect(response.error.graphQLErrors).toEqual(
390 expect.arrayContaining([
391 {
392 message: 'An error occurred when fetching the topic'
393 }
394 ])
395 );
396 });
397 });
398 });
3435a35c 399});