]> git.r.bdr.sh - rbdr/forum/commitdiff
Add topics store pact tests
authorRuben Beltran del Rio <redacted>
Sun, 2 May 2021 18:39:30 +0000 (20:39 +0200)
committerRuben Beltran del Rio <redacted>
Sun, 2 May 2021 18:39:30 +0000 (20:39 +0200)
pacts/forumclient-forumserver.json
src/stores/topics.test.js [new file with mode: 0644]

index 3933bccffb7a932fd69599e6f8a0ba9edf00854d..337ff86fb4ef6653fadfbbd1bbab120d433a49a7 100644 (file)
         "headers": {
         }
       }
+    },
+    {
+      "description": "a request to get a single topic",
+      "providerState": "there's data",
+      "request": {
+        "method": "POST",
+        "path": "/graphql",
+        "headers": {
+          "content-type": "application/json"
+        },
+        "body": {
+          "operationName": "GetTopic",
+          "query": "query GetTopic($id: ID!) {\n              topic(id: $id) {\n                id\n                title\n                updated_at\n                ttl\n                forum {\n                  id\n                  glyph\n                  label\n                  __typename\n                }\n                tags {\n                  id\n                  weight\n                  __typename\n                }\n                posts {\n                  id\n                  text\n                  created_at\n                  author {\n                    id\n                    handle\n                    __typename\n                  }\n                  __typename\n                }\n                __typename\n              }\n            }",
+          "variables": {
+            "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
+          }
+        },
+        "matchingRules": {
+          "$.body.query": {
+            "match": "regex",
+            "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+          }
+        }
+      },
+      "response": {
+        "status": 200,
+        "headers": {
+          "Content-Type": "application/json; charset=utf-8"
+        },
+        "body": {
+          "data": {
+            "topic": {
+              "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1",
+              "title": "The pacty topic of the day",
+              "updated_at": 1619979888906,
+              "ttl": 3399,
+              "forum": {
+                "id": "cucumber",
+                "glyph": "✽",
+                "label": "test_forums.cucumber"
+              },
+              "tags": [
+                {
+                  "id": "skunk",
+                  "weight": 44
+                }
+              ],
+              "posts": [
+                {
+                  "id": "ed93530e-6f9c-4701-91ef-14f9e0ed3e26",
+                  "text": "The content of this post is very relevant",
+                  "created_at": 1619979889798,
+                  "author": {
+                    "id": "07fb2ba0-0945-464a-b215-873296710c8c",
+                    "handle": "cucumber_fan92"
+                  }
+                }
+              ]
+            }
+          }
+        },
+        "matchingRules": {
+          "$.body.data.topic.id": {
+            "match": "type"
+          },
+          "$.body.data.topic.title": {
+            "match": "type"
+          },
+          "$.body.data.topic.updated_at": {
+            "match": "type"
+          },
+          "$.body.data.topic.ttl": {
+            "match": "type"
+          },
+          "$.body.data.topic.forum.id": {
+            "match": "type"
+          },
+          "$.body.data.topic.forum.glyph": {
+            "match": "type"
+          },
+          "$.body.data.topic.forum.label": {
+            "match": "type"
+          },
+          "$.body.data.topic.tags": {
+            "min": 1
+          },
+          "$.body.data.topic.tags[*].*": {
+            "match": "type"
+          },
+          "$.body.data.topic.tags[*].id": {
+            "match": "type"
+          },
+          "$.body.data.topic.tags[*].weight": {
+            "match": "type"
+          },
+          "$.body.data.topic.posts": {
+            "min": 1
+          },
+          "$.body.data.topic.posts[*].*": {
+            "match": "type"
+          },
+          "$.body.data.topic.posts[*].id": {
+            "match": "type"
+          },
+          "$.body.data.topic.posts[*].text": {
+            "match": "type"
+          },
+          "$.body.data.topic.posts[*].created_at": {
+            "match": "type"
+          },
+          "$.body.data.topic.posts[*].author": {
+            "match": "type"
+          },
+          "$.body.data.topic.posts[*].author.id": {
+            "match": "type"
+          },
+          "$.body.data.topic.posts[*].author.handle": {
+            "match": "type"
+          }
+        }
+      }
+    },
+    {
+      "description": "a request to get a single topic",
+      "providerState": "there's no data",
+      "request": {
+        "method": "POST",
+        "path": "/graphql",
+        "headers": {
+          "content-type": "application/json"
+        },
+        "body": {
+          "operationName": "GetTopic",
+          "query": "query GetTopic($id: ID!) {\n              topic(id: $id) {\n                id\n                title\n                updated_at\n                ttl\n                forum {\n                  id\n                  glyph\n                  label\n                  __typename\n                }\n                tags {\n                  id\n                  weight\n                  __typename\n                }\n                posts {\n                  id\n                  text\n                  created_at\n                  author {\n                    id\n                    handle\n                    __typename\n                  }\n                  __typename\n                }\n                __typename\n              }\n            }",
+          "variables": {
+            "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
+          }
+        },
+        "matchingRules": {
+          "$.body.query": {
+            "match": "regex",
+            "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+          }
+        }
+      },
+      "response": {
+        "status": 200,
+        "headers": {
+          "Content-Type": "application/json; charset=utf-8"
+        },
+        "body": {
+          "data": {
+            "topic": null
+          }
+        }
+      }
+    },
+    {
+      "description": "a request to get a single topic",
+      "providerState": "there's an error",
+      "request": {
+        "method": "POST",
+        "path": "/graphql",
+        "headers": {
+          "content-type": "application/json"
+        },
+        "body": {
+          "operationName": "GetTopic",
+          "query": "query GetTopic($id: ID!) {\n              topic(id: $id) {\n                id\n                title\n                updated_at\n                ttl\n                forum {\n                  id\n                  glyph\n                  label\n                  __typename\n                }\n                tags {\n                  id\n                  weight\n                  __typename\n                }\n                posts {\n                  id\n                  text\n                  created_at\n                  author {\n                    id\n                    handle\n                    __typename\n                  }\n                  __typename\n                }\n                __typename\n              }\n            }",
+          "variables": {
+            "id": "0b58959d-d448-4a4e-84b6-35e5ac0028d1"
+          }
+        },
+        "matchingRules": {
+          "$.body.query": {
+            "match": "regex",
+            "regex": "query\\s*GetTopic\\(\\$id:\\s*ID!\\)\\s*\\{\\s*topic\\(id:\\s*\\$id\\)\\s*\\{\\s*id\\s*title\\s*updated_at\\s*ttl\\s*forum\\s*\\{\\s*id\\s*glyph\\s*label\\s*__typename\\s*\\}\\s*tags\\s*\\{\\s*id\\s*weight\\s*__typename\\s*\\}\\s*posts\\s*\\{\\s*id\\s*text\\s*created_at\\s*author\\s*\\{\\s*id\\s*handle\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*__typename\\s*\\}\\s*\\}"
+          }
+        }
+      },
+      "response": {
+        "status": 500,
+        "headers": {
+        }
+      }
     }
   ],
   "metadata": {
diff --git a/src/stores/topics.test.js b/src/stores/topics.test.js
new file mode 100644 (file)
index 0000000..280bddb
--- /dev/null
@@ -0,0 +1,326 @@
+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 { getTopic } from './topics';
+
+const internals = {
+  provider: null
+};
+
+describe('Topics 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('GetTopic', () => {
+
+      beforeAll(async () => {
+
+        const topicQuery = new GraphQLInteraction()
+          .given('there\'s data')
+          .uponReceiving('a request to get a single topic')
+          .withRequest({
+            path: '/graphql',
+            method: 'POST'
+          })
+          .withOperation('GetTopic')
+          .withQuery(
+            `query GetTopic($id: ID!) {
+              topic(id: $id) {
+                id
+                title
+                updated_at
+                ttl
+                forum {
+                  id
+                  glyph
+                  label
+                  __typename
+                }
+                tags {
+                  id
+                  weight
+                  __typename
+                }
+                posts {
+                  id
+                  text
+                  created_at
+                  author {
+                    id
+                    handle
+                    __typename
+                  }
+                  __typename
+                }
+                __typename
+              }
+            }`
+          )
+          .withVariables({
+            id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1'
+          })
+          .willRespondWith({
+            status: 200,
+            headers: {
+              'Content-Type': 'application/json; charset=utf-8'
+            },
+            body: {
+              data: {
+                topic: {
+                  id: like('0b58959d-d448-4a4e-84b6-35e5ac0028d1'),
+                  title: like('The pacty topic of the day'),
+                  updated_at: like(1619979888906),
+                  ttl: like(3399),
+                  forum: {
+                    id: like('cucumber'),
+                    glyph: like('✽'),
+                    label: like('test_forums.cucumber')
+                  },
+                  tags: eachLike({
+                    id: like('skunk'),
+                    weight: like(44)
+                  }),
+                  posts: eachLike({
+                    id: like('ed93530e-6f9c-4701-91ef-14f9e0ed3e26'),
+                    text: like('The content of this post is very relevant'),
+                    created_at: like(1619979889798),
+                    author: like({
+                      id: like('07fb2ba0-0945-464a-b215-873296710c8c'),
+                      handle: like('cucumber_fan92')
+                    })
+                  })
+                }
+              }
+            }
+          });
+        return await internals.provider.addInteraction(topicQuery);
+      });
+
+      test('it returns the topic', async () => {
+
+        const topic = getTopic('0b58959d-d448-4a4e-84b6-35e5ac0028d1');
+        const { counter, promise: resolveAfterTwo } = resolveAfter(2);
+        let response = null;
+        topic.subscribe((topicValue) => {
+
+          response = topicValue;
+          counter();
+        });
+        expect(response.data).toBe(null);
+        expect(response.loading).toBe(true);
+        expect(response.error).toBe(undefined);
+        await resolveAfterTwo;
+        expect(response.data).toEqual({
+          id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1',
+          title: 'The pacty topic of the day',
+          updated_at: 1619979888906,
+          ttl: 3399,
+          forum: {
+            id: 'cucumber',
+            glyph: '✽',
+            label: 'test_forums.cucumber'
+          },
+          tags: [{
+            id: 'skunk',
+            weight: 44
+          }],
+          posts: [{
+            id: 'ed93530e-6f9c-4701-91ef-14f9e0ed3e26',
+            text: 'The content of this post is very relevant',
+            created_at: 1619979889798,
+            author: {
+              id: '07fb2ba0-0945-464a-b215-873296710c8c',
+              handle: 'cucumber_fan92'
+            }
+          }]
+        });
+        expect(response.loading).toBe(false);
+        expect(response.error).toBe(undefined);
+      });
+    });
+  });
+
+  describe('When there\'s no data', () => {
+
+    describe('GetTopic', () => {
+
+      beforeAll(async () => {
+
+        const topicQuery = new GraphQLInteraction()
+          .given('there\'s no data')
+          .uponReceiving('a request to get a single topic')
+          .withRequest({
+            path: '/graphql',
+            method: 'POST'
+          })
+          .withOperation('GetTopic')
+          .withQuery(
+            `query GetTopic($id: ID!) {
+              topic(id: $id) {
+                id
+                title
+                updated_at
+                ttl
+                forum {
+                  id
+                  glyph
+                  label
+                  __typename
+                }
+                tags {
+                  id
+                  weight
+                  __typename
+                }
+                posts {
+                  id
+                  text
+                  created_at
+                  author {
+                    id
+                    handle
+                    __typename
+                  }
+                  __typename
+                }
+                __typename
+              }
+            }`
+          )
+          .withVariables({
+            id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1'
+          })
+          .willRespondWith({
+            status: 200,
+            headers: {
+              'Content-Type': 'application/json; charset=utf-8'
+            },
+            body: {
+              data: {
+                topic: null
+              }
+            }
+          });
+        return await internals.provider.addInteraction(topicQuery);
+      });
+
+      test('it returns the topic', async () => {
+
+        const topic = getTopic('0b58959d-d448-4a4e-84b6-35e5ac0028d1');
+        const { counter, promise: resolveAfterTwo } = resolveAfter(2);
+        let response = null;
+        topic.subscribe((topicValue) => {
+
+          response = topicValue;
+          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('GetTopic', () => {
+
+      beforeAll(async () => {
+
+        const topicQuery = new GraphQLInteraction()
+          .given('there\'s an error')
+          .uponReceiving('a request to get a single topic')
+          .withRequest({
+            path: '/graphql',
+            method: 'POST'
+          })
+          .withOperation('GetTopic')
+          .withQuery(
+            `query GetTopic($id: ID!) {
+              topic(id: $id) {
+                id
+                title
+                updated_at
+                ttl
+                forum {
+                  id
+                  glyph
+                  label
+                  __typename
+                }
+                tags {
+                  id
+                  weight
+                  __typename
+                }
+                posts {
+                  id
+                  text
+                  created_at
+                  author {
+                    id
+                    handle
+                    __typename
+                  }
+                  __typename
+                }
+                __typename
+              }
+            }`
+          )
+          .withVariables({
+            id: '0b58959d-d448-4a4e-84b6-35e5ac0028d1'
+          })
+          .willRespondWith({
+            status: 500
+          });
+        return await internals.provider.addInteraction(topicQuery);
+      });
+
+      test('it returns the error', async () => {
+
+        const topic = getTopic('0b58959d-d448-4a4e-84b6-35e5ac0028d1');
+        const { counter, promise: resolveAfterTwo } = resolveAfter(2);
+        let response = null;
+        topic.subscribe((topicValue) => {
+
+          response = topicValue;
+          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);
+      });
+    });
+  });
+});