diff --git a/admin/src/components/CreationTransactionListFormular.spec.js b/admin/src/components/CreationTransactionListFormular.spec.js index 32dcb6c9d..88cda89ee 100644 --- a/admin/src/components/CreationTransactionListFormular.spec.js +++ b/admin/src/components/CreationTransactionListFormular.spec.js @@ -15,7 +15,7 @@ const apolloQueryMock = jest.fn().mockResolvedValue({ decayDuration: 0, memo: 'Testing', transactionId: 1, - name: 'Bibi', + name: 'Gradido Akademie', email: 'bibi@bloxberg.de', date: new Date(), decay: { @@ -34,7 +34,7 @@ const apolloQueryMock = jest.fn().mockResolvedValue({ decayDuration: 0, memo: 'Testing 2', transactionId: 2, - name: 'Bibi', + name: 'Gradido Akademie', email: 'bibi@bloxberg.de', date: new Date(), decay: { @@ -53,6 +53,7 @@ const apolloQueryMock = jest.fn().mockResolvedValue({ const toastedErrorMock = jest.fn() const mocks = { + $d: jest.fn((t) => t), $t: jest.fn((t) => t), $apollo: { query: apolloQueryMock, @@ -64,6 +65,7 @@ const mocks = { const propsData = { userId: 1, + fields: ['date', 'balance', 'name', 'memo', 'decay'], } describe('CreationTransactionListFormular', () => { diff --git a/admin/src/components/CreationTransactionListFormular.vue b/admin/src/components/CreationTransactionListFormular.vue index 7fed4adcc..627647534 100644 --- a/admin/src/components/CreationTransactionListFormular.vue +++ b/admin/src/components/CreationTransactionListFormular.vue @@ -1,7 +1,7 @@ + diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 1af76e4df..d92f42f5d 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -1,5 +1,6 @@ { "admin_area": "Adminbereich", + "advanced-calculation": "Vorausberechnung", "back": "Zurück", "community": { "choose-another-community": "Eine andere Gemeinschaft auswählen", @@ -120,7 +121,6 @@ "overview": "Übersicht", "privacy_policy": "Datenschutzerklärung", "publisher": { - "infoNoRegister": "Dies ist für die Registrieung nicht nötig.", "infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!", "publisherId": "Publisher-Id" }, @@ -198,7 +198,7 @@ }, "thx": { "activateEmail": "Dein Konto wurde noch nicht aktiviert. Bitte überprüfe deine E-Mail und klicke den Aktivierungslink!", - "checkEmail": "Deine E-Mail wurde erfolgreich verifiziert.", + "checkEmail": "Deine E-Mail wurde erfolgreich verifiziert. Du kannst dich jetzt anmelden.", "email": "Wir haben dir eine E-Mail gesendet.", "emailActivated": "Danke dass Du deine E-Mail bestätigt hast.", "errorTitle": "Achtung!", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 71ce6f9ef..014d449a0 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -1,5 +1,6 @@ { "admin_area": "Admin Area", + "advanced-calculation": "Advanced calculation", "back": "Back", "community": { "choose-another-community": "Choose another community", @@ -120,7 +121,6 @@ "overview": "Overview", "privacy_policy": "Privacy policy", "publisher": { - "infoNoRegister": "This is not necessary for registration.", "infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!", "publisherId": "PublisherID" }, @@ -198,7 +198,7 @@ }, "thx": { "activateEmail": "Your account has not been activated yet, please check your emails and click the activation link!", - "checkEmail": "Your email has been successfully verified.", + "checkEmail": "Your email has been successfully verified. You can sign in now.", "email": "We have sent you an email.", "emailActivated": "Thank you your email has been activated.", "errorTitle": "Attention!", diff --git a/frontend/src/main.js b/frontend/src/main.js index 544dff66d..edc9e575e 100755 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -28,7 +28,7 @@ Vue.toasted.register( loadAllRules(i18n) -addNavigationGuards(router, store, apolloProvider.defaultClient, i18n) +addNavigationGuards(router, store, apolloProvider.defaultClient) if (!store) { setTimeout( diff --git a/frontend/src/routes/guards.js b/frontend/src/routes/guards.js index 15d1eb5a1..1838fa0fc 100644 --- a/frontend/src/routes/guards.js +++ b/frontend/src/routes/guards.js @@ -1,6 +1,6 @@ import { verifyLogin } from '../graphql/queries' -const addNavigationGuards = (router, store, apollo, i18n) => { +const addNavigationGuards = (router, store, apollo) => { // handle publisherId router.beforeEach((to, from, next) => { const publisherId = to.query.pid @@ -21,7 +21,6 @@ const addNavigationGuards = (router, store, apollo, i18n) => { fetchPolicy: 'network-only', }) .then((result) => { - i18n.locale = result.data.verifyLogin.language store.dispatch('login', result.data.verifyLogin) next({ path: '/overview' }) }) diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js index d219ecacd..1a6521cd7 100644 --- a/frontend/src/store/store.js +++ b/frontend/src/store/store.js @@ -1,11 +1,15 @@ import Vue from 'vue' import Vuex from 'vuex' import createPersistedState from 'vuex-persistedstate' +import { localeChanged } from 'vee-validate' +import i18n from '../i18n.js' Vue.use(Vuex) export const mutations = { language: (state, language) => { + i18n.locale = language + localeChanged(language) state.language = language }, email: (state, email) => { diff --git a/frontend/src/store/store.test.js b/frontend/src/store/store.test.js index da108b9ff..4c0c03178 100644 --- a/frontend/src/store/store.test.js +++ b/frontend/src/store/store.test.js @@ -1,8 +1,18 @@ import { mutations, actions } from './store' import Vuex from 'vuex' import Vue from 'vue' +import i18n from '../i18n.js' +import { localeChanged } from 'vee-validate' jest.mock('vuex') +jest.mock('../i18n.js') +jest.mock('vee-validate', () => { + return { + localeChanged: jest.fn(), + } +}) + +i18n.locale = 'blubb' const { language, @@ -29,6 +39,14 @@ describe('Vuex store', () => { language(state, 'de') expect(state.language).toEqual('de') }) + + it('sets the i18n locale', () => { + expect(i18n.locale).toBe('de') + }) + + it('calls localChanged of vee-validate', () => { + expect(localeChanged).toBeCalledWith('de') + }) }) describe('email', () => { diff --git a/frontend/src/views/Layout/DashboardLayout_gdd.vue b/frontend/src/views/Layout/DashboardLayout_gdd.vue index 0c910bca5..932f3efdd 100755 --- a/frontend/src/views/Layout/DashboardLayout_gdd.vue +++ b/frontend/src/views/Layout/DashboardLayout_gdd.vue @@ -4,6 +4,7 @@ class="main-navbar" :balance="balance" :visible="visible" + :pending="pending" :elopageUri="elopageUri" @set-visible="setVisible" @admin="admin" diff --git a/frontend/src/views/Pages/Register.spec.js b/frontend/src/views/Pages/Register.spec.js index 56f97549d..1a966e5b6 100644 --- a/frontend/src/views/Pages/Register.spec.js +++ b/frontend/src/views/Pages/Register.spec.js @@ -214,21 +214,55 @@ describe('Register', () => { }) */ - describe('API calls', () => { + describe('API calls when form is missing input', () => { + beforeEach(() => { + wrapper.find('#registerFirstname').setValue('Max') + wrapper.find('#registerLastname').setValue('Mustermann') + wrapper.find('.language-switch-select').findAll('option').at(1).setSelected() + wrapper.find('#publisherid').setValue('12345') + }) + it('has disabled submit button when missing input checked box', () => { + wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net') + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled') + }) + + it('has disabled submit button when missing email input', () => { + wrapper.find('#registerCheckbox').setChecked() + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled') + }) + }) + + describe('API calls when completely filled and missing publisherid', () => { + beforeEach(() => { + wrapper.find('#registerFirstname').setValue('Max') + wrapper.find('#registerLastname').setValue('Mustermann') + wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net') + wrapper.find('.language-switch-select').findAll('option').at(1).setSelected() + wrapper.find('#registerCheckbox').setChecked() + }) + it('has enabled submit button when completely filled', async () => { + await wrapper.vm.$nextTick() + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe(undefined) + }) + }) + + describe('API calls when completely filled', () => { beforeEach(() => { wrapper.find('#registerFirstname').setValue('Max') wrapper.find('#registerLastname').setValue('Mustermann') wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net') wrapper.find('.language-switch-select').findAll('option').at(1).setSelected() wrapper.find('#publisherid').setValue('12345') + wrapper.find('#registerCheckbox').setChecked() }) it('commits publisherId to store', () => { expect(mockStoreCommit).toBeCalledWith('publisherId', 12345) }) - it('has enabled submit button when completely filled', () => { - expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled') + it('has enabled submit button when completely filled', async () => { + await wrapper.vm.$nextTick() + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe(undefined) }) describe('server sends back error', () => { diff --git a/frontend/src/views/Pages/Register.vue b/frontend/src/views/Pages/Register.vue index 070d80bb9..05cf61c46 100755 --- a/frontend/src/views/Pages/Register.vue +++ b/frontend/src/views/Pages/Register.vue @@ -145,7 +145,6 @@ class="text-center mt-1 shadow-lg p-3 mb-5 rounded" > {{ $t('publisher.infoText') }} - {{ $t('publisher.infoNoRegister') }}
@@ -162,9 +161,9 @@ {{ $t('signup') }} @@ -192,7 +191,6 @@ import InputEmail from '../../components/Inputs/InputEmail.vue' import LanguageSwitchSelect from '../../components/LanguageSwitchSelect.vue' import { createUser } from '../../graphql/mutations' -import { localeChanged } from 'vee-validate' import { getCommunityInfoMixin } from '../../mixins/getCommunityInfo' export default { @@ -219,8 +217,6 @@ export default { updateLanguage(e) { this.language = e this.$store.commit('language', this.language) - this.$i18n.locale = this.language - localeChanged(this.language) }, getValidationState({ dirty, validated, valid = null }) { return dirty || validated ? valid : null @@ -268,6 +264,9 @@ export default { emailFilled() { return this.form.email !== '' }, + disabled() { + return !(this.namesFilled && this.emailFilled && this.form.agree && !!this.language) + }, }, } diff --git a/frontend/src/views/Pages/ResetPassword.spec.js b/frontend/src/views/Pages/ResetPassword.spec.js index e28d16c3e..da8b4bc4f 100644 --- a/frontend/src/views/Pages/ResetPassword.spec.js +++ b/frontend/src/views/Pages/ResetPassword.spec.js @@ -15,54 +15,48 @@ const stubs = { RouterLink: RouterLinkStub, } -const createMockObject = (comingFrom) => { - return { - localVue, - mocks: { - $i18n: { - locale: 'en', - }, - $t: jest.fn((t) => t), - $route: { - params: { - optin: '123', - comingFrom, - }, - path: { - includes: (t) => t, - }, - }, - $toasted: { - global: { - error: toasterMock, - }, - }, - $router: { - push: routerPushMock, - }, - $loading: { - show: jest.fn(() => { - return { hide: jest.fn() } - }), - }, - $apollo: { - mutate: apolloMutationMock, - }, +const mocks = { + $i18n: { + locale: 'en', + }, + $t: jest.fn((t) => t), + $route: { + params: { + optin: '123', }, - stubs, - } + path: { + mock: 'checkEmail', + includes: jest.fn((t) => t === mocks.$route.path.mock), + }, + }, + $toasted: { + global: { + error: toasterMock, + }, + }, + $router: { + push: routerPushMock, + }, + $loading: { + show: jest.fn(() => { + return { hide: jest.fn() } + }), + }, + $apollo: { + mutate: apolloMutationMock, + }, } describe('ResetPassword', () => { let wrapper - const Wrapper = (functionName) => { - return mount(ResetPassword, functionName) + const Wrapper = () => { + return mount(ResetPassword, { localVue, mocks, stubs }) } describe('mount', () => { beforeEach(() => { - wrapper = Wrapper(createMockObject()) + wrapper = Wrapper() }) describe('No valid optin', () => { @@ -86,11 +80,32 @@ describe('ResetPassword', () => { }) describe('Register header', () => { - it('has a welcome message', async () => { - expect(wrapper.find('div.header').text()).toContain('settings.password.reset') - expect(wrapper.find('div.header').text()).toContain( - 'settings.password.reset-password.text', - ) + describe('from reset', () => { + beforeEach(() => { + mocks.$route.path.mock = 'reset' + wrapper = Wrapper() + }) + + it('has a welcome message', async () => { + expect(wrapper.find('div.header').text()).toContain('settings.password.reset') + expect(wrapper.find('div.header').text()).toContain( + 'settings.password.reset-password.text', + ) + }) + }) + + describe('from checkEmail', () => { + beforeEach(() => { + mocks.$route.path.mock = 'checkEmail' + wrapper = Wrapper() + }) + + it('has a welcome message', async () => { + expect(wrapper.find('div.header').text()).toContain('settings.password.set') + expect(wrapper.find('div.header').text()).toContain( + 'settings.password.set-password.text', + ) + }) }) }) @@ -128,7 +143,6 @@ describe('ResetPassword', () => { describe('submit form', () => { beforeEach(async () => { - // wrapper = Wrapper(createMockObject()) await wrapper.findAll('input').at(0).setValue('Aa123456_') await wrapper.findAll('input').at(1).setValue('Aa123456_') await flushPromises() @@ -164,14 +178,14 @@ describe('ResetPassword', () => { }) }) - describe('server response with success', () => { + describe('server response with success on /checkEmail', () => { beforeEach(async () => { + mocks.$route.path.mock = 'checkEmail' apolloMutationMock.mockResolvedValue({ data: { resetPassword: 'success', }, }) - wrapper = Wrapper(createMockObject('checkEmail')) await wrapper.findAll('input').at(0).setValue('Aa123456_') await wrapper.findAll('input').at(1).setValue('Aa123456_') await wrapper.find('form').trigger('submit') @@ -189,6 +203,26 @@ describe('ResetPassword', () => { ) }) + it('redirects to "/thx/checkEmail"', () => { + expect(routerPushMock).toHaveBeenCalledWith('/thx/checkEmail') + }) + }) + + describe('server response with success on /reset', () => { + beforeEach(async () => { + mocks.$route.path.mock = 'reset' + wrapper = Wrapper() + apolloMutationMock.mockResolvedValue({ + data: { + resetPassword: 'success', + }, + }) + await wrapper.findAll('input').at(0).setValue('Aa123456_') + await wrapper.findAll('input').at(1).setValue('Aa123456_') + await wrapper.find('form').trigger('submit') + await flushPromises() + }) + it('redirects to "/thx/reset"', () => { expect(routerPushMock).toHaveBeenCalledWith('/thx/reset') }) diff --git a/frontend/src/views/Pages/ResetPassword.vue b/frontend/src/views/Pages/ResetPassword.vue index 05d8a0f6e..0023c3838 100644 --- a/frontend/src/views/Pages/ResetPassword.vue +++ b/frontend/src/views/Pages/ResetPassword.vue @@ -92,7 +92,11 @@ export default { }) .then(() => { this.form.password = '' - this.$router.push('/thx/reset') + if (this.$route.path.includes('checkEmail')) { + this.$router.push('/thx/checkEmail') + } else { + this.$router.push('/thx/reset') + } }) .catch((error) => { this.$toasted.global.error(error.message) diff --git a/frontend/src/views/Pages/SendOverview/GddSend/TransactionConfirmation.vue b/frontend/src/views/Pages/SendOverview/GddSend/TransactionConfirmation.vue index dd5caf0f8..4acb95dcd 100644 --- a/frontend/src/views/Pages/SendOverview/GddSend/TransactionConfirmation.vue +++ b/frontend/src/views/Pages/SendOverview/GddSend/TransactionConfirmation.vue @@ -34,6 +34,7 @@ +

{{ $t('advanced-calculation') }}

{{ $t('form.current_balance') }} {{ $n(balance, 'decimal') }} @@ -42,18 +43,13 @@ {{ $t('form.your_amount') }} - + - {{ $n(amount, 'decimal') }} - - {{ $t('decay.decay') }} - - {{ $n(decay, 'decimal') }} - - {{ $t('form.new_balance') }} - ~ {{ $n(balance - amount - decay, 'decimal') }} + ~ {{ $n(balance - amount, 'decimal') }}
@@ -95,5 +91,6 @@ export default { } .borderbottom { border-bottom: 1px solid rgb(70, 65, 65); + border-bottom-style: double; } diff --git a/frontend/src/views/Pages/UserProfile/UserCard_Language.spec.js b/frontend/src/views/Pages/UserProfile/UserCard_Language.spec.js index e13d4a1d1..dab5a4945 100644 --- a/frontend/src/views/Pages/UserProfile/UserCard_Language.spec.js +++ b/frontend/src/views/Pages/UserProfile/UserCard_Language.spec.js @@ -138,10 +138,6 @@ describe('UserCard_Language', () => { expect(storeCommitMock).toBeCalledWith('language', 'en') }) - it('changes the i18n locale', () => { - expect(mocks.$i18n.locale).toBe('en') - }) - it('has no select field anymore', () => { expect(wrapper.find('select').exists()).toBeFalsy() }) diff --git a/frontend/src/views/Pages/UserProfile/UserCard_Language.vue b/frontend/src/views/Pages/UserProfile/UserCard_Language.vue index dfaf6cf55..a7b9d7f70 100644 --- a/frontend/src/views/Pages/UserProfile/UserCard_Language.vue +++ b/frontend/src/views/Pages/UserProfile/UserCard_Language.vue @@ -60,7 +60,6 @@