]> git.r.bdr.sh - rbdr/forum/commitdiff
Add posts store pact test
authorRuben Beltran del Rio <redacted>
Sun, 2 May 2021 17:53:10 +0000 (19:53 +0200)
committerRuben Beltran del Rio <redacted>
Sun, 2 May 2021 17:53:10 +0000 (19:53 +0200)
package.json
pacts/forumclient-forumserver.json [moved from pacts/forumsstore-forumapiserver.json with 61% similarity]
src/stores/forums.test.js
src/stores/posts.test.js [new file with mode: 0644]

index c76c68181c879824df5ef9b4de5ef06292d0a63c..0e47818b7f7cb014082a44e82dbe7ac580fb3c4f 100644 (file)
@@ -6,7 +6,7 @@
                "build": "svelte-kit build",
                "start": "svelte-kit start",
                "lint": "eslint --fix .",
-               "test": "jest src",
+               "test": "jest src --runInBand",
                "test:watch": "npm run test -- --watch"
        },
        "devDependencies": {
similarity index 61%
rename from pacts/forumsstore-forumapiserver.json
rename to pacts/forumclient-forumserver.json
index c0e784bd26965e4f00d101a26590f711be397acd..b1c7fcbc06839cb8db9dd5471a613de33cab83a4 100644 (file)
 {
   "consumer": {
-    "name": "ForumsStore"
+    "name": "ForumClient"
   },
   "provider": {
-    "name": "ForumAPIServer"
+    "name": "ForumServer"
   },
   "interactions": [
+    {
+      "description": "a request to get a single post",
+      "providerState": "there's data",
+      "request": {
+        "method": "POST",
+        "path": "/graphql",
+        "headers": {
+          "content-type": "application/json"
+        },
+        "body": {
+          "operationName": "GetPost",
+          "query": "query GetPost($id: ID!) {\n              post(id: $id) {\n                id\n                text\n                created_at\n                author {\n                  id\n                  handle\n                  __typename\n                }\n                topic {\n                  id\n                  title\n                  __typename\n                }\n                __typename\n              }\n            }",
+          "variables": {
+            "id": "freezer"
+          }
+        },
+        "matchingRules": {
+          "$.body.query": {
+            "match": "regex",
+            "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+          }
+        }
+      },
+      "response": {
+        "status": 200,
+        "headers": {
+          "Content-Type": "application/json; charset=utf-8"
+        },
+        "body": {
+          "data": {
+            "post": {
+              "id": "8f75eba5-6989-4dd3-b466-e464546ce374",
+              "text": "This is a very pacty post",
+              "created_at": 1619976194937,
+              "author": {
+                "id": "a805b3de-cac4-451c-a1e6-f078869c9db9",
+                "handle": "pacts_person"
+              },
+              "topic": {
+                "id": "5c283ce1-0470-4b98-86f5-1fec9a22c9ac",
+                "title": "The parent pacts topic"
+              }
+            }
+          }
+        },
+        "matchingRules": {
+          "$.body.data.post": {
+            "match": "type"
+          },
+          "$.body.data.post.id": {
+            "match": "type"
+          },
+          "$.body.data.post.text": {
+            "match": "type"
+          },
+          "$.body.data.post.created_at": {
+            "match": "type"
+          },
+          "$.body.data.post.author": {
+            "match": "type"
+          },
+          "$.body.data.post.author.id": {
+            "match": "type"
+          },
+          "$.body.data.post.author.handle": {
+            "match": "type"
+          },
+          "$.body.data.post.topic": {
+            "match": "type"
+          },
+          "$.body.data.post.topic.id": {
+            "match": "type"
+          },
+          "$.body.data.post.topic.title": {
+            "match": "type"
+          }
+        }
+      }
+    },
+    {
+      "description": "a request to get a single post",
+      "providerState": "there's no data",
+      "request": {
+        "method": "POST",
+        "path": "/graphql",
+        "headers": {
+          "content-type": "application/json"
+        },
+        "body": {
+          "operationName": "GetPost",
+          "query": "query GetPost($id: ID!) {\n              post(id: $id) {\n                id\n                text\n                created_at\n                author {\n                  id\n                  handle\n                  __typename\n                }\n                topic {\n                  id\n                  title\n                  __typename\n                }\n                __typename\n              }\n            }",
+          "variables": {
+            "id": "freezer"
+          }
+        },
+        "matchingRules": {
+          "$.body.query": {
+            "match": "regex",
+            "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+          }
+        }
+      },
+      "response": {
+        "status": 200,
+        "headers": {
+          "Content-Type": "application/json; charset=utf-8"
+        },
+        "body": {
+          "data": {
+            "post": null
+          }
+        }
+      }
+    },
+    {
+      "description": "a request to get a single post",
+      "providerState": "there's an error",
+      "request": {
+        "method": "POST",
+        "path": "/graphql",
+        "headers": {
+          "content-type": "application/json"
+        },
+        "body": {
+          "operationName": "GetPost",
+          "query": "query GetPost($id: ID!) {\n              post(id: $id) {\n                id\n                text\n                created_at\n                author {\n                  id\n                  handle\n                  __typename\n                }\n                topic {\n                  id\n                  title\n                  __typename\n                }\n                __typename\n              }\n            }",
+          "variables": {
+            "id": "freezer"
+          }
+        },
+        "matchingRules": {
+          "$.body.query": {
+            "match": "regex",
+            "regex": "query\\s*GetPost\\(\\$id:\\s*ID!\\)\\s*\\{\\s*post\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*topic\\s*\\{\\s*id\\s*title\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+          }
+        }
+      },
+      "response": {
+        "status": 500,
+        "headers": {
+        }
+      }
+    },
     {
       "description": "a request to list the forums",
-      "providerState": "there's forums",
+      "providerState": "there's data",
       "request": {
         "method": "POST",
         "path": "/graphql",
     },
     {
       "description": "a request to get a single forum",
-      "providerState": "there's forums",
+      "providerState": "there's data",
       "request": {
         "method": "POST",
         "path": "/graphql",
     },
     {
       "description": "a request to list the forums",
-      "providerState": "there's no forums",
+      "providerState": "there's no data",
       "request": {
         "method": "POST",
         "path": "/graphql",
     },
     {
       "description": "a request to get a single forum",
-      "providerState": "there's no forums",
+      "providerState": "there's no data",
       "request": {
         "method": "POST",
         "path": "/graphql",
index e117828dddc1d1dcded15ae77db16ca459776332..eb4bc071bf77d930127fa5d2e2ee760815466d2d 100644 (file)
@@ -20,8 +20,9 @@ describe('Forums store pact', () => {
     internals.provider = new Pact({
       port: 1234,
       dir: resolve(process.cwd(), 'pacts'),
-      consumer: 'ForumsStore',
-      provider: 'ForumAPIServer'
+      consumer: 'ForumClient',
+      provider: 'ForumServer',
+      pactfileWriteMode: 'update'
     });
 
     await internals.provider.setup();
@@ -30,14 +31,14 @@ describe('Forums store pact', () => {
   afterEach(() => internals.provider.verify());
   afterAll(() => internals.provider.finalize());
 
-  describe('When there\'s forums', () => {
+  describe('When there\'s data', () => {
 
     describe('GetForums', () => {
 
       beforeAll(async () => {
 
         const forumQuery = new GraphQLInteraction()
-          .given('there\'s forums')
+          .given('there\'s data')
           .uponReceiving('a request to list the forums')
           .withRequest({
             path: '/graphql',
@@ -106,7 +107,7 @@ describe('Forums store pact', () => {
       beforeAll(async () => {
 
         const forumQuery = new GraphQLInteraction()
-          .given('there\'s forums')
+          .given('there\'s data')
           .uponReceiving('a request to get a single forum')
           .withRequest({
             path: '/graphql',
@@ -189,14 +190,14 @@ describe('Forums store pact', () => {
     });
   });
 
-  describe('When there\'s no forums', () => {
+  describe('When there\'s no data', () => {
 
     describe('GetForums', () => {
 
       beforeAll(async () => {
 
         const forumQuery = new GraphQLInteraction()
-          .given('there\'s no forums')
+          .given('there\'s no data')
           .uponReceiving('a request to list the forums')
           .withRequest({
             path: '/graphql',
@@ -256,7 +257,7 @@ describe('Forums store pact', () => {
       beforeAll(async () => {
 
         const forumQuery = new GraphQLInteraction()
-          .given('there\'s no forums')
+          .given('there\'s no data')
           .uponReceiving('a request to get a single forum')
           .withRequest({
             path: '/graphql',
diff --git a/src/stores/posts.test.js b/src/stores/posts.test.js
new file mode 100644 (file)
index 0000000..acd843c
--- /dev/null
@@ -0,0 +1,265 @@
+import { GraphQLInteraction, Pact, Matchers } from '@pact-foundation/pact';
+import { resolve } from 'path';
+
+import { resolveAfter } from '$/utils/resolve_after';
+
+const { eachLike, like } = Matchers;
+
+jest.mock('$/config/config.js');
+
+import { getPost } from './posts';
+
+const internals = {
+  provider: null
+};
+
+describe('Posts store pact', () => {
+
+  beforeAll(async () => {
+
+    internals.provider = new Pact({
+      port: 1234,
+      dir: resolve(process.cwd(), 'pacts'),
+      consumer: 'ForumClient',
+      provider: 'ForumServer',
+      pactfileWriteMode: 'update'
+    });
+
+    await internals.provider.setup();
+  });
+
+  afterEach(() => internals.provider.verify());
+  afterAll(() => internals.provider.finalize());
+
+  describe('When there\'s data', () => {
+
+    describe('GetPost', () => {
+
+      beforeAll(async () => {
+
+        const postQuery = new GraphQLInteraction()
+          .given('there\'s data')
+          .uponReceiving('a request to get a single post')
+          .withRequest({
+            path: '/graphql',
+            method: 'POST'
+          })
+          .withOperation('GetPost')
+          .withQuery(
+            `query GetPost($id: ID!) {
+              post(id: $id) {
+                id
+                text
+                created_at
+                author {
+                  id
+                  handle
+                  __typename
+                }
+                topic {
+                  id
+                  title
+                  __typename
+                }
+                __typename
+              }
+            }`
+          )
+          .withVariables({
+            id: 'freezer'
+          })
+          .willRespondWith({
+            status: 200,
+            headers: {
+              'Content-Type': 'application/json; charset=utf-8'
+            },
+            body: {
+              data: {
+                post: like({
+                  id: like('8f75eba5-6989-4dd3-b466-e464546ce374'),
+                  text: like('This is a very pacty post'),
+                  created_at: like(1619976194937),
+                  author: like({
+                    id: like('a805b3de-cac4-451c-a1e6-f078869c9db9'),
+                    handle: like('pacts_person')
+                  }),
+                  topic: like({
+                    id: like('5c283ce1-0470-4b98-86f5-1fec9a22c9ac'),
+                    title: like('The parent pacts topic')
+                  })
+                })
+              }
+            }
+          });
+        return await internals.provider.addInteraction(postQuery);
+      });
+
+      test('it returns the post', async () => {
+
+        const post = getPost('freezer');
+        const { counter, promise: resolveAfterTwo } = resolveAfter(2);
+        let response = null;
+        post.subscribe((postValue) => {
+
+          response = postValue;
+          counter();
+        });
+        expect(response.data).toBe(null);
+        expect(response.loading).toBe(true);
+        expect(response.error).toBe(undefined);
+        await resolveAfterTwo;
+        expect(response.data).toEqual({
+          id: '8f75eba5-6989-4dd3-b466-e464546ce374',
+          text: 'This is a very pacty post',
+          created_at: 1619976194937,
+          author: {
+            id: 'a805b3de-cac4-451c-a1e6-f078869c9db9',
+            handle: 'pacts_person'
+          },
+          topic: {
+            id: '5c283ce1-0470-4b98-86f5-1fec9a22c9ac',
+            title: 'The parent pacts topic'
+          }
+        });
+        expect(response.loading).toBe(false);
+        expect(response.error).toBe(undefined);
+      });
+    });
+  });
+
+  describe('When there\'s no data', () => {
+
+    describe('GetPost', () => {
+
+      beforeAll(async () => {
+
+        const postQuery = new GraphQLInteraction()
+          .given('there\'s no data')
+          .uponReceiving('a request to get a single post')
+          .withRequest({
+            path: '/graphql',
+            method: 'POST'
+          })
+          .withOperation('GetPost')
+          .withQuery(
+            `query GetPost($id: ID!) {
+              post(id: $id) {
+                id
+                text
+                created_at
+                author {
+                  id
+                  handle
+                  __typename
+                }
+                topic {
+                  id
+                  title
+                  __typename
+                }
+                __typename
+              }
+            }`
+          )
+          .withVariables({
+            id: 'freezer'
+          })
+          .willRespondWith({
+            status: 200,
+            headers: {
+              'Content-Type': 'application/json; charset=utf-8'
+            },
+            body: {
+              data: {
+                post: null
+              }
+            }
+          });
+        return await internals.provider.addInteraction(postQuery);
+      });
+
+      test('it returns the post', async () => {
+
+        const post = getPost('freezer');
+        const { counter, promise: resolveAfterTwo } = resolveAfter(2);
+        let response = null;
+        post.subscribe((postValue) => {
+
+          response = postValue;
+          counter();
+        });
+        expect(response.data).toBe(null);
+        expect(response.loading).toBe(true);
+        expect(response.error).toBe(undefined);
+        await resolveAfterTwo;
+        expect(response.data).toBe(null);
+        expect(response.loading).toBe(false);
+        expect(response.error).toBe(undefined);
+      });
+    });
+  });
+
+  describe('When there\'s an error', () => {
+
+    describe('GetPost', () => {
+
+      beforeAll(async () => {
+
+        const postQuery = new GraphQLInteraction()
+          .given('there\'s an error')
+          .uponReceiving('a request to get a single post')
+          .withRequest({
+            path: '/graphql',
+            method: 'POST'
+          })
+          .withOperation('GetPost')
+          .withQuery(
+            `query GetPost($id: ID!) {
+              post(id: $id) {
+                id
+                text
+                created_at
+                author {
+                  id
+                  handle
+                  __typename
+                }
+                topic {
+                  id
+                  title
+                  __typename
+                }
+                __typename
+              }
+            }`
+          )
+          .withVariables({
+            id: 'freezer'
+          })
+          .willRespondWith({
+            status: 500
+          });
+        return await internals.provider.addInteraction(postQuery);
+      });
+
+      test('it returns the error', async () => {
+
+        const post = getPost('freezer');
+        const { counter, promise: resolveAfterTwo } = resolveAfter(2);
+        let response = null;
+        post.subscribe((postValue) => {
+
+          response = postValue;
+          counter();
+        });
+        expect(response.data).toBe(null);
+        expect(response.loading).toBe(true);
+        expect(response.error).toBe(undefined);
+        await resolveAfterTwo;
+        expect(response.data).toBe(null);
+        expect(response.loading).toBe(false);
+        expect(response.error).toBeInstanceOf(Error);
+      });
+    });
+  });
+});