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