diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d7aff56f3..383735507 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -448,7 +448,7 @@ jobs: report_name: Coverage Admin Interface type: lcov result_path: ./coverage/lcov.info - min_coverage: 91 + min_coverage: 93 token: ${{ github.token }} ############################################################################## diff --git a/admin/src/components/UserTable.spec.js b/admin/src/components/UserTable.spec.js index 982b65a81..d900b126d 100644 --- a/admin/src/components/UserTable.spec.js +++ b/admin/src/components/UserTable.spec.js @@ -11,22 +11,36 @@ describe('UserTable', () => { const defaultItemsUser = [ { - email: 'bibi@bloxberg.de', + userId: 1, firstName: 'Bibi', lastName: 'Bloxberg', - creation: [1000, 1000, 1000], + email: 'bibi@bloxberg.de', + creation: [200, 400, 600], + emailChecked: true, }, { - email: 'bibi@bloxberg.de', - firstName: 'Bibi', - lastName: 'Bloxberg', + userId: 2, + firstName: 'Benjamin', + lastName: 'Blümchen', + email: 'benjamin@bluemchen.de', creation: [1000, 1000, 1000], + emailChecked: true, }, { - email: 'bibi@bloxberg.de', - firstName: 'Bibi', - lastName: 'Bloxberg', + userId: 3, + firstName: 'Peter', + lastName: 'Lustig', + email: 'peter@lustig.de', + creation: [0, 0, 0], + emailChecked: true, + }, + { + userId: 4, + firstName: 'New', + lastName: 'User', + email: 'new@user.ch', creation: [1000, 1000, 1000], + emailChecked: false, }, ] @@ -107,7 +121,7 @@ describe('UserTable', () => { const mocks = { $t: jest.fn((t) => t), - $d: jest.fn((d) => d), + $d: jest.fn((d) => String(d)), $apollo: { query: apolloQueryMock, }, @@ -122,7 +136,7 @@ describe('UserTable', () => { describe('mount', () => { describe('type PageUserSearch', () => { - beforeEach(() => { + beforeEach(async () => { wrapper = Wrapper(propsDataPageUserSearch) }) @@ -175,12 +189,12 @@ describe('UserTable', () => { }) describe('content', () => { - it('has 3 rows', () => { - expect(wrapper.findAll('tbody tr').length).toBe(3) + it('has 4 rows', () => { + expect(wrapper.findAll('tbody tr')).toHaveLength(4) }) it('has 7 columns', () => { - expect(wrapper.findAll('tr:nth-child(1) > td').length).toBe(7) + expect(wrapper.findAll('tr:nth-child(1) > td')).toHaveLength(7) }) it('find button on fifth column', () => { @@ -189,6 +203,110 @@ describe('UserTable', () => { ).toBeTruthy() }) }) + + describe('row toggling', () => { + describe('user with email not activated', () => { + it('has no details button', () => { + expect( + wrapper.findAll('tbody > tr').at(3).findAll('td').at(4).find('button').exists(), + ).toBeFalsy() + }) + + it('has a red confirmed button with envelope item', () => { + const row = wrapper.findAll('tbody > tr').at(3) + expect(row.findAll('td').at(5).find('button').exists()).toBeTruthy() + expect(row.findAll('td').at(5).find('button').classes('btn-danger')).toBeTruthy() + expect(row.findAll('td').at(5).find('svg').classes('bi-envelope')).toBeTruthy() + }) + + describe('click on envelope', () => { + beforeEach(async () => { + await wrapper + .findAll('tbody > tr') + .at(3) + .findAll('td') + .at(5) + .find('button') + .trigger('click') + }) + + it('opens the details', async () => { + expect(wrapper.findAll('tbody > tr')).toHaveLength(6) + expect(wrapper.findAll('tbody > tr').at(5).find('input').element.value).toBe( + 'new@user.ch', + ) + expect(wrapper.findAll('tbody > tr').at(5).text()).toContain( + 'unregister_mail.text_false', + ) + // HACK: for some reason we need to close the row details after this test + await wrapper + .findAll('tbody > tr') + .at(3) + .findAll('td') + .at(5) + .find('button') + .trigger('click') + }) + + describe('click on envelope again', () => { + beforeEach(async () => { + await wrapper + .findAll('tbody > tr') + .at(3) + .findAll('td') + .at(5) + .find('button') + .trigger('click') + }) + + it('closes the details', () => { + expect(wrapper.findAll('tbody > tr')).toHaveLength(4) + }) + }) + + describe('click on close details', () => { + beforeEach(async () => { + await wrapper.findAll('tbody > tr').at(5).findAll('button').at(1).trigger('click') + }) + + it('closes the details', () => { + expect(wrapper.findAll('tbody > tr')).toHaveLength(4) + }) + }) + }) + }) + + describe('different details', () => { + it.skip('shows the creation formular for second user', async () => { + await wrapper + .findAll('tbody > tr') + .at(1) + .findAll('td') + .at(4) + .find('button') + .trigger('click') + expect(wrapper.findAll('tbody > tr')).toHaveLength(6) + expect( + wrapper + .findAll('tbody > tr') + .at(3) + .find('div.component-creation-formular') + .exists(), + ).toBeTruthy() + }) + + it.skip('shows the transactions for third user', async () => { + await wrapper + .findAll('tbody > tr') + .at(4) + .findAll('td') + .at(6) + .find('button') + .trigger('click') + expect(wrapper.findAll('tbody > tr')).toHaveLength(6) + }) + }) + }) }) }) diff --git a/admin/src/components/UserTable.vue b/admin/src/components/UserTable.vue index 0fa72f573..e518ac6d1 100644 --- a/admin/src/components/UserTable.vue +++ b/admin/src/components/UserTable.vue @@ -133,7 +133,7 @@ variant="danger" v-show="type === 'UserListMassCreation' || type === 'PageCreationConfirm'" size="md" - @click="overlayShow('remove', row.item)" + @click="bookmarkRemove(row.item)" class="mr-2" > @@ -242,13 +242,6 @@ export default { this.overlayBookmarkType = bookmarkType this.overlayItem = item - if (bookmarkType === 'remove') { - this.overlayText.header = this.$t('overlay.remove.title') - this.overlayText.text1 = this.$t('overlay.remove.text') - this.overlayText.text2 = this.$t('overlay.remove.question') - this.overlayText.button_ok = this.$t('overlay.remove.yes') - this.overlayText.button_cancel = this.$t('overlay.remove.no') - } if (bookmarkType === 'confirm') { this.overlayText.header = this.$t('overlay.confirm.title') this.overlayText.text1 = this.$t('overlay.confirm.text') @@ -258,9 +251,6 @@ export default { } }, overlayOK(bookmarkType, item) { - if (bookmarkType === 'remove') { - this.bookmarkRemove(item) - } if (bookmarkType === 'confirm') { this.$emit('confirm-creation', item) } diff --git a/admin/src/locales/de.json b/admin/src/locales/de.json index 7585ee122..327cfd302 100644 --- a/admin/src/locales/de.json +++ b/admin/src/locales/de.json @@ -54,6 +54,7 @@ } }, "remove": "Entfernen", + "remove_all": "alle Nutzer entfernen", "transaction": "Transaktion", "transactionlist": { "amount": "Betrag", diff --git a/admin/src/locales/en.json b/admin/src/locales/en.json index 2680a1c00..3f12f10a8 100644 --- a/admin/src/locales/en.json +++ b/admin/src/locales/en.json @@ -54,6 +54,7 @@ } }, "remove": "Remove", + "remove_all": "Remove all users", "transaction": "Transaction", "transactionlist": { "amount": "Amount", diff --git a/admin/src/pages/Creation.spec.js b/admin/src/pages/Creation.spec.js index 9ba282ef8..81d556e9b 100644 --- a/admin/src/pages/Creation.spec.js +++ b/admin/src/pages/Creation.spec.js @@ -154,55 +154,16 @@ describe('Creation', () => { }, ]) }) - }) - describe('remove item', () => { - beforeEach(async () => { - await wrapper - .findAll('table') - .at(0) - .findAll('tbody > tr') - .at(1) - .find('button') - .trigger('click') - await wrapper - .findAll('table') - .at(1) - .findAll('tbody > tr') - .at(0) - .find('button') - .trigger('click') - }) - - it('opens a dialog', () => { - expect(wrapper.findAll('#overlay').at(1).isVisible()).toBeTruthy() - }) - - describe('cancel remove item', () => { + describe('remove item', () => { beforeEach(async () => { - await wrapper.findAll('#overlay').at(1).findAll('button').at(0).trigger('click') - }) - - it('closes the dialog', () => { - expect(wrapper.findAll('#overlay').at(1).isVisible()).toBeFalsy() - }) - - it('has one item in left table', () => { - expect(wrapper.findAll('table').at(0).findAll('tbody > tr')).toHaveLength(1) - }) - - it('has one item in right table', () => { - expect(wrapper.findAll('table').at(1).findAll('tbody > tr')).toHaveLength(1) - }) - }) - - describe('confirm remove item', () => { - beforeEach(async () => { - await wrapper.findAll('#overlay').at(1).findAll('button').at(1).trigger('click') - }) - - it('closes the dialog', () => { - expect(wrapper.findAll('#overlay').at(1).isVisible()).toBeFalsy() + await wrapper + .findAll('table') + .at(1) + .findAll('tbody > tr') + .at(0) + .find('button') + .trigger('click') }) it('has two items in left table', () => { @@ -223,32 +184,24 @@ describe('Creation', () => { expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', []) }) }) - }) - // this can only happen after API call in CreationForm - describe('remove all bookmarks', () => { - beforeEach(async () => { - await wrapper - .findAll('table') - .at(0) - .findAll('tbody > tr') - .at(1) - .find('button') - .trigger('click') - jest.clearAllMocks() - wrapper.findComponent({ name: 'CreationFormular' }).vm.$emit('remove-all-bookmark') - }) + describe('remove all bookmarks', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.find('button.btn-light').trigger('click') + }) - it('has no items in right table', () => { - expect(wrapper.findAll('table').at(1).findAll('tbody > tr')).toHaveLength(0) - }) + it('has no items in right table', () => { + expect(wrapper.findAll('table').at(1).findAll('tbody > tr')).toHaveLength(0) + }) - it('commits empty array to userSelectedInMassCreation', () => { - expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', []) - }) + it('commits empty array to userSelectedInMassCreation', () => { + expect(storeCommitMock).toBeCalledWith('setUserSelectedInMassCreation', []) + }) - it('calls searchUsers', () => { - expect(apolloQueryMock).toBeCalled() + it('calls searchUsers', () => { + expect(apolloQueryMock).toBeCalled() + }) }) }) diff --git a/admin/src/pages/Creation.vue b/admin/src/pages/Creation.vue index 9b26b63b6..64efab997 100644 --- a/admin/src/pages/Creation.vue +++ b/admin/src/pages/Creation.vue @@ -33,14 +33,22 @@ > - + + + + + + {{ $t('remove_all') }} + + + + {{ $t('multiple_creation_text') }} @@ -49,7 +57,7 @@ type="massCreation" :creation="creation" :items="itemsMassCreation" - @remove-all-bookmark="removeAllBookmark" + @remove-all-bookmark="removeAllBookmarks" /> @@ -131,7 +139,7 @@ export default { ) this.$store.commit('setUserSelectedInMassCreation', this.itemsMassCreation) }, - removeAllBookmark() { + removeAllBookmarks() { this.itemsMassCreation = [] this.$store.commit('setUserSelectedInMassCreation', []) this.getUsers() diff --git a/admin/src/pages/CreationConfirm.spec.js b/admin/src/pages/CreationConfirm.spec.js index 5768e1078..2520fd37b 100644 --- a/admin/src/pages/CreationConfirm.spec.js +++ b/admin/src/pages/CreationConfirm.spec.js @@ -78,6 +78,7 @@ describe('CreationConfirm', () => { it('commits resetOpenCreations to store', () => { expect(storeCommitMock).toBeCalledWith('resetOpenCreations') }) + it('commits setOpenCreations to store', () => { expect(storeCommitMock).toBeCalledWith('setOpenCreations', 2) }) @@ -85,7 +86,7 @@ describe('CreationConfirm', () => { describe('remove creation with success', () => { beforeEach(async () => { - await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('remove-creation', { id: 1 }) + await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click') }) it('calls the deletePendingCreation mutation', () => { @@ -107,7 +108,7 @@ describe('CreationConfirm', () => { describe('remove creation with error', () => { beforeEach(async () => { apolloMutateMock.mockRejectedValue({ message: 'Ouchhh!' }) - await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('remove-creation', { id: 1 }) + await wrapper.findAll('tr').at(1).findAll('button').at(0).trigger('click') }) it('toasts an error message', () => { @@ -118,22 +119,52 @@ describe('CreationConfirm', () => { describe('confirm creation with success', () => { beforeEach(async () => { apolloMutateMock.mockResolvedValue({}) - await wrapper.findComponent({ name: 'UserTable' }).vm.$emit('confirm-creation', { id: 2 }) + await wrapper.findAll('tr').at(2).findAll('button').at(2).trigger('click') }) - it('calls the confirmPendingCreation mutation', () => { - expect(apolloMutateMock).toBeCalledWith({ - mutation: confirmPendingCreation, - variables: { id: 2 }, + describe('overlay', () => { + it('opens the overlay', () => { + expect(wrapper.find('#overlay').isVisible()).toBeTruthy() }) - }) - it('commits openCreationsMinus to store', () => { - expect(storeCommitMock).toBeCalledWith('openCreationsMinus', 1) - }) + describe('cancel confirmation', () => { + beforeEach(async () => { + await wrapper.find('#overlay').findAll('button').at(0).trigger('click') + }) - it('toasts a success message', () => { - expect(toastedSuccessMock).toBeCalledWith('creation_form.toasted_created') + it('closes the overlay', () => { + expect(wrapper.find('#overlay').isVisible()).toBeFalsy() + }) + + it('still has 2 items in the table', () => { + expect(wrapper.findAll('tbody > tr')).toHaveLength(2) + }) + }) + + describe('confirm creation', () => { + beforeEach(async () => { + await wrapper.find('#overlay').findAll('button').at(1).trigger('click') + }) + + it('calls the confirmPendingCreation mutation', () => { + expect(apolloMutateMock).toBeCalledWith({ + mutation: confirmPendingCreation, + variables: { id: 2 }, + }) + }) + + it('commits openCreationsMinus to store', () => { + expect(storeCommitMock).toBeCalledWith('openCreationsMinus', 1) + }) + + it('toasts a success message', () => { + expect(toastedSuccessMock).toBeCalledWith('creation_form.toasted_created') + }) + + it('has 1 item left in the table', () => { + expect(wrapper.findAll('tbody > tr')).toHaveLength(1) + }) + }) }) }) diff --git a/admin/src/pages/UserSearch.spec.js b/admin/src/pages/UserSearch.spec.js index a4eefc21e..fe7bde0cc 100644 --- a/admin/src/pages/UserSearch.spec.js +++ b/admin/src/pages/UserSearch.spec.js @@ -88,100 +88,6 @@ describe('UserSearch', () => { ) }) - describe('row toggling', () => { - it('has 4 users in the table', () => { - expect(wrapper.findAll('tbody > tr')).toHaveLength(4) - }) - - describe('user with email not activated', () => { - it('has no details button', () => { - expect( - wrapper.findAll('tbody > tr').at(3).findAll('td').at(4).find('button').exists(), - ).toBeFalsy() - }) - - it('has a red confirmed button with envelope item', () => { - const row = wrapper.findAll('tbody > tr').at(3) - expect(row.findAll('td').at(5).find('button').exists()).toBeTruthy() - expect(row.findAll('td').at(5).find('button').classes('btn-danger')).toBeTruthy() - expect(row.findAll('td').at(5).find('svg').classes('bi-envelope')).toBeTruthy() - }) - - describe('click on envelope', () => { - it('opens the details', async () => { - await wrapper - .findAll('tbody > tr') - .at(3) - .findAll('td') - .at(5) - .find('button') - .trigger('click') - expect(wrapper.findAll('tbody > tr')).toHaveLength(6) - expect(wrapper.findAll('tbody > tr').at(5).find('input').element.value).toBe( - 'new@user.ch', - ) - expect(wrapper.findAll('tbody > tr').at(5).text()).toContain( - 'unregister_mail.text_false', - ) - }) - - describe('click on envelope again', () => { - it('closes the details', async () => { - await wrapper - .findAll('tbody > tr') - .at(3) - .findAll('td') - .at(5) - .find('button') - .trigger('click') - expect(wrapper.findAll('tbody > tr')).toHaveLength(4) - }) - }) - - describe('click on close details', () => { - it('closes the details', async () => { - await wrapper - .findAll('tbody > tr') - .at(3) - .findAll('td') - .at(5) - .find('button') - .trigger('click') - await wrapper.findAll('tbody > tr').at(5).findAll('button').at(1).trigger('click') - expect(wrapper.findAll('tbody > tr')).toHaveLength(4) - }) - }) - }) - }) - - describe('different details', () => { - it.skip('shows the creation formular for second user', async () => { - await wrapper - .findAll('tbody > tr') - .at(1) - .findAll('td') - .at(4) - .find('button') - .trigger('click') - expect(wrapper.findAll('tbody > tr')).toHaveLength(6) - expect( - wrapper.findAll('tbody > tr').at(3).find('div.component-creation-formular').exists(), - ).toBeTruthy() - }) - - it.skip('shows the transactions for third user', async () => { - await wrapper - .findAll('tbody > tr') - .at(4) - .findAll('td') - .at(6) - .find('button') - .trigger('click') - expect(wrapper.findAll('tbody > tr')).toHaveLength(6) - }) - }) - }) - describe('unconfirmed emails', () => { beforeEach(async () => { await wrapper.find('button.btn-block').trigger('click')