From e0b31a8e4daa01d136cc42504fb2ccfde305b8b7 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 17 Aug 2021 15:45:54 +0200 Subject: [PATCH 1/7] stub GdtTransactionList --- frontend/src/views/Pages/UserProfileTransactionList.spec.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frontend/src/views/Pages/UserProfileTransactionList.spec.js b/frontend/src/views/Pages/UserProfileTransactionList.spec.js index 61a23345b..93a5eb40f 100644 --- a/frontend/src/views/Pages/UserProfileTransactionList.spec.js +++ b/frontend/src/views/Pages/UserProfileTransactionList.spec.js @@ -30,8 +30,12 @@ describe('UserProfileTransactionList', () => { }, } + const stubs = { + GdtTransactionList: true, + } + const Wrapper = () => { - return mount(UserProfileTransactionList, { localVue, mocks }) + return mount(UserProfileTransactionList, { localVue, mocks, stubs }) } describe('mount', () => { From 3c4c0bf8440036bd486b5bb50995eb22c8fd795b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 17 Aug 2021 17:37:37 +0200 Subject: [PATCH 2/7] disable warnings of bootstrap-vue in tests, network-only fetchPolicy in Login, testsing tabs of TransactionsLists --- frontend/src/views/Pages/Login.vue | 1 + .../Pages/UserProfileTransactionList.spec.js | 50 +++++++++++++++---- frontend/test/testSetup.js | 3 ++ frontend/yarn.lock | 6 +-- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/frontend/src/views/Pages/Login.vue b/frontend/src/views/Pages/Login.vue index 5d1072d45..e5b365d75 100755 --- a/frontend/src/views/Pages/Login.vue +++ b/frontend/src/views/Pages/Login.vue @@ -88,6 +88,7 @@ export default { email: this.form.email, password: this.form.password, }, + fetchPolicy: 'network-only', }) .then((result) => { const { diff --git a/frontend/src/views/Pages/UserProfileTransactionList.spec.js b/frontend/src/views/Pages/UserProfileTransactionList.spec.js index 93a5eb40f..484dd10f1 100644 --- a/frontend/src/views/Pages/UserProfileTransactionList.spec.js +++ b/frontend/src/views/Pages/UserProfileTransactionList.spec.js @@ -3,16 +3,6 @@ import UserProfileTransactionList from './UserProfileTransactionList' const localVue = global.localVue -const mutationObserverMock = jest.fn(function MutationObserver(callback) { - this.observe = jest.fn() - this.disconnect = jest.fn() - this.trigger = (mockedMutationsList) => { - callback(mockedMutationsList, this) - } -}) - -global.MutationObserver = mutationObserverMock - describe('UserProfileTransactionList', () => { let wrapper @@ -33,7 +23,7 @@ describe('UserProfileTransactionList', () => { const stubs = { GdtTransactionList: true, } - + const Wrapper = () => { return mount(UserProfileTransactionList, { localVue, mocks, stubs }) } @@ -65,5 +55,43 @@ describe('UserProfileTransactionList', () => { it('renders the transaction gradido transform table', () => { expect(wrapper.findComponent({ name: 'GdtTransactionList' }).exists()).toBeTruthy() }) + + describe('tabs', () => { + it('shows the GDD transactions by default', () => { + expect(wrapper.findAll('div[role="tabpanel"]').at(0).isVisible()).toBeTruthy() + }) + + it('does not show the GDT transactions by default', () => { + expect(wrapper.findAll('div[role="tabpanel"]').at(1).isVisible()).toBeFalsy() + }) + + describe('click on GDT tab', () => { + beforeEach(() => { + wrapper.findAll('li[ role="presentation"]').at(1).find('a').trigger('click') + }) + + it('does not show the GDD transactions', () => { + expect(wrapper.findAll('div[role="tabpanel"]').at(0).isVisible()).toBeFalsy() + }) + + it('shows the GDT transactions', () => { + expect(wrapper.findAll('div[role="tabpanel"]').at(1).isVisible()).toBeTruthy() + }) + + describe('click on GDD tab', () => { + beforeEach(() => { + wrapper.findAll('li[ role="presentation"]').at(0).find('a').trigger('click') + }) + + it('shows the GDD transactions', () => { + expect(wrapper.findAll('div[role="tabpanel"]').at(0).isVisible()).toBeTruthy() + }) + + it('does not show the GDT', () => { + expect(wrapper.findAll('div[role="tabpanel"]').at(1).isVisible()).toBeFalsy() + }) + }) + }) + }) }) }) diff --git a/frontend/test/testSetup.js b/frontend/test/testSetup.js index 565ebc33f..7005ff5be 100644 --- a/frontend/test/testSetup.js +++ b/frontend/test/testSetup.js @@ -33,6 +33,9 @@ loadAllRules(i18nMock) global.localVue = createLocalVue() +// switch of warnings from bootstrap vue +global.process.env.BOOTSTRAP_VUE_NO_WARN = true + global.localVue.use(BootstrapVue) global.localVue.use(Vuex) global.localVue.use(IconsPlugin) diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 1e12bd647..eff78ada1 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3750,9 +3750,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001181: - version "1.0.30001191" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001191.tgz#bacb432b6701f690c8c5f7c680166b9a9f0843d9" - integrity sha512-xJJqzyd+7GCJXkcoBiQ1GuxEiOBCLQ0aVW9HMekifZsAVGdj5eJ4mFB9fEhSHipq9IOk/QXFJUiIr9lZT+EsGw== + version "1.0.30001251" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz" + integrity sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A== capture-exit@^2.0.0: version "2.0.0" From 8dd64f54524da3b90b2190f8766913bf0d9627cc Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 17 Aug 2021 18:27:36 +0200 Subject: [PATCH 3/7] add test for thx page --- frontend/src/views/Pages/thx.spec.js | 108 +++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 frontend/src/views/Pages/thx.spec.js diff --git a/frontend/src/views/Pages/thx.spec.js b/frontend/src/views/Pages/thx.spec.js new file mode 100644 index 000000000..359890fc8 --- /dev/null +++ b/frontend/src/views/Pages/thx.spec.js @@ -0,0 +1,108 @@ +import { mount } from '@vue/test-utils' +import Thx from './thx' + +const localVue = global.localVue + +describe('Thx', () => { + let wrapper + + const Wrapper = (mocks) => { + return mount(Thx, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper({ + $t: jest.fn((t) => t), + $route: { + params: { + comingFrom: 'password', + }, + }, + }) + }) + + it('renders the thx page', () => { + expect(wrapper.find('div.header').exists()).toBeTruthy() + }) + + it('renders the title', () => { + expect(wrapper.find('p.h1').text()).toBe('site.thx.title') + }) + }) + + describe('coming from /password', () => { + beforeEach(() => { + wrapper = Wrapper({ + $t: jest.fn((t) => t), + $route: { + params: { + comingFrom: 'password', + }, + }, + }) + }) + + it('renders the thanks text', () => { + expect(wrapper.find('p.h4').text()).toBe('site.thx.email') + }) + + it('renders the thanks redirect button', () => { + expect(wrapper.find('a.btn').text()).toBe('login') + }) + + it('links the redirect button to /login', () => { + expect(wrapper.find('a.btn').attributes('href')).toBe('/login') + }) + }) + + describe('coming from /reset', () => { + beforeEach(() => { + wrapper = Wrapper({ + $t: jest.fn((t) => t), + $route: { + params: { + comingFrom: 'reset', + }, + }, + }) + }) + + it('renders the thanks text', () => { + expect(wrapper.find('p.h4').text()).toBe('site.thx.reset') + }) + + it('renders the thanks redirect button', () => { + expect(wrapper.find('a.btn').text()).toBe('login') + }) + + it('links the redirect button to /login', () => { + expect(wrapper.find('a.btn').attributes('href')).toBe('/login') + }) + }) + + describe('coming from /register', () => { + beforeEach(() => { + wrapper = Wrapper({ + $t: jest.fn((t) => t), + $route: { + params: { + comingFrom: 'register', + }, + }, + }) + }) + + it('renders the thanks text', () => { + expect(wrapper.find('p.h4').text()).toBe('site.thx.register') + }) + + it('renders the thanks redirect button', () => { + expect(wrapper.find('a.btn').text()).toBe('site.login.signin') + }) + + it('links the redirect button to /login', () => { + expect(wrapper.find('a.btn').attributes('href')).toBe('/overview') + }) + }) +}) From 080f5f257a596c262a5c9750d01952a2e8f3929b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 17 Aug 2021 18:32:53 +0200 Subject: [PATCH 4/7] more compact wrapper creation --- frontend/src/views/Pages/thx.spec.js | 47 +++++++++------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/frontend/src/views/Pages/thx.spec.js b/frontend/src/views/Pages/thx.spec.js index 359890fc8..f1bc59b80 100644 --- a/frontend/src/views/Pages/thx.spec.js +++ b/frontend/src/views/Pages/thx.spec.js @@ -3,6 +3,17 @@ import Thx from './thx' const localVue = global.localVue +const createMockObject = (comingFrom) => { + return { + $t: jest.fn((t) => t), + $route: { + params: { + comingFrom, + }, + }, + } +} + describe('Thx', () => { let wrapper @@ -12,14 +23,7 @@ describe('Thx', () => { describe('mount', () => { beforeEach(() => { - wrapper = Wrapper({ - $t: jest.fn((t) => t), - $route: { - params: { - comingFrom: 'password', - }, - }, - }) + wrapper = Wrapper(createMockObject('password')) }) it('renders the thx page', () => { @@ -33,14 +37,7 @@ describe('Thx', () => { describe('coming from /password', () => { beforeEach(() => { - wrapper = Wrapper({ - $t: jest.fn((t) => t), - $route: { - params: { - comingFrom: 'password', - }, - }, - }) + wrapper = Wrapper(createMockObject('password')) }) it('renders the thanks text', () => { @@ -58,14 +55,7 @@ describe('Thx', () => { describe('coming from /reset', () => { beforeEach(() => { - wrapper = Wrapper({ - $t: jest.fn((t) => t), - $route: { - params: { - comingFrom: 'reset', - }, - }, - }) + wrapper = Wrapper(createMockObject('reset')) }) it('renders the thanks text', () => { @@ -83,14 +73,7 @@ describe('Thx', () => { describe('coming from /register', () => { beforeEach(() => { - wrapper = Wrapper({ - $t: jest.fn((t) => t), - $route: { - params: { - comingFrom: 'register', - }, - }, - }) + wrapper = Wrapper(createMockObject('register')) }) it('renders the thanks text', () => { From bfe806988e309b88d3f8f3f3aa0cd9ca86319300 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 17 Aug 2021 19:21:36 +0200 Subject: [PATCH 5/7] test for GDT transaction list --- .../GdtTransactionList.spec.js | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js diff --git a/frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js b/frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js new file mode 100644 index 000000000..1d6726a43 --- /dev/null +++ b/frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js @@ -0,0 +1,131 @@ +import { mount } from '@vue/test-utils' +import GdtTransactionList from './GdtTransactionList' + +const localVue = global.localVue + +const apolloMock = jest.fn().mockResolvedValue({ + data: { + listGDTEntries: { + count: 4, + gdtEntries: [ + { + amount: 100, + amount2: 0, + gdt: 1700, + factor: 17, + factor2: 1, + comment: '', + coupon_code: '', + date: '2021-05-02T17:20:11+00:00', + email: 'bob@example.org', + gdt_entry_type_id: 1, + }, + { + amount: 1810, + amount2: 0, + gdt: 362, + factor: 0.2, + factor2: 1, + comment: 'Dezember 20', + coupon_code: '', + date: '2020-12-31T12:00:00+00:00', + email: 'bob@example.org', + gdt_entry_type_id: 7, + }, + { + amount: 100, + amount2: 0, + gdt: 1700, + factor: 17, + factor2: 1, + comment: '', + coupon_code: '', + date: '2020-05-07T17:00:00+00:00', + email: 'bob@example.org', + gdt_entry_type_id: 1, + }, + { + amount: 100, + amount2: 0, + gdt: 110, + factor: 22, + factor2: 0.05, + comment: '', + coupon_code: '', + date: '2020-04-10T13:28:00+00:00', + email: 'em741@gmx.de', + gdt_entry_type_id: 4, + }, + ], + }, + }, +}) + +const toastErrorMock = jest.fn() + +describe('GdtTransactionList', () => { + let wrapper + + const mocks = { + $i18n: { + locale: 'en', + }, + $t: jest.fn((t) => t), + $n: jest.fn((n) => n), + $d: jest.fn((d) => d), + $store: { + state: { + sessionId: 1, + }, + }, + $toasted: { + error: toastErrorMock, + }, + $apollo: { + query: apolloMock, + }, + } + + const Wrapper = () => { + return mount(GdtTransactionList, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the component', () => { + expect(wrapper.find('div.gdt-transaction-list').exists()).toBeTruthy() + }) + + describe('server returns valid data', () => { + it('calls the API', async () => { + await wrapper.vm.$nextTick() + expect(apolloMock).toBeCalledWith( + expect.objectContaining({ + variables: { + sessionId: 1, + currentPage: 1, + pageSize: 25, + }, + }), + ) + }) + }) + + describe('server returns error', () => { + beforeEach(() => { + jest.resetAllMocks() + apolloMock.mockRejectedValue({ + message: 'Ouch!', + }) + wrapper = Wrapper() + }) + + it('toasts an error message', () => { + expect(toastErrorMock).toBeCalledWith('Ouch!') + }) + }) + }) +}) From e416bd1b34dca232943289f11dca6ffd36b00d87 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 17 Aug 2021 19:28:56 +0200 Subject: [PATCH 6/7] coverage frontend to 60% --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2be814cc0..cab31e0f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -261,7 +261,7 @@ jobs: report_name: Coverage Frontend type: lcov result_path: ./coverage/lcov.info - min_coverage: 59 + min_coverage: 60 token: ${{ github.token }} ############################################################################## From 32fb0698b9eb77ad986a280d11cea84178c5eed9 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 18 Aug 2021 09:43:29 +0200 Subject: [PATCH 7/7] better test data --- .../GdtTransactionList.spec.js | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js b/frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js index 1d6726a43..5ad12be97 100644 --- a/frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js +++ b/frontend/src/views/Pages/AccountOverview/GdtTransactionList.spec.js @@ -10,51 +10,35 @@ const apolloMock = jest.fn().mockResolvedValue({ gdtEntries: [ { amount: 100, - amount2: 0, gdt: 1700, factor: 17, - factor2: 1, comment: '', - coupon_code: '', date: '2021-05-02T17:20:11+00:00', - email: 'bob@example.org', - gdt_entry_type_id: 1, + gdtEntryType: 1, }, { amount: 1810, - amount2: 0, gdt: 362, factor: 0.2, - factor2: 1, comment: 'Dezember 20', - coupon_code: '', date: '2020-12-31T12:00:00+00:00', - email: 'bob@example.org', - gdt_entry_type_id: 7, + gdtEntryType: 7, }, { amount: 100, - amount2: 0, gdt: 1700, factor: 17, - factor2: 1, comment: '', - coupon_code: '', date: '2020-05-07T17:00:00+00:00', - email: 'bob@example.org', - gdt_entry_type_id: 1, + gdtEntryType: 1, }, { amount: 100, - amount2: 0, gdt: 110, factor: 22, - factor2: 0.05, comment: '', - coupon_code: '', date: '2020-04-10T13:28:00+00:00', - email: 'em741@gmx.de', - gdt_entry_type_id: 4, + gdtEntryType: 4, }, ], },