From b590a82b04cc3d4197e2bf060538c54634a6add6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Tue, 26 Jul 2022 16:20:29 +0200 Subject: [PATCH 01/83] Change reset button to cancel and dev comments --- .../src/components/Contributions/ContributionForm.vue | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 647cd0067..97d012516 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -68,8 +68,8 @@ - - {{ $t('form.reset') }} + + {{ $t('form.cancel') }} @@ -136,6 +136,7 @@ export default { return false }, lastMonthObject() { + // Wolle: refine logic and melt with 'thisMonthObject' // new Date().getMonth === 1 If the current month is January, then one year must be gone back in the previous month const obj = { monthAndYear: this.$d(new Date(this.minimalDate), 'monthAndYear'), @@ -144,6 +145,7 @@ export default { return this.$t('contribution.formText.openAmountForMonth', obj) }, thisMonthObject() { + // Wolle: refine logic and melt with 'lastMonthObject' const obj = { monthAndYear: this.$d(new Date(), 'monthAndYear'), creation: this.maxGddThisMonth, @@ -151,15 +153,18 @@ export default { return this.$t('contribution.formText.openAmountForMonth', obj) }, isThisMonth() { + // Wolle: Jahr testen return new Date(this.form.date).getMonth() === new Date().getMonth() }, maxGddLastMonth() { + // Wolle: refine logic and melt with 'maxGddThisMonth' // When edited, the amount is added back on top of the amount return this.form.id && !this.isThisMonth ? parseInt(this.$store.state.creation[1]) + parseInt(this.updateAmount) : this.$store.state.creation[1] }, maxGddThisMonth() { + // Wolle: refine logic and melt with 'maxGddLastMonth' // When edited, the amount is added back on top of the amount return this.form.id && this.isThisMonth ? parseInt(this.$store.state.creation[2]) + parseInt(this.updateAmount) From 7eb6fc6c5165c5b88a8fbfe02061555da947e691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Tue, 26 Jul 2022 16:20:49 +0200 Subject: [PATCH 02/83] Refactor and enhance tests, try --- .../Contributions/ContributionForm.spec.js | 131 +++++++++++++++++- 1 file changed, 128 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 5b05957bb..00a3d9578 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -1,4 +1,5 @@ import { mount } from '@vue/test-utils' +import flushPromises from 'flush-promises' import ContributionForm from './ContributionForm.vue' const localVue = global.localVue @@ -6,7 +7,7 @@ const localVue = global.localVue describe('ContributionForm', () => { let wrapper - const propsData = { + let propsData = { value: { id: null, date: '', @@ -42,8 +43,132 @@ describe('ContributionForm', () => { expect(wrapper.find('div.contribution-form').exists()).toBe(true) }) - it('is submit button disable of true', () => { - expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled') + describe('empty form data', () => { + describe('has button', () => { + it('reset enabled', () => { + expect(wrapper.find('button[type="reset"]').attributes('disabled')).toBeFalsy() + }) + + it('submit disabled', () => { + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled') + }) + }) + }) + + describe('set contrubtion', () => { + describe('fill in form data', () => { + 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', + }, + }) + }) + + describe('has button', () => { + it('reset enabled', () => { + expect(wrapper.find('button[type="reset"]').attributes('disabled')).toBeFalsy() + }) + + it('submit enabled', () => { + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBeFalsy() + }) + }) + + describe.skip('on trigger submit', () => { + beforeEach(async () => { + // await wrapper.find('.test-submit').trigger('click') + await wrapper.find('button[type="submit"]').trigger('click') + }) + + it('emits "set-contribution"', () => { + expect(wrapper.emitted('set-contribution')).toEqual({ + id: null, + date: now, + memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + amount: '200', + }) + }) + }) + }) + }) + + describe('update contrubtion', () => { + describe('fill in form data and "id"', () => { + const now = new Date().toISOString() + + beforeEach(async () => { + // Wolle: await wrapper.setData({ + // form: { + // id: 2, + // date: now, + // memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + // amount: '200', + // }, + // }) + // await wrapper.setData({ + // form: { + // id: 2, + // }, + // }) + propsData = { + value: { + id: 2, + date: '', + memo: '', + amount: '', + }, + } + wrapper = Wrapper() + // await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper + .find('#contribution-memo') + .find('textarea') + .setValue('Mein Beitrag zur Gemeinschaft für diesen Monat ...') + await wrapper.find('#contribution-amount').find('input').setValue('200') + await flushPromises() + // Wolle: + await wrapper.vm.$nextTick() + }) + + describe('has button', () => { + it('reset enabled', () => { + expect(wrapper.find('button[type="reset"]').attributes('disabled')).toBeFalsy() + }) + + it('submit enabled', () => { + expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBeFalsy() + }) + }) + + describe.only('on trigger submit', () => { + beforeEach(async () => { + // await wrapper.find('.test-submit').trigger('click') + // await wrapper.find('button[type="submit"]').trigger('click') + await wrapper.find('form').trigger('submit') + }) + + it('emits "update-contribution"', () => { + expect(wrapper.emitted('update-contribution')).toEqual( + expect.arrayContaining([ + expect.arrayContaining([ + { + id: 2, + date: now, + memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + amount: '200', + }, + ]), + ]), + ) + }) + }) + }) }) }) }) From 14360fb8afba8ba129a31870cf2867e953648da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Tue, 26 Jul 2022 16:26:10 +0200 Subject: [PATCH 03/83] Cleanup a little --- frontend/src/components/Contributions/ContributionForm.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 97d012516..da5b2fbee 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -94,7 +94,6 @@ export default { maxlength: 255, maximalDate: new Date(), form: this.value, // includes 'id' - // Wolle: id: this.value.id, } }, methods: { @@ -108,7 +107,6 @@ export default { }, reset() { this.$refs.form.reset() - // Wolle: this.id = null this.form.id = null this.form.date = '' this.form.memo = '' From 3a183918c5306b868fdb8b7d653bdef709143b5b Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Aug 2022 11:34:46 +0200 Subject: [PATCH 04/83] Change checkOptInCode to check if emailChecked before changing optInState. --- backend/src/graphql/resolver/UserResolver.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a89a8cb0b..bd1fff918 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -187,7 +187,7 @@ const newEmailOptIn = (userId: number): LoginEmailOptIn => { // if optIn does not exits, it is created export const checkOptInCode = async ( optInCode: LoginEmailOptIn | undefined, - userId: number, + user: DbUser, optInType: OptInType = OptInType.EMAIL_OPT_IN_REGISTER, ): Promise => { logger.info(`checkOptInCode... ${optInCode}`) @@ -207,15 +207,18 @@ export const checkOptInCode = async ( optInCode.updatedAt = new Date() optInCode.resendCount++ } else { - logger.trace('create new OptIn for userId=' + userId) - optInCode = newEmailOptIn(userId) + logger.trace('create new OptIn for userId=' + user.id) + optInCode = newEmailOptIn(user.id) + } + + if (user.emailChecked) { + optInCode.emailOptInTypeId = optInType } - optInCode.emailOptInTypeId = optInType await LoginEmailOptIn.save(optInCode).catch(() => { logger.error('Unable to save optin code= ' + optInCode) throw new Error('Unable to save optin code.') }) - logger.debug(`checkOptInCode...successful: ${optInCode} for userid=${userId}`) + logger.debug(`checkOptInCode...successful: ${optInCode} for userid=${user.id}`) return optInCode } @@ -493,7 +496,7 @@ export class UserResolver { userId: user.id, }) - optInCode = await checkOptInCode(optInCode, user.id, OptInType.EMAIL_OPT_IN_RESET_PASSWORD) + optInCode = await checkOptInCode(optInCode, user, OptInType.EMAIL_OPT_IN_RESET_PASSWORD) logger.info(`optInCode for ${email}=${optInCode}`) // eslint-disable-next-line @typescript-eslint/no-unused-vars const emailSent = await sendResetPasswordEmailMailer({ From f42ba0557295453104bd9b619a16b3e3915381aa Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Aug 2022 11:35:34 +0200 Subject: [PATCH 05/83] Change call of checkOptInCode since signature changed. --- backend/src/graphql/resolver/AdminResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 84ae09cf8..b7ac63842 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -501,7 +501,7 @@ export class AdminResolver { order: { updatedAt: 'DESC' }, }) - optInCode = await checkOptInCode(optInCode, user.id) + optInCode = await checkOptInCode(optInCode, user) // eslint-disable-next-line @typescript-eslint/no-unused-vars const emailSent = await sendAccountActivationEmail({ From 6c748fdb30e30251a74150b8cb9b7a2c1a92b47f Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Aug 2022 11:46:48 +0200 Subject: [PATCH 06/83] Add new logger for klicktipp. --- backend/log4js-config.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/backend/log4js-config.json b/backend/log4js-config.json index 451da56ab..848a4fa79 100644 --- a/backend/log4js-config.json +++ b/backend/log4js-config.json @@ -25,6 +25,14 @@ "keepFileExt" : true, "fileNameSep" : "_" }, + "klicktipp": + { + "type": "dateFile", + "filename": "../logs/backend/klicktipp.log", + "pattern": "%d{ISO8601} %p %c %X{user} %f:%l %m", + "keepFileExt" : true, + "fileNameSep" : "_" + }, "errorFile": { "type": "dateFile", @@ -90,6 +98,17 @@ "level": "debug", "enableCallStack": true }, + "klicktipp": + { + "appenders": + [ + "klicktipp", + "out", + "errors" + ], + "level": "debug", + "enableCallStack": true + }, "http": { "appenders": From 87055e732c5242791ced8b158d3d9c2f2b331514 Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Aug 2022 11:47:10 +0200 Subject: [PATCH 07/83] Define klicktipp logger. --- backend/src/server/logger.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/server/logger.ts b/backend/src/server/logger.ts index cbc8c9b9b..0cfa5689b 100644 --- a/backend/src/server/logger.ts +++ b/backend/src/server/logger.ts @@ -12,7 +12,8 @@ log4js.configure(options) const apolloLogger = log4js.getLogger('apollo') const backendLogger = log4js.getLogger('backend') +const klickTippLogger = log4js.getLogger('klicktipp') backendLogger.addContext('user', 'unknown') -export { apolloLogger, backendLogger } +export { apolloLogger, backendLogger, klickTippLogger } From 140a374291b452830a088047c3866446d0940735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 4 Aug 2022 11:47:29 +0200 Subject: [PATCH 08/83] Add data-test properties to buttons --- .../Contributions/ContributionForm.spec.js | 12 ++++++++---- .../components/Contributions/ContributionForm.vue | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 00a3d9578..80dcd28c1 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -138,15 +138,19 @@ describe('ContributionForm', () => { describe('has button', () => { it('reset enabled', () => { - expect(wrapper.find('button[type="reset"]').attributes('disabled')).toBeFalsy() + expect( + wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), + ).toBeFalsy() }) - it('submit enabled', () => { - expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBeFalsy() + it.only('submit enabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBeFalsy() }) }) - describe.only('on trigger submit', () => { + describe.skip('on trigger submit', () => { beforeEach(async () => { // await wrapper.find('.test-submit').trigger('click') // await wrapper.find('button[type="submit"]').trigger('click') diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index da5b2fbee..5434881ab 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -68,12 +68,12 @@ - + {{ $t('form.cancel') }} - + {{ form.id ? $t('form.change') : $t('contribution.submit') }} From 174d592d5a6b4140f1af164aae7dcc00555bed4e Mon Sep 17 00:00:00 2001 From: elweyn Date: Thu, 4 Aug 2022 11:47:55 +0200 Subject: [PATCH 09/83] Log error for klicktipp for not found users. --- backend/src/middleware/klicktippMiddleware.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/src/middleware/klicktippMiddleware.ts b/backend/src/middleware/klicktippMiddleware.ts index b3699f29b..5f0c28477 100644 --- a/backend/src/middleware/klicktippMiddleware.ts +++ b/backend/src/middleware/klicktippMiddleware.ts @@ -2,6 +2,7 @@ import { MiddlewareFn } from 'type-graphql' import { /* klicktippSignIn, */ getKlickTippUser } from '@/apis/KlicktippController' import { KlickTipp } from '@model/KlickTipp' import CONFIG from '@/config' +import { klickTippLogger as logger } from '@/server/logger' // export const klicktippRegistrationMiddleware: MiddlewareFn = async ( // // Only for demo @@ -29,7 +30,9 @@ export const klicktippNewsletterStateMiddleware: MiddlewareFn = async ( if (klickTippUser) { klickTipp = new KlickTipp(klickTippUser) } - } catch (err) {} + } catch (err) { + logger.info(`Their is no user for (email='${result.email}') ${err}`) + } } result.klickTipp = klickTipp return result From 2759c7011d8065d1849689d60c3b178512e14ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 4 Aug 2022 12:18:50 +0200 Subject: [PATCH 10/83] Fix test in 'ContributionForm.spec.js' --- .../Contributions/ContributionForm.spec.js | 37 ++++--------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 80dcd28c1..fdd037b63 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -7,7 +7,7 @@ const localVue = global.localVue describe('ContributionForm', () => { let wrapper - let propsData = { + const propsData = { value: { id: null, date: '', @@ -103,37 +103,13 @@ describe('ContributionForm', () => { const now = new Date().toISOString() beforeEach(async () => { - // Wolle: await wrapper.setData({ - // form: { - // id: 2, - // date: now, - // memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', - // amount: '200', - // }, - // }) - // await wrapper.setData({ - // form: { - // id: 2, - // }, - // }) - propsData = { - value: { - id: 2, - date: '', - memo: '', - amount: '', - }, - } wrapper = Wrapper() - // await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) await wrapper .find('#contribution-memo') .find('textarea') .setValue('Mein Beitrag zur Gemeinschaft für diesen Monat ...') await wrapper.find('#contribution-amount').find('input').setValue('200') - await flushPromises() - // Wolle: - await wrapper.vm.$nextTick() }) describe('has button', () => { @@ -143,21 +119,24 @@ describe('ContributionForm', () => { ).toBeFalsy() }) - it.only('submit enabled', () => { + it('submit enabled', () => { expect( wrapper.find('button[data-test="button-submit"]').attributes('disabled'), ).toBeFalsy() }) }) - describe.skip('on trigger submit', () => { + describe('on trigger submit', () => { beforeEach(async () => { // await wrapper.find('.test-submit').trigger('click') // await wrapper.find('button[type="submit"]').trigger('click') await wrapper.find('form').trigger('submit') + await flushPromises() + // Wolle: + await wrapper.vm.$nextTick() }) - it('emits "update-contribution"', () => { + it.only('emits "update-contribution"', () => { expect(wrapper.emitted('update-contribution')).toEqual( expect.arrayContaining([ expect.arrayContaining([ From f7dccb04b61a90fbe902cfa12bfa65c9b5304360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 4 Aug 2022 15:45:38 +0200 Subject: [PATCH 11/83] Fix all tests in 'ContributionForm.spec.js' --- .../Contributions/ContributionForm.spec.js | 121 ++++++++++-------- .../Contributions/ContributionForm.vue | 7 +- 2 files changed, 69 insertions(+), 59 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index fdd037b63..9dfc090f2 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -1,5 +1,4 @@ import { mount } from '@vue/test-utils' -import flushPromises from 'flush-promises' import ContributionForm from './ContributionForm.vue' const localVue = global.localVue @@ -46,64 +45,24 @@ describe('ContributionForm', () => { describe('empty form data', () => { describe('has button', () => { it('reset enabled', () => { - expect(wrapper.find('button[type="reset"]').attributes('disabled')).toBeFalsy() + expect( + wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), + ).toBeFalsy() }) it('submit disabled', () => { - expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBe('disabled') + expect(wrapper.find('button[data-test="button-submit"]').attributes('disabled')).toBe( + 'disabled', + ) }) }) }) describe('set contrubtion', () => { - describe('fill in form data', () => { + describe('fill in form data with "id === null"', () => { 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', - }, - }) - }) - - describe('has button', () => { - it('reset enabled', () => { - expect(wrapper.find('button[type="reset"]').attributes('disabled')).toBeFalsy() - }) - - it('submit enabled', () => { - expect(wrapper.find('button[type="submit"]').attributes('disabled')).toBeFalsy() - }) - }) - - describe.skip('on trigger submit', () => { - beforeEach(async () => { - // await wrapper.find('.test-submit').trigger('click') - await wrapper.find('button[type="submit"]').trigger('click') - }) - - it('emits "set-contribution"', () => { - expect(wrapper.emitted('set-contribution')).toEqual({ - id: null, - date: now, - memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', - amount: '200', - }) - }) - }) - }) - }) - - describe('update contrubtion', () => { - describe('fill in form data and "id"', () => { - const now = new Date().toISOString() - - beforeEach(async () => { - wrapper = Wrapper() await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) await wrapper .find('#contribution-memo') @@ -128,15 +87,69 @@ describe('ContributionForm', () => { describe('on trigger submit', () => { beforeEach(async () => { - // await wrapper.find('.test-submit').trigger('click') - // await wrapper.find('button[type="submit"]').trigger('click') await wrapper.find('form').trigger('submit') - await flushPromises() - // Wolle: - await wrapper.vm.$nextTick() }) - it.only('emits "update-contribution"', () => { + it('emits "set-contribution"', () => { + expect(wrapper.emitted('set-contribution')).toEqual( + expect.arrayContaining([ + expect.arrayContaining([ + { + id: null, + date: now, + memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + amount: '200', + }, + ]), + ]), + ) + }) + }) + }) + }) + + describe('update contrubtion', () => { + describe('fill in form data with set "id"', () => { + const now = new Date().toISOString() + + beforeEach(async () => { + wrapper = Wrapper() + await wrapper.setData({ + form: { + id: 2, + date: now, + memo: 'Mein kommerzieller Beitrag für diesen Monat ...', + amount: '100', + }, + }) + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper + .find('#contribution-memo') + .find('textarea') + .setValue('Mein Beitrag zur Gemeinschaft für diesen Monat ...') + await wrapper.find('#contribution-amount').find('input').setValue('200') + }) + + describe('has button', () => { + it('reset enabled', () => { + expect( + wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), + ).toBeFalsy() + }) + + it('submit enabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBeFalsy() + }) + }) + + describe('on trigger submit', () => { + beforeEach(async () => { + await wrapper.find('form').trigger('submit') + }) + + it('emits "update-contribution"', () => { expect(wrapper.emitted('update-contribution')).toEqual( expect.arrayContaining([ expect.arrayContaining([ diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 5434881ab..e19fb2b9a 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -98,11 +98,8 @@ export default { }, methods: { submit() { - if (this.form.id) { - this.$emit('update-contribution', this.form) - } else { - this.$emit('set-contribution', this.form) - } + // this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', this.form) // is not working for testing + this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', { ...this.form }) // this works for testing, why ever, we have to make a spread '...', to evaluate the values it looks like this.reset() }, reset() { From 9c8f76d080ff1daee0ec5847fa77d4a62dd883ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 4 Aug 2022 16:02:15 +0200 Subject: [PATCH 12/83] Write new tests in 'ContributionForm.spec.js' --- .../Contributions/ContributionForm.spec.js | 52 +++++++++++++------ .../Contributions/ContributionForm.vue | 6 ++- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 9dfc090f2..298f4a82f 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -72,16 +72,26 @@ describe('ContributionForm', () => { }) describe('has button', () => { - it('reset enabled', () => { - expect( - wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), - ).toBeFalsy() + describe('reset', () => { + it('enabled', () => { + expect( + wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), + ).toBeFalsy() + }) }) - it('submit enabled', () => { - expect( - wrapper.find('button[data-test="button-submit"]').attributes('disabled'), - ).toBeFalsy() + describe('submit', () => { + it('enabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBeFalsy() + }) + + it('labeled with "contribution.submit"', () => { + expect(wrapper.find('button[data-test="button-submit"]').text()).toContain( + 'contribution.submit', + ) + }) }) }) @@ -131,16 +141,26 @@ describe('ContributionForm', () => { }) describe('has button', () => { - it('reset enabled', () => { - expect( - wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), - ).toBeFalsy() + describe('reset', () => { + it('enabled', () => { + expect( + wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), + ).toBeFalsy() + }) }) - it('submit enabled', () => { - expect( - wrapper.find('button[data-test="button-submit"]').attributes('disabled'), - ).toBeFalsy() + describe('submit', () => { + it('enabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBeFalsy() + }) + + it('labeled with "form.change"', () => { + expect(wrapper.find('button[data-test="button-submit"]').text()).toContain( + 'form.change', + ) + }) }) }) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index e19fb2b9a..a24c07ec2 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -98,8 +98,10 @@ export default { }, methods: { submit() { - // this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', this.form) // is not working for testing - this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', { ...this.form }) // this works for testing, why ever, we have to make a spread '...', to evaluate the values it looks like + // not working for testing: + // this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', this.form) + // works for testing, why ever, we have to make a spread '...', to evaluate the values it looks like: (I didn't find a solution in the test itmself) + this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', { ...this.form }) this.reset() }, reset() { From 6823ff548804a9f0600dbc0a81e74100c22a1e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 4 Aug 2022 16:06:48 +0200 Subject: [PATCH 13/83] Fix locales --- frontend/src/locales/de.json | 2 +- frontend/src/locales/en.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index d06299245..0deec9ae1 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -105,12 +105,12 @@ "amount": "Betrag", "at": "am", "cancel": "Abbrechen", + "change": "Ändern", "check_now": "Jetzt prüfen", "close": "Schließen", "current_balance": "Aktueller Kontostand", "date": "Datum", "description": "Beschreibung", - "change": "Ändern", "email": "E-Mail", "firstname": "Vorname", "from": "Von", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index de1ee6900..65b7abc87 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -105,12 +105,12 @@ "amount": "Amount", "at": "at", "cancel": "Cancel", + "change": "Change", "check_now": "Check now", "close": "Close", "current_balance": "Current Balance", "date": "Date", "description": "Description", - "change": "Change", "email": "Email", "firstname": "Firstname", "from": "from", From 9b97608a24a81e64eb98f4f82367de6ebb63df28 Mon Sep 17 00:00:00 2001 From: ogerly Date: Fri, 5 Aug 2022 15:49:37 +0200 Subject: [PATCH 14/83] remove required from form.memo --- frontend/src/components/Contributions/ContributionForm.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index d0de061d3..d79a19a09 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -31,7 +31,6 @@ {{ error }} From ff2ecd5363679ac9cba56ed2ed242941a3ae116c Mon Sep 17 00:00:00 2001 From: ogerly Date: Fri, 5 Aug 2022 16:47:08 +0200 Subject: [PATCH 15/83] add formatter on input amount replace point and comma --- frontend/src/components/Contributions/ContributionForm.vue | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index d0de061d3..890ffe363 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -58,6 +58,7 @@ type="number" min="1" :max="isThisMonth ? maxGddThisMonth : maxGddLastMonth" + :formatter="numberFormat" >
Date: Fri, 5 Aug 2022 17:56:54 +0200 Subject: [PATCH 16/83] add asteriks to mandatory field --- .../src/components/Contributions/ContributionForm.vue | 9 ++++++--- frontend/src/locales/de.json | 5 ++++- frontend/src/locales/en.json | 5 ++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index d79a19a09..53610ca6b 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -13,7 +13,7 @@
- + - + {{ error }}
- +
+

{{ $t('math.asterisk') }} {{ $t('form.mandatoryField') }}

diff --git a/frontend/src/routes/routes.js b/frontend/src/routes/routes.js index 540ef9d69..2c727304b 100755 --- a/frontend/src/routes/routes.js +++ b/frontend/src/routes/routes.js @@ -34,6 +34,15 @@ const routes = [ { path: '/transactions', component: () => import('@/pages/Transactions.vue'), + props: { gdt: false }, + meta: { + requiresAuth: true, + }, + }, + { + path: '/gdt', + component: () => import('@/pages/Transactions.vue'), + props: { gdt: true }, meta: { requiresAuth: true, }, From 6be065b0b68a276def8589ff73a6ba6a07499de4 Mon Sep 17 00:00:00 2001 From: ogerly Date: Sun, 7 Aug 2022 13:11:01 +0200 Subject: [PATCH 19/83] add tests for navbar and sidebar --- frontend/src/components/Menu/Navbar.spec.js | 24 ++++++++++++-------- frontend/src/components/Menu/Navbar.vue | 4 ++++ frontend/src/components/Menu/Sidebar.spec.js | 24 ++++++++++++-------- frontend/src/pages/Transactions.spec.js | 6 +++++ frontend/src/routes/router.test.js | 13 ++++++++++- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/Menu/Navbar.spec.js b/frontend/src/components/Menu/Navbar.spec.js index 3f12682c0..a348ffa9c 100644 --- a/frontend/src/components/Menu/Navbar.spec.js +++ b/frontend/src/components/Menu/Navbar.spec.js @@ -49,7 +49,7 @@ describe('Navbar', () => { }) it('has ten b-nav-item in the navbar', () => { - expect(wrapper.findAll('.nav-item')).toHaveLength(11) + expect(wrapper.findAll('.nav-item')).toHaveLength(12) }) it('has first nav-item "amount GDD" in navbar', () => { @@ -68,29 +68,33 @@ describe('Navbar', () => { expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.transactions') }) - it('has first nav-item "navigation.transactions" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.community') + it('has first nav-item "gdt.gdt" in navbar', () => { + expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('gdt.gdt') + }) + + it('has first nav-item "navigation.community" in navbar', () => { + expect(wrapper.findAll('.nav-item').at(7).text()).toEqual('navigation.community') }) it('has first nav-item "navigation.profile" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(7).text()).toEqual('navigation.profile') + expect(wrapper.findAll('.nav-item').at(8).text()).toEqual('navigation.profile') }) }) describe('navigation Navbar (user has an elopage account)', () => { it('has a link to the members area', () => { - expect(wrapper.findAll('.nav-item').at(8).text()).toContain('navigation.members_area') - expect(wrapper.findAll('.nav-item').at(8).find('a').attributes('href')).toBe( + expect(wrapper.findAll('.nav-item').at(9).text()).toContain('navigation.members_area') + expect(wrapper.findAll('.nav-item').at(9).find('a').attributes('href')).toBe( 'https://elopage.com', ) }) it('has first nav-item "navigation.admin_area" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(9).text()).toEqual('navigation.admin_area') + expect(wrapper.findAll('.nav-item').at(10).text()).toEqual('navigation.admin_area') }) it('has first nav-item "navigation.logout" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(10).text()).toEqual('navigation.logout') + expect(wrapper.findAll('.nav-item').at(11).text()).toEqual('navigation.logout') }) }) @@ -101,11 +105,11 @@ describe('Navbar', () => { }) it('has first nav-item "navigation.admin_area" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(8).text()).toEqual('navigation.admin_area') + expect(wrapper.findAll('.nav-item').at(9).text()).toEqual('navigation.admin_area') }) it('has first nav-item "navigation.logout" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(9).text()).toEqual('navigation.logout') + expect(wrapper.findAll('.nav-item').at(10).text()).toEqual('navigation.logout') }) }) }) diff --git a/frontend/src/components/Menu/Navbar.vue b/frontend/src/components/Menu/Navbar.vue index ef222fdb4..a0f6e5a9d 100644 --- a/frontend/src/components/Menu/Navbar.vue +++ b/frontend/src/components/Menu/Navbar.vue @@ -52,6 +52,10 @@ {{ $t('navigation.transactions') }} + + + {{ $t('gdt.gdt') }} + {{ $t('navigation.community') }} diff --git a/frontend/src/components/Menu/Sidebar.spec.js b/frontend/src/components/Menu/Sidebar.spec.js index 1593a79a8..1ffa8bf15 100644 --- a/frontend/src/components/Menu/Sidebar.spec.js +++ b/frontend/src/components/Menu/Sidebar.spec.js @@ -45,31 +45,35 @@ describe('Sidebar', () => { expect(wrapper.findAll('.nav-item').at(2).text()).toEqual('navigation.transactions') }) + it('has first nav-item "gdt.gdt" in navbar', () => { + expect(wrapper.findAll('.nav-item').at(3).text()).toEqual('gdt.gdt') + }) + it('has first nav-item "navigation.community" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(3).text()).toContain('navigation.community') + expect(wrapper.findAll('.nav-item').at(4).text()).toContain('navigation.community') }) it('has first nav-item "navigation.profile" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(4).text()).toEqual('navigation.profile') + expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.profile') }) }) describe('navigation Navbar (user has an elopage account)', () => { it('has eight b-nav-item in the navbar', () => { - expect(wrapper.findAll('.nav-item')).toHaveLength(8) + expect(wrapper.findAll('.nav-item')).toHaveLength(9) }) it('has a link to the members area', () => { - expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.members_area') - expect(wrapper.findAll('.nav-item').at(5).find('a').attributes('href')).toBe('#') + expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.members_area') + expect(wrapper.findAll('.nav-item').at(6).find('a').attributes('href')).toBe('#') }) it('has first nav-item "navigation.admin_area" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.admin_area') + expect(wrapper.findAll('.nav-item').at(7).text()).toEqual('navigation.admin_area') }) it('has first nav-item "navigation.logout" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(7).text()).toEqual('navigation.logout') + expect(wrapper.findAll('.nav-item').at(8).text()).toEqual('navigation.logout') }) }) @@ -80,15 +84,15 @@ describe('Sidebar', () => { }) it('has seven b-nav-item in the navbar', () => { - expect(wrapper.findAll('.nav-item')).toHaveLength(7) + expect(wrapper.findAll('.nav-item')).toHaveLength(8) }) it('has first nav-item "navigation.admin_area" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.admin_area') + expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.admin_area') }) it('has first nav-item "navigation.logout" in navbar', () => { - expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.logout') + expect(wrapper.findAll('.nav-item').at(7).text()).toEqual('navigation.logout') }) }) }) diff --git a/frontend/src/pages/Transactions.spec.js b/frontend/src/pages/Transactions.spec.js index 94e0f51c1..d364d3be7 100644 --- a/frontend/src/pages/Transactions.spec.js +++ b/frontend/src/pages/Transactions.spec.js @@ -1,11 +1,13 @@ import { mount } from '@vue/test-utils' import Transactions from './Transactions' import { GdtEntryType } from '@/graphql/enums' +import flushPromises from 'flush-promises' import { toastErrorSpy } from '@test/testSetup' const localVue = global.localVue +const mockRouterReplace = jest.fn() const windowScrollToMock = jest.fn() window.scrollTo = windowScrollToMock @@ -39,6 +41,9 @@ describe('Transactions', () => { $apollo: { query: apolloMock, }, + $router: { + push: mockRouterReplace, + }, } const Wrapper = () => { @@ -158,6 +163,7 @@ describe('Transactions', () => { describe('click on GDD tab', () => { beforeEach(() => { + flushPromises() wrapper.findAll('li[ role="presentation"]').at(0).find('a').trigger('click') }) diff --git a/frontend/src/routes/router.test.js b/frontend/src/routes/router.test.js index 2eefaeb36..d3f9cf992 100644 --- a/frontend/src/routes/router.test.js +++ b/frontend/src/routes/router.test.js @@ -50,7 +50,7 @@ describe('router', () => { }) it('has sixteen routes defined', () => { - expect(routes).toHaveLength(17) + expect(routes).toHaveLength(18) }) describe('overview', () => { @@ -108,6 +108,17 @@ describe('router', () => { }) }) + describe('gdt', () => { + it('requires authorization', () => { + expect(routes.find((r) => r.path === '/gdt').meta.requiresAuth).toBeTruthy() + }) + + it('loads the "GDT" page', async () => { + const component = await routes.find((r) => r.path === '/gdt').component() + expect(component.default.name).toBe('Transactions') + }) + }) + describe('login', () => { it('loads the "Login" page', async () => { const component = await routes.find((r) => r.path === '/login/:code?').component() From 19b21aa14567b19d9ee30d52559ee2e6c5e39956 Mon Sep 17 00:00:00 2001 From: ogerly Date: Sun, 7 Aug 2022 22:38:09 +0200 Subject: [PATCH 20/83] =?UTF-8?q?add=20language=20Espa=C3=B1ol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/LanguageSwitchSelect.vue | 1 + frontend/src/i18n.js | 7 + frontend/src/locales/de.json | 1 + frontend/src/locales/en.json | 1 + frontend/src/locales/es.json | 320 ++++++++++++++++++ frontend/src/locales/index.js | 6 + 6 files changed, 336 insertions(+) create mode 100644 frontend/src/locales/es.json diff --git a/frontend/src/components/LanguageSwitchSelect.vue b/frontend/src/components/LanguageSwitchSelect.vue index 545cef4e9..5803a6300 100644 --- a/frontend/src/components/LanguageSwitchSelect.vue +++ b/frontend/src/components/LanguageSwitchSelect.vue @@ -16,6 +16,7 @@ export default { options: [ { value: 'de', text: this.$t('settings.language.de') }, { value: 'en', text: this.$t('settings.language.en') }, + { value: 'es', text: this.$t('settings.language.es') }, ], } }, diff --git a/frontend/src/i18n.js b/frontend/src/i18n.js index 3136c6d80..3fc9552a1 100644 --- a/frontend/src/i18n.js +++ b/frontend/src/i18n.js @@ -3,6 +3,7 @@ import VueI18n from 'vue-i18n' import en from 'vee-validate/dist/locale/en' import de from 'vee-validate/dist/locale/de' +import es from 'vee-validate/dist/locale/es' Vue.use(VueI18n) @@ -26,6 +27,12 @@ function loadLocaleMessages() { ...messages[locale], } } + if (locale === 'es') { + messages[locale] = { + validations: es, + ...messages[locale], + } + } } }) return messages diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 422a445bd..d6424f5a4 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -243,6 +243,7 @@ "changeLanguage": "Sprache ändern", "de": "Deutsch", "en": "English", + "es": "Español", "success": "Deine Sprache wurde erfolgreich geändert." }, "name": { diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 89c18a106..63a4244ed 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -243,6 +243,7 @@ "changeLanguage": "Change language", "de": "Deutsch", "en": "English", + "es": "Español", "success": "Your language has been successfully updated." }, "name": { diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json new file mode 100644 index 000000000..a62db9c95 --- /dev/null +++ b/frontend/src/locales/es.json @@ -0,0 +1,320 @@ +{ + "100": "100%", + "1000thanks": "1000 Gracias, por estar con nosotros!", + "125": "125%", + "85": "85%", + "advanced-calculation": "Proyección", + "auth": { + "left": { + "dignity": "Dignidad", + "donation": "Donación", + "gratitude": "Gratitud", + "hasAccount": "Ya estas registrado?", + "hereLogin": "Registrate aquí", + "learnMore": "Informate aquí …", + "oneDignity": "Damos los unos a los otros y agradecemos con Gradido.", + "oneDonation": "Eres un regalo para la comunidad. 1000 gracias por estar con nosotros.", + "oneGratitude": "Por los demás, por toda la humanidad, por la naturaleza." + }, + "navbar": { + "aboutGradido": "Sobre Gradido" + } + }, + "back": "Volver", + "community": { + "choose-another-community": "Escoger otra comunidad", + "community": "Comunidad", + "continue-to-registration": "Continuar con el registro", + "current-community": "Comunidad actual", + "myContributions": "Mis contribuciones al bien común", + "other-communities": "Otras comunidades", + "submitContribution": "Aportar una contribución", + "switch-to-this-community": "cambiar a esta comunidad" + }, + "contribution": { + "activity": "Actividad", + "alert": { + "communityNoteList": "Aquí encontrarás todas las contribuciones enviadas y confirmadas de todos los miembros de esta comunidad..", + "confirm": "confirmado", + "myContributionNoteList": "Puedes editar o eliminar las contribuciones enviadas que aún no han sido confirmadas en cualquier momento..", + "myContributionNoteSupport": "Pronto existirá la posibilidad de que puedas dialogar con los moderadores. Si tienes algún problema ahora, ponte en contacto con el equipo de asistencia..", + "pending": "Enviado y a la espera de confirmación", + "rejected": "rechazado" + }, + "date": "Contribución para:", + "delete": "Eliminar la contribución. ¿Estás seguro?", + "deleted": "¡La contribución ha sido borrada! Pero seguirá siendo visible.", + "formText": { + "bringYourTalentsTo": "¡Contribuye a la comunidad con tus talentos! Premiamos tu compromiso voluntario con 20 GDD por hora hasta un máximo de 1.000 GDD al mes..", + "describeYourCommunity": "¡Describe tu contribución al bien-común con detalles de las horas e introduce una cantidad de 20 GDD por hora! Tras la confirmación de un moderador, el importe se abonará en tu cuenta.", + "maxGDDforMonth": "Sólo puede presentar un máximo de {amount} GDD para el mes seleccionado..", + "openAmountForMonth": "Para {monthAndYear} aún puedes presentar {creation} GDD.", + "yourContribution": "Tu contribución a la comunidad." + }, + "noDateSelected": "Elige cualquier fecha del mes.", + "selectDate": "¿Cuando fue tu contribución?", + "submit": "Enviar", + "submitted": "Tu contribución ha sido enviada.", + "updated": "La contribución se modificó." + }, + "contribution-link": { + "thanksYouWith": "agradecidos con" + }, + "decay": { + "before_startblock_transaction": "Esta transacción no implica disminución en su valor.", + "calculation_decay": "Cálculo de la disminución gradual del valor", + "calculation_total": "Cálculo de la suma total", + "decay": "Disminución gradual del valor", + "decay_introduced": "La disminución gradual empezó el:", + "decay_since_last_transaction": "Disminución gradual", + "last_transaction": "Transacción anterior", + "past_time": "Tiempo transcurrido", + "Starting_block_decay": "Startblock disminución gradual", + "total": "Total", + "types": { + "creation": "Creado", + "noDecay": "sin disminución gradual", + "receive": "Recibido", + "send": "Enviado" + } + }, + "delete": "Eliminar", + "em-dash": "—", + "error": { + "email-already-sent": "Ya te hemos enviado un correo electrónico hace menos de 10 minutos.", + "empty-transactionlist": "Ha habido un error en la transmisión del número de sus transacciones.", + "error": "Error!", + "no-account": "Lamentablemente no hemos podido encontrar una cuenta (activada) con estos datos.", + "no-transactionlist": "Lamentablemente, hubo un error. No se ha transmitido ninguna transacción desde el servidor.", + "no-user": "No hay usuario con estas referencias.", + "session-expired": "La sesión se cerró por razones de seguridad.", + "unknown-error": "Error desconocido: " + }, + "followUs": "sigue nos:", + "footer": { + "app_version": "App version {version}", + "copyright": { + "link": "Gradido-Akademie", + "year": "© {year}" + }, + "imprint": "Impressum", + "privacy_policy": "Protección de Datos", + "short_hash": "({shortHash})", + "whitepaper": "Whitepaper" + }, + "form": { + "amount": "Monto", + "at": "am", + "cancel": "Cancelar", + "change": "Cambiar", + "check_now": "Revisar", + "close": "Cerrar", + "current_balance": "Saldo de cuenta actual", + "date": "Fecha", + "description": "Descripción", + "email": "E-Mail", + "firstname": "Nombre", + "from": "De", + "generate_now": "crear ahora", + "lastname": "Apellido", + "memo": "Mensaje", + "message": "Notcia", + "new_balance": "Saldo de cuenta nuevo depués de confirmación", + "no_gdd_available": "No dispones de GDD para enviar.", + "password": "Contraseña", + "passwordRepeat": "Repetir contraseña", + "password_new": "contraseña nueva", + "password_new_repeat": "Repetir contraseña nueva", + "password_old": "contraseña antigua", + "recipient": "Destinatario", + "reset": "Restablecer", + "save": "Guardar", + "scann_code": "QR Code Scanner - Escanea el código QR de tu pareja", + "sender": "Remitente", + "send_check": "Confirma tu transacción. Por favor revisa toda la información nuevamente!", + "send_now": "Enviar ahora", + "send_transaction_error": "Desafortunadamente, la transacción no se pudo ejecutar!", + "send_transaction_success": "Su transacción fue ejecutada con éxito", + "sorry": "Disculpa", + "thx": "Gracias", + "time": "Tiempo", + "to": "hasta", + "to1": "para", + "validation": { + "gddSendAmount": "El campo {_field_} debe ser un número entre {min} y {max} con un máximo de dos decimales", + "is-not": "No es posible transferirte Gradidos a ti mismo", + "usernmae-regex": "El nombre de usuario debe comenzar con una letra seguida de al menos dos caracteres alfanuméricos.", + "usernmae-unique": "Este nombre de usuario ya está adjudicado." + }, + "your_amount": "Tu monto" + }, + "GDD": "GDD", + "gdd_per_link": { + "choose-amount": "Selecciona una cantidad que te gustaría enviar a través de un enlace. También puedes ingresar un mensaje. Cuando haces clic en 'Generar ahora', se crea un enlace que puedes enviar.", + "copy-link": "Copiar enlace", + "copy-link-with-text": "Copiar texto y enlace", + "created": "El enlace ha sido creado", + "credit-your-gradido": "Para que se te acrediten los Gradidos, haz clic en el enlace!", + "decay-14-day": "Disminución gradual por 14 días", + "delete-the-link": "Eliminar el enlace?", + "deleted": "El enlace ha sido eliminado!", + "expiredOn": "Vencido el:", + "has-account": "Ya tienes una cuenta Gradido?", + "header": "Transferir Gradidos por medio de un enlace", + "isFree": "Gradido es gratis en todo el mundoi.", + "link-and-text-copied": "El enlace y su mensaje se han copiado en el portapapeles. Ahora puedes ponerlo en un correo electrónico o mensaje einfügen.", + "link-copied": "El enlace se ha copiado en el portapapeles. Ahora puedes pegarlo en un correo electrónico o mensaje.", + "link-deleted": "El enlace se eliminó el {date}.", + "link-expired": "El enlace ya no es válido. La validez expiró el {date}.", + "link-overview": "Resumen de enlaces", + "links_count": "Enlaces activos", + "links_sum": "Enlaces abiertos y códigos QR", + "no-account": "Aún no tienes una cuenta de Gradido?", + "no-redeem": "No puedes canjear tu propio enlace!", + "not-copied": "¡Desafortunadamente, su dispositivo no permite copiar! Copie el enlace manualmente!", + "redeem": "Canjear", + "redeem-text": "¿Quieres canjear el importe ahora?", + "redeemed": "¡Canjeado con éxito! Tu cuenta ha sido acreditada con {n} GDD.", + "redeemed-at": "El enlace ya se canjeó el {date}.", + "redeemed-title": "canjeado", + "to-login": "iniciar sesión", + "to-register": "Registre una nueva cuenta.", + "validUntil": "Válido hasta", + "validUntilDate": "El enlace es válido hasta el {date} ." + }, + "gdt": { + "calculation": "Cálculo del Gradido Transform", + "contribution": "Monto", + "conversion": "Conversión", + "conversion-gdt-euro": "Conversión Euro / Gradido Transform (GDT)", + "credit": "Abono", + "factor": "Factor", + "formula": "Formula de cálculo", + "funding": "Las donaciones", + "gdt": "Gradido Transform", + "gdt-received": "Gradido Transform (GDT) recibido", + "no-transactions": "Aún no tienes un Gradido Transform (GDT).", + "not-reachable": "No es posible acceder al servidor GDT.", + "publisher": "Tu nuevo miembro referido ha pagado la cuota", + "raise": "Aumento", + "recruited-member": "Miembro invitado" + }, + "language": "Idioma", + "link-load": "recargar el último enlace |recargar los últimos {n} enlaces | descargar más {n} enlaces", + "login": "iniciar sesión", + "math": { + "aprox": "~", + "minus": "−", + "pipe": "|" + }, + "message": { + "activateEmail": "Tu cuenta aún no ha sido activada. Por favor revisa tu correo electrónico y haz clic en el enlace de activación o solicita uno nuevo Aktivierungslink über die Password Reset Seite an.", + "checkEmail": "Tu correo electrónico ha sido verificado con éxito. Puedes registrarte ahora.", + "email": "Te hemos enviado un correo electrónico.", + "errorTitle": "Atención!", + "register": "Ya estás registrado, por favor revisa tu correo electrónico y haz clic en el enlace de activación.", + "reset": "Tu contraseña ha sido cambiada.", + "title": "Gracias!", + "unsetPassword": "Tu contraseña aún no ha sido configurada. Por favor reinícialo." + }, + "navigation": { + "admin_area": "Área de administración", + "community": "Comunidad", + "logout": "Salir", + "members_area": "Área de afiliados", + "overview": "Resumen", + "profile": "Mi Perfil", + "send": "Enviar", + "support": "Soporte", + "transactions": "Transacciones" + }, + "qrCode": "Código QR", + "send_gdd": "Enviar GDD", + "send_per_link": "Enviar GDD mediante un enlace", + "session": { + "extend": "Permanecer en sesión iniciada", + "lightText": "Si no has realizado ninguna acción durante más de 10 minutos, se cerrará tu sesión por razones de seguridad.", + "logoutIn": "Cerrar sesión en ", + "warningText": "Aún estas?" + }, + "settings": { + "language": { + "changeLanguage": "Cambiar idioma", + "de": "Deutsch", + "en": "English", + "es": "Español", + "success": "Tu idioma ha sido cambiado con éxito." + }, + "name": { + "change-name": "Cambiar nombre", + "change-success": "Tu nombre ha sido cambiado con éxito." + }, + "newsletter": { + "newsletter": "Informaciones por correo electrónico", + "newsletterFalse": "No recibirás informaciones por correo electrónico.", + "newsletterTrue": "Recibirás informaciones por correo electrónico." + }, + "password": { + "change-password": "Cambiar contraseña", + "forgot_pwd": "Olvide la contraseña?", + "resend_subtitle": "Su enlace de activación ha caducado. Puedes solicitar uno nuevo aquí.", + "reset": "Restablecer contraseña", + "reset-password": { + "text": "Ahora introduce una nueva contraseña con la que quieras acceder a tu cuenta de Gradido en el futuro.." + }, + "send_now": "Enviar", + "set": "Establecer contraseña", + "set-password": { + "text": "Ahora guarda tu nueva contraseña, que podrás utilizar para acceder a tu cuenta de Gradido en el futuro." + }, + "subtitle": "Si has olvidado tu contraseña, puedes restablecerla aquí." + } + }, + "signin": "Iniciar sesión", + "signup": "Registrarse", + "site": { + "forgotPassword": { + "heading": "Por favor, introduce la dirección de correo electrónico con la que estas registrado en Gradido." + }, + "login": { + "heading": "Inicia sesión con tus datos de acceso. Manténlos seguros en todo momento!" + }, + "resetPassword": { + "heading": "Por favor, introduce tu contraseña y repítela." + }, + "signup": { + "agree": "Acepto la Política de privacidad.", + "dont_match": "Las contraseñas no coinciden.", + "heading": "Regístrate introduciendo todos los datos completos y en los campos correctos.", + "lowercase": "Se requiere una letra minúscula.", + "minimum": "Al menos 8 caracteres.", + "no-whitespace": "Sin espacios ni tabulaciones.", + "one_number": "Se requiere un número.", + "special-char": "Caracteres especiales requeridos (por ejemplo, _ o &)", + "uppercase": "Letra mayúscula requerida." + } + }, + "success": "Lo lograste", + "time": { + "days": "Dias", + "hours": "Horas", + "minutes": "Minutos", + "month": "Mes", + "months": "Meses", + "seconds": "Segundos", + "years": "Año" + }, + "transaction": { + "gdd-text": "Transacciones Gradido", + "gdt-text": "Transacciones GradidoTransform ", + "nullTransactions": "Todavía no tienes ninguna transacción en tu cuenta.", + "receiverDeleted": "La cuenta del destinatario ha sido eliminada.", + "receiverNotFound": "Destinatario no encontrado", + "show_all": "Ver todas las transacciones de {count}" + }, + "transaction-link": { + "send_you": "te envía" + }, + "via_link": "atraves de un enlace", + "welcome": "Bienvenido a la comunidad." +} diff --git a/frontend/src/locales/index.js b/frontend/src/locales/index.js index 4cb375b40..f36121c90 100644 --- a/frontend/src/locales/index.js +++ b/frontend/src/locales/index.js @@ -11,6 +11,12 @@ const locales = [ iso: 'de-DE', enabled: true, }, + { + name: 'Espanol', + code: 'es', + iso: 'es-ES', + enabled: true, + }, ] export default locales From 5e241c124c2a5276659ca76d1f64ea0d54bed94e Mon Sep 17 00:00:00 2001 From: ogerly Date: Sun, 7 Aug 2022 22:40:47 +0200 Subject: [PATCH 21/83] add math equal to locales es --- frontend/src/locales/es.json | 1 + frontend/src/locales/index.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index a62db9c95..31541447a 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -204,6 +204,7 @@ "login": "iniciar sesión", "math": { "aprox": "~", + "equal": "=", "minus": "−", "pipe": "|" }, diff --git a/frontend/src/locales/index.js b/frontend/src/locales/index.js index f36121c90..17d41cad2 100644 --- a/frontend/src/locales/index.js +++ b/frontend/src/locales/index.js @@ -12,7 +12,7 @@ const locales = [ enabled: true, }, { - name: 'Espanol', + name: 'Español', code: 'es', iso: 'es-ES', enabled: true, From 2c06fbdbd0338db2387bfab8830be5e3fac88b2f Mon Sep 17 00:00:00 2001 From: ogerly Date: Sun, 7 Aug 2022 22:41:26 +0200 Subject: [PATCH 22/83] add orginal file espanol exel in docu --- docu/Locales/GRADIDO_register_page_spanish.xlsx | Bin 0 -> 21840 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docu/Locales/GRADIDO_register_page_spanish.xlsx diff --git a/docu/Locales/GRADIDO_register_page_spanish.xlsx b/docu/Locales/GRADIDO_register_page_spanish.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6b6ec70c0f4895fc8850d21957403138ceee4098 GIT binary patch literal 21840 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

0iQpMuDu0WbY;&!~UT>As4Fyv&#T% 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 Date: Sun, 7 Aug 2022 22:41:57 +0200 Subject: [PATCH 23/83] refactor UserResolver.ts --- backend/src/graphql/resolver/UserResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a89a8cb0b..47aefe12d 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -43,7 +43,7 @@ const isPassword = (password: string): boolean => { return !!password.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9 \\t\\n\\r]).{8,}$/) } -const LANGUAGES = ['de', 'en'] +const LANGUAGES = ['de', 'en', 'es'] const DEFAULT_LANGUAGE = 'de' const isLanguage = (language: string): boolean => { return LANGUAGES.includes(language) From 9f9395c7ab8244a1f288b499479b2e8ef5c60164 Mon Sep 17 00:00:00 2001 From: ogerly Date: Sun, 7 Aug 2022 23:05:34 +0200 Subject: [PATCH 24/83] fix test for frontend --- .../src/components/LanguageSwitch.spec.js | 32 ++++++++++++++++--- .../src/components/LanguageSwitch2.spec.js | 28 +++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/LanguageSwitch.spec.js b/frontend/src/components/LanguageSwitch.spec.js index cf7c4a35e..1843155e1 100644 --- a/frontend/src/components/LanguageSwitch.spec.js +++ b/frontend/src/components/LanguageSwitch.spec.js @@ -45,7 +45,7 @@ describe('LanguageSwitch', () => { expect(wrapper.find('div.language-switch').exists()).toBeTruthy() }) - describe('with locales en and de', () => { + describe('with locales en, de and es', () => { describe('empty store', () => { describe('navigator language is "en-US"', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') @@ -69,11 +69,22 @@ describe('LanguageSwitch', () => { }) }) - describe('navigator language is "es-ES" (not supported)', () => { + describe('navigator language is "es-ES"', () => { + const languageGetter = jest.spyOn(navigator, 'language', 'get') + + it('shows Español as language ', async () => { + languageGetter.mockReturnValue('es-ES') + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + expect(wrapper.find('button.dropdown-toggle').text()).toBe('Español - es') + }) + }) + + describe('navigator language is "fr-FR" (not supported)', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') it('shows English as language ', async () => { - languageGetter.mockReturnValue('es-ES') + languageGetter.mockReturnValue('fr-FR') wrapper.vm.setCurrentLanguage() await wrapper.vm.$nextTick() expect(wrapper.find('button.dropdown-toggle').text()).toBe('English - en') @@ -101,9 +112,18 @@ describe('LanguageSwitch', () => { }) }) + describe('language "es" in store', () => { + it('shows Español as language', async () => { + wrapper.vm.$store.state.language = 'es' + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + expect(wrapper.find('button.dropdown-toggle').text()).toBe('Español - es') + }) + }) + describe('dropdown menu', () => { it('has English and German as languages to choose', () => { - expect(wrapper.findAll('li')).toHaveLength(2) + expect(wrapper.findAll('li')).toHaveLength(3) }) it('has English as first language to choose', () => { @@ -113,6 +133,10 @@ describe('LanguageSwitch', () => { it('has German as second language to choose', () => { expect(wrapper.findAll('li').at(1).text()).toBe('Deutsch') }) + + it('has Español as second language to choose', () => { + expect(wrapper.findAll('li').at(2).text()).toBe('Español') + }) }) }) diff --git a/frontend/src/components/LanguageSwitch2.spec.js b/frontend/src/components/LanguageSwitch2.spec.js index 600e2513e..85a8afa45 100644 --- a/frontend/src/components/LanguageSwitch2.spec.js +++ b/frontend/src/components/LanguageSwitch2.spec.js @@ -66,10 +66,19 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(1).text()).toBe('Deutsch') }) }) - describe('navigator language is "es-ES" (not supported)', () => { + describe('navigator language is "es-ES"', () => { + const languageGetter = jest.spyOn(navigator, 'language', 'get') + it('shows Español as language ', async () => { + languageGetter.mockReturnValue('es-ES') + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + expect(wrapper.findAll('span.locales').at(2).text()).toBe('Español') + }) + }) + describe('navigator language is "fr-FR" (not supported)', () => { const languageGetter = jest.spyOn(navigator, 'language', 'get') it('shows English as language ', async () => { - languageGetter.mockReturnValue('es-ES') + languageGetter.mockReturnValue('fr-FR') wrapper.vm.setCurrentLanguage() await wrapper.vm.$nextTick() expect(wrapper.findAll('span.locales').at(0).text()).toBe('English') @@ -93,9 +102,17 @@ describe('LanguageSwitch', () => { expect(wrapper.findAll('span.locales').at(1).text()).toBe('Deutsch') }) }) + describe('language "es" in store', () => { + it('shows Español as language', async () => { + wrapper.vm.$store.state.language = 'es' + wrapper.vm.setCurrentLanguage() + await wrapper.vm.$nextTick() + expect(wrapper.findAll('span.locales').at(2).text()).toBe('Español') + }) + }) describe('language menu', () => { - it('has English and German as languages to choose', () => { - expect(wrapper.findAll('span.locales')).toHaveLength(2) + it('has English, German and Español as languages to choose', () => { + expect(wrapper.findAll('span.locales')).toHaveLength(3) }) it('has English as first language to choose', () => { expect(wrapper.findAll('span.locales').at(0).text()).toBe('English') @@ -103,6 +120,9 @@ describe('LanguageSwitch', () => { it('has German as second language to choose', () => { expect(wrapper.findAll('span.locales').at(1).text()).toBe('Deutsch') }) + it('has Español as third language to choose', () => { + expect(wrapper.findAll('span.locales').at(2).text()).toBe('Español') + }) }) }) From 56bd17a265c8d80d7ebd9e6c055ff3a8f88d3c2e Mon Sep 17 00:00:00 2001 From: ogerly Date: Sun, 7 Aug 2022 23:08:44 +0200 Subject: [PATCH 25/83] fix test for backend --- backend/src/graphql/resolver/UserResolver.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index a2a499224..14e86fa1c 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -198,7 +198,7 @@ describe('UserResolver', () => { it('sets "de" as default language', async () => { await mutate({ mutation: createUser, - variables: { ...variables, email: 'bibi@bloxberg.de', language: 'es' }, + variables: { ...variables, email: 'bibi@bloxberg.de', language: 'fr' }, }) await expect(User.find()).resolves.toEqual( expect.arrayContaining([ From 3c632e0d631b8457c9b37a6ac256c55495a6fc49 Mon Sep 17 00:00:00 2001 From: ogerly Date: Mon, 8 Aug 2022 09:37:04 +0200 Subject: [PATCH 26/83] fix test add mockRouterReplace --- frontend/src/pages/Transactions.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/pages/Transactions.spec.js b/frontend/src/pages/Transactions.spec.js index d364d3be7..822a8f558 100644 --- a/frontend/src/pages/Transactions.spec.js +++ b/frontend/src/pages/Transactions.spec.js @@ -42,7 +42,7 @@ describe('Transactions', () => { query: apolloMock, }, $router: { - push: mockRouterReplace, + replace: mockRouterReplace, }, } From aa91e2b41007104fe838887def58d90bab2b9208 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 8 Aug 2022 10:48:09 +0200 Subject: [PATCH 27/83] Add RIGHTS.LIST_CONTRIBUTION_LINKS to ROLE_USER --- backend/src/auth/RIGHTS.ts | 2 +- backend/src/auth/ROLES.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index d5e2cc7ce..1e38eab7f 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -30,6 +30,7 @@ export enum RIGHTS { LIST_CONTRIBUTIONS = 'LIST_CONTRIBUTIONS', LIST_ALL_CONTRIBUTIONS = 'LIST_ALL_CONTRIBUTIONS', UPDATE_CONTRIBUTION = 'UPDATE_CONTRIBUTION', + LIST_CONTRIBUTION_LINKS = 'LIST_CONTRIBUTION_LINKS', // Admin SEARCH_USERS = 'SEARCH_USERS', SET_USER_ROLE = 'SET_USER_ROLE', @@ -45,7 +46,6 @@ export enum RIGHTS { CREATION_TRANSACTION_LIST = 'CREATION_TRANSACTION_LIST', LIST_TRANSACTION_LINKS_ADMIN = 'LIST_TRANSACTION_LINKS_ADMIN', CREATE_CONTRIBUTION_LINK = 'CREATE_CONTRIBUTION_LINK', - LIST_CONTRIBUTION_LINKS = 'LIST_CONTRIBUTION_LINKS', DELETE_CONTRIBUTION_LINK = 'DELETE_CONTRIBUTION_LINK', UPDATE_CONTRIBUTION_LINK = 'UPDATE_CONTRIBUTION_LINK', } diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index 9dcba0a4b..500c8bec4 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -28,6 +28,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.LIST_CONTRIBUTIONS, RIGHTS.LIST_ALL_CONTRIBUTIONS, RIGHTS.UPDATE_CONTRIBUTION, + RIGHTS.LIST_CONTRIBUTION_LINKS, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights From 7201fb6fc3f326e959616f41b6c65fb623ee1393 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 8 Aug 2022 10:57:56 +0200 Subject: [PATCH 28/83] A User has now the right to get listContributionLinks. --- .../src/graphql/resolver/AdminResolver.test.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index 7b1c6ffcd..69a68ead0 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -1861,7 +1861,22 @@ describe('AdminResolver', () => { it('returns an error', async () => { await expect(query({ query: listContributionLinks })).resolves.toEqual( expect.objectContaining({ - errors: [new GraphQLError('401 Unauthorized')], + data: { + createContributionLink: expect.objectContaining({ + id: expect.any(Number), + amount: '200', + code: expect.stringMatching(/^[0-9a-f]{24,24}$/), + link: expect.stringMatching(/^.*?\/CL-[0-9a-f]{24,24}$/), + createdAt: expect.any(String), + name: 'Dokumenta 2022', + memo: 'Danke für deine Teilnahme an der Dokumenta 2022', + validFrom: expect.any(String), + validTo: expect.any(String), + maxAmountPerMonth: '200', + cycle: 'once', + maxPerCycle: 1, + }), + }, }), ) }) From 5fb491572dbed5377ef7aa5715a6e7b9ee4fa5dd Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 8 Aug 2022 11:04:24 +0200 Subject: [PATCH 29/83] Change test for listCOntributionLinks to get empty object as user without admin rights. --- .../graphql/resolver/AdminResolver.test.ts | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index 69a68ead0..c0531a96c 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -1858,24 +1858,14 @@ describe('AdminResolver', () => { }) describe('listContributionLinks', () => { - it('returns an error', async () => { + it('returns an empty object', async () => { await expect(query({ query: listContributionLinks })).resolves.toEqual( expect.objectContaining({ data: { - createContributionLink: expect.objectContaining({ - id: expect.any(Number), - amount: '200', - code: expect.stringMatching(/^[0-9a-f]{24,24}$/), - link: expect.stringMatching(/^.*?\/CL-[0-9a-f]{24,24}$/), - createdAt: expect.any(String), - name: 'Dokumenta 2022', - memo: 'Danke für deine Teilnahme an der Dokumenta 2022', - validFrom: expect.any(String), - validTo: expect.any(String), - maxAmountPerMonth: '200', - cycle: 'once', - maxPerCycle: 1, - }), + listContributionLinks: { + count: 0, + links: [], + }, }, }), ) From 9a7073415c51fc21bb3595f9429b5259aa9b2839 Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 8 Aug 2022 11:14:11 +0200 Subject: [PATCH 30/83] Add TODO for listContributionLinks test of user without admin rights. --- backend/src/graphql/resolver/AdminResolver.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index c0531a96c..f0ce064b4 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -1857,6 +1857,7 @@ describe('AdminResolver', () => { }) }) + // TODO: Set this test in new location to have datas describe('listContributionLinks', () => { it('returns an empty object', async () => { await expect(query({ query: listContributionLinks })).resolves.toEqual( From d377fc0241ef9c0cc53018c015c545cdbb2b33bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 8 Aug 2022 11:25:49 +0200 Subject: [PATCH 31/83] Add invalid tests for memo length --- .../Contributions/ContributionForm.spec.js | 277 ++++++++++++------ .../Contributions/ContributionForm.vue | 2 + 2 files changed, 196 insertions(+), 83 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 52e876de9..6d6f2164b 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -66,58 +66,118 @@ describe('ContributionForm', () => { const now = new Date().toISOString() beforeEach(async () => { - await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) - await wrapper - .find('#contribution-memo') - .find('textarea') - .setValue('Mein Beitrag zur Gemeinschaft für diesen Monat ...') - await wrapper.find('#contribution-amount').find('input').setValue('200') + await wrapper.setData({ + form: { + id: null, + date: '', + memo: '', + amount: '', + }, + }) }) - describe('buttons', () => { - describe('reset', () => { - it('has enabled', () => { - expect( - wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), - ).toBeFalsy() + describe('invalid form data', () => { + beforeEach(async () => { + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper.find('#contribution-amount').find('input').setValue('200') + }) + + describe('memo lenght < 5, others are valid', () => { + beforeEach(async () => { + await wrapper.find('#contribution-memo').find('textarea').setValue('1234') + }) + + describe('buttons', () => { + describe('submit', () => { + it('has disabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBe('disabled') + }) + }) }) }) - describe('submit', () => { - it('has enabled', () => { - expect( - wrapper.find('button[data-test="button-submit"]').attributes('disabled'), - ).toBeFalsy() + describe('memo lenght > 255, others are valid', () => { + beforeEach(async () => { + await wrapper + .find('#contribution-memo') + .find('textarea') + .setValue( + '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' + + '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' + + '01234567890123456789012345678901234567890123456789012345', + ) + await wrapper.vm.$nextTick() }) - it('has label "contribution.submit"', () => { - expect(wrapper.find('button[data-test="button-submit"]').text()).toContain( - 'contribution.submit', + describe('buttons', () => { + describe('submit', () => { + it('has disabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBe('disabled') + }) + }) + }) + }) + }) + + describe('valid form data', () => { + beforeEach(async () => { + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper + .find('#contribution-memo') + .find('textarea') + .setValue('Mein Beitrag zur Gemeinschaft für diesen Monat ...') + await wrapper.find('#contribution-amount').find('input').setValue('200') + }) + + describe('buttons', () => { + describe('reset', () => { + it('has enabled', () => { + expect( + wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), + ).toBeFalsy() + }) + }) + + describe('submit', () => { + it('has enabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBeFalsy() + }) + + it('has label "contribution.submit"', () => { + expect(wrapper.find('button[data-test="button-submit"]').text()).toContain( + 'contribution.submit', + ) + }) + }) + }) + + describe('on trigger submit', () => { + beforeEach(async () => { + await wrapper.find('form').trigger('submit') + }) + + it('emits "set-contribution"', () => { + expect(wrapper.emitted('set-contribution')).toEqual( + expect.arrayContaining([ + expect.arrayContaining([ + { + id: null, + date: now, + memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + amount: '200', + }, + ]), + ]), ) }) }) }) - - describe('on trigger submit', () => { - beforeEach(async () => { - await wrapper.find('form').trigger('submit') - }) - - it('emits "set-contribution"', () => { - expect(wrapper.emitted('set-contribution')).toEqual( - expect.arrayContaining([ - expect.arrayContaining([ - { - id: null, - date: now, - memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', - amount: '200', - }, - ]), - ]), - ) - }) - }) }) }) @@ -126,7 +186,6 @@ describe('ContributionForm', () => { const now = new Date().toISOString() beforeEach(async () => { - wrapper = Wrapper() await wrapper.setData({ form: { id: 2, @@ -135,58 +194,110 @@ describe('ContributionForm', () => { amount: '100', }, }) - await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) - await wrapper - .find('#contribution-memo') - .find('textarea') - .setValue('Mein Beitrag zur Gemeinschaft für diesen Monat ...') - await wrapper.find('#contribution-amount').find('input').setValue('200') }) - describe('buttons', () => { - describe('reset', () => { - it('has enabled', () => { - expect( - wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), - ).toBeFalsy() + describe('invalid form data', () => { + beforeEach(async () => { + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper.find('#contribution-amount').find('input').setValue('200') + }) + + describe('memo lenght < 5, others are valid', () => { + beforeEach(async () => { + await wrapper.find('#contribution-memo').find('textarea').setValue('1234') + }) + + describe('buttons', () => { + describe('submit', () => { + it('has disabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBe('disabled') + }) + }) }) }) - describe('submit', () => { - it('has enabled', () => { - expect( - wrapper.find('button[data-test="button-submit"]').attributes('disabled'), - ).toBeFalsy() + describe('memo lenght > 255, others are valid', () => { + beforeEach(async () => { + await wrapper + .find('#contribution-memo') + .find('textarea') + .setValue( + '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' + + '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' + + '01234567890123456789012345678901234567890123456789012345', + ) + await wrapper.vm.$nextTick() }) - it('has label "form.change"', () => { - expect(wrapper.find('button[data-test="button-submit"]').text()).toContain( - 'form.change', + describe('buttons', () => { + describe('submit', () => { + it('has disabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBe('disabled') + }) + }) + }) + }) + }) + + describe('valid form data', () => { + beforeEach(async () => { + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper + .find('#contribution-memo') + .find('textarea') + .setValue('Mein Beitrag zur Gemeinschaft für diesen Monat ...') + await wrapper.find('#contribution-amount').find('input').setValue('200') + }) + + describe('buttons', () => { + describe('reset', () => { + it('has enabled', () => { + expect( + wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), + ).toBeFalsy() + }) + }) + + describe('submit', () => { + it('has enabled', () => { + expect( + wrapper.find('button[data-test="button-submit"]').attributes('disabled'), + ).toBeFalsy() + }) + + it('has label "form.change"', () => { + expect(wrapper.find('button[data-test="button-submit"]').text()).toContain( + 'form.change', + ) + }) + }) + }) + + describe('on trigger submit', () => { + beforeEach(async () => { + await wrapper.find('form').trigger('submit') + }) + + it('emits "update-contribution"', () => { + expect(wrapper.emitted('update-contribution')).toEqual( + expect.arrayContaining([ + expect.arrayContaining([ + { + id: 2, + date: now, + memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', + amount: '200', + }, + ]), + ]), ) }) }) }) - - describe('on trigger submit', () => { - beforeEach(async () => { - await wrapper.find('form').trigger('submit') - }) - - it('emits "update-contribution"', () => { - expect(wrapper.emitted('update-contribution')).toEqual( - expect.arrayContaining([ - expect.arrayContaining([ - { - id: 2, - date: now, - memo: 'Mein Beitrag zur Gemeinschaft für diesen Monat ...', - amount: '200', - }, - ]), - ]), - ) - }) - }) }) }) }) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 19731c683..d890e6a1e 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -127,9 +127,11 @@ export default { return new Date(this.maximalDate.getFullYear(), this.maximalDate.getMonth() - 1, 1) }, disabled() { + // Wolle: refactor if ( this.form.date === '' || this.form.memo.length < this.minlength || + this.form.memo.length > this.maxlength || this.form.amount <= 0 || this.form.amount > 1000 || (this.isThisMonth && parseInt(this.form.amount) > parseInt(this.maxGddThisMonth)) || From d49a99fcfffc16628d8b9ea399b6830758ab134d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 8 Aug 2022 11:28:31 +0200 Subject: [PATCH 32/83] Refactor method 'disabled' --- frontend/src/components/Contributions/ContributionForm.vue | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index d890e6a1e..e9feb72d7 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -127,8 +127,7 @@ export default { return new Date(this.maximalDate.getFullYear(), this.maximalDate.getMonth() - 1, 1) }, disabled() { - // Wolle: refactor - if ( + return ( this.form.date === '' || this.form.memo.length < this.minlength || this.form.memo.length > this.maxlength || @@ -137,8 +136,6 @@ export default { (this.isThisMonth && parseInt(this.form.amount) > parseInt(this.maxGddThisMonth)) || (!this.isThisMonth && parseInt(this.form.amount) > parseInt(this.maxGddLastMonth)) ) - return true - return false }, lastMonthObject() { // Wolle: refine logic and melt with 'thisMonthObject' From 1d63d5bf70ee3fc6c84f7e9892ab91ab6abfa000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 8 Aug 2022 14:40:55 +0200 Subject: [PATCH 33/83] Remove yarn package 'jest-environment-jsdom-sixteen', because it's not needed anymore since jest@v26 --- admin/jest.config.js | 2 +- admin/package.json | 1 - admin/yarn.lock | 80 +---------------- frontend/jest.config.js | 2 +- frontend/package.json | 1 - frontend/yarn.lock | 195 +++------------------------------------- 6 files changed, 13 insertions(+), 268 deletions(-) diff --git a/admin/jest.config.js b/admin/jest.config.js index 9b9842bad..3e416e7b6 100644 --- a/admin/jest.config.js +++ b/admin/jest.config.js @@ -26,5 +26,5 @@ module.exports = { testMatch: ['**/?(*.)+(spec|test).js?(x)'], // snapshotSerializers: ['jest-serializer-vue'], transformIgnorePatterns: ['/node_modules/(?!vee-validate/dist/rules)'], - testEnvironment: 'jest-environment-jsdom-sixteen', + // testEnvironment: 'jest-environment-jsdom-sixteen', // not needed anymore since jest@26, see: https://www.npmjs.com/package/jest-environment-jsdom-sixteen } diff --git a/admin/package.json b/admin/package.json index 5da80bd1f..98746be6d 100644 --- a/admin/package.json +++ b/admin/package.json @@ -70,7 +70,6 @@ "eslint-plugin-prettier": "3.3.1", "eslint-plugin-promise": "^5.1.1", "eslint-plugin-vue": "^7.20.0", - "jest-environment-jsdom-sixteen": "^2.0.0", "postcss": "^8.4.8", "postcss-html": "^1.3.0", "postcss-scss": "^4.0.3", diff --git a/admin/yarn.lock b/admin/yarn.lock index 09b543354..b5b76cee8 100644 --- a/admin/yarn.lock +++ b/admin/yarn.lock @@ -1282,17 +1282,6 @@ jest-message-util "^24.9.0" jest-mock "^24.9.0" -"@jest/fake-timers@^25.1.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.5.0.tgz#46352e00533c024c90c2bc2ad9f2959f7f114185" - integrity sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ== - dependencies: - "@jest/types" "^25.5.0" - jest-message-util "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - lolex "^5.0.0" - "@jest/fake-timers@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" @@ -1504,16 +1493,6 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@jest/types@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" - integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -4130,14 +4109,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4 escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -8012,16 +7983,6 @@ jest-environment-jsdom-fifteen@^1.0.2: jest-util "^24.0.0" jsdom "^15.2.1" -jest-environment-jsdom-sixteen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom-sixteen/-/jest-environment-jsdom-sixteen-2.0.0.tgz#0f8c12663ccd9836d248574decffc575bfb091e1" - integrity sha512-BF+8P67aEJcd78TQzwSb9P4a73cArOWb5KgqI8eU6cHRWDIJdDRE8XTeZAmOuDSDhKpuEXjKkXwWB3GOJvqHJQ== - dependencies: - "@jest/fake-timers" "^25.1.0" - jest-mock "^25.1.0" - jest-util "^25.1.0" - jsdom "^16.2.1" - jest-environment-jsdom@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" @@ -8236,20 +8197,6 @@ jest-message-util@^24.9.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-message-util@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea" - integrity sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/types" "^25.5.0" - "@types/stack-utils" "^1.0.1" - chalk "^3.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.2" - slash "^3.0.0" - stack-utils "^1.0.1" - jest-message-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" @@ -8272,13 +8219,6 @@ jest-mock@^24.0.0, jest-mock@^24.9.0: dependencies: "@jest/types" "^24.9.0" -jest-mock@^25.1.0, jest-mock@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.5.0.tgz#a91a54dabd14e37ecd61665d6b6e06360a55387a" - integrity sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA== - dependencies: - "@jest/types" "^25.5.0" - jest-mock@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" @@ -8555,17 +8495,6 @@ jest-util@^24.0.0, jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" -jest-util@^25.1.0, jest-util@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.5.0.tgz#31c63b5d6e901274d264a4fec849230aa3fa35b0" - integrity sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA== - dependencies: - "@jest/types" "^25.5.0" - chalk "^3.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - make-dir "^3.0.0" - jest-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" @@ -8812,7 +8741,7 @@ jsdom@^15.2.1: ws "^7.0.0" xml-name-validator "^3.0.0" -jsdom@^16.2.1, jsdom@^16.4.0: +jsdom@^16.4.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== @@ -9167,13 +9096,6 @@ loglevel@^1.6.8: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== -lolex@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== - dependencies: - "@sinonjs/commons" "^1.7.0" - loose-envify@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" diff --git a/frontend/jest.config.js b/frontend/jest.config.js index 2a52ec707..a32330f3b 100644 --- a/frontend/jest.config.js +++ b/frontend/jest.config.js @@ -23,5 +23,5 @@ module.exports = { testMatch: ['**/?(*.)+(spec|test).js?(x)'], // snapshotSerializers: ['jest-serializer-vue'], transformIgnorePatterns: ['/node_modules/(?!vee-validate/dist/rules)'], - testEnvironment: 'jest-environment-jsdom-sixteen', + // testEnvironment: 'jest-environment-jsdom-sixteen', // not needed anymore since jest@26, see: https://www.npmjs.com/package/jest-environment-jsdom-sixteen } diff --git a/frontend/package.json b/frontend/package.json index 71baf4764..8121e2ca2 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,7 +44,6 @@ "identity-obj-proxy": "^3.0.0", "jest": "^26.6.3", "jest-canvas-mock": "^2.3.1", - "jest-environment-jsdom-sixteen": "^2.0.0", "jwt-decode": "^3.1.2", "portal-vue": "^2.1.7", "prettier": "^2.2.1", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 829b63dcf..fe7ab7947 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2156,17 +2156,6 @@ jest-message-util "^24.9.0" jest-mock "^24.9.0" -"@jest/fake-timers@^25.1.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.5.0.tgz#46352e00533c024c90c2bc2ad9f2959f7f114185" - integrity sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ== - dependencies: - "@jest/types" "^25.5.0" - jest-message-util "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - lolex "^5.0.0" - "@jest/fake-timers@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" @@ -2378,16 +2367,6 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@jest/types@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" - integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -2482,11 +2461,6 @@ string-width "^2.0.0" strip-ansi "^5" -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7": version "7.1.17" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.17.tgz#f50ac9d20d64153b510578d84f9643f9a3afbe64" @@ -3293,11 +3267,6 @@ acorn@^8.0.5: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== -acorn@^8.2.4: - version "8.6.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" - integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== - acorn@^8.5.0, acorn@^8.7.0: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" @@ -3308,13 +3277,6 @@ address@^1.0.3: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -4657,14 +4619,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4 escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -4995,7 +4949,7 @@ colors@^1.1.2: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -5578,13 +5532,6 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== - dependencies: - ms "2.1.2" - debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -5599,6 +5546,13 @@ debug@^4.0.1, debug@^4.1.1: dependencies: ms "2.1.2" +debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -7162,15 +7116,6 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -7864,15 +7809,6 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -7906,14 +7842,6 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -8430,11 +8358,6 @@ is-potential-custom-element-name@^1.0.0: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - is-regex@^1.0.4, is-regex@^1.1.1, is-regex@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" @@ -8849,16 +8772,6 @@ jest-environment-jsdom-fifteen@^1.0.2: jest-util "^24.0.0" jsdom "^15.2.1" -jest-environment-jsdom-sixteen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom-sixteen/-/jest-environment-jsdom-sixteen-2.0.0.tgz#0f8c12663ccd9836d248574decffc575bfb091e1" - integrity sha512-BF+8P67aEJcd78TQzwSb9P4a73cArOWb5KgqI8eU6cHRWDIJdDRE8XTeZAmOuDSDhKpuEXjKkXwWB3GOJvqHJQ== - dependencies: - "@jest/fake-timers" "^25.1.0" - jest-mock "^25.1.0" - jest-util "^25.1.0" - jsdom "^16.2.1" - jest-environment-jsdom@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" @@ -9073,20 +8986,6 @@ jest-message-util@^24.9.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-message-util@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea" - integrity sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/types" "^25.5.0" - "@types/stack-utils" "^1.0.1" - chalk "^3.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.2" - slash "^3.0.0" - stack-utils "^1.0.1" - jest-message-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" @@ -9109,13 +9008,6 @@ jest-mock@^24.0.0, jest-mock@^24.9.0: dependencies: "@jest/types" "^24.9.0" -jest-mock@^25.1.0, jest-mock@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.5.0.tgz#a91a54dabd14e37ecd61665d6b6e06360a55387a" - integrity sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA== - dependencies: - "@jest/types" "^25.5.0" - jest-mock@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" @@ -9392,17 +9284,6 @@ jest-util@^24.0.0, jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" -jest-util@^25.1.0, jest-util@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.5.0.tgz#31c63b5d6e901274d264a4fec849230aa3fa35b0" - integrity sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA== - dependencies: - "@jest/types" "^25.5.0" - chalk "^3.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - make-dir "^3.0.0" - jest-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" @@ -9655,39 +9536,6 @@ jsdom@^15.2.1: ws "^7.0.0" xml-name-validator "^3.0.0" -jsdom@^16.2.1: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - jsdom@^16.4.0: version "16.5.1" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.1.tgz#4ced6bbd7b77d67fb980e64d9e3e6fb900f97dd6" @@ -10050,7 +9898,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.7.0: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -10067,13 +9915,6 @@ loglevel@^1.6.8: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== -lolex@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== - dependencies: - "@sinonjs/commons" "^1.7.0" - loose-envify@^1.0.0, loose-envify@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -13848,13 +13689,6 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -14792,15 +14626,6 @@ whatwg-url@^8.0.0: tr46 "^2.0.2" webidl-conversions "^6.1.0" -whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - which-boxed-primitive@^1.0.1, which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -14923,7 +14748,7 @@ ws@^6.0.0, ws@^6.2.1: dependencies: async-limiter "~1.0.0" -ws@^7.0.0, ws@^7.4.6: +ws@^7.0.0: version "7.5.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== From 6d38b9a23278c8dc807659ae2b8092fb2fc302a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 8 Aug 2022 14:43:03 +0200 Subject: [PATCH 34/83] Add date test that didn't work unfortunately for now and be skipped --- .../Contributions/ContributionForm.spec.js | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 6d6f2164b..1cb2b3e8a 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -61,6 +61,117 @@ describe('ContributionForm', () => { }) }) + describe('dates', () => { + beforeEach(async () => { + await wrapper.setData({ + form: { + id: null, + date: '', + memo: '', + amount: '', + }, + }) + }) + + describe('actual date', () => { + describe('same month', () => { + beforeEach(async () => { + const now = new Date().toISOString() + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + }) + + describe('isThisMonth', () => { + it('has true', () => { + expect(wrapper.vm.isThisMonth).toBe(true) + }) + }) + }) + + describe('month before', () => { + beforeEach(async () => { + await wrapper + .findComponent({ name: 'BFormDatepicker' }) + .vm.$emit('input', wrapper.vm.minimalDate) + }) + + describe('isThisMonth', () => { + it('has false', () => { + expect(wrapper.vm.isThisMonth).toBe(false) + }) + }) + }) + }) + + // jest-environment-jsdom-sixteen + // testEnvironment: 'jest-environment-jsdom-sixteen', + // https://www.npmjs.com/package/jest-environment-jsdom-sixteen + // https://dev.to/philw_/problems-with-using-usefaketimersmodern-in-a-create-react-app-cra-project-with-jest-26-and-lodashs-debounce-function-3ohd + describe.skip('date in middle of year', () => { + describe('same month', () => { + beforeEach(async () => { + jest.useFakeTimers('modern') + jest.setSystemTime(new Date('2020-07-06')) + const now = new Date().toISOString() + // Wolle: console.log('middle of year date – now:', now) + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + }) + + describe('isThisMonth', () => { + it('has true', () => { + expect(wrapper.vm.isThisMonth).toBe(true) + }) + }) + }) + + describe('month before', () => { + beforeEach(async () => { + // Wolle: console.log('middle of year date – now:', wrapper.vm.minimalDate) + await wrapper + .findComponent({ name: 'BFormDatepicker' }) + .vm.$emit('input', wrapper.vm.minimalDate) + }) + + describe('isThisMonth', () => { + it('has false', () => { + expect(wrapper.vm.isThisMonth).toBe(false) + }) + }) + }) + }) + + describe.skip('date in january', () => { + describe('same month', () => { + beforeEach(async () => { + jest.useFakeTimers('modern').setSystemTime(new Date('2020-01-12')) + const now = new Date().toISOString() + // Wolle: console.log('in january date – now:', now) + await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + }) + + describe('isThisMonth', () => { + it('has true', () => { + expect(wrapper.vm.isThisMonth).toBe(true) + }) + }) + }) + + describe('month before', () => { + beforeEach(async () => { + // Wolle: console.log('in january date – wrapper.vm.minimalDate:', wrapper.vm.minimalDate) + await wrapper + .findComponent({ name: 'BFormDatepicker' }) + .vm.$emit('input', wrapper.vm.minimalDate) + }) + + describe('isThisMonth', () => { + it('has false', () => { + expect(wrapper.vm.isThisMonth).toBe(false) + }) + }) + }) + }) + }) + describe('set contrubtion', () => { describe('fill in form data with "id === null"', () => { const now = new Date().toISOString() From b21f52c9455c2c5ae1bd98d726e5660d0d90249b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 8 Aug 2022 14:45:34 +0200 Subject: [PATCH 35/83] Refactor 'isThisMonth' and 'minimalDate' as well as replace 'lastMonthObject' and 'thisMonthObject' by 'textForMonth' --- .../Contributions/ContributionForm.vue | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index e9feb72d7..aa14e08f3 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -4,8 +4,8 @@

{{ $t('contribution.formText.yourContribution') }}

{{ $t('contribution.formText.bringYourTalentsTo') }}
    -
  • -
  • +
  • +
@@ -106,7 +106,8 @@ export default { submit() { // not working for testing: // this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', this.form) - // works for testing, why ever, we have to make a spread '...', to evaluate the values it looks like: (I didn't find a solution in the test itmself) + // works for testing: + // why ever, we have to make a spread '...', to evaluate the values it looks like: (I didn't find a solution in the test itmself) this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', { ...this.form }) this.reset() }, @@ -117,14 +118,20 @@ export default { this.form.memo = '' this.form.amount = '' }, + textForMonth(date, availableAmount) { + const obj = { + monthAndYear: this.$d(date, 'monthAndYear'), + creation: availableAmount, + } + return this.$t('contribution.formText.openAmountForMonth', obj) + }, }, computed: { - /* - * minimalDate() = Sets the date to the 1st of the previous month. - * - */ + // sets the date to the 1st of the previous month minimalDate() { - return new Date(this.maximalDate.getFullYear(), this.maximalDate.getMonth() - 1, 1) + const month = this.maximalDate.getMonth() + const year = this.maximalDate.getFullYear() + return new Date(year + (month === 0 ? -1 : 0), month === 0 ? 11 : month - 1, 1) }, disabled() { return ( @@ -137,37 +144,22 @@ export default { (!this.isThisMonth && parseInt(this.form.amount) > parseInt(this.maxGddLastMonth)) ) }, - lastMonthObject() { - // Wolle: refine logic and melt with 'thisMonthObject' - // new Date().getMonth === 1 If the current month is January, then one year must be gone back in the previous month - const obj = { - monthAndYear: this.$d(new Date(this.minimalDate), 'monthAndYear'), - creation: this.maxGddLastMonth, - } - return this.$t('contribution.formText.openAmountForMonth', obj) - }, - thisMonthObject() { - // Wolle: refine logic and melt with 'lastMonthObject' - const obj = { - monthAndYear: this.$d(new Date(), 'monthAndYear'), - creation: this.maxGddThisMonth, - } - return this.$t('contribution.formText.openAmountForMonth', obj) - }, isThisMonth() { - // Wolle: Jahr testen - return new Date(this.form.date).getMonth() === new Date().getMonth() + const formDate = new Date(this.form.date) + const actualDate = new Date() + return ( + formDate.getFullYear() === actualDate.getFullYear() && + formDate.getMonth() === actualDate.getMonth() + ) }, maxGddLastMonth() { - // Wolle: refine logic and melt with 'maxGddThisMonth' - // When edited, the amount is added back on top of the amount + // when existing contribution is edited, the amount is added back on top of the amount return this.form.id && !this.isThisMonth ? parseInt(this.$store.state.creation[1]) + parseInt(this.updateAmount) : this.$store.state.creation[1] }, maxGddThisMonth() { - // Wolle: refine logic and melt with 'maxGddLastMonth' - // When edited, the amount is added back on top of the amount + // when existing contribution is edited, the amount is added back on top of the amount return this.form.id && this.isThisMonth ? parseInt(this.$store.state.creation[2]) + parseInt(this.updateAmount) : this.$store.state.creation[2] From adef450bd0781ca8c637962d8707af9195d6225f Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Mon, 8 Aug 2022 15:24:50 +0200 Subject: [PATCH 36/83] Update ContributionForm.vue --- frontend/src/components/Contributions/ContributionForm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 03fc08a92..3dda5ea41 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -106,7 +106,7 @@ export default { }, methods: { numberFormat(value) { - return (this.form.amount = value.replace(/\.|,/, '')) + return (this.form.amount = value.replace(/\.|,, '')) }, submit() { this.numberFormat(this.form.amount) From 1fbea40c4dca6da4776f5493c7357f69a9946914 Mon Sep 17 00:00:00 2001 From: ogerly Date: Mon, 8 Aug 2022 15:27:42 +0200 Subject: [PATCH 37/83] remove regex --- frontend/src/components/Contributions/ContributionForm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 3dda5ea41..03fc08a92 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -106,7 +106,7 @@ export default { }, methods: { numberFormat(value) { - return (this.form.amount = value.replace(/\.|,, '')) + return (this.form.amount = value.replace(/\.|,/, '')) }, submit() { this.numberFormat(this.form.amount) From 3a2f27f519fbdd0b5e865674c96d66042e9ed436 Mon Sep 17 00:00:00 2001 From: ogerly Date: Mon, 8 Aug 2022 16:57:14 +0200 Subject: [PATCH 38/83] refactor amount to string in ContributionForm, fix thousand error --- .../components/Contributions/ContributionForm.vue | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 03fc08a92..5fad059fb 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -51,13 +51,11 @@ - + @@ -106,10 +104,10 @@ export default { }, methods: { numberFormat(value) { - return (this.form.amount = value.replace(/\.|,/, '')) + return value.replace(/\D/g, '') }, submit() { - this.numberFormat(this.form.amount) + this.form.amount = this.numberFormat(this.form.amount) if (this.form.id) { this.$emit('update-contribution', this.form) } else { @@ -137,8 +135,8 @@ export default { if ( this.form.date === '' || this.form.memo.length < this.minlength || - this.form.amount <= 0 || - this.form.amount > 1000 || + parseInt(this.form.amount) <= 0 || + parseInt(this.form.amount) > 1000 || (this.isThisMonth && parseInt(this.form.amount) > parseInt(this.maxGddThisMonth)) || (!this.isThisMonth && parseInt(this.form.amount) > parseInt(this.maxGddLastMonth)) ) From 0284ecb9265acdb0f29167c5f94e4ab705828cef Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 9 Aug 2022 08:54:04 +0200 Subject: [PATCH 39/83] add missing values --- frontend/src/locales/es.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 31541447a..d9eb9dbf6 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -55,7 +55,8 @@ "selectDate": "¿Cuando fue tu contribución?", "submit": "Enviar", "submitted": "Tu contribución ha sido enviada.", - "updated": "La contribución se modificó." + "updated": "La contribución se modificó.", + "yourActivity": "¡Por favor, introduzca una actividad!" }, "contribution-link": { "thanksYouWith": "agradecidos con" @@ -117,6 +118,7 @@ "from": "De", "generate_now": "crear ahora", "lastname": "Apellido", + "mandatoryField": "campo obligatorio", "memo": "Mensaje", "message": "Notcia", "new_balance": "Saldo de cuenta nuevo depués de confirmación", @@ -204,6 +206,7 @@ "login": "iniciar sesión", "math": { "aprox": "~", + "asterisk": "*", "equal": "=", "minus": "−", "pipe": "|" From 506ba5b625858a6d2acffad2cdc1c02766b33e4e Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:22:36 +0200 Subject: [PATCH 40/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index d9eb9dbf6..1eaabb3b6 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -36,7 +36,7 @@ "alert": { "communityNoteList": "Aquí encontrarás todas las contribuciones enviadas y confirmadas de todos los miembros de esta comunidad..", "confirm": "confirmado", - "myContributionNoteList": "Puedes editar o eliminar las contribuciones enviadas que aún no han sido confirmadas en cualquier momento..", + "myContributionNoteList": "Puedes editar o eliminar las contribuciones enviadas que aún no han sido confirmadas en cualquier momento.", "myContributionNoteSupport": "Pronto existirá la posibilidad de que puedas dialogar con los moderadores. Si tienes algún problema ahora, ponte en contacto con el equipo de asistencia..", "pending": "Enviado y a la espera de confirmación", "rejected": "rechazado" From 08b439a53d44fd542b12a0c5907e249abd2bbd23 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:22:47 +0200 Subject: [PATCH 41/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 1eaabb3b6..078834d54 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -93,7 +93,7 @@ }, "followUs": "sigue nos:", "footer": { - "app_version": "App version {version}", + "app_version": "App versión {version}", "copyright": { "link": "Gradido-Akademie", "year": "© {year}" From 7e94822d94591086c5da56791728f06384483e40 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:23:01 +0200 Subject: [PATCH 42/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 078834d54..4ec4409a2 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -120,7 +120,7 @@ "lastname": "Apellido", "mandatoryField": "campo obligatorio", "memo": "Mensaje", - "message": "Notcia", + "message": "Noticia", "new_balance": "Saldo de cuenta nuevo depués de confirmación", "no_gdd_available": "No dispones de GDD para enviar.", "password": "Contraseña", From a1a103bb6d84c4765272e4d33f769850de659b67 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:23:14 +0200 Subject: [PATCH 43/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 4ec4409a2..d2eaaf658 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -98,7 +98,7 @@ "link": "Gradido-Akademie", "year": "© {year}" }, - "imprint": "Impressum", + "imprint": "Aviso legal", "privacy_policy": "Protección de Datos", "short_hash": "({shortHash})", "whitepaper": "Whitepaper" From 262bde615c456b875000503c2e692b2184290d44 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:23:35 +0200 Subject: [PATCH 44/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index d2eaaf658..d3b507841 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -56,7 +56,7 @@ "submit": "Enviar", "submitted": "Tu contribución ha sido enviada.", "updated": "La contribución se modificó.", - "yourActivity": "¡Por favor, introduzca una actividad!" + "yourActivity": "¡Por favor, introduce una actividad!" }, "contribution-link": { "thanksYouWith": "agradecidos con" From 05fb34fc801eb55c71d1bfcdaee7caff5b18719d Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:23:45 +0200 Subject: [PATCH 45/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index d3b507841..15064a16b 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -163,7 +163,7 @@ "expiredOn": "Vencido el:", "has-account": "Ya tienes una cuenta Gradido?", "header": "Transferir Gradidos por medio de un enlace", - "isFree": "Gradido es gratis en todo el mundoi.", + "isFree": "Gradido es gratis en todo el mundo.", "link-and-text-copied": "El enlace y su mensaje se han copiado en el portapapeles. Ahora puedes ponerlo en un correo electrónico o mensaje einfügen.", "link-copied": "El enlace se ha copiado en el portapapeles. Ahora puedes pegarlo en un correo electrónico o mensaje.", "link-deleted": "El enlace se eliminó el {date}.", From 36e86438b1ce3eede004134098468eabb5e6fd66 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:23:57 +0200 Subject: [PATCH 46/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 15064a16b..c491d50a0 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -34,7 +34,7 @@ "contribution": { "activity": "Actividad", "alert": { - "communityNoteList": "Aquí encontrarás todas las contribuciones enviadas y confirmadas de todos los miembros de esta comunidad..", + "communityNoteList": "Aquí encontrarás todas las contribuciones enviadas y confirmadas de todos los miembros de esta comunidad.", "confirm": "confirmado", "myContributionNoteList": "Puedes editar o eliminar las contribuciones enviadas que aún no han sido confirmadas en cualquier momento.", "myContributionNoteSupport": "Pronto existirá la posibilidad de que puedas dialogar con los moderadores. Si tienes algún problema ahora, ponte en contacto con el equipo de asistencia..", From 99d23990dd03abe52cce45a90a80fc8f3f93bbea Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:24:07 +0200 Subject: [PATCH 47/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index c491d50a0..936c7576e 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -11,7 +11,7 @@ "gratitude": "Gratitud", "hasAccount": "Ya estas registrado?", "hereLogin": "Registrate aquí", - "learnMore": "Informate aquí …", + "learnMore": "Infórmate aquí …", "oneDignity": "Damos los unos a los otros y agradecemos con Gradido.", "oneDonation": "Eres un regalo para la comunidad. 1000 gracias por estar con nosotros.", "oneGratitude": "Por los demás, por toda la humanidad, por la naturaleza." From 81fd9910aab0148bea37f045fcb520f41b5b7f2c Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:24:56 +0200 Subject: [PATCH 48/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 936c7576e..ed4277cd3 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -164,7 +164,7 @@ "has-account": "Ya tienes una cuenta Gradido?", "header": "Transferir Gradidos por medio de un enlace", "isFree": "Gradido es gratis en todo el mundo.", - "link-and-text-copied": "El enlace y su mensaje se han copiado en el portapapeles. Ahora puedes ponerlo en un correo electrónico o mensaje einfügen.", + "link-and-text-copied": "El enlace y su mensaje se han copiado en el portapapeles. Ahora puedes ponerlo en un correo electrónico o mensaje.", "link-copied": "El enlace se ha copiado en el portapapeles. Ahora puedes pegarlo en un correo electrónico o mensaje.", "link-deleted": "El enlace se eliminó el {date}.", "link-expired": "El enlace ya no es válido. La validez expiró el {date}.", From 200af0ebd7e6dd9044bbc6953cfada989e449d1c Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:25:09 +0200 Subject: [PATCH 49/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index ed4277cd3..100c35413 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -37,7 +37,7 @@ "communityNoteList": "Aquí encontrarás todas las contribuciones enviadas y confirmadas de todos los miembros de esta comunidad.", "confirm": "confirmado", "myContributionNoteList": "Puedes editar o eliminar las contribuciones enviadas que aún no han sido confirmadas en cualquier momento.", - "myContributionNoteSupport": "Pronto existirá la posibilidad de que puedas dialogar con los moderadores. Si tienes algún problema ahora, ponte en contacto con el equipo de asistencia..", + "myContributionNoteSupport": "Pronto existirá la posibilidad de que puedas dialogar con los moderadores. Si tienes algún problema ahora, ponte en contacto con el equipo de asistencia.", "pending": "Enviado y a la espera de confirmación", "rejected": "rechazado" }, From dce0038169c6e1f9cc312895a751939beb127f64 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:25:29 +0200 Subject: [PATCH 50/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 100c35413..cc8cd34f3 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -47,7 +47,7 @@ "formText": { "bringYourTalentsTo": "¡Contribuye a la comunidad con tus talentos! Premiamos tu compromiso voluntario con 20 GDD por hora hasta un máximo de 1.000 GDD al mes..", "describeYourCommunity": "¡Describe tu contribución al bien-común con detalles de las horas e introduce una cantidad de 20 GDD por hora! Tras la confirmación de un moderador, el importe se abonará en tu cuenta.", - "maxGDDforMonth": "Sólo puede presentar un máximo de {amount} GDD para el mes seleccionado..", + "maxGDDforMonth": "Sólo puede presentar un máximo de {amount} GDD para el mes seleccionado.", "openAmountForMonth": "Para {monthAndYear} aún puedes presentar {creation} GDD.", "yourContribution": "Tu contribución a la comunidad." }, From a72c6cc8272398fe3700eb984d377def046916ea Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:25:38 +0200 Subject: [PATCH 51/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index cc8cd34f3..48cc5cef4 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -45,7 +45,7 @@ "delete": "Eliminar la contribución. ¿Estás seguro?", "deleted": "¡La contribución ha sido borrada! Pero seguirá siendo visible.", "formText": { - "bringYourTalentsTo": "¡Contribuye a la comunidad con tus talentos! Premiamos tu compromiso voluntario con 20 GDD por hora hasta un máximo de 1.000 GDD al mes..", + "bringYourTalentsTo": "¡Contribuye a la comunidad con tus talentos! Premiamos tu compromiso voluntario con 20 GDD por hora hasta un máximo de 1.000 GDD al mes.", "describeYourCommunity": "¡Describe tu contribución al bien-común con detalles de las horas e introduce una cantidad de 20 GDD por hora! Tras la confirmación de un moderador, el importe se abonará en tu cuenta.", "maxGDDforMonth": "Sólo puede presentar un máximo de {amount} GDD para el mes seleccionado.", "openAmountForMonth": "Para {monthAndYear} aún puedes presentar {creation} GDD.", From 6ee5734499fc5e1df9ec8ae16dcadf277f565e5b Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 9 Aug 2022 14:26:10 +0200 Subject: [PATCH 52/83] Update frontend/src/locales/es.json Co-authored-by: Moriz Wahl --- frontend/src/locales/es.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 48cc5cef4..f61a052da 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -10,7 +10,7 @@ "donation": "Donación", "gratitude": "Gratitud", "hasAccount": "Ya estas registrado?", - "hereLogin": "Registrate aquí", + "hereLogin": "Regístrate aquí", "learnMore": "Infórmate aquí …", "oneDignity": "Damos los unos a los otros y agradecemos con Gradido.", "oneDonation": "Eres un regalo para la comunidad. 1000 gracias por estar con nosotros.", From 7686c805466fede1c033bd231cf682fb70d46b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 9 Aug 2022 20:11:58 +0200 Subject: [PATCH 53/83] install uuid package --- database/package.json | 4 +++- database/yarn.lock | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/database/package.json b/database/package.json index 05e1c2ac8..837e61438 100644 --- a/database/package.json +++ b/database/package.json @@ -37,6 +37,7 @@ "typescript": "^4.3.5" }, "dependencies": { + "@types/uuid": "^8.3.4", "cross-env": "^7.0.3", "crypto": "^1.0.1", "decimal.js-light": "^2.5.1", @@ -44,6 +45,7 @@ "mysql2": "^2.3.0", "reflect-metadata": "^0.1.13", "ts-mysql-migrate": "^1.0.2", - "typeorm": "^0.2.38" + "typeorm": "^0.2.38", + "uuid": "^8.3.2" } } diff --git a/database/yarn.lock b/database/yarn.lock index e5d74929c..b30db4595 100644 --- a/database/yarn.lock +++ b/database/yarn.lock @@ -137,6 +137,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5" integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ== +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/zen-observable@0.8.3": version "0.8.3" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3" @@ -2088,6 +2093,11 @@ util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" From 37c5015079965c5882d13c1c1d79c4caa6eefb75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 9 Aug 2022 20:50:10 +0200 Subject: [PATCH 54/83] add gradidoId in users table --- .../User.ts | 111 ++++++++++++++++++ database/entity/User.ts | 2 +- .../0045-adapt_users_table_for_gradidoid.ts | 44 +++++++ 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 database/entity/0045-adapt_users_table_for_gradidoid/User.ts create mode 100644 database/migrations/0045-adapt_users_table_for_gradidoid.ts diff --git a/database/entity/0045-adapt_users_table_for_gradidoid/User.ts b/database/entity/0045-adapt_users_table_for_gradidoid/User.ts new file mode 100644 index 000000000..3f2547cad --- /dev/null +++ b/database/entity/0045-adapt_users_table_for_gradidoid/User.ts @@ -0,0 +1,111 @@ +import { + BaseEntity, + Entity, + PrimaryGeneratedColumn, + Column, + DeleteDateColumn, + OneToMany, + JoinColumn, +} from 'typeorm' +import { Contribution } from '../Contribution' + +@Entity('users', { engine: 'InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci' }) +export class User extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ + name: 'gradido_id', + length: 36, + nullable: false, + unique: true, + collation: 'utf8mb4_unicode_ci', + }) + gradidoID: string + + @Column({ + name: 'alias', + length: 20, + nullable: true, + unique: true, + default: null, + collation: 'utf8mb4_unicode_ci', + }) + alias: string + + @Column({ name: 'public_key', type: 'binary', length: 32, default: null, nullable: true }) + pubKey: Buffer + + @Column({ name: 'privkey', type: 'binary', length: 80, default: null, nullable: true }) + privKey: Buffer + + @Column({ length: 255, unique: true, nullable: false, collation: 'utf8mb4_unicode_ci' }) + email: string + + @Column({ + name: 'first_name', + length: 255, + nullable: true, + default: null, + collation: 'utf8mb4_unicode_ci', + }) + firstName: string + + @Column({ + name: 'last_name', + length: 255, + nullable: true, + default: null, + collation: 'utf8mb4_unicode_ci', + }) + lastName: string + + @DeleteDateColumn() + deletedAt: Date | null + + @Column({ type: 'bigint', default: 0, unsigned: true }) + password: BigInt + + @Column({ name: 'email_hash', type: 'binary', length: 32, default: null, nullable: true }) + emailHash: Buffer + + @Column({ name: 'created', default: () => 'CURRENT_TIMESTAMP', nullable: false }) + createdAt: Date + + @Column({ name: 'email_checked', type: 'bool', nullable: false, default: false }) + emailChecked: boolean + + @Column({ length: 4, default: 'de', collation: 'utf8mb4_unicode_ci', nullable: false }) + language: string + + @Column({ name: 'is_admin', type: 'datetime', nullable: true, default: null }) + isAdmin: Date | null + + @Column({ name: 'referrer_id', type: 'int', unsigned: true, nullable: true, default: null }) + referrerId?: number | null + + @Column({ + name: 'contribution_link_id', + type: 'int', + unsigned: true, + nullable: true, + default: null, + }) + contributionLinkId?: number | null + + @Column({ name: 'publisher_id', default: 0 }) + publisherId: number + + @Column({ + type: 'text', + name: 'passphrase', + collation: 'utf8mb4_unicode_ci', + nullable: true, + default: null, + }) + passphrase: string + + @OneToMany(() => Contribution, (contribution) => contribution.user) + @JoinColumn({ name: 'user_id' }) + contributions?: Contribution[] +} diff --git a/database/entity/User.ts b/database/entity/User.ts index 99b8c8ca9..89b5d3d7f 100644 --- a/database/entity/User.ts +++ b/database/entity/User.ts @@ -1 +1 @@ -export { User } from './0040-add_contribution_link_id_to_user/User' +export { User } from './0045-adapt_users_table_for_gradidoid/User' diff --git a/database/migrations/0045-adapt_users_table_for_gradidoid.ts b/database/migrations/0045-adapt_users_table_for_gradidoid.ts new file mode 100644 index 000000000..8e8372efa --- /dev/null +++ b/database/migrations/0045-adapt_users_table_for_gradidoid.ts @@ -0,0 +1,44 @@ +/* MIGRATION TO ADD GRADIDO_ID + * + * This migration adds new columns to the table `users` and creates the + * new table `user_contacts` + */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { v4 as uuidv4 } from 'uuid' + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // First add gradido_id as nullable column without Default + await queryFn('ALTER TABLE `users` ADD COLUMN `gradido_id` CHAR(36) NULL AFTER `id`;') + + // Second update gradido_id with ensured unique uuidv4 + const usersToUpdate = await queryFn('SELECT `id`, `gradido_id` FROM `users`') // WHERE 'u.gradido_id' is null`,) + for (const id in usersToUpdate) { + const user = usersToUpdate[id] + let gradidoId = null + let countIds = null + do { + gradidoId = uuidv4() + countIds = await queryFn( + `SELECT COUNT(*) FROM \`users\` WHERE \`gradido_id\` = "${gradidoId}"`, + ) + } while (countIds[0] > 0) + await queryFn( + `UPDATE \`users\` SET \`gradido_id\` = "${gradidoId}" WHERE \`id\` = "${user.id}"`, + ) + } + + // third modify gradido_id to not nullable and unique + await queryFn('ALTER TABLE `users` MODIFY COLUMN `gradido_id` CHAR(36) NOT NULL UNIQUE;') + + await queryFn( + 'ALTER TABLE `users` ADD COLUMN `alias` varchar(20) NULL UNIQUE AFTER `gradido_id`;', + ) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('ALTER TABLE users DROP COLUMN gradido_id;') + await queryFn('ALTER TABLE users DROP COLUMN alias;') +} From 14229edf5993a7bd762b08865d84c974840d2364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 9 Aug 2022 20:52:07 +0200 Subject: [PATCH 55/83] install uuid package --- backend/package.json | 4 +++- backend/yarn.lock | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/package.json b/backend/package.json index c56c8e960..d31d12eda 100644 --- a/backend/package.json +++ b/backend/package.json @@ -19,6 +19,7 @@ "dependencies": { "@types/jest": "^27.0.2", "@types/lodash.clonedeep": "^4.5.6", + "@types/uuid": "^8.3.4", "apollo-server-express": "^2.25.2", "apollo-server-testing": "^2.25.2", "axios": "^0.21.1", @@ -39,7 +40,8 @@ "reflect-metadata": "^0.1.13", "sodium-native": "^3.3.0", "ts-jest": "^27.0.5", - "type-graphql": "^1.1.1" + "type-graphql": "^1.1.1", + "uuid": "^8.3.2" }, "devDependencies": { "@types/express": "^4.17.12", diff --git a/backend/yarn.lock b/backend/yarn.lock index 53a53cb9b..dd84e2ce5 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -1000,6 +1000,11 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + "@types/validator@^13.1.3": version "13.6.3" resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.6.3.tgz#31ca2e997bf13a0fffca30a25747d5b9f7dbb7de" @@ -5437,7 +5442,7 @@ uuid@^3.1.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.0.0: +uuid@^8.0.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== From 95332546184127fa09a2e2e083daaa5bd0382b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 9 Aug 2022 23:33:58 +0200 Subject: [PATCH 56/83] upgrade DB-Version --- backend/src/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index f44aa584c..677090ee2 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0044-insert_missing_contributions', + DB_VERSION: '0045-adapt_users_table_for_gradidoid', DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 LOG4JS_CONFIG: 'log4js-config.json', // default log level on production should be info From 35da60c572fa5000a702536917b87cb605633ca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 9 Aug 2022 23:36:00 +0200 Subject: [PATCH 57/83] change User to create a gradidoID as uuidv4 during createUser --- backend/src/graphql/model/User.ts | 8 ++++++++ backend/src/graphql/resolver/UserResolver.ts | 21 +++++++++++++++++++- backend/src/util/communityUser.ts | 2 ++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/model/User.ts b/backend/src/graphql/model/User.ts index 0642be630..1ec33b27d 100644 --- a/backend/src/graphql/model/User.ts +++ b/backend/src/graphql/model/User.ts @@ -8,6 +8,8 @@ import { FULL_CREATION_AVAILABLE } from '../resolver/const/const' export class User { constructor(user: dbUser, creation: Decimal[] = FULL_CREATION_AVAILABLE) { this.id = user.id + this.gradidoID = user.gradidoID + this.alias = user.alias this.email = user.email this.firstName = user.firstName this.lastName = user.lastName @@ -28,6 +30,12 @@ export class User { // `public_key` binary(32) DEFAULT NULL, // `privkey` binary(80) DEFAULT NULL, + @Field(() => String) + gradidoID: string + + @Field(() => String, { nullable: true }) + alias: string + // TODO privacy issue here @Field(() => String) email: string diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a89a8cb0b..03ed3043e 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -32,6 +32,8 @@ import { EventSendConfirmationEmail, } from '@/event/Event' import { getUserCreation } from './util/creations' +import { v4 as uuidv4 } from 'uuid' + // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -224,6 +226,19 @@ export const activationLink = (optInCode: LoginEmailOptIn): string => { return CONFIG.EMAIL_LINK_SETPASSWORD.replace(/{optin}/g, optInCode.verificationCode.toString()) } +const newGradidoID = async (): Promise => { + let gradidoId: string + let countIds: number + do { + gradidoId = uuidv4() + countIds = await DbUser.count({ where: { gradidoID: gradidoId } }) + if (countIds > 0) { + logger.info('Gradido-ID creation conflict...') + } + } while (countIds > 0) + return gradidoId +} + @Resolver() export class UserResolver { @Authorized([RIGHTS.VERIFY_LOGIN]) @@ -344,11 +359,13 @@ export class UserResolver { logger.info(`DbUser.findOne(email=${email}) = ${userFound}`) if (userFound) { - logger.info('User already exists with this email=' + email) + // ATTENTION: this logger-message will be exactly expected during tests + logger.info(`User already exists with this email=${email}`) // TODO: this is unsecure, but the current implementation of the login server. This way it can be queried if the user with given EMail is existent. const user = new User(communityDbUser) user.id = sodium.randombytes_random() % (2048 * 16) // TODO: for a better faking derive id from email so that it will be always the same id when the same email comes in? + user.gradidoID = '11111111-2222-4333-4444-55555555' user.email = email user.firstName = firstName user.lastName = lastName @@ -378,11 +395,13 @@ export class UserResolver { // const passwordHash = SecretKeyCryptographyCreateKey(email, password) // return short and long hash // const encryptedPrivkey = SecretKeyCryptographyEncrypt(keyPair[1], passwordHash[1]) const emailHash = getEmailHash(email) + const gradidoID = await newGradidoID() const eventRegister = new EventRegister() const eventRedeemRegister = new EventRedeemRegister() const eventSendConfirmEmail = new EventSendConfirmationEmail() const dbUser = new DbUser() + dbUser.gradidoID = gradidoID dbUser.email = email dbUser.firstName = firstName dbUser.lastName = lastName diff --git a/backend/src/util/communityUser.ts b/backend/src/util/communityUser.ts index 1a84c2cdf..d850c5382 100644 --- a/backend/src/util/communityUser.ts +++ b/backend/src/util/communityUser.ts @@ -6,6 +6,8 @@ import { User } from '@model/User' const communityDbUser: dbUser = { id: -1, + gradidoID: '11111111-2222-4333-4444-55555555', + alias: '', email: 'support@gradido.net', firstName: 'Gradido', lastName: 'Akademie', From 2b4e94ef66502c1bbcca1e9ebb7a71837ff70c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 9 Aug 2022 23:41:39 +0200 Subject: [PATCH 58/83] add gradidoID-Test during createUser --- backend/src/graphql/resolver/UserResolver.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index a2a499224..39ff70b22 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -20,6 +20,7 @@ import { ContributionLink } from '@model/ContributionLink' // import { TransactionLink } from '@entity/TransactionLink' import { logger } from '@test/testSetup' +import { validate as validateUUID, version as versionUUID } from 'uuid' // import { klicktippSignIn } from '@/apis/KlicktippController' @@ -111,6 +112,8 @@ describe('UserResolver', () => { expect(user).toEqual([ { id: expect.any(Number), + gradidoID: expect.any(String), + alias: null, email: 'peter@lustig.de', firstName: 'Peter', lastName: 'Lustig', @@ -129,6 +132,10 @@ describe('UserResolver', () => { contributionLinkId: null, }, ]) + const valUUID = validateUUID(user[0].gradidoID) + const verUUID = versionUUID(user[0].gradidoID) + expect(valUUID).toEqual(true) + expect(verUUID).toEqual(4) }) it('creates an email optin', () => { From cd71bf76617c8a5aebbef1528dac7e934f165557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 9 Aug 2022 23:59:13 +0200 Subject: [PATCH 59/83] linting --- backend/src/graphql/resolver/UserResolver.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 03ed3043e..d9245f51d 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -34,7 +34,6 @@ import { import { getUserCreation } from './util/creations' import { v4 as uuidv4 } from 'uuid' - // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') // eslint-disable-next-line @typescript-eslint/no-var-requires From 6d2cbfbab1e1cec8fbc64e2c28637ad00445097b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 10 Aug 2022 15:57:13 +0200 Subject: [PATCH 60/83] add number and date formats for locale es --- frontend/src/i18n.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/frontend/src/i18n.js b/frontend/src/i18n.js index 3fc9552a1..488012ce2 100644 --- a/frontend/src/i18n.js +++ b/frontend/src/i18n.js @@ -65,6 +65,19 @@ const numberFormats = { useGrouping: false, }, }, + es: { + decimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }, + ungroupedDecimal: { + style: 'decimal', + minimumFractionDigits: 2, + maximumFractionDigits: 2, + useGrouping: false, + }, + }, } const dateTimeFormats = { @@ -124,6 +137,34 @@ const dateTimeFormats = { year: 'numeric', }, }, + es: { + short: { + day: 'numeric', + month: 'numeric', + year: 'numeric', + }, + long: { + day: 'numeric', + month: 'long', + year: 'numeric', + weekday: 'long', + hour: 'numeric', + minute: 'numeric', + }, + monthShort: { + month: 'short', + }, + month: { + month: 'long', + }, + year: { + year: 'numeric', + }, + monthAndYear: { + month: 'long', + year: 'numeric', + }, + }, } export default new VueI18n({ From f98f38773d665b717903c6093a8d041de83c7db5 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 10 Aug 2022 15:57:30 +0200 Subject: [PATCH 61/83] fix missing translations --- frontend/src/locales/es.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index f61a052da..fa2cd31a9 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -104,7 +104,7 @@ "whitepaper": "Whitepaper" }, "form": { - "amount": "Monto", + "amount": "Importe", "at": "am", "cancel": "Cancelar", "change": "Cambiar", @@ -148,7 +148,7 @@ "usernmae-regex": "El nombre de usuario debe comenzar con una letra seguida de al menos dos caracteres alfanuméricos.", "usernmae-unique": "Este nombre de usuario ya está adjudicado." }, - "your_amount": "Tu monto" + "your_amount": "Tu importe" }, "GDD": "GDD", "gdd_per_link": { @@ -186,7 +186,7 @@ }, "gdt": { "calculation": "Cálculo del Gradido Transform", - "contribution": "Monto", + "contribution": "Importe", "conversion": "Conversión", "conversion-gdt-euro": "Conversión Euro / Gradido Transform (GDT)", "credit": "Abono", @@ -212,7 +212,7 @@ "pipe": "|" }, "message": { - "activateEmail": "Tu cuenta aún no ha sido activada. Por favor revisa tu correo electrónico y haz clic en el enlace de activación o solicita uno nuevo Aktivierungslink über die Password Reset Seite an.", + "activateEmail": "Tu cuenta aún no ha sido activada. Por favor revisa tu correo electrónico y haz clic en el enlace de activación o solicita uno nuevo enlace de activación a través de la página restablecer contraseña.", "checkEmail": "Tu correo electrónico ha sido verificado con éxito. Puedes registrarte ahora.", "email": "Te hemos enviado un correo electrónico.", "errorTitle": "Atención!", @@ -300,7 +300,7 @@ }, "success": "Lo lograste", "time": { - "days": "Dias", + "days": "Días", "hours": "Horas", "minutes": "Minutos", "month": "Mes", From 24c763c00f14ade25bd04202fc476cbc8f857c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 10 Aug 2022 16:54:51 +0200 Subject: [PATCH 62/83] Remove comments in favor of an issue --- .../Contributions/ContributionForm.spec.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 1cb2b3e8a..d3cc315a5 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -102,17 +102,13 @@ describe('ContributionForm', () => { }) }) - // jest-environment-jsdom-sixteen - // testEnvironment: 'jest-environment-jsdom-sixteen', - // https://www.npmjs.com/package/jest-environment-jsdom-sixteen - // https://dev.to/philw_/problems-with-using-usefaketimersmodern-in-a-create-react-app-cra-project-with-jest-26-and-lodashs-debounce-function-3ohd describe.skip('date in middle of year', () => { describe('same month', () => { beforeEach(async () => { jest.useFakeTimers('modern') jest.setSystemTime(new Date('2020-07-06')) const now = new Date().toISOString() - // Wolle: console.log('middle of year date – now:', now) + // console.log('middle of year date – now:', now) await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) }) @@ -125,7 +121,7 @@ describe('ContributionForm', () => { describe('month before', () => { beforeEach(async () => { - // Wolle: console.log('middle of year date – now:', wrapper.vm.minimalDate) + // console.log('middle of year date – now:', wrapper.vm.minimalDate) await wrapper .findComponent({ name: 'BFormDatepicker' }) .vm.$emit('input', wrapper.vm.minimalDate) @@ -144,7 +140,7 @@ describe('ContributionForm', () => { beforeEach(async () => { jest.useFakeTimers('modern').setSystemTime(new Date('2020-01-12')) const now = new Date().toISOString() - // Wolle: console.log('in january date – now:', now) + // console.log('in january date – now:', now) await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) }) @@ -157,7 +153,7 @@ describe('ContributionForm', () => { describe('month before', () => { beforeEach(async () => { - // Wolle: console.log('in january date – wrapper.vm.minimalDate:', wrapper.vm.minimalDate) + // console.log('in january date – wrapper.vm.minimalDate:', wrapper.vm.minimalDate) await wrapper .findComponent({ name: 'BFormDatepicker' }) .vm.$emit('input', wrapper.vm.minimalDate) From 59f415bd0a6cf6a3735e1d5d3dde9e92e1102739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 11 Aug 2022 08:50:40 +0200 Subject: [PATCH 63/83] Add some comments for trying to fullfil Moriz suggestion --- .../components/Contributions/ContributionForm.spec.js | 2 +- .../src/components/Contributions/ContributionForm.vue | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index d3cc315a5..b107d7d69 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -73,7 +73,7 @@ describe('ContributionForm', () => { }) }) - describe('actual date', () => { + describe.only('actual date', () => { describe('same month', () => { beforeEach(async () => { const now = new Date().toISOString() diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 2ee94db58..52438d175 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -131,11 +131,18 @@ export default { }, }, computed: { - // sets the date to the 1st of the previous month minimalDate() { + // sets the date to the 1st of the previous month const month = this.maximalDate.getMonth() const year = this.maximalDate.getFullYear() return new Date(year + (month === 0 ? -1 : 0), month === 0 ? 11 : month - 1, 1) + + // // const date = new Date().setMonth(this.maximalDate.getMonth() - 1) + // console.log(new Date('Mon Jan 10 2022 16:32:58 GMT+0100')) + // const date = new Date('Mon Jan 10 2022 16:32:58 GMT+0100').setMonth(this.maximalDate.getMonth() - 1) + // // console.log(date.toISOString()) + // console.log(new Date(date.getFullYear(), date.getMonth(), 1)) + // return new Date(date.getFullYear(), date.getMonth(), 1) }, disabled() { return ( From 826bd6892defbd4cb7f2a04cd8ecb56e36c67346 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Thu, 11 Aug 2022 10:59:20 +0200 Subject: [PATCH 64/83] Update frontend/src/components/Menu/Navbar.spec.js Co-authored-by: Moriz Wahl --- frontend/src/components/Menu/Navbar.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/Menu/Navbar.spec.js b/frontend/src/components/Menu/Navbar.spec.js index a348ffa9c..e7a0f4784 100644 --- a/frontend/src/components/Menu/Navbar.spec.js +++ b/frontend/src/components/Menu/Navbar.spec.js @@ -48,7 +48,7 @@ describe('Navbar', () => { expect(wrapper.find('.navbar-toggler').exists()).toBeTruthy() }) - it('has ten b-nav-item in the navbar', () => { + it('has twelve b-nav-item in the navbar', () => { expect(wrapper.findAll('.nav-item')).toHaveLength(12) }) From 9d5325c1999e491e31f6b3a53d9bd466c0a76338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 11 Aug 2022 11:12:55 +0200 Subject: [PATCH 65/83] Fix date tests Co-Authored-By: elweyn --- .../Contributions/ContributionForm.spec.js | 76 ++++++++++++++----- .../Contributions/ContributionForm.vue | 18 ++--- 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index b107d7d69..24b1f6cb3 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -73,7 +73,7 @@ describe('ContributionForm', () => { }) }) - describe.only('actual date', () => { + describe('actual date', () => { describe('same month', () => { beforeEach(async () => { const now = new Date().toISOString() @@ -102,14 +102,22 @@ describe('ContributionForm', () => { }) }) - describe.skip('date in middle of year', () => { + describe('date in middle of year', () => { describe('same month', () => { beforeEach(async () => { - jest.useFakeTimers('modern') - jest.setSystemTime(new Date('2020-07-06')) - const now = new Date().toISOString() - // console.log('middle of year date – now:', now) - await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + // jest.useFakeTimers('modern') + // jest.setSystemTime(new Date('2020-07-06')) + // await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper.setData({ + maximalDate: new Date(2020, 6, 6), + form: { date: new Date(2020, 6, 6) }, + }) + }) + + describe('minimalDate', () => { + it('has "2020-06-01T00:00:00.000Z"', () => { + expect(wrapper.vm.minimalDate.toISOString()).toBe('2020-06-01T00:00:00.000Z') + }) }) describe('isThisMonth', () => { @@ -121,10 +129,22 @@ describe('ContributionForm', () => { describe('month before', () => { beforeEach(async () => { + // jest.useFakeTimers('modern') + // jest.setSystemTime(new Date('2020-07-06')) // console.log('middle of year date – now:', wrapper.vm.minimalDate) - await wrapper - .findComponent({ name: 'BFormDatepicker' }) - .vm.$emit('input', wrapper.vm.minimalDate) + // await wrapper + // .findComponent({ name: 'BFormDatepicker' }) + // .vm.$emit('input', wrapper.vm.minimalDate) + await wrapper.setData({ + maximalDate: new Date(2020, 6, 6), + form: { date: new Date(2020, 5, 6) }, + }) + }) + + describe('minimalDate', () => { + it('has "2020-06-01T00:00:00.000Z"', () => { + expect(wrapper.vm.minimalDate.toISOString()).toBe('2020-06-01T00:00:00.000Z') + }) }) describe('isThisMonth', () => { @@ -135,13 +155,19 @@ describe('ContributionForm', () => { }) }) - describe.skip('date in january', () => { + describe('date in january', () => { describe('same month', () => { beforeEach(async () => { - jest.useFakeTimers('modern').setSystemTime(new Date('2020-01-12')) - const now = new Date().toISOString() - // console.log('in january date – now:', now) - await wrapper.findComponent({ name: 'BFormDatepicker' }).vm.$emit('input', now) + await wrapper.setData({ + maximalDate: new Date(2020, 0, 6), + form: { date: new Date(2020, 0, 6) }, + }) + }) + + describe('minimalDate', () => { + it('has "2019-12-01T00:00:00.000Z"', () => { + expect(wrapper.vm.minimalDate.toISOString()).toBe('2019-12-01T00:00:00.000Z') + }) }) describe('isThisMonth', () => { @@ -153,10 +179,22 @@ describe('ContributionForm', () => { describe('month before', () => { beforeEach(async () => { - // console.log('in january date – wrapper.vm.minimalDate:', wrapper.vm.minimalDate) - await wrapper - .findComponent({ name: 'BFormDatepicker' }) - .vm.$emit('input', wrapper.vm.minimalDate) + // jest.useFakeTimers('modern') + // jest.setSystemTime(new Date('2020-07-06')) + // console.log('middle of year date – now:', wrapper.vm.minimalDate) + // await wrapper + // .findComponent({ name: 'BFormDatepicker' }) + // .vm.$emit('input', wrapper.vm.minimalDate) + await wrapper.setData({ + maximalDate: new Date(2020, 0, 6), + form: { date: new Date(2019, 11, 6) }, + }) + }) + + describe('minimalDate', () => { + it('has "2019-12-01T00:00:00.000Z"', () => { + expect(wrapper.vm.minimalDate.toISOString()).toBe('2019-12-01T00:00:00.000Z') + }) }) describe('isThisMonth', () => { diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index 52438d175..bec2e56e1 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -133,16 +133,9 @@ export default { computed: { minimalDate() { // sets the date to the 1st of the previous month - const month = this.maximalDate.getMonth() - const year = this.maximalDate.getFullYear() - return new Date(year + (month === 0 ? -1 : 0), month === 0 ? 11 : month - 1, 1) - - // // const date = new Date().setMonth(this.maximalDate.getMonth() - 1) - // console.log(new Date('Mon Jan 10 2022 16:32:58 GMT+0100')) - // const date = new Date('Mon Jan 10 2022 16:32:58 GMT+0100').setMonth(this.maximalDate.getMonth() - 1) - // // console.log(date.toISOString()) - // console.log(new Date(date.getFullYear(), date.getMonth(), 1)) - // return new Date(date.getFullYear(), date.getMonth(), 1) + let date = new Date(this.maximalDate) // has to be a new object, because of 'setMonth' changes the objects date + date = new Date(date.setMonth(date.getMonth() - 1)) + return new Date(date.getFullYear(), date.getMonth(), 1) }, disabled() { return ( @@ -157,10 +150,9 @@ export default { }, isThisMonth() { const formDate = new Date(this.form.date) - const actualDate = new Date() return ( - formDate.getFullYear() === actualDate.getFullYear() && - formDate.getMonth() === actualDate.getMonth() + formDate.getFullYear() === this.maximalDate.getFullYear() && + formDate.getMonth() === this.maximalDate.getMonth() ) }, maxGddLastMonth() { From 50fd74bb6ae86bab64acb08dde192453a8e98b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 11 Aug 2022 14:14:47 +0200 Subject: [PATCH 66/83] Remove tests of disabled cancel button, because they are always enabled yet --- .../Contributions/ContributionForm.spec.js | 36 ++++--------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.spec.js b/frontend/src/components/Contributions/ContributionForm.spec.js index 24b1f6cb3..cf47577a3 100644 --- a/frontend/src/components/Contributions/ContributionForm.spec.js +++ b/frontend/src/components/Contributions/ContributionForm.spec.js @@ -46,13 +46,7 @@ describe('ContributionForm', () => { }) describe('empty form data', () => { - describe('buttons', () => { - it('has reset enabled', () => { - expect( - wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), - ).toBeFalsy() - }) - + describe('button', () => { it('has submit disabled', () => { expect(wrapper.find('button[data-test="button-submit"]').attributes('disabled')).toBe( 'disabled', @@ -232,7 +226,7 @@ describe('ContributionForm', () => { await wrapper.find('#contribution-memo').find('textarea').setValue('1234') }) - describe('buttons', () => { + describe('button', () => { describe('submit', () => { it('has disabled', () => { expect( @@ -256,7 +250,7 @@ describe('ContributionForm', () => { await wrapper.vm.$nextTick() }) - describe('buttons', () => { + describe('button', () => { describe('submit', () => { it('has disabled', () => { expect( @@ -278,15 +272,7 @@ describe('ContributionForm', () => { await wrapper.find('#contribution-amount').find('input').setValue('200') }) - describe('buttons', () => { - describe('reset', () => { - it('has enabled', () => { - expect( - wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), - ).toBeFalsy() - }) - }) - + describe('button', () => { describe('submit', () => { it('has enabled', () => { expect( @@ -352,7 +338,7 @@ describe('ContributionForm', () => { await wrapper.find('#contribution-memo').find('textarea').setValue('1234') }) - describe('buttons', () => { + describe('button', () => { describe('submit', () => { it('has disabled', () => { expect( @@ -376,7 +362,7 @@ describe('ContributionForm', () => { await wrapper.vm.$nextTick() }) - describe('buttons', () => { + describe('button', () => { describe('submit', () => { it('has disabled', () => { expect( @@ -398,15 +384,7 @@ describe('ContributionForm', () => { await wrapper.find('#contribution-amount').find('input').setValue('200') }) - describe('buttons', () => { - describe('reset', () => { - it('has enabled', () => { - expect( - wrapper.find('button[data-test="button-cancel"]').attributes('disabled'), - ).toBeFalsy() - }) - }) - + describe('button', () => { describe('submit', () => { it('has enabled', () => { expect( From 289b758ca6e38034f382d07fd3d226e16da60b99 Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 11 Aug 2022 14:23:56 +0200 Subject: [PATCH 67/83] delete flushPromisesin test --- frontend/src/pages/Transactions.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/pages/Transactions.spec.js b/frontend/src/pages/Transactions.spec.js index 822a8f558..171a089ca 100644 --- a/frontend/src/pages/Transactions.spec.js +++ b/frontend/src/pages/Transactions.spec.js @@ -1,7 +1,6 @@ import { mount } from '@vue/test-utils' import Transactions from './Transactions' import { GdtEntryType } from '@/graphql/enums' -import flushPromises from 'flush-promises' import { toastErrorSpy } from '@test/testSetup' @@ -163,7 +162,6 @@ describe('Transactions', () => { describe('click on GDD tab', () => { beforeEach(() => { - flushPromises() wrapper.findAll('li[ role="presentation"]').at(0).find('a').trigger('click') }) From ad9202efeda70539223812d214c9aee9dd0dbcc2 Mon Sep 17 00:00:00 2001 From: Hannes Heine Date: Thu, 11 Aug 2022 14:57:17 +0200 Subject: [PATCH 68/83] Update backend/src/middleware/klicktippMiddleware.ts Co-authored-by: Moriz Wahl --- backend/src/middleware/klicktippMiddleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/middleware/klicktippMiddleware.ts b/backend/src/middleware/klicktippMiddleware.ts index 5f0c28477..5bd1484d1 100644 --- a/backend/src/middleware/klicktippMiddleware.ts +++ b/backend/src/middleware/klicktippMiddleware.ts @@ -31,7 +31,7 @@ export const klicktippNewsletterStateMiddleware: MiddlewareFn = async ( klickTipp = new KlickTipp(klickTippUser) } } catch (err) { - logger.info(`Their is no user for (email='${result.email}') ${err}`) + logger.info(`There is no user for (email='${result.email}') ${err}`) } } result.klickTipp = klickTipp From df0f3e21b65c224ac82e5b213cab2c44aea0eef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 11 Aug 2022 15:05:43 +0200 Subject: [PATCH 69/83] Reduce comment to a minimal --- frontend/src/components/Contributions/ContributionForm.vue | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/src/components/Contributions/ContributionForm.vue b/frontend/src/components/Contributions/ContributionForm.vue index bec2e56e1..3a9010ec2 100644 --- a/frontend/src/components/Contributions/ContributionForm.vue +++ b/frontend/src/components/Contributions/ContributionForm.vue @@ -108,10 +108,7 @@ export default { }, submit() { this.form.amount = this.numberFormat(this.form.amount) - // not working for testing: - // this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', this.form) - // works for testing: - // why ever, we have to make a spread '...', to evaluate the values it looks like: (I didn't find a solution in the test itmself) + // spreading is needed for testing this.$emit(this.form.id ? 'update-contribution' : 'set-contribution', { ...this.form }) this.reset() }, From d4cd6c2b30735b2c902d2676cb5c2f748bbbf71d Mon Sep 17 00:00:00 2001 From: Hannes Heine Date: Thu, 11 Aug 2022 15:07:48 +0200 Subject: [PATCH 70/83] Update klicktippMiddleware.ts Change log level from info to error --- backend/src/middleware/klicktippMiddleware.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/middleware/klicktippMiddleware.ts b/backend/src/middleware/klicktippMiddleware.ts index 5bd1484d1..6bdaa63fd 100644 --- a/backend/src/middleware/klicktippMiddleware.ts +++ b/backend/src/middleware/klicktippMiddleware.ts @@ -31,7 +31,7 @@ export const klicktippNewsletterStateMiddleware: MiddlewareFn = async ( klickTipp = new KlickTipp(klickTippUser) } } catch (err) { - logger.info(`There is no user for (email='${result.email}') ${err}`) + logger.error(`There is no user for (email='${result.email}') ${err}`) } } result.klickTipp = klickTipp From 661c9fd2ad08df69d98c40d80dbbc885ead32006 Mon Sep 17 00:00:00 2001 From: ogerly Date: Sun, 14 Aug 2022 15:13:23 +0200 Subject: [PATCH 71/83] fix lint --- frontend/src/components/SessionLogoutTimeout.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/SessionLogoutTimeout.spec.js b/frontend/src/components/SessionLogoutTimeout.spec.js index bd6911d13..ebaf4110f 100644 --- a/frontend/src/components/SessionLogoutTimeout.spec.js +++ b/frontend/src/components/SessionLogoutTimeout.spec.js @@ -1,6 +1,7 @@ import { mount } from '@vue/test-utils' import SessionLogoutTimeout from './SessionLogoutTimeout' + const localVue = global.localVue const apolloQueryMock = jest.fn() From d83024cb51ec1e7019b0a60a8161d697359f652f Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 15 Aug 2022 18:31:42 +0200 Subject: [PATCH 72/83] feat: Add status, type, denied_at and denied_by to contributions Table --- ...denied_type_and_status_to_contributions.ts | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 database/migrations/0045-add_denied_type_and_status_to_contributions.ts diff --git a/database/migrations/0045-add_denied_type_and_status_to_contributions.ts b/database/migrations/0045-add_denied_type_and_status_to_contributions.ts new file mode 100644 index 000000000..b3653589b --- /dev/null +++ b/database/migrations/0045-add_denied_type_and_status_to_contributions.ts @@ -0,0 +1,39 @@ +/* MIGRATION TO ADD denied_by, denied_at, contribution_type and contrinution_status +FIELDS TO contributions */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `denied_at` datetime DEFAULT NULL AFTER `confirmed_at`;', + ) + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `denied_by` int(10) unsigned DEFAULT NULL AFTER `denied_at`;', + ) + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `contribution_type` varchar(12) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "ADMIN" AFTER `denied_by`;', + ) + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `contribution_status` varchar(12) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "PENDING" AFTER `contribution_type`;', + ) + await queryFn( + 'UPDATE `contributions` SET `contribution_type` = "LINK" WHERE `contribution_link_id` IS NOT NULL;', + ) + await queryFn( + 'UPDATE `contributions` SET `contribution_type` = "USER" WHERE `contribution_link_id` IS NULL AND `moderator_id` IS NULL;', + ) + await queryFn( + 'UPDATE `contributions` SET `contribution_status` = "CONFIRMED" WHERE `confirmed_at` IS NOT NULL;', + ) + await queryFn( + 'UPDATE `contributions` SET `contribution_status` = "DELETED" WHERE `deleted_at` IS NOT NULL;', + ) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('ALTER TABLE `contributions` DROP COLUMN `contribution_status`;') + await queryFn('ALTER TABLE `contributions` DROP COLUMN `contribution_type`;') + await queryFn('ALTER TABLE `contributions` DROP COLUMN `denied_by`;') + await queryFn('ALTER TABLE `contributions` DROP COLUMN `denied_at`;') +} From d4150f123c6663d2759f00e436613cecd00e4dcc Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 15 Aug 2022 18:32:50 +0200 Subject: [PATCH 73/83] update db version --- backend/src/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index f44aa584c..66bea06f5 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0044-insert_missing_contributions', + DB_VERSION: '0045-add_denied_type_and_status_to_contributions', DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0 LOG4JS_CONFIG: 'log4js-config.json', // default log level on production should be info From cc2cc93b60d67dc247abaf3eaa1b12d0b94661ed Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 15 Aug 2022 18:38:50 +0200 Subject: [PATCH 74/83] update db entity for contributions --- .../Contribution.ts | 83 +++++++++++++++++++ database/entity/Contribution.ts | 2 +- 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 database/entity/0045-add_denied_type_and_status_to_contributions/Contribution.ts diff --git a/database/entity/0045-add_denied_type_and_status_to_contributions/Contribution.ts b/database/entity/0045-add_denied_type_and_status_to_contributions/Contribution.ts new file mode 100644 index 000000000..c376ae53e --- /dev/null +++ b/database/entity/0045-add_denied_type_and_status_to_contributions/Contribution.ts @@ -0,0 +1,83 @@ +import Decimal from 'decimal.js-light' +import { + BaseEntity, + Column, + Entity, + PrimaryGeneratedColumn, + DeleteDateColumn, + JoinColumn, + ManyToOne, +} from 'typeorm' +import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' +import { User } from '../User' + +@Entity('contributions') +export class Contribution extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ unsigned: true, nullable: false, name: 'user_id' }) + userId: number + + @ManyToOne(() => User, (user) => user.contributions) + @JoinColumn({ name: 'user_id' }) + user: User + + @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP', name: 'created_at' }) + createdAt: Date + + @Column({ type: 'datetime', nullable: false, name: 'contribution_date' }) + contributionDate: Date + + @Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' }) + memo: string + + @Column({ + type: 'decimal', + precision: 40, + scale: 20, + nullable: false, + transformer: DecimalTransformer, + }) + amount: Decimal + + @Column({ unsigned: true, nullable: true, name: 'moderator_id' }) + moderatorId: number + + @Column({ unsigned: true, nullable: true, name: 'contribution_link_id' }) + contributionLinkId: number + + @Column({ unsigned: true, nullable: true, name: 'confirmed_by' }) + confirmedBy: number + + @Column({ nullable: true, name: 'confirmed_at' }) + confirmedAt: Date + + @Column({ unsigned: true, nullable: true, name: 'denied_by' }) + deniedBy: number + + @Column({ nullable: true, name: 'denied_at' }) + deniedAt: Date + + @Column({ + name: 'contribution_type', + length: 12, + nullable: false, + collation: 'utf8mb4_unicode_ci', + }) + contributionType: string + + @Column({ + name: 'contribution_status', + length: 12, + nullable: false, + collation: 'utf8mb4_unicode_ci', + }) + contributionStatus: string + + @Column({ unsigned: true, nullable: true, name: 'transaction_id' }) + transactionId: number + + @DeleteDateColumn({ name: 'deleted_at' }) + deletedAt: Date | null +} diff --git a/database/entity/Contribution.ts b/database/entity/Contribution.ts index 82dd6478c..800e7f9cd 100644 --- a/database/entity/Contribution.ts +++ b/database/entity/Contribution.ts @@ -1 +1 @@ -export { Contribution } from './0039-contributions_table/Contribution' +export { Contribution } from './0045-add_denied_type_and_status_to_contributions/Contribution' From daa8d48ca651d9938c1551a5da75a1fa5d2c8404 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 15 Aug 2022 18:50:25 +0200 Subject: [PATCH 75/83] add contribution type enum and set contribution type on creation --- backend/src/graphql/enum/ContributionType.ts | 12 ++++++++++++ backend/src/graphql/resolver/AdminResolver.ts | 2 ++ backend/src/graphql/resolver/ContributionResolver.ts | 2 ++ .../src/graphql/resolver/TransactionLinkResolver.ts | 3 +++ 4 files changed, 19 insertions(+) create mode 100644 backend/src/graphql/enum/ContributionType.ts diff --git a/backend/src/graphql/enum/ContributionType.ts b/backend/src/graphql/enum/ContributionType.ts new file mode 100644 index 000000000..e8529edc4 --- /dev/null +++ b/backend/src/graphql/enum/ContributionType.ts @@ -0,0 +1,12 @@ +import { registerEnumType } from 'type-graphql' + +export enum ContributionType { + ADMIN = 'ADMIN', + USER = 'USER', + LINK = 'LINK', +} + +registerEnumType(ContributionType, { + name: 'ContributionType', + description: 'Name of the Type of the Contribution', +}) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index b7ac63842..3c082314f 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -36,6 +36,7 @@ import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User as dbUser } from '@entity/User' import { User } from '@model/User' import { TransactionTypeId } from '@enum/TransactionTypeId' +import { ContributionType } from '@enum/ContributionType' import Decimal from 'decimal.js-light' import { Decay } from '@model/Decay' import Paginated from '@arg/Paginated' @@ -260,6 +261,7 @@ export class AdminResolver { contribution.contributionDate = creationDateObj contribution.memo = memo contribution.moderatorId = moderator.id + contribution.contributionType = ContributionType.ADMIN logger.trace('contribution to save', contribution) await Contribution.save(contribution) diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 3307252e4..4acf8a215 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -7,6 +7,7 @@ import { FindOperator, IsNull, getConnection } from '@dbTools/typeorm' import ContributionArgs from '@arg/ContributionArgs' import Paginated from '@arg/Paginated' import { Order } from '@enum/Order' +import { ContributionType } from '@enum/ContributionType' import { Contribution, ContributionListResult } from '@model/Contribution' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { User } from '@model/User' @@ -43,6 +44,7 @@ export class ContributionResolver { contribution.createdAt = new Date() contribution.contributionDate = creationDateObj contribution.memo = memo + contribution.contributionType = ContributionType.USER logger.trace('contribution to save', contribution) await dbContribution.save(contribution) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 8696065ed..49ef1e592 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -26,6 +26,7 @@ import { User } from '@model/User' import { calculateDecay } from '@/util/decay' import { executeTransaction } from './TransactionResolver' import { Order } from '@enum/Order' +import { ContributionType } from '@enum/ContributionType' import { Contribution as DbContribution } from '@entity/Contribution' import { ContributionLink as DbContributionLink } from '@entity/ContributionLink' import { getUserCreation, validateContribution } from './util/creations' @@ -231,6 +232,8 @@ export class TransactionLinkResolver { contribution.memo = contributionLink.memo contribution.amount = contributionLink.amount contribution.contributionLinkId = contributionLink.id + contribution.contributionType = ContributionType.LINK + await queryRunner.manager.insert(DbContribution, contribution) const lastTransaction = await queryRunner.manager From c417bc7a10406ffa56bb0a0ee9e49dc9b47c9bd1 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 15 Aug 2022 19:02:06 +0200 Subject: [PATCH 76/83] add contribution status enum and set it --- backend/src/graphql/enum/ContributionStatus.ts | 14 ++++++++++++++ backend/src/graphql/resolver/AdminResolver.ts | 5 +++++ .../src/graphql/resolver/ContributionResolver.ts | 4 ++++ .../graphql/resolver/TransactionLinkResolver.ts | 2 ++ 4 files changed, 25 insertions(+) create mode 100644 backend/src/graphql/enum/ContributionStatus.ts diff --git a/backend/src/graphql/enum/ContributionStatus.ts b/backend/src/graphql/enum/ContributionStatus.ts new file mode 100644 index 000000000..67cdf5398 --- /dev/null +++ b/backend/src/graphql/enum/ContributionStatus.ts @@ -0,0 +1,14 @@ +import { registerEnumType } from 'type-graphql' + +export enum ContributionStatus { + PENDING = 'PENDING', + DELETED = 'DELETED', + IN_PROGRESS = 'IN_PROGRESS', + DENIED = 'DENIED', + CONFIRMED = 'CONFIRMED', +} + +registerEnumType(ContributionStatus, { + name: 'ContributionStatus', + description: 'Name of the Type of the Contribution Status', +}) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 3c082314f..419de142b 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -37,6 +37,7 @@ import { User as dbUser } from '@entity/User' import { User } from '@model/User' import { TransactionTypeId } from '@enum/TransactionTypeId' import { ContributionType } from '@enum/ContributionType' +import { ContributionStatus } from '@enum/ContributionStatus' import Decimal from 'decimal.js-light' import { Decay } from '@model/Decay' import Paginated from '@arg/Paginated' @@ -262,6 +263,7 @@ export class AdminResolver { contribution.memo = memo contribution.moderatorId = moderator.id contribution.contributionType = ContributionType.ADMIN + contribution.contributionStatus = ContributionStatus.PENDING logger.trace('contribution to save', contribution) await Contribution.save(contribution) @@ -339,6 +341,7 @@ export class AdminResolver { contributionToUpdate.memo = memo contributionToUpdate.contributionDate = new Date(creationDate) contributionToUpdate.moderatorId = moderator.id + contributionToUpdate.contributionStatus = ContributionStatus.PENDING await Contribution.save(contributionToUpdate) const result = new AdminUpdateContribution() @@ -389,6 +392,7 @@ export class AdminResolver { if (!contribution) { throw new Error('Contribution not found for given id.') } + contribution.contributionStatus = ContributionStatus.DELETED const res = await contribution.softRemove() return !!res } @@ -456,6 +460,7 @@ export class AdminResolver { contribution.confirmedAt = receivedCallDate contribution.confirmedBy = moderatorUser.id contribution.transactionId = transaction.id + contribution.contributionStatus = ContributionStatus.CONFIRMED await queryRunner.manager.update(Contribution, { id: contribution.id }, contribution) await queryRunner.commitTransaction() diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 4acf8a215..041cc4dd9 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -8,6 +8,7 @@ import ContributionArgs from '@arg/ContributionArgs' import Paginated from '@arg/Paginated' import { Order } from '@enum/Order' import { ContributionType } from '@enum/ContributionType' +import { ContributionStatus } from '@enum/ContributionStatus' import { Contribution, ContributionListResult } from '@model/Contribution' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import { User } from '@model/User' @@ -45,6 +46,7 @@ export class ContributionResolver { contribution.contributionDate = creationDateObj contribution.memo = memo contribution.contributionType = ContributionType.USER + contribution.contributionStatus = ContributionStatus.PENDING logger.trace('contribution to save', contribution) await dbContribution.save(contribution) @@ -68,6 +70,7 @@ export class ContributionResolver { if (contribution.confirmedAt) { throw new Error('A confirmed contribution can not be deleted') } + contribution.contributionStatus = ContributionStatus.DELETED const res = await contribution.softRemove() return !!res } @@ -166,6 +169,7 @@ export class ContributionResolver { contributionToUpdate.amount = amount contributionToUpdate.memo = memo contributionToUpdate.contributionDate = new Date(creationDate) + contributionToUpdate.contributionStatus = ContributionStatus.PENDING dbContribution.save(contributionToUpdate) return new UnconfirmedContribution(contributionToUpdate, user, creations) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.ts b/backend/src/graphql/resolver/TransactionLinkResolver.ts index 49ef1e592..ccc0f628d 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.ts @@ -27,6 +27,7 @@ import { calculateDecay } from '@/util/decay' import { executeTransaction } from './TransactionResolver' import { Order } from '@enum/Order' import { ContributionType } from '@enum/ContributionType' +import { ContributionStatus } from '@enum/ContributionStatus' import { Contribution as DbContribution } from '@entity/Contribution' import { ContributionLink as DbContributionLink } from '@entity/ContributionLink' import { getUserCreation, validateContribution } from './util/creations' @@ -233,6 +234,7 @@ export class TransactionLinkResolver { contribution.amount = contributionLink.amount contribution.contributionLinkId = contributionLink.id contribution.contributionType = ContributionType.LINK + contribution.contributionStatus = ContributionStatus.CONFIRMED await queryRunner.manager.insert(DbContribution, contribution) From f2f8989746d2b5ddd07d40a41659a41939a957fa Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 15 Aug 2022 19:06:59 +0200 Subject: [PATCH 77/83] save contribution when setting status DELETED before softDelete --- backend/src/graphql/resolver/AdminResolver.ts | 1 + backend/src/graphql/resolver/ContributionResolver.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 419de142b..e70fe71ee 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -393,6 +393,7 @@ export class AdminResolver { throw new Error('Contribution not found for given id.') } contribution.contributionStatus = ContributionStatus.DELETED + await contribution.save() const res = await contribution.softRemove() return !!res } diff --git a/backend/src/graphql/resolver/ContributionResolver.ts b/backend/src/graphql/resolver/ContributionResolver.ts index 041cc4dd9..8056ffde3 100644 --- a/backend/src/graphql/resolver/ContributionResolver.ts +++ b/backend/src/graphql/resolver/ContributionResolver.ts @@ -71,6 +71,7 @@ export class ContributionResolver { throw new Error('A confirmed contribution can not be deleted') } contribution.contributionStatus = ContributionStatus.DELETED + await contribution.save() const res = await contribution.softRemove() return !!res } From 90fb72a64847fb0a01575d4e3bccbd011aef078e Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 16 Aug 2022 09:10:23 +0200 Subject: [PATCH 78/83] fix lint --- frontend/src/components/SessionLogoutTimeout.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/components/SessionLogoutTimeout.spec.js b/frontend/src/components/SessionLogoutTimeout.spec.js index ebaf4110f..bd6911d13 100644 --- a/frontend/src/components/SessionLogoutTimeout.spec.js +++ b/frontend/src/components/SessionLogoutTimeout.spec.js @@ -1,7 +1,6 @@ import { mount } from '@vue/test-utils' import SessionLogoutTimeout from './SessionLogoutTimeout' - const localVue = global.localVue const apolloQueryMock = jest.fn() From 32e32521555bc1155805dedb5708af7b7f5bd419 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 16 Aug 2022 09:34:16 +0200 Subject: [PATCH 79/83] test for TransactionConfirmationLink --- .../GddSend/TransactionConfirmationLink.spec.js | 12 ++++++++++++ .../GddSend/TransactionConfirmationLink.vue | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js b/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js index a28c2d185..10c1f3a9e 100644 --- a/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js +++ b/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js @@ -46,5 +46,17 @@ describe('GddSend confirm', () => { expect(wrapper.findAll('div.confirm-box-link').at(0).exists()).toBeTruthy() }) }) + + describe('has totalBalance under 0', () => { + beforeEach(async () => { + await wrapper.setProps({ + balance: 0, + }) + }) + + it('has button disable', () => { + expect(wrapper.find('.send-button').attributes('disabled')).toBe('disabled') + }) + }) }) }) diff --git a/frontend/src/components/GddSend/TransactionConfirmationLink.vue b/frontend/src/components/GddSend/TransactionConfirmationLink.vue index c23ed35d2..03031673f 100644 --- a/frontend/src/components/GddSend/TransactionConfirmationLink.vue +++ b/frontend/src/components/GddSend/TransactionConfirmationLink.vue @@ -42,7 +42,7 @@ {{ $t('back') }} - + {{ $t('form.generate_now') }} From 13478960bc88c0790c7be61afa08b8e7380e3551 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 16 Aug 2022 09:50:47 +0200 Subject: [PATCH 80/83] fix lint --- .../src/components/GddSend/TransactionConfirmationLink.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/GddSend/TransactionConfirmationLink.vue b/frontend/src/components/GddSend/TransactionConfirmationLink.vue index 03031673f..2620753ee 100644 --- a/frontend/src/components/GddSend/TransactionConfirmationLink.vue +++ b/frontend/src/components/GddSend/TransactionConfirmationLink.vue @@ -42,7 +42,12 @@ {{ $t('back') }} - + {{ $t('form.generate_now') }} From 9a1b73ebf3a98b74f11d970b8629aef0d8f82a07 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 16 Aug 2022 11:37:03 +0200 Subject: [PATCH 81/83] Update frontend/src/components/GddSend/TransactionConfirmationLink.spec.js Co-authored-by: Moriz Wahl --- .../src/components/GddSend/TransactionConfirmationLink.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js b/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js index 10c1f3a9e..91207901c 100644 --- a/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js +++ b/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js @@ -54,7 +54,7 @@ describe('GddSend confirm', () => { }) }) - it('has button disable', () => { + it('has send button disabled', () => { expect(wrapper.find('.send-button').attributes('disabled')).toBe('disabled') }) }) From 722b0e4757dc5c04ade2afb479cd3f350e9f3f11 Mon Sep 17 00:00:00 2001 From: Alexander Friedland Date: Tue, 16 Aug 2022 11:37:10 +0200 Subject: [PATCH 82/83] Update frontend/src/components/GddSend/TransactionConfirmationLink.spec.js Co-authored-by: Moriz Wahl --- .../src/components/GddSend/TransactionConfirmationLink.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js b/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js index 91207901c..56694296a 100644 --- a/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js +++ b/frontend/src/components/GddSend/TransactionConfirmationLink.spec.js @@ -47,7 +47,7 @@ describe('GddSend confirm', () => { }) }) - describe('has totalBalance under 0', () => { + describe('has total balance equal 0', () => { beforeEach(async () => { await wrapper.setProps({ balance: 0, From e876f32ad529ad63632f0faef309dab3d65724d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus-Peter=20H=C3=BCbner?= Date: Tue, 16 Aug 2022 17:05:31 +0200 Subject: [PATCH 83/83] initialize gradidoID of fakedUser per uuidv4() instead of constant --- backend/src/graphql/resolver/UserResolver.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index d9245f51d..a8967e963 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -364,7 +364,7 @@ export class UserResolver { const user = new User(communityDbUser) user.id = sodium.randombytes_random() % (2048 * 16) // TODO: for a better faking derive id from email so that it will be always the same id when the same email comes in? - user.gradidoID = '11111111-2222-4333-4444-55555555' + user.gradidoID = uuidv4() user.email = email user.firstName = firstName user.lastName = lastName