diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b7000100e..34ebeff11 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -528,7 +528,7 @@ jobs: report_name: Coverage Backend type: lcov result_path: ./backend/coverage/lcov.info - min_coverage: 68 + min_coverage: 74 token: ${{ github.token }} ########################################################################## diff --git a/admin/src/components/ContributionLink.spec.js b/admin/src/components/ContributionLink.spec.js index f1b9cfb97..9818e8b93 100644 --- a/admin/src/components/ContributionLink.spec.js +++ b/admin/src/components/ContributionLink.spec.js @@ -5,6 +5,7 @@ const localVue = global.localVue const mocks = { $t: jest.fn((t) => t), + $d: jest.fn((d) => d), } const propsData = { diff --git a/admin/src/components/ContributionLinkForm.spec.js b/admin/src/components/ContributionLinkForm.spec.js index 7182fb2e9..2baefcbe2 100644 --- a/admin/src/components/ContributionLinkForm.spec.js +++ b/admin/src/components/ContributionLinkForm.spec.js @@ -1,6 +1,7 @@ import { mount } from '@vue/test-utils' import ContributionLinkForm from './ContributionLinkForm.vue' -import { toastErrorSpy } from '../../test/testSetup' +import { toastErrorSpy, toastSuccessSpy } from '../../test/testSetup' +import { createContributionLink } from '@/graphql/createContributionLink.js' const localVue = global.localVue @@ -72,48 +73,70 @@ describe('ContributionLinkForm', () => { }) }) - // describe('successfull submit', () => { - // beforeEach(async () => { - // mockAPIcall.mockResolvedValue({ - // data: { - // createContributionLink: { - // link: 'https://localhost/redeem/CL-1a2345678', - // }, - // }, - // }) - // await wrapper.find('input.test-validFrom').setValue('2022-6-18') - // await wrapper.find('input.test-validTo').setValue('2022-7-18') - // await wrapper.find('input.test-name').setValue('test name') - // await wrapper.find('input.test-memo').setValue('test memo') - // await wrapper.find('input.test-amount').setValue('100') - // await wrapper.find('form').trigger('submit') - // }) + describe('successfull submit', () => { + beforeEach(async () => { + apolloMutateMock.mockResolvedValue({ + data: { + createContributionLink: { + link: 'https://localhost/redeem/CL-1a2345678', + }, + }, + }) + await wrapper + .findAllComponents({ name: 'BFormDatepicker' }) + .at(0) + .vm.$emit('input', '2022-6-18') + await wrapper + .findAllComponents({ name: 'BFormDatepicker' }) + .at(1) + .vm.$emit('input', '2022-7-18') + await wrapper.find('input.test-name').setValue('test name') + await wrapper.find('textarea.test-memo').setValue('test memo') + await wrapper.find('input.test-amount').setValue('100') + await wrapper.find('form').trigger('submit') + }) - // it('calls the API', () => { - // expect(mockAPIcall).toHaveBeenCalledWith( - // expect.objectContaining({ - // variables: { - // link: 'https://localhost/redeem/CL-1a2345678', - // }, - // }), - // ) - // }) + it('calls the API', () => { + expect(apolloMutateMock).toHaveBeenCalledWith({ + mutation: createContributionLink, + variables: { + validFrom: '2022-6-18', + validTo: '2022-7-18', + name: 'test name', + amount: '100', + memo: 'test memo', + cycle: 'ONCE', + maxPerCycle: 1, + maxAmountPerMonth: '0', + }, + }) + }) - // it('displays the new username', () => { - // expect(wrapper.find('div.display-username').text()).toEqual('@username') - // }) - // }) - }) - - describe('send createContributionLink with error', () => { - beforeEach(() => { - apolloMutateMock.mockRejectedValue({ message: 'OUCH!' }) - wrapper = Wrapper() - wrapper.vm.onSubmit() + it('toasts a succes message', () => { + expect(toastSuccessSpy).toBeCalledWith('https://localhost/redeem/CL-1a2345678') + }) }) - it('toasts an error message', () => { - expect(toastErrorSpy).toBeCalledWith('contributionLink.noStartDate') + describe('send createContributionLink with error', () => { + beforeEach(async () => { + apolloMutateMock.mockRejectedValue({ message: 'OUCH!' }) + await wrapper + .findAllComponents({ name: 'BFormDatepicker' }) + .at(0) + .vm.$emit('input', '2022-6-18') + await wrapper + .findAllComponents({ name: 'BFormDatepicker' }) + .at(1) + .vm.$emit('input', '2022-7-18') + await wrapper.find('input.test-name').setValue('test name') + await wrapper.find('textarea.test-memo').setValue('test memo') + await wrapper.find('input.test-amount').setValue('100') + await wrapper.find('form').trigger('submit') + }) + + it('toasts an error message', () => { + expect(toastErrorSpy).toBeCalledWith('OUCH!') + }) }) }) }) diff --git a/admin/src/components/ContributionLinkForm.vue b/admin/src/components/ContributionLinkForm.vue index 6daf1e299..c21a7f17c 100644 --- a/admin/src/components/ContributionLinkForm.vue +++ b/admin/src/components/ContributionLinkForm.vue @@ -1,8 +1,5 @@ diff --git a/frontend/src/components/ContributionMessages/slots/IsModerator.spec.js b/frontend/src/components/ContributionMessages/slots/IsModerator.spec.js deleted file mode 100644 index b1e09da94..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsModerator.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { mount } from '@vue/test-utils' -import IsModerator from './IsModerator.vue' - -const localVue = global.localVue - -describe('IsModerator', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - } - - const propsData = { - message: { - id: 111, - message: 'asd asda sda sda', - createdAt: '2022-08-29T12:23:27.000Z', - updatedAt: null, - type: 'DIALOG', - userFirstName: 'Peter', - userLastName: 'Lustig', - userId: 107, - __typename: 'ContributionMessage', - }, - } - - const Wrapper = () => { - return mount(IsModerator, { - localVue, - mocks, - propsData, - }) - } - - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) - - it('has a DIV .slot-is-moderator', () => { - expect(wrapper.find('div.slot-is-moderator').exists()).toBe(true) - }) - - it('props.message.default', () => { - expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) - }) - }) -}) diff --git a/frontend/src/components/ContributionMessages/slots/IsModerator.vue b/frontend/src/components/ContributionMessages/slots/IsModerator.vue deleted file mode 100644 index 343b92d97..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsModerator.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/frontend/src/components/ContributionMessages/slots/IsNotModerator.spec.js b/frontend/src/components/ContributionMessages/slots/IsNotModerator.spec.js deleted file mode 100644 index 24152ad1e..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsNotModerator.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { mount } from '@vue/test-utils' -import IsNotModerator from './IsNotModerator.vue' - -const localVue = global.localVue - -describe('IsNotModerator', () => { - let wrapper - - const mocks = { - $t: jest.fn((t) => t), - $d: jest.fn((d) => d), - } - - const propsData = { - message: { - id: 113, - message: 'asda sdad ad asdasd ', - createdAt: '2022-08-29T12:25:34.000Z', - updatedAt: null, - type: 'DIALOG', - userFirstName: 'Bibi', - userLastName: 'Bloxberg', - userId: 108, - __typename: 'ContributionMessage', - }, - } - - const Wrapper = () => { - return mount(IsNotModerator, { - localVue, - mocks, - propsData, - }) - } - - describe('mount', () => { - beforeEach(() => { - wrapper = Wrapper() - }) - - it('has a DIV .slot-is-not-moderator', () => { - expect(wrapper.find('div.slot-is-not-moderator').exists()).toBe(true) - }) - - it('props.message.default', () => { - expect(wrapper.vm.$options.props.message.default.call()).toEqual({}) - }) - }) -}) diff --git a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue b/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue deleted file mode 100644 index 8efca7270..000000000 --- a/frontend/src/components/ContributionMessages/slots/IsNotModerator.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index cf47577a3..8f35948f9 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -329,7 +329,8 @@ describe('ContributionForm', () => { describe('invalid form data', () => { beforeEach(async () => { - await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + // skip this precondition as long as the datepicker is disabled in the component + // await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) await wrapper.find('#contribution-amount').find('input').setValue('200') }) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 47f2be4c4..efe80f494 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -25,6 +25,7 @@ reset-value="" :label-no-date-selected="$t('contribution.noDateSelected')" required + :disabled="this.form.id !== null" > diff --git a/frontend/src/components/LinkInformations/RedeemLoggedOut.vue b/frontend/src/components/LinkInformations/RedeemLoggedOut.vue index 982bfdf08..6673b3c5b 100644 --- a/frontend/src/components/LinkInformations/RedeemLoggedOut.vue +++ b/frontend/src/components/LinkInformations/RedeemLoggedOut.vue @@ -25,9 +25,11 @@ diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 9846784d5..3156c2861 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -136,3 +136,27 @@ export const createContributionMessage = gql` } } ` + +export const login = gql` + mutation($email: String!, $password: String!, $publisherId: Int) { + login(email: $email, password: $password, publisherId: $publisherId) { + email + firstName + lastName + language + klickTipp { + newsletterState + } + hasElopage + publisherId + isAdmin + creation + } + } +` + +export const logout = gql` + mutation { + logout + } +` diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index 07b016d0a..f772aa931 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -1,23 +1,5 @@ import gql from 'graphql-tag' -export const login = gql` - query($email: String!, $password: String!, $publisherId: Int) { - login(email: $email, password: $password, publisherId: $publisherId) { - email - firstName - lastName - language - klickTipp { - newsletterState - } - hasElopage - publisherId - isAdmin - creation - } - } -` - export const verifyLogin = gql` query { verifyLogin { @@ -36,12 +18,6 @@ export const verifyLogin = gql` } ` -export const logout = gql` - query { - logout - } -` - export const transactionsQuery = gql` query($currentPage: Int = 1, $pageSize: Int = 25, $order: Order = DESC) { transactionList(currentPage: $currentPage, pageSize: $pageSize, order: $order) { diff --git a/frontend/src/layouts/AuthLayout.spec.js b/frontend/src/layouts/AuthLayout.spec.js index 4a1d7fef0..8d9411a71 100644 --- a/frontend/src/layouts/AuthLayout.spec.js +++ b/frontend/src/layouts/AuthLayout.spec.js @@ -19,6 +19,7 @@ describe('AuthLayout', () => { meta: { requiresAuth: false, }, + params: {}, }, } diff --git a/frontend/src/layouts/DashboardLayout.spec.js b/frontend/src/layouts/DashboardLayout.spec.js index 398724201..846974781 100644 --- a/frontend/src/layouts/DashboardLayout.spec.js +++ b/frontend/src/layouts/DashboardLayout.spec.js @@ -18,6 +18,7 @@ const apolloMock = jest.fn().mockResolvedValue({ logout: 'success', }, }) +const apolloQueryMock = jest.fn() describe('DashboardLayout', () => { let wrapper @@ -40,7 +41,8 @@ describe('DashboardLayout', () => { }, }, $apollo: { - query: apolloMock, + mutate: apolloMock, + query: apolloQueryMock, }, $store: { state: { @@ -142,7 +144,7 @@ describe('DashboardLayout', () => { describe('update transactions', () => { beforeEach(async () => { - apolloMock.mockResolvedValue({ + apolloQueryMock.mockResolvedValue({ data: { transactionList: { balance: { @@ -163,7 +165,7 @@ describe('DashboardLayout', () => { }) it('calls the API', () => { - expect(apolloMock).toBeCalledWith( + expect(apolloQueryMock).toBeCalledWith( expect.objectContaining({ variables: { currentPage: 2, @@ -201,7 +203,7 @@ describe('DashboardLayout', () => { describe('update transactions returns error', () => { beforeEach(async () => { - apolloMock.mockRejectedValue({ + apolloQueryMock.mockRejectedValue({ message: 'Ouch!', }) await wrapper diff --git a/frontend/src/layouts/DashboardLayout.vue b/frontend/src/layouts/DashboardLayout.vue index 8e778ab01..2a103a574 100755 --- a/frontend/src/layouts/DashboardLayout.vue +++ b/frontend/src/layouts/DashboardLayout.vue @@ -41,7 +41,8 @@ import Navbar from '@/components/Menu/Navbar.vue' import Sidebar from '@/components/Menu/Sidebar.vue' import SessionLogoutTimeout from '@/components/SessionLogoutTimeout.vue' -import { logout, transactionsQuery } from '@/graphql/queries' +import { transactionsQuery } from '@/graphql/queries' +import { logout } from '@/graphql/mutations' import ContentFooter from '@/components/ContentFooter.vue' import { FadeTransition } from 'vue2-transitions' import CONFIG from '@/config' @@ -75,8 +76,8 @@ export default { methods: { async logout() { this.$apollo - .query({ - query: logout, + .mutate({ + mutation: logout, }) .then(() => { this.$store.dispatch('logout') diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 1ed8af19f..a9ad47911 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -24,7 +24,8 @@ "moderator": "Moderator", "moderators": "Moderatoren", "myContributions": "Meine Beiträge zum Gemeinwohl", - "openContributionLinks": "öffentliche Beitrags-Linkliste", + "noOpenContributionLinkText": "Zur Zeit gibt es keine automatischen Schöpfungen.", + "openContributionLinks": "Öffentliche Beitrags-Linkliste", "openContributionLinkText": "Folgende {count} automatische Schöpfungen werden zur Zeit durch die Gemeinschaft „{name}“ bereitgestellt.", "other-communities": "Weitere Gemeinschaften", "submitContribution": "Beitrag einreichen", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 113fa1cb9..d9f69581d 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -24,7 +24,8 @@ "moderator": "Moderator", "moderators": "Moderators", "myContributions": "My contributions to the common good", - "openContributionLinks": "open Contribution links list", + "noOpenContributionLinkText": "Currently there are no automatic creations.", + "openContributionLinks": "Open contribution-link list", "openContributionLinkText": "The following {count} automatic creations are currently provided by the \"{name}\" community.", "other-communities": "Other communities", "submitContribution": "Submit contribution", diff --git a/frontend/src/mixins/authLinks.js b/frontend/src/mixins/authLinks.js new file mode 100644 index 000000000..6dedd8612 --- /dev/null +++ b/frontend/src/mixins/authLinks.js @@ -0,0 +1,12 @@ +export const authLinks = { + computed: { + login() { + if (this.$route.params.code) return '/login/' + this.$route.params.code + return '/login' + }, + register() { + if (this.$route.params.code) return '/register/' + this.$route.params.code + return '/register' + }, + }, +} diff --git a/frontend/src/pages/InfoStatistic.vue b/frontend/src/pages/InfoStatistic.vue index 1e09f83ed..de4b9e224 100644 --- a/frontend/src/pages/InfoStatistic.vue +++ b/frontend/src/pages/InfoStatistic.vue @@ -14,7 +14,7 @@
{{ $t('community.openContributionLinks') }}
- + {{ $t('community.openContributionLinkText', { name: CONFIG.COMMUNITY_NAME, @@ -22,6 +22,9 @@ }) }} + + {{ $t('community.noOpenContributionLinkText') }} +