From: Ruben Beltran del Rio Date: Sun, 2 May 2021 18:39:30 +0000 (+0200) Subject: Add topics store pact tests X-Git-Url: https://git.r.bdr.sh/rbdr/forum/commitdiff_plain/3435a35ccb828fe81720d057e38eaa4223e917a7?ds=inline Add topics store pact tests --- diff --git a/pacts/forumclient-forumserver.json b/pacts/forumclient-forumserver.json index 3933bcc..337ff86 100644 --- a/pacts/forumclient-forumserver.json +++ b/pacts/forumclient-forumserver.json @@ -549,6 +549,191 @@ "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 index 0000000..280bddb --- /dev/null +++ b/src/stores/topics.test.js @@ -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); + }); + }); + }); +});