diff --git a/frontend/src/pages/Community.spec.js b/frontend/src/pages/Community.spec.js index 2dd119233..34fc3dba4 100644 --- a/frontend/src/pages/Community.spec.js +++ b/frontend/src/pages/Community.spec.js @@ -1,8 +1,8 @@ import { mount } from '@vue/test-utils' import Community from './Community' -import { toastErrorSpy, toastSuccessSpy } from '@test/testSetup' +import { toastErrorSpy, toastSuccessSpy, toastInfoSpy } from '@test/testSetup' import { createContribution, updateContribution, deleteContribution } from '@/graphql/mutations' -import { listContributions, listAllContributions } from '@/graphql/queries' +import { listContributions, listAllContributions, openCreations } from '@/graphql/queries' import { createMockClient } from 'mock-apollo-client' import VueApollo from 'vue-apollo' @@ -12,54 +12,48 @@ const apolloProvider = new VueApollo({ }) const localVue = global.localVue +localVue.use(VueApollo) const mockStoreDispach = jest.fn() -const apolloQueryMock = jest.fn() -const apolloMutationMock = jest.fn() -const apolloRefetchMock = jest.fn() +const routerPushMock = jest.fn() describe('Community', () => { let wrapper - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - $apollo: { - query: apolloQueryMock, - mutate: apolloMutationMock, - queries: { - OpenCreations: { - refetch: apolloRefetchMock, + mockClient.setRequestHandler( + openCreations, + jest + .fn() + .mockRejectedValueOnce({ message: 'Open Creations failed!' }) + .mockResolvedValue({ + data: { + openCreations: [ + { + month: 0, + year: 2023, + amount: '1000', + }, + { + month: 1, + year: 2023, + amount: '1000', + }, + { + month: 2, + year: 2023, + amount: '1000', + }, + ], }, - }, - }, - $store: { - dispatch: mockStoreDispach, - state: { - creation: ['1000', '1000', '1000'], - }, - }, - $i18n: { - locale: 'en', - }, - $router: { - push: jest.fn(), - }, - $route: { - hash: 'my', - }, - } + }), + ) - const Wrapper = () => { - return mount(Community, { - localVue, - mocks, - }) - } - - describe('mount', () => { - beforeEach(() => { - apolloQueryMock.mockResolvedValue({ + mockClient.setRequestHandler( + listContributions, + jest + .fn() + .mockRejectedValueOnce({ message: 'List Contributions failed!' }) + .mockResolvedValue({ data: { listContributions: { contributionList: [ @@ -71,10 +65,40 @@ describe('Community', () => { deletedAt: null, confirmedBy: null, confirmedAt: null, + firstName: 'Bibi', + contributionDate: '2022-07-15T08:47:06.000Z', + lastName: 'Bloxberg', + state: 'IN_PROGRESS', + messagesCount: 0, + }, + { + id: 1550, + amount: '200', + memo: 'Fleisig, fleisig am Arbeiten gewesen', + createdAt: '2022-07-15T08:47:06.000Z', + deletedAt: null, + confirmedBy: null, + confirmedAt: null, + firstName: 'Bibi', + contributionDate: '2022-06-15T08:47:06.000Z', + lastName: 'Bloxberg', + state: 'CONFIRMED', + messagesCount: 0, }, ], contributionCount: 1, }, + }, + }), + ) + + mockClient.setRequestHandler( + listAllContributions, + jest + .fn() + .mockRejectedValueOnce({ message: 'List All Contributions failed!' }) + .mockResolvedValue({ + data: { listAllContributions: { contributionList: [ { @@ -82,29 +106,137 @@ describe('Community', () => { amount: '200', memo: 'Fleisig, fleisig am Arbeiten mein lieber Freund, 50 Zeichen sind viel', createdAt: '2022-07-15T08:47:06.000Z', + contributionDate: '2022-07-15T08:47:06.000Z', deletedAt: null, confirmedBy: null, confirmedAt: null, + firstName: 'Bibi', + lastName: 'Bloxberg', + }, + { + id: 1550, + amount: '200', + memo: 'Fleisig, fleisig am Arbeiten gewesen', + createdAt: '2022-07-15T08:47:06.000Z', + deletedAt: null, + confirmedBy: null, + confirmedAt: null, + firstName: 'Bibi', + contributionDate: '2022-06-15T08:47:06.000Z', + lastName: 'Bloxberg', + messagesCount: 0, }, { id: 1556, amount: '400', memo: 'Ein anderer lieber Freund ist auch sehr felißig am Arbeiten!!!!', createdAt: '2022-07-16T08:47:06.000Z', + contributionDate: '2022-07-16T08:47:06.000Z', deletedAt: null, confirmedBy: null, confirmedAt: null, + firstName: 'Bob', + lastName: 'der Baumeister', }, ], - contributionCount: 2, + contributionCount: 3, }, }, - }) + }), + ) + + mockClient.setRequestHandler( + createContribution, + jest + .fn() + .mockRejectedValueOnce({ message: 'Create Contribution failed!' }) + .mockResolvedValue({ + data: { + createContribution: true, + }, + }), + ) + + mockClient.setRequestHandler( + updateContribution, + jest + .fn() + .mockRejectedValueOnce({ message: 'Update Contribution failed!' }) + .mockResolvedValue({ + data: { + updateContribution: true, + }, + }), + ) + + mockClient.setRequestHandler( + deleteContribution, + jest + .fn() + .mockRejectedValueOnce({ message: 'Delete Contribution failed!' }) + .mockResolvedValue({ + data: { + deleteContribution: true, + }, + }), + ) + + const mocks = { + $t: jest.fn((t) => t), + $d: jest.fn((d) => d), + $store: { + dispatch: mockStoreDispach, + state: { + user: { + firstName: 'Bibi', + lastName: 'Bloxberg', + }, + }, + }, + $i18n: { + locale: 'en', + }, + $router: { + push: routerPushMock, + }, + $route: { + hash: '#edit', + }, + } + + const Wrapper = () => { + return mount(Community, { + localVue, + mocks, + apolloProvider, + }) + } + + let apolloMutateSpy + let refetchContributionsSpy + let refetchAllContributionsSpy + let refetchOpenCreationsSpy + + describe('mount', () => { + beforeEach(() => { + jest.clearAllMocks() wrapper = Wrapper() + apolloMutateSpy = jest.spyOn(wrapper.vm.$apollo, 'mutate') + refetchContributionsSpy = jest.spyOn(wrapper.vm.$apollo.queries.ListContributions, 'refetch') + refetchAllContributionsSpy = jest.spyOn( + wrapper.vm.$apollo.queries.ListAllContributions, + 'refetch', + ) + refetchOpenCreationsSpy = jest.spyOn(wrapper.vm.$apollo.queries.OpenCreations, 'refetch') }) - it('has a DIV .community-page', () => { - expect(wrapper.find('div.community-page').exists()).toBe(true) + describe('server response for queries is error', () => { + it('toasts three errors', () => { + expect(toastErrorSpy).toBeCalledTimes(3) + expect(toastErrorSpy).toBeCalledWith('Open Creations failed!') + expect(toastErrorSpy).toBeCalledWith('List Contributions failed!') + expect(toastErrorSpy).toBeCalledWith('List All Contributions failed!') + }) }) describe('tabs', () => { @@ -112,60 +244,51 @@ describe('Community', () => { expect(wrapper.findAll('div[role="tabpanel"]')).toHaveLength(3) }) - it.todo('check for correct tabIndex if state is "IN_PROGRESS" or not') + it('check for correct tabIndex if state is "IN_PROGRESS" or not', () => { + expect(routerPushMock).toBeCalledWith({ path: '/community#my' }) + }) + + it('toasts an info', () => { + expect(toastInfoSpy).toBeCalledWith( + 'Du hast eine Rückfrage auf eine Contribution. Bitte beantworte diese!', + ) + }) }) describe('API calls after creation', () => { + it('has a DIV .community-page', () => { + expect(wrapper.find('div.community-page').exists()).toBe(true) + }) + it('emits update transactions', () => { expect(wrapper.emitted('update-transactions')).toEqual([[0]]) }) - - it('queries list of own contributions', () => { - expect(apolloQueryMock).toBeCalledWith({ - fetchPolicy: 'no-cache', - query: listContributions, - variables: { - currentPage: 1, - pageSize: 25, - }, - }) - }) - - it('queries list of all contributions', () => { - expect(apolloQueryMock).toBeCalledWith({ - fetchPolicy: 'no-cache', - query: listAllContributions, - variables: { - currentPage: 1, - pageSize: 25, - }, - }) - }) - - describe('server response is error', () => { - beforeEach(() => { - jest.clearAllMocks() - apolloQueryMock.mockRejectedValue({ message: 'Ups' }) - wrapper = Wrapper() - }) - - it('toasts two errors', () => { - expect(toastErrorSpy).toBeCalledTimes(2) - expect(toastErrorSpy).toBeCalledWith('Ups') - }) - }) }) - describe('set contrubtion', () => { + describe('save contrubtion', () => { + describe('with error', () => { + const now = new Date().toISOString() + beforeEach(async () => { + await wrapper.setData({ + form: { + id: null, + date: now, + memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + amount: '200', + }, + }) + await wrapper.find('form').trigger('submit') + }) + + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('Create Contribution failed!') + }) + }) + describe('with success', () => { const now = new Date().toISOString() beforeEach(async () => { jest.clearAllMocks() - apolloMutationMock.mockResolvedValue({ - data: { - createContribution: true, - }, - }) await wrapper.setData({ form: { id: null, @@ -178,7 +301,7 @@ describe('Community', () => { }) it('calls the create contribution mutation', () => { - expect(apolloMutationMock).toBeCalledWith({ + expect(apolloMutateSpy).toBeCalledWith({ fetchPolicy: 'no-cache', mutation: createContribution, variables: { @@ -194,62 +317,49 @@ describe('Community', () => { }) it('updates the contribution list', () => { - expect(apolloQueryMock).toBeCalledWith({ - fetchPolicy: 'no-cache', - query: listContributions, - variables: { - currentPage: 1, - pageSize: 25, - }, - }) + expect(refetchContributionsSpy).toBeCalled() }) - it('verifies the login (to get the new creations available)', () => { - expect(apolloRefetchMock).toBeCalled() + it('updates the all contribution list', () => { + expect(refetchAllContributionsSpy).toBeCalled() }) - it('set all data to the default values)', () => { + it('updates the open creations', () => { + expect(refetchOpenCreationsSpy).toBeCalled() + }) + + it('sets all data to the default values)', () => { expect(wrapper.vm.form.id).toBe(null) expect(wrapper.vm.form.date).toBe('') expect(wrapper.vm.form.memo).toBe('') expect(wrapper.vm.form.amount).toBe('') }) }) - - describe('with error', () => { - const now = new Date().toISOString() - beforeEach(async () => { - jest.clearAllMocks() - apolloMutationMock.mockRejectedValue({ - message: 'Ouch!', - }) - await wrapper.setData({ - form: { - id: null, - date: now, - memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', - amount: '200', - }, - }) - await wrapper.find('form').trigger('submit') - }) - - it('toasts the error message', () => { - expect(toastErrorSpy).toBeCalledWith('Ouch!') - }) - }) }) describe('update contrubtion', () => { + describe('with error', () => { + const now = new Date().toISOString() + beforeEach(async () => { + await wrapper + .findComponent({ name: 'ContributionForm' }) + .vm.$emit('update-contribution', { + id: 2, + date: now, + memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + amount: '400', + }) + }) + + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('Update Contribution failed!') + }) + }) + describe('with success', () => { const now = new Date().toISOString() beforeEach(async () => { jest.clearAllMocks() - apolloMutationMock.mockResolvedValue({ - data: { - updateContribution: true, - }, - }) await wrapper .findComponent({ name: 'ContributionForm' }) .vm.$emit('update-contribution', { @@ -261,7 +371,7 @@ describe('Community', () => { }) it('calls the update contribution mutation', () => { - expect(apolloMutationMock).toBeCalledWith({ + expect(apolloMutateSpy).toBeCalledWith({ fetchPolicy: 'no-cache', mutation: updateContribution, variables: { @@ -278,40 +388,15 @@ describe('Community', () => { }) it('updates the contribution list', () => { - expect(apolloQueryMock).toBeCalledWith({ - fetchPolicy: 'no-cache', - query: listContributions, - variables: { - currentPage: 1, - pageSize: 25, - }, - }) + expect(refetchContributionsSpy).toBeCalled() }) - it('verifies the login (to get the new creations available)', () => { - expect(apolloRefetchMock).toBeCalled() - }) - }) - - describe('with error', () => { - const now = new Date().toISOString() - beforeEach(async () => { - jest.clearAllMocks() - apolloMutationMock.mockRejectedValue({ - message: 'Oh No!', - }) - await wrapper - .findComponent({ name: 'ContributionForm' }) - .vm.$emit('update-contribution', { - id: 2, - date: now, - memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', - amount: '400', - }) + it('updates the all contribution list', () => { + expect(refetchAllContributionsSpy).toBeCalled() }) - it('toasts the error message', () => { - expect(toastErrorSpy).toBeCalledWith('Oh No!') + it('updates the open creations', () => { + expect(refetchOpenCreationsSpy).toBeCalled() }) }) }) @@ -324,19 +409,25 @@ describe('Community', () => { contributionListComponent = await wrapper.findComponent({ name: 'ContributionList' }) }) - describe('with success', () => { + describe('with error', () => { beforeEach(async () => { jest.clearAllMocks() - apolloMutationMock.mockResolvedValue({ - data: { - deleteContribution: true, - }, - }) contributionListComponent.vm.$emit('delete-contribution', { id: 2 }) }) + it('toasts the error message', () => { + expect(toastErrorSpy).toBeCalledWith('Delete Contribution failed!') + }) + }) + + describe('with success', () => { + beforeEach(async () => { + jest.clearAllMocks() + await contributionListComponent.vm.$emit('delete-contribution', { id: 2 }) + }) + it('calls the API', () => { - expect(apolloMutationMock).toBeCalledWith({ + expect(apolloMutateSpy).toBeCalledWith({ fetchPolicy: 'no-cache', mutation: deleteContribution, variables: { @@ -350,32 +441,15 @@ describe('Community', () => { }) it('updates the contribution list', () => { - expect(apolloQueryMock).toBeCalledWith({ - fetchPolicy: 'no-cache', - query: listContributions, - variables: { - currentPage: 1, - pageSize: 25, - }, - }) + expect(refetchContributionsSpy).toBeCalled() }) - it('verifies the login (to get the new creations available)', () => { - expect(apolloRefetchMock).toBeCalled() - }) - }) - - describe('with error', () => { - beforeEach(async () => { - jest.clearAllMocks() - apolloMutationMock.mockRejectedValue({ - message: 'Oh my god!', - }) - contributionListComponent.vm.$emit('delete-contribution', { id: 2 }) + it('updates the all contribution list', () => { + expect(refetchAllContributionsSpy).toBeCalled() }) - it('toasts the error message', () => { - expect(toastErrorSpy).toBeCalledWith('Oh my god!') + it('updates the open creations', () => { + expect(refetchOpenCreationsSpy).toBeCalled() }) }) }) diff --git a/frontend/src/pages/Community.vue b/frontend/src/pages/Community.vue index 13aad1a72..5bfa4f99a 100644 --- a/frontend/src/pages/Community.vue +++ b/frontend/src/pages/Community.vue @@ -10,7 +10,7 @@ />
item.state === 'IN_PROGRESS')) { + this.tabIndex = 1 + if (this.$route.hash !== '#my') { + this.$router.push({ path: '/community#my' }) + } + this.toastInfo('Du hast eine Rückfrage auf eine Contribution. Bitte beantworte diese!') + } + }, + error({ message }) { + this.toastError(message) + }, + }, }, watch: { $route(to, from) { @@ -160,7 +206,12 @@ export default { this.$root.$emit('bv::toggle::collapse', value.id) }) }, - setContribution(data) { + refetchData() { + this.$apollo.queries.ListAllContributions.refetch() + this.$apollo.queries.ListContributions.refetch() + this.$apollo.queries.OpenCreations.refetch() + }, + saveContribution(data) { this.$apollo .mutate({ fetchPolicy: 'no-cache', @@ -173,15 +224,7 @@ export default { }) .then((result) => { this.toastSuccess(this.$t('contribution.submitted')) - this.updateListContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) - this.updateListAllContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) - this.$apollo.queries.OpenCreations.refetch() + this.refetchData() }) .catch((err) => { this.toastError(err.message) @@ -201,15 +244,7 @@ export default { }) .then((result) => { this.toastSuccess(this.$t('contribution.updated')) - this.updateListContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) - this.updateListAllContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) - this.$apollo.queries.OpenCreations.refetch() + this.refetchData() }) .catch((err) => { this.toastError(err.message) @@ -226,68 +261,21 @@ export default { }) .then((result) => { this.toastSuccess(this.$t('contribution.deleted')) - this.updateListContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) - this.updateListAllContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) - this.$apollo.queries.OpenCreations.refetch() + this.refetchData() }) .catch((err) => { this.toastError(err.message) }) }, updateListAllContributions(pagination) { - this.$apollo - .query({ - fetchPolicy: 'no-cache', - query: listAllContributions, - variables: { - currentPage: pagination.currentPage, - pageSize: pagination.pageSize, - }, - }) - .then((result) => { - const { - data: { listAllContributions }, - } = result - this.contributionCountAll = listAllContributions.contributionCount - this.itemsAll = listAllContributions.contributionList - }) - .catch((err) => { - this.toastError(err.message) - }) + this.currentPageAll = pagination.currentPage + this.pageSizeAll = pagination.pageSize + this.$apollo.queries.ListAllContributions.refetch() }, updateListContributions(pagination) { - this.$apollo - .query({ - fetchPolicy: 'no-cache', - query: listContributions, - variables: { - currentPage: pagination.currentPage, - pageSize: pagination.pageSize, - }, - }) - .then((result) => { - const { - data: { listContributions }, - } = result - this.contributionCount = listContributions.contributionCount - this.items = listContributions.contributionList - if (this.items.find((item) => item.state === 'IN_PROGRESS')) { - this.tabIndex = 1 - if (this.$route.hash !== '#my') { - this.$router.push({ path: '/community#my' }) - } - this.toastInfo('Du hast eine Rückfrage auf eine Contribution. Bitte beantworte diese!') - } - }) - .catch((err) => { - this.toastError(err.message) - }) + this.currentPage = pagination.currentPage + this.pageSize = pagination.pageSize + this.$apollo.queries.ListContributions.refetch() }, updateContributionForm(item) { this.form.id = item.id @@ -306,16 +294,7 @@ export default { this.items.find((item) => item.id === id).state = 'PENDING' }, }, - created() { - this.updateListContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) - this.updateListAllContributions({ - currentPage: this.currentPage, - pageSize: this.pageSize, - }) this.updateTransactions(0) this.tabIndex = 1 this.$router.push({ path: '/community#my' }) diff --git a/frontend/test/testSetup.js b/frontend/test/testSetup.js index 06e84b269..ffe4caf41 100644 --- a/frontend/test/testSetup.js +++ b/frontend/test/testSetup.js @@ -22,6 +22,7 @@ import { loadFilters } from '@/filters/amount' import { toasters } from '@/mixins/toaster' export const toastErrorSpy = jest.spyOn(toasters.methods, 'toastError') export const toastSuccessSpy = jest.spyOn(toasters.methods, 'toastSuccess') +export const toastInfoSpy = jest.spyOn(toasters.methods, 'toastInfo') Object.keys(rules).forEach((rule) => { extend(rule, {