diff options
| author | Ruben Beltran del Rio <ruben@unlimited.pizza> | 2021-05-02 00:23:16 +0200 |
|---|---|---|
| committer | Ruben Beltran del Rio <ruben@unlimited.pizza> | 2021-05-02 00:23:16 +0200 |
| commit | 73973edab9aaa81312ba80a68bfe34bf5abcecd9 (patch) | |
| tree | 9d3916655c416407e12dc66e9f1f865cec0fb2b3 /src | |
| parent | 55fb920baa9792266be1a6b981f954c622c1eaf9 (diff) | |
Add pact test for forums store
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/header/header.test.js | 2 | ||||
| -rw-r--r-- | src/config/__mocks__/config.js | 7 | ||||
| -rw-r--r-- | src/routes/$layout.svelte | 13 | ||||
| -rw-r--r-- | src/stores/forums.js | 2 | ||||
| -rw-r--r-- | src/stores/forums.test.js | 101 | ||||
| -rw-r--r-- | src/utils/resolve_after.js | 25 | ||||
| -rw-r--r-- | src/utils/resolve_after.test.js | 45 |
7 files changed, 189 insertions, 6 deletions
diff --git a/src/components/header/header.test.js b/src/components/header/header.test.js index 7d57265..6be2516 100644 --- a/src/components/header/header.test.js +++ b/src/components/header/header.test.js @@ -4,6 +4,8 @@ import { render } from '@testing-library/svelte'; import '$/config/i18n'; import { enableTopicActions } from '$/stores/actions'; +jest.mock('$/config/config.js'); + import Header from './header.svelte'; describe('Header component', () => { diff --git a/src/config/__mocks__/config.js b/src/config/__mocks__/config.js new file mode 100644 index 0000000..0cd8b97 --- /dev/null +++ b/src/config/__mocks__/config.js @@ -0,0 +1,7 @@ +export const apollo = { + uri: 'http://localhost:1234/graphql', + name: 'COOL_APP', + version: '9.9.9' +}; + +export const version = '9.9.9'; diff --git a/src/routes/$layout.svelte b/src/routes/$layout.svelte index 8fd2ae0..234d26a 100644 --- a/src/routes/$layout.svelte +++ b/src/routes/$layout.svelte @@ -4,13 +4,16 @@ import { isLoading } from 'svelte-i18n'; import { _ } from 'svelte-i18n'; - import { forums } from '$/stores/forums'; + import { getForums } from '$/stores/forums'; import ErrorBlock from '$/components/error_block/error_block.svelte'; import ForumList from '$/components/forum_list/forum_list.svelte'; import Header from '$/components/header/header.svelte'; import Loader from '$/components/loader/loader.svelte'; import Footer from '$/components/footer/footer.svelte'; + + $: store = getForums(); + $: forums = $store.data; </script> {#if $isLoading} @@ -21,14 +24,14 @@ <slot /> </main> <nav title={$_('forum_list.title')}> - {#if $forums.loading} + {#if $store.loading} <Loader /> {/if} - {#if $forums.error} + {#if $store.error} <ErrorBlock message={$_('forum_list.error.unavailable')} /> {/if} - {#if $forums.data} - <ForumList forums={$forums.data} /> + {#if forums} + <ForumList forums={forums} /> {/if} </nav> <Footer /> diff --git a/src/stores/forums.js b/src/stores/forums.js index 583b0d3..39822a3 100644 --- a/src/stores/forums.js +++ b/src/stores/forums.js @@ -1,4 +1,4 @@ import { store } from './apollo'; import { GET_FORUMS } from '$/data/queries'; -export const forums = store({ key: 'forums', query: GET_FORUMS, initialValue: [] }); +export const getForums = () => store({ key: 'forums', query: GET_FORUMS, initialValue: [] }); diff --git a/src/stores/forums.test.js b/src/stores/forums.test.js new file mode 100644 index 0000000..25293c8 --- /dev/null +++ b/src/stores/forums.test.js @@ -0,0 +1,101 @@ +import { GraphQLInteraction, Pact, Matchers } from '@pact-foundation/pact'; +import { resolve } from 'path'; + +import { resolveAfter } from '$/utils/resolve_after'; + +import { act } from '@testing-library/svelte'; + +const { eachLike, like } = Matchers; + +jest.mock('$/config/config.js'); + +import { getForums } from './forums'; + +const internals = { + provider: null +}; + +describe('Forum store pact', () => { + + beforeAll(async () => { + + internals.provider = new Pact({ + port: 1234, + dir: resolve(process.cwd(), 'pacts'), + consumer: 'ForumsStore', + provider: 'ForumAPIServer' + }); + + await internals.provider.setup(); + }); + + afterEach(() => internals.provider.verify()); + afterAll(() => internals.provider.finalize()); + + describe('there are forums', () => { + + beforeAll(async () => { + + const forumQuery = new GraphQLInteraction() + .uponReceiving('a request to list the forums') + .withRequest({ + path: '/graphql', + method: 'POST' + }) + .withOperation('GetForums') + .withQuery( + `query GetForums { + forums { + id + glyph + label + position + __typename + } + }` + ) + .withVariables({}) + .willRespondWith({ + status: 200, + headers: { + 'Content-Type': 'application/json; charset=utf-8' + }, + body: { + data: { + forums: eachLike({ + id: like('butter'), + glyph: like('⌘'), + label: like('test_forums.butter'), + position: like(1) + }) + } + } + }); + return await internals.provider.addInteraction(forumQuery); + }); + + test('it returns the forums', async () => { + + const forums = getForums(); + const { counter, promise: resolveAfterTwo } = resolveAfter(2); + let response = null; + forums.subscribe((forumsValue) => { + + response = forumsValue; + counter(); + }); + expect(response.data).toEqual(expect.arrayContaining([])); + expect(response.loading).toBe(true); + expect(response.error).toBe(undefined); + await resolveAfterTwo; + expect(response.data).toEqual(expect.arrayContaining([{ + id: 'butter', + glyph: '⌘', + label: 'test_forums.butter', + position: 1 + }])); + expect(response.loading).toBe(false); + expect(response.error).toBe(undefined); + }); + }); +}); diff --git a/src/utils/resolve_after.js b/src/utils/resolve_after.js new file mode 100644 index 0000000..0884401 --- /dev/null +++ b/src/utils/resolve_after.js @@ -0,0 +1,25 @@ +export const resolveAfter = function (timesUntilResolve) { + + let counter = null; + let currentValue = 0; + + if (typeof timesUntilResolve !== 'number' || timesUntilResolve <= 0) { + throw new Error('Resolve after requires a positive integer'); + } + + const promise = new Promise((resolvePromise) => { + + counter = () => { + + if (++currentValue === timesUntilResolve) { + resolvePromise(); + } + }; + }); + + return { + counter, + promise + }; + +}; diff --git a/src/utils/resolve_after.test.js b/src/utils/resolve_after.test.js new file mode 100644 index 0000000..f7fc753 --- /dev/null +++ b/src/utils/resolve_after.test.js @@ -0,0 +1,45 @@ +import { resolveAfter } from './resolve_after'; + +describe('Resolve After', () => { + + test('it should throw if given 0', () => { + + expect(() => { + + resolveAfter(0); + }).toThrow(); + }); + + test('it should throw if given a negative number', () => { + + expect(() => { + + resolveAfter(-1); + }).toThrow(); + }); + + test('it should throw if given a negative number', () => { + + expect(() => { + + resolveAfter('lol'); + }).toThrow(); + }); + + test('it should resolve after the specified number of times', () => { + + expect(() => { + + const { counter, resolveAfterThree } = resolveAfter(3); + let resolved = false; + + resolveAfterThree.then(() => (resolved = true)); + counter(); + expect(resolved).toBe(false); + counter(); + expect(resolved).toBe(false); + counter(); + expect(resolved).toBe(true); + }).toThrow(); + }); +}); |