From ded649f342a61798b521ff68406a8549efeedff0 Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 15 Sep 2022 11:42:03 +0200 Subject: [PATCH 01/18] Events and logs completed in User Resolver --- .../src/graphql/resolver/UserResolver.test.ts | 67 +++++++++++++++++-- backend/src/graphql/resolver/UserResolver.ts | 6 +- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 36bae56de..58d697d8e 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -19,6 +19,8 @@ import { contributionLinkFactory } from '@/seeds/factory/contributionLink' import { ContributionLink } from '@model/ContributionLink' // import { TransactionLink } from '@entity/TransactionLink' +import { EventProtocolType } from '@/event/EventProtocolType' +import { EventProtocol } from '@entity/EventProtocol' import { logger } from '@test/testSetup' import { validate as validateUUID, version as versionUUID } from 'uuid' import { peterLustig } from '@/seeds/users/peter-lustig' @@ -169,6 +171,14 @@ describe('UserResolver', () => { duration: expect.any(String), }) }) + + it('stores the send confirmation event in the database', () => { + expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.SEND_CONFIRMATION_EMAIL, + }), + ) + }) }) describe('email already exists', () => { @@ -383,6 +393,10 @@ bei Gradidio sei dabei!`, }), ) }) + + it('logs the error thrown', () => { + expect(logger.error).toBeCalledWith('Password entered is lexically invalid') + }) }) describe('no valid optin code', () => { @@ -405,6 +419,10 @@ bei Gradidio sei dabei!`, }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('Could not login with emailVerificationCode') + }) }) }) @@ -433,6 +451,10 @@ bei Gradidio sei dabei!`, }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('User with email=bibi@bloxberg.de does not exist') + }) }) describe('user is in database and correct login data', () => { @@ -475,6 +497,7 @@ bei Gradidio sei dabei!`, describe('user is in database and wrong password', () => { beforeAll(async () => { await userFactory(testEnv, bibiBloxberg) + result = await query({ query: login, variables: { ...variables, password: 'wrong' } }) }) afterAll(async () => { @@ -482,14 +505,16 @@ bei Gradidio sei dabei!`, }) it('returns an error', () => { - expect( - query({ query: login, variables: { ...variables, password: 'wrong' } }), - ).resolves.toEqual( + expect(result).toEqual( expect.objectContaining({ errors: [new GraphQLError('No user with this credentials')], }), ) }) + + it('logs the error thrown', () => { + expect(logger.error).toBeCalledWith('The User has no valid credentials.') + }) }) }) @@ -595,6 +620,14 @@ bei Gradidio sei dabei!`, }), ) }) + + it('stores the login event in the database', () => { + expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.LOGIN, + }), + ) + }) }) }) }) @@ -649,13 +682,17 @@ bei Gradidio sei dabei!`, }) describe('request reset password again', () => { - it('thows an error', async () => { + it('throws an error', async () => { await expect(mutate({ mutation: forgotPassword, variables })).resolves.toEqual( expect.objectContaining({ errors: [new GraphQLError('email already sent less than 10 minutes minutes ago')], }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith(`email already sent less than 10 minutes minutes ago`) + }) }) }) }) @@ -766,7 +803,7 @@ bei Gradidio sei dabei!`, }) describe('language is not valid', () => { - it('thows an error', async () => { + it('throws an error', async () => { await expect( mutate({ mutation: updateUserInfos, @@ -780,6 +817,10 @@ bei Gradidio sei dabei!`, }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith(`"not-valid" isn't a valid language`) + }) }) describe('password', () => { @@ -799,6 +840,10 @@ bei Gradidio sei dabei!`, }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith(`Old password is invalid`) + }) }) describe('invalid new password', () => { @@ -821,6 +866,10 @@ bei Gradidio sei dabei!`, }), ) }) + + it('logs the error found', () => { + expect(logger.error).toBeCalledWith('newPassword does not fullfil the rules') + }) }) describe('correct old and new password', () => { @@ -840,7 +889,7 @@ bei Gradidio sei dabei!`, ) }) - it('can login wtih new password', async () => { + it('can login with new password', async () => { await expect( query({ query: login, @@ -860,7 +909,7 @@ bei Gradidio sei dabei!`, ) }) - it('cannot login wtih old password', async () => { + it('cannot login with old password', async () => { await expect( query({ query: login, @@ -875,6 +924,10 @@ bei Gradidio sei dabei!`, }), ) }) + + it('logs the error thrown', () => { + expect(logger.error).toBeCalledWith('The User has no valid credentials.') + }) }) }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 3b7013323..2e2f5aeec 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -273,7 +273,7 @@ export class UserResolver { logger.info(`login with ${email}, ***, ${publisherId} ...`) email = email.trim().toLowerCase() const dbUser = await DbUser.findOneOrFail({ email }, { withDeleted: true }).catch(() => { - logger.error(`User with email=${email} does not exists`) + logger.error(`User with email=${email} does not exist`) throw new Error('No user with this credentials') }) if (dbUser.deletedAt) { @@ -389,7 +389,7 @@ export class UserResolver { /* uncomment this, when you need the activation link on the console */ // In case EMails are disabled log the activation link for the user if (!emailSent) { - logger.debug(`Email not send!`) + logger.debug(`Email not sent!`) } logger.info('createUser() faked and send multi registration mail...') @@ -548,6 +548,7 @@ export class UserResolver { logger.info(`setPassword(${code}, ***)...`) // Validate Password if (!isPassword(password)) { + logger.error('Password entered is lexically invalid') throw new Error( 'Please enter a valid password with at least 8 characters, upper and lower case letters, at least one number and one special character!', ) @@ -727,6 +728,7 @@ export class UserResolver { try { await queryRunner.manager.save(userEntity).catch((error) => { + logger.error('error saving user: ' + error) throw new Error('error saving user: ' + error) }) From e3e5fdd12b4566287bd9e28b8761c73b8ef22abd Mon Sep 17 00:00:00 2001 From: ogerly Date: Fri, 16 Sep 2022 08:22:24 +0200 Subject: [PATCH 02/18] remove modal box if redeem a redeemlink --- .../LinkInformations/RedeemValid.vue | 2 +- frontend/src/pages/TransactionLink.spec.js | 56 +++++++++---------- frontend/src/pages/TransactionLink.vue | 7 +-- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/frontend/src/components/LinkInformations/RedeemValid.vue b/frontend/src/components/LinkInformations/RedeemValid.vue index 353fefaf8..c468a396a 100644 --- a/frontend/src/components/LinkInformations/RedeemValid.vue +++ b/frontend/src/components/LinkInformations/RedeemValid.vue @@ -3,7 +3,7 @@
- + {{ $t('gdd_per_link.redeem') }}
diff --git a/frontend/src/pages/TransactionLink.spec.js b/frontend/src/pages/TransactionLink.spec.js index b1bbd8950..fd58d6e1c 100644 --- a/frontend/src/pages/TransactionLink.spec.js +++ b/frontend/src/pages/TransactionLink.spec.js @@ -282,18 +282,18 @@ describe('TransactionLink', () => { }) describe('redeem link with success', () => { - let spy + // let spy beforeEach(async () => { - spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') + // spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') apolloMutateMock.mockResolvedValue() - spy.mockImplementation(() => Promise.resolve(true)) + // spy.mockImplementation(() => Promise.resolve(true)) await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') }) - it('opens the modal', () => { - expect(spy).toBeCalledWith('gdd_per_link.redeem-text') - }) + // it('opens the modal', () => { + // expect(spy).toBeCalledWith('gdd_per_link.redeem-text') + // }) it('calls the API', () => { expect(apolloMutateMock).toBeCalledWith( @@ -316,37 +316,37 @@ describe('TransactionLink', () => { }) }) - describe('cancel redeem link', () => { - let spy + // describe('cancel redeem link', () => { + // let spy - beforeEach(async () => { - spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') - apolloMutateMock.mockResolvedValue() - spy.mockImplementation(() => Promise.resolve(false)) - await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') - }) + // beforeEach(async () => { + // spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') + // apolloMutateMock.mockResolvedValue() + // spy.mockImplementation(() => Promise.resolve(false)) + // await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') + // }) - it('does not call the API', () => { - expect(apolloMutateMock).not.toBeCalled() - }) + // it('does not call the API', () => { + // expect(apolloMutateMock).not.toBeCalled() + // }) - it('does not toasts a success message', () => { - expect(mocks.$t).not.toBeCalledWith('gdd_per_link.redeemed', { n: '22' }) - expect(toastSuccessSpy).not.toBeCalled() - }) + // it('does not toasts a success message', () => { + // expect(mocks.$t).not.toBeCalledWith('gdd_per_link.redeemed', { n: '22' }) + // expect(toastSuccessSpy).not.toBeCalled() + // }) - it('does not push the route', () => { - expect(routerPushMock).not.toBeCalled() - }) - }) + // it('does not push the route', () => { + // expect(routerPushMock).not.toBeCalled() + // }) + // }) describe('redeem link with error', () => { - let spy + // let spy beforeEach(async () => { - spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') + // spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') apolloMutateMock.mockRejectedValue({ message: 'Oh Noo!' }) - spy.mockImplementation(() => Promise.resolve(true)) + // spy.mockImplementation(() => Promise.resolve(true)) await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') }) diff --git a/frontend/src/pages/TransactionLink.vue b/frontend/src/pages/TransactionLink.vue index 57236b55c..bd1909d7d 100644 --- a/frontend/src/pages/TransactionLink.vue +++ b/frontend/src/pages/TransactionLink.vue @@ -14,7 +14,7 @@ @@ -98,11 +98,6 @@ export default { this.$router.push('/overview') }) }, - redeemLink(amount) { - this.$bvModal.msgBoxConfirm(this.$t('gdd_per_link.redeem-text')).then((value) => { - if (value) this.mutationLink(amount) - }) - }, }, computed: { isContributionLink() { From caf487d2062667ac77794d0ea8624362b7737924 Mon Sep 17 00:00:00 2001 From: ogerly Date: Fri, 16 Sep 2022 08:24:31 +0200 Subject: [PATCH 03/18] remove text from modal for redeem link --- frontend/src/locales/de.json | 1 - frontend/src/locales/en.json | 1 - frontend/src/locales/es.json | 1 - frontend/src/locales/fr.json | 1 - frontend/src/locales/nl.json | 1 - frontend/src/pages/TransactionLink.spec.js | 34 ---------------------- 6 files changed, 39 deletions(-) diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index e6b12b0fa..1ed8af19f 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -178,7 +178,6 @@ "no-redeem": "Du darfst deinen eigenen Link nicht einlösen!", "not-copied": "Dein Gerät lässt das Kopieren leider nicht zu! Bitte kopiere den Link von Hand!", "redeem": "Einlösen", - "redeem-text": "Willst du den Betrag jetzt einlösen?", "redeemed": "Erfolgreich eingelöst! Deinem Konto wurden {n} GDD gutgeschrieben.", "redeemed-at": "Der Link wurde bereits am {date} eingelöst.", "redeemed-title": "eingelöst", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 07125eceb..113fa1cb9 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -178,7 +178,6 @@ "no-redeem": "You not allowed to redeem your own link!", "not-copied": "Unfortunately, your device does not allow copying! Please copy the link by hand!", "redeem": "Redeem", - "redeem-text": "Do you want to redeem the amount now?", "redeemed": "Successfully redeemed! Your account has been credited with {n} GDD.", "redeemed-at": "The link was already redeemed on {date}.", "redeemed-title": "redeemed", diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 987bb71ef..b2a229f1c 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -180,7 +180,6 @@ "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", diff --git a/frontend/src/locales/fr.json b/frontend/src/locales/fr.json index 61037af1a..e7ac18a18 100644 --- a/frontend/src/locales/fr.json +++ b/frontend/src/locales/fr.json @@ -180,7 +180,6 @@ "no-redeem": "Vous n´êtes pas autorisé à percevoir votre propre lien!", "not-copied": "Malheureusement votre appareil ne permet pas de copier! Veuillez copier le lien manuellement svp!", "redeem": "Encaisser", - "redeem-text": "Voulez-vous percevoir le montant maintenant?", "redeemed": "Encaissé avec succès! Votre compte est crédité de {n} GDD.", "redeemed-at": "Le lien a déjà été perçu le {date}.", "redeemed-title": "encaisser", diff --git a/frontend/src/locales/nl.json b/frontend/src/locales/nl.json index 99b972514..34f484fd7 100644 --- a/frontend/src/locales/nl.json +++ b/frontend/src/locales/nl.json @@ -180,7 +180,6 @@ "no-redeem": "Je mag je eigen link niet inwisselen!", "not-copied": "Jouw apparaat laat het kopiëren helaas niet toe! Kopieer de link alsjeblieft met de hand!", "redeem": "Inwisselen", - "redeem-text": "Wil je het bedrag nu inwisselen?", "redeemed": "Succesvol ingewisseld! Op jouw rekening werden {n} GDD bijgeschreven.", "redeemed-at": "De link werd al op {date} ingewisseld.", "redeemed-title": "ingewisseld", diff --git a/frontend/src/pages/TransactionLink.spec.js b/frontend/src/pages/TransactionLink.spec.js index fd58d6e1c..831502acd 100644 --- a/frontend/src/pages/TransactionLink.spec.js +++ b/frontend/src/pages/TransactionLink.spec.js @@ -282,19 +282,12 @@ describe('TransactionLink', () => { }) describe('redeem link with success', () => { - // let spy beforeEach(async () => { - // spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') apolloMutateMock.mockResolvedValue() - // spy.mockImplementation(() => Promise.resolve(true)) await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') }) - // it('opens the modal', () => { - // expect(spy).toBeCalledWith('gdd_per_link.redeem-text') - // }) - it('calls the API', () => { expect(apolloMutateMock).toBeCalledWith( expect.objectContaining({ @@ -316,37 +309,10 @@ describe('TransactionLink', () => { }) }) - // describe('cancel redeem link', () => { - // let spy - - // beforeEach(async () => { - // spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') - // apolloMutateMock.mockResolvedValue() - // spy.mockImplementation(() => Promise.resolve(false)) - // await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') - // }) - - // it('does not call the API', () => { - // expect(apolloMutateMock).not.toBeCalled() - // }) - - // it('does not toasts a success message', () => { - // expect(mocks.$t).not.toBeCalledWith('gdd_per_link.redeemed', { n: '22' }) - // expect(toastSuccessSpy).not.toBeCalled() - // }) - - // it('does not push the route', () => { - // expect(routerPushMock).not.toBeCalled() - // }) - // }) - describe('redeem link with error', () => { - // let spy beforeEach(async () => { - // spy = jest.spyOn(wrapper.vm.$bvModal, 'msgBoxConfirm') apolloMutateMock.mockRejectedValue({ message: 'Oh Noo!' }) - // spy.mockImplementation(() => Promise.resolve(true)) await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') }) From 222d8c2f579a936221c362a8f05921fc9c7fe359 Mon Sep 17 00:00:00 2001 From: ogerly Date: Fri, 16 Sep 2022 08:25:55 +0200 Subject: [PATCH 04/18] fix lint --- frontend/src/pages/TransactionLink.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/pages/TransactionLink.spec.js b/frontend/src/pages/TransactionLink.spec.js index 831502acd..d5a75aa4a 100644 --- a/frontend/src/pages/TransactionLink.spec.js +++ b/frontend/src/pages/TransactionLink.spec.js @@ -282,7 +282,6 @@ describe('TransactionLink', () => { }) describe('redeem link with success', () => { - beforeEach(async () => { apolloMutateMock.mockResolvedValue() await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') @@ -310,7 +309,6 @@ describe('TransactionLink', () => { }) describe('redeem link with error', () => { - beforeEach(async () => { apolloMutateMock.mockRejectedValue({ message: 'Oh Noo!' }) await wrapper.findComponent({ name: 'RedeemValid' }).find('button').trigger('click') From 390bb1db3de2c1621a2e44a502737056c352ce9a Mon Sep 17 00:00:00 2001 From: joseji Date: Fri, 16 Sep 2022 12:22:32 +0200 Subject: [PATCH 05/18] IDs also tested while event saving, added ActivateAccount event when setting password --- backend/src/graphql/resolver/UserResolver.test.ts | 12 ++++++++++++ backend/src/graphql/resolver/UserResolver.ts | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 58d697d8e..2c6406939 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -176,6 +176,7 @@ describe('UserResolver', () => { expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.SEND_CONFIRMATION_EMAIL, + userId: expect.any(Number), // as it is randomly generated }), ) }) @@ -255,6 +256,7 @@ describe('UserResolver', () => { mutation: setPassword, variables: { code: emailOptIn, password: 'Aa12345_' }, }) + // make Peter Lustig Admin const peter = await User.findOneOrFail({ id: user[0].id }) peter.isAdmin = new Date() @@ -281,6 +283,15 @@ describe('UserResolver', () => { }), ) }) + + it('stores the account activated event in the database', () => { + expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.ACTIVATE_ACCOUNT, + userId: expect.any(Number), // as it is randomly generated + }), + ) + }) }) /* A transaction link requires GDD on account @@ -625,6 +636,7 @@ bei Gradidio sei dabei!`, expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.LOGIN, + userId: expect.any(Number), // as it is randomly generated }), ) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 2e2f5aeec..fad0fadd3 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -30,6 +30,7 @@ import { EventRedeemRegister, EventRegister, EventSendConfirmationEmail, + EventActivateAccount, } from '@/event/Event' import { getUserCreation } from './util/creations' import { UserRepository } from '@/typeorm/repository/User' @@ -611,6 +612,8 @@ export class UserResolver { await queryRunner.connect() await queryRunner.startTransaction('READ UNCOMMITTED') + const event = new Event() + try { // Save user await queryRunner.manager.save(user).catch((error) => { @@ -619,6 +622,9 @@ export class UserResolver { }) await queryRunner.commitTransaction() + const eventActivateAccount = new EventActivateAccount() + eventActivateAccount.userId = user.id + eventProtocol.writeEvent(event.setEventActivateAccount(eventActivateAccount)) logger.info('User data written successfully...') } catch (e) { await queryRunner.rollbackTransaction() From b8442e172565baa6120a6fdee55458e61b6484fb Mon Sep 17 00:00:00 2001 From: joseji Date: Fri, 16 Sep 2022 13:42:45 +0200 Subject: [PATCH 06/18] added redeem register event test, transaction link execution failing --- .../src/graphql/resolver/UserResolver.test.ts | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 2c6406939..1103f8bf2 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -24,6 +24,8 @@ import { EventProtocol } from '@entity/EventProtocol' import { logger } from '@test/testSetup' import { validate as validateUUID, version as versionUUID } from 'uuid' import { peterLustig } from '@/seeds/users/peter-lustig' +import { TransactionLink } from '@entity/TransactionLink' +import { transactionLinkFactory } from '@/seeds/factory/transactionLink' // import { klicktippSignIn } from '@/apis/KlicktippController' @@ -261,13 +263,19 @@ describe('UserResolver', () => { const peter = await User.findOneOrFail({ id: user[0].id }) peter.isAdmin = new Date() await peter.save() + + // date statement + const actualDate = new Date() + const futureDate = new Date() // Create a future day from the executed day + futureDate.setDate(futureDate.getDate() + 1) + // factory logs in as Peter Lustig link = await contributionLinkFactory(testEnv, { name: 'Dokumenta 2022', memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2022', amount: 200, - validFrom: new Date(2022, 5, 18), - validTo: new Date(2022, 8, 25), + validFrom: actualDate, + validTo: futureDate, }) resetToken() await mutate({ @@ -292,6 +300,39 @@ describe('UserResolver', () => { }), ) }) + + it('stores the redeem register event in the database', () => { + expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.REDEEM_REGISTER, + userId: expect.any(Number), // as it is randomly generated + }), + ) + }) + }) + + describe('transaction link', () => { + beforeAll(async () => { + await transactionLinkFactory(testEnv, { + email: 'peter@lustig.de', + amount: 19.99, + memo: `Kein Trick, keine Zauberrei, + bei Gradidio sei dabei!`, + }) + + const transactionLink = await TransactionLink.findOneOrFail() + resetToken() + await mutate({ + mutation: createUser, + variables: { ...variables, email: 'neuer@user.de', redeemCode: transactionLink.code }, + }) + }) + + it('sets the referrer id to Peter Lustigs id', () => { + expect(User.findOne({ email: 'neuer@user.de' })).resolves.toEqual( + expect.objectContaining({ referrerId: user[0].id }), + ) + }) }) /* A transaction link requires GDD on account From cfdec3d1226a029e719d28d0db5c09cccf267bd2 Mon Sep 17 00:00:00 2001 From: joseji Date: Fri, 16 Sep 2022 13:45:20 +0200 Subject: [PATCH 07/18] Fixed wrong handling of dates in tests failing depending on the day you execute them --- backend/src/graphql/resolver/UserResolver.test.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 2c6406939..367f82b4f 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -261,14 +261,21 @@ describe('UserResolver', () => { const peter = await User.findOneOrFail({ id: user[0].id }) peter.isAdmin = new Date() await peter.save() + + // date statement + const actualDate = new Date() + const futureDate = new Date() // Create a future day from the executed day + futureDate.setDate(futureDate.getDate() + 1) + // factory logs in as Peter Lustig link = await contributionLinkFactory(testEnv, { name: 'Dokumenta 2022', memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2022', amount: 200, - validFrom: new Date(2022, 5, 18), - validTo: new Date(2022, 8, 25), + validFrom: actualDate, + validTo: futureDate, }) + resetToken() await mutate({ mutation: createUser, From 5f94cfca88de2896624a8de48c4457adf8331556 Mon Sep 17 00:00:00 2001 From: jjimenezgarcia <99907380+jjimenezgarcia@users.noreply.github.com> Date: Mon, 19 Sep 2022 15:40:59 +0200 Subject: [PATCH 08/18] Update backend/src/graphql/resolver/UserResolver.test.ts Co-authored-by: Moriz Wahl --- 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 367f82b4f..5be3c3e20 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -176,7 +176,7 @@ describe('UserResolver', () => { expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.SEND_CONFIRMATION_EMAIL, - userId: expect.any(Number), // as it is randomly generated + userId: user.id, }), ) }) From 1203dada61f234a8afc8ca4878c06b7fccb44a5b Mon Sep 17 00:00:00 2001 From: joseji Date: Mon, 19 Sep 2022 19:18:06 +0200 Subject: [PATCH 09/18] ids are now checked in event creation --- backend/src/graphql/resolver/UserResolver.test.ts | 9 ++++++--- backend/src/graphql/resolver/UserResolver.ts | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 5be3c3e20..13715e088 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -176,7 +176,7 @@ describe('UserResolver', () => { expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.SEND_CONFIRMATION_EMAIL, - userId: user.id, + userId: user[0].id, }), ) }) @@ -295,7 +295,7 @@ describe('UserResolver', () => { expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.ACTIVATE_ACCOUNT, - userId: expect.any(Number), // as it is randomly generated + userId: user[0].id, }), ) }) @@ -605,6 +605,8 @@ bei Gradidio sei dabei!`, }) describe('authenticated', () => { + let user: User[] + const variables = { email: 'bibi@bloxberg.de', password: 'Aa12345_', @@ -612,6 +614,7 @@ bei Gradidio sei dabei!`, beforeAll(async () => { await query({ query: login, variables }) + user = await User.find() }) afterAll(() => { @@ -643,7 +646,7 @@ bei Gradidio sei dabei!`, expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.LOGIN, - userId: expect.any(Number), // as it is randomly generated + userId: user[0].id, }), ) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index fad0fadd3..f2fd048fc 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -622,9 +622,11 @@ export class UserResolver { }) await queryRunner.commitTransaction() + const eventActivateAccount = new EventActivateAccount() eventActivateAccount.userId = user.id eventProtocol.writeEvent(event.setEventActivateAccount(eventActivateAccount)) + logger.info('User data written successfully...') } catch (e) { await queryRunner.rollbackTransaction() From bf6ed35c6e1b359599fa6f28483e8e3c8eb65587 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 21 Sep 2022 12:05:49 +0200 Subject: [PATCH 10/18] Change text template of ContributionMessageReceived. --- .../src/mailer/text/contributionMessageReceived.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/backend/src/mailer/text/contributionMessageReceived.ts b/backend/src/mailer/text/contributionMessageReceived.ts index 4affb71a8..b0c9c4d30 100644 --- a/backend/src/mailer/text/contributionMessageReceived.ts +++ b/backend/src/mailer/text/contributionMessageReceived.ts @@ -14,17 +14,15 @@ export const contributionMessageReceived = { }): string => `Hallo ${data.recipientFirstName} ${data.recipientLastName}, -Du hast soeben zu deinem eingereichten Gradido Schöpfungsantrag "${data.contributionMemo}" eine Rückfrage von ${data.senderFirstName} ${data.senderLastName} erhalten. -Die Rückfrage lautet: +du hast soeben zu deinem eingereichten Gemeinwohl-Beitrag "${data.contributionMemo}" eine Rückfrage von ${data.senderFirstName} ${data.senderLastName} erhalten. -${data.message} +Bitte beantworte die Rückfrage in deinem Gradido-Konto im Menü "Gemeinschaft" im Tab "Meine Beiträge zum Gemeinwohl"! + +Link zu deinem Konto: ${data.overviewURL} Bitte antworte nicht auf diese E-Mail! Mit freundlichen Grüßen, -dein Gradido-Team - - -Link zu deinem Konto: ${data.overviewURL}`, +dein Gradido-Team`, }, } From 6c446fb4772d7af635658c6d25e86eb68b9a6029 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 21 Sep 2022 12:07:19 +0200 Subject: [PATCH 11/18] Change text template of transactionReceived. --- backend/src/mailer/text/transactionReceived.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/backend/src/mailer/text/transactionReceived.ts b/backend/src/mailer/text/transactionReceived.ts index 2764d1b60..c533b5b1f 100644 --- a/backend/src/mailer/text/transactionReceived.ts +++ b/backend/src/mailer/text/transactionReceived.ts @@ -19,17 +19,13 @@ export const transactionReceived = { Du hast soeben ${data.amount.toFixed(2).replace('.', ',')} GDD von ${data.senderFirstName} ${ data.senderLastName } (${data.senderEmail}) erhalten. -${data.senderFirstName} ${data.senderLastName} schreibt: -${data.memo} +Details zur Transaktion findest du in deinem Gradido-Konto: ${data.overviewURL} Bitte antworte nicht auf diese E-Mail! Mit freundlichen Grüßen, -dein Gradido-Team - - -Link zu deinem Konto: ${data.overviewURL}`, +dein Gradido-Team`, }, } From 3b3a963ac5cc4c1a35b63a45957b71292d31ce89 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 21 Sep 2022 12:09:36 +0200 Subject: [PATCH 12/18] Change text template of contributionConfirmed. --- backend/src/mailer/text/contributionConfirmed.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/src/mailer/text/contributionConfirmed.ts b/backend/src/mailer/text/contributionConfirmed.ts index 2d9fce6a8..dc82d7615 100644 --- a/backend/src/mailer/text/contributionConfirmed.ts +++ b/backend/src/mailer/text/contributionConfirmed.ts @@ -14,9 +14,10 @@ export const contributionConfirmed = { }): string => `Hallo ${data.recipientFirstName} ${data.recipientLastName}, -Dein Gradido Schöpfungsantrag "${data.contributionMemo}" wurde soeben von ${data.senderFirstName} ${ - data.senderLastName - } bestätigt. +Dein eingereichter Gemeinwohl-Beitrag "${data.contributionMemo}" wurde soeben von ${ + data.senderFirstName + } ${data.senderLastName} bestätigt. + Betrag: ${data.contributionAmount.toFixed(2).replace('.', ',')} GDD Bitte antworte nicht auf diese E-Mail! From 686c43fa895ced5ad94042b2469365ccabe35d10 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 21 Sep 2022 12:12:23 +0200 Subject: [PATCH 13/18] Change text of linkRedeemed template. --- backend/src/mailer/text/transactionReceived.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/src/mailer/text/transactionReceived.ts b/backend/src/mailer/text/transactionReceived.ts index c533b5b1f..4f10f41c8 100644 --- a/backend/src/mailer/text/transactionReceived.ts +++ b/backend/src/mailer/text/transactionReceived.ts @@ -47,15 +47,16 @@ export const transactionLinkRedeemed = { ${data.senderFirstName} ${data.senderLastName} (${ data.senderEmail - }) hat soeben deinen Link eingelösst. + }) hat soeben deinen Link eingelöst. + Betrag: ${data.amount.toFixed(2).replace('.', ',')} GDD, Memo: ${data.memo} +Details zur Transaktion findest du in deinem Gradido-Konto: ${data.overviewURL} + Bitte antworte nicht auf diese E-Mail! Mit freundlichen Grüßen, -dein Gradido-Team - -Link zu deinem Konto: ${data.overviewURL}`, +dein Gradido-Team`, }, } From 6c0cb17196e82119f16e57f9130006361ab112ea Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 21 Sep 2022 12:41:25 +0200 Subject: [PATCH 14/18] Refactor sendTransactionLinkredeemed . --- .../graphql/resolver/TransactionResolver.ts | 7 +-- .../sendTransactionLinkRedeemed.test.ts | 44 +++++++++++++++++++ .../src/mailer/sendTransactionLinkRedeemed.ts | 28 ++++++++++++ .../sendTransactionReceivedEmail.test.ts | 2 - .../mailer/sendTransactionReceivedEmail.ts | 27 +----------- .../mailer/text/transactionLinkRedeemed.ts | 33 ++++++++++++++ .../src/mailer/text/transactionReceived.ts | 33 -------------- 7 files changed, 108 insertions(+), 66 deletions(-) create mode 100644 backend/src/mailer/sendTransactionLinkRedeemed.test.ts create mode 100644 backend/src/mailer/sendTransactionLinkRedeemed.ts create mode 100644 backend/src/mailer/text/transactionLinkRedeemed.ts diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 1d8748f58..c192ae9dc 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -8,10 +8,7 @@ import { Context, getUser } from '@/server/context' import { Resolver, Query, Args, Authorized, Ctx, Mutation } from 'type-graphql' import { getCustomRepository, getConnection } from '@dbTools/typeorm' -import { - sendTransactionLinkRedeemedEmail, - sendTransactionReceivedEmail, -} from '@/mailer/sendTransactionReceivedEmail' +import { sendTransactionReceivedEmail } from '@/mailer/sendTransactionReceivedEmail' import { Transaction } from '@model/Transaction' import { TransactionList } from '@model/TransactionList' @@ -38,6 +35,7 @@ import Decimal from 'decimal.js-light' import { BalanceResolver } from './BalanceResolver' import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const' +import { sendTransactionLinkRedeemedEmail } from '@/mailer/sendTransactionLinkRedeemed' export const executeTransaction = async ( amount: Decimal, @@ -154,7 +152,6 @@ export const executeTransaction = async ( email: recipient.email, senderEmail: sender.email, amount, - memo, overviewURL: CONFIG.EMAIL_LINK_OVERVIEW, }) if (transactionLink) { diff --git a/backend/src/mailer/sendTransactionLinkRedeemed.test.ts b/backend/src/mailer/sendTransactionLinkRedeemed.test.ts new file mode 100644 index 000000000..b56ff40a1 --- /dev/null +++ b/backend/src/mailer/sendTransactionLinkRedeemed.test.ts @@ -0,0 +1,44 @@ +import { sendEMail } from './sendEMail' +import Decimal from 'decimal.js-light' +import { sendTransactionLinkRedeemedEmail } from './sendTransactionLinkRedeemed' + +jest.mock('./sendEMail', () => { + return { + __esModule: true, + sendEMail: jest.fn(), + } +}) + +describe('sendTransactionLinkRedeemedEmail', () => { + beforeEach(async () => { + await sendTransactionLinkRedeemedEmail({ + email: 'bibi@bloxberg.de', + senderFirstName: 'Peter', + senderLastName: 'Lustig', + recipientFirstName: 'Bibi', + recipientLastName: 'Bloxberg', + senderEmail: 'peter@lustig.de', + amount: new Decimal(42.0), + memo: 'Vielen Dank dass Du dabei bist', + overviewURL: 'http://localhost/overview', + }) + }) + + it('calls sendEMail', () => { + expect(sendEMail).toBeCalledWith({ + to: `Bibi Bloxberg `, + subject: 'Gradido-Link wurde eingelöst', + text: + expect.stringContaining('Hallo Bibi Bloxberg') && + expect.stringContaining( + 'Peter Lustig (peter@lustig.de) hat soeben deinen Link eingelöst.', + ) && + expect.stringContaining('Betrag: 42,00 GDD,') && + expect.stringContaining('Memo: Vielen Dank dass Du dabei bist') && + expect.stringContaining( + 'Details zur Transaktion findest du in deinem Gradido-Konto: http://localhost/overview', + ) && + expect.stringContaining('Bitte antworte nicht auf diese E-Mail!'), + }) + }) +}) diff --git a/backend/src/mailer/sendTransactionLinkRedeemed.ts b/backend/src/mailer/sendTransactionLinkRedeemed.ts new file mode 100644 index 000000000..a78f3b3c9 --- /dev/null +++ b/backend/src/mailer/sendTransactionLinkRedeemed.ts @@ -0,0 +1,28 @@ +import { backendLogger as logger } from '@/server/logger' +import Decimal from 'decimal.js-light' +import { sendEMail } from './sendEMail' +import { transactionLinkRedeemed } from './text/transactionLinkRedeemed' + +export const sendTransactionLinkRedeemedEmail = (data: { + email: string + senderFirstName: string + senderLastName: string + recipientFirstName: string + recipientLastName: string + senderEmail: string + amount: Decimal + memo: string + overviewURL: string +}): Promise => { + logger.info( + `sendEmail(): to=${data.recipientFirstName} ${data.recipientLastName}, + <${data.email}>, + subject=${transactionLinkRedeemed.de.subject}, + text=${transactionLinkRedeemed.de.text(data)}`, + ) + return sendEMail({ + to: `${data.recipientFirstName} ${data.recipientLastName} <${data.email}>`, + subject: transactionLinkRedeemed.de.subject, + text: transactionLinkRedeemed.de.text(data), + }) +} diff --git a/backend/src/mailer/sendTransactionReceivedEmail.test.ts b/backend/src/mailer/sendTransactionReceivedEmail.test.ts index 75631cc7a..9f2ba9938 100644 --- a/backend/src/mailer/sendTransactionReceivedEmail.test.ts +++ b/backend/src/mailer/sendTransactionReceivedEmail.test.ts @@ -19,7 +19,6 @@ describe('sendTransactionReceivedEmail', () => { email: 'peter@lustig.de', senderEmail: 'bibi@bloxberg.de', amount: new Decimal(42.0), - memo: 'Vielen herzlichen Dank für den neuen Hexenbesen!', overviewURL: 'http://localhost/overview', }) }) @@ -33,7 +32,6 @@ describe('sendTransactionReceivedEmail', () => { expect.stringContaining('42,00 GDD') && expect.stringContaining('Bibi Bloxberg') && expect.stringContaining('(bibi@bloxberg.de)') && - expect.stringContaining('Vielen herzlichen Dank für den neuen Hexenbesen!') && expect.stringContaining('http://localhost/overview'), }) }) diff --git a/backend/src/mailer/sendTransactionReceivedEmail.ts b/backend/src/mailer/sendTransactionReceivedEmail.ts index 55f63e37e..5e981659c 100644 --- a/backend/src/mailer/sendTransactionReceivedEmail.ts +++ b/backend/src/mailer/sendTransactionReceivedEmail.ts @@ -1,7 +1,7 @@ import { backendLogger as logger } from '@/server/logger' import Decimal from 'decimal.js-light' import { sendEMail } from './sendEMail' -import { transactionLinkRedeemed, transactionReceived } from './text/transactionReceived' +import { transactionReceived } from './text/transactionReceived' export const sendTransactionReceivedEmail = (data: { senderFirstName: string @@ -11,7 +11,6 @@ export const sendTransactionReceivedEmail = (data: { email: string senderEmail: string amount: Decimal - memo: string overviewURL: string }): Promise => { logger.info( @@ -26,27 +25,3 @@ export const sendTransactionReceivedEmail = (data: { text: transactionReceived.de.text(data), }) } - -export const sendTransactionLinkRedeemedEmail = (data: { - email: string - senderFirstName: string - senderLastName: string - recipientFirstName: string - recipientLastName: string - senderEmail: string - amount: Decimal - memo: string - overviewURL: string -}): Promise => { - logger.info( - `sendEmail(): to=${data.recipientFirstName} ${data.recipientLastName}, - <${data.email}>, - subject=${transactionLinkRedeemed.de.subject}, - text=${transactionLinkRedeemed.de.text(data)}`, - ) - return sendEMail({ - to: `${data.recipientFirstName} ${data.recipientLastName} <${data.email}>`, - subject: transactionLinkRedeemed.de.subject, - text: transactionLinkRedeemed.de.text(data), - }) -} diff --git a/backend/src/mailer/text/transactionLinkRedeemed.ts b/backend/src/mailer/text/transactionLinkRedeemed.ts new file mode 100644 index 000000000..4d8e89cae --- /dev/null +++ b/backend/src/mailer/text/transactionLinkRedeemed.ts @@ -0,0 +1,33 @@ +import Decimal from 'decimal.js-light' + +export const transactionLinkRedeemed = { + de: { + subject: 'Gradido-Link wurde eingelöst', + text: (data: { + email: string + senderFirstName: string + senderLastName: string + recipientFirstName: string + recipientLastName: string + senderEmail: string + amount: Decimal + memo: string + overviewURL: string + }): string => + `Hallo ${data.recipientFirstName} ${data.recipientLastName} + + ${data.senderFirstName} ${data.senderLastName} (${ + data.senderEmail + }) hat soeben deinen Link eingelöst. + + Betrag: ${data.amount.toFixed(2).replace('.', ',')} GDD, + Memo: ${data.memo} + + Details zur Transaktion findest du in deinem Gradido-Konto: ${data.overviewURL} + + Bitte antworte nicht auf diese E-Mail! + + Mit freundlichen Grüßen, + dein Gradido-Team`, + }, +} diff --git a/backend/src/mailer/text/transactionReceived.ts b/backend/src/mailer/text/transactionReceived.ts index 4f10f41c8..ba61ae680 100644 --- a/backend/src/mailer/text/transactionReceived.ts +++ b/backend/src/mailer/text/transactionReceived.ts @@ -11,7 +11,6 @@ export const transactionReceived = { email: string senderEmail: string amount: Decimal - memo: string overviewURL: string }): string => `Hallo ${data.recipientFirstName} ${data.recipientLastName} @@ -28,35 +27,3 @@ Mit freundlichen Grüßen, dein Gradido-Team`, }, } - -export const transactionLinkRedeemed = { - de: { - subject: 'Gradido link eingelösst', - text: (data: { - email: string - senderFirstName: string - senderLastName: string - recipientFirstName: string - recipientLastName: string - senderEmail: string - amount: Decimal - memo: string - overviewURL: string - }): string => - `Hallo ${data.recipientFirstName} ${data.recipientLastName} - -${data.senderFirstName} ${data.senderLastName} (${ - data.senderEmail - }) hat soeben deinen Link eingelöst. - -Betrag: ${data.amount.toFixed(2).replace('.', ',')} GDD, -Memo: ${data.memo} - -Details zur Transaktion findest du in deinem Gradido-Konto: ${data.overviewURL} - -Bitte antworte nicht auf diese E-Mail! - -Mit freundlichen Grüßen, -dein Gradido-Team`, - }, -} From 6202ca64ad809f888cae855723f421b3f121a70a Mon Sep 17 00:00:00 2001 From: joseji Date: Wed, 21 Sep 2022 19:50:27 +0200 Subject: [PATCH 15/18] test for register through transaction link done --- .../src/graphql/resolver/UserResolver.test.ts | 180 +++++++++++++----- 1 file changed, 128 insertions(+), 52 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 1103f8bf2..08256a11a 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -4,7 +4,15 @@ import { testEnvironment, headerPushMock, resetToken, cleanDB, resetEntity } from '@test/helpers' import { userFactory } from '@/seeds/factory/user' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' -import { createUser, setPassword, forgotPassword, updateUserInfos } from '@/seeds/graphql/mutations' +import { + createUser, + setPassword, + forgotPassword, + updateUserInfos, + createTransactionLink, + createContribution, + confirmContribution, +} from '@/seeds/graphql/mutations' import { login, logout, verifyLogin, queryOptIn, searchAdminUsers } from '@/seeds/graphql/queries' import { GraphQLError } from 'graphql' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' @@ -15,17 +23,18 @@ import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegi import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail' import { printTimeDuration, activationLink } from './UserResolver' import { contributionLinkFactory } from '@/seeds/factory/contributionLink' -// import { transactionLinkFactory } from '@/seeds/factory/transactionLink' +import { transactionLinkFactory } from '@/seeds/factory/transactionLink' import { ContributionLink } from '@model/ContributionLink' -// import { TransactionLink } from '@entity/TransactionLink' +import { TransactionLink } from '@entity/TransactionLink' import { EventProtocolType } from '@/event/EventProtocolType' import { EventProtocol } from '@entity/EventProtocol' import { logger } from '@test/testSetup' import { validate as validateUUID, version as versionUUID } from 'uuid' import { peterLustig } from '@/seeds/users/peter-lustig' -import { TransactionLink } from '@entity/TransactionLink' -import { transactionLinkFactory } from '@/seeds/factory/transactionLink' +import { creationFactory } from '@/seeds/factory/creation' +import { creations } from '@/seeds/creation' +import { bobBaumeister } from '@/seeds/users/bob-baumeister' // import { klicktippSignIn } from '@/apis/KlicktippController' @@ -250,40 +259,47 @@ describe('UserResolver', () => { }) describe('redeem codes', () => { - describe('contribution link', () => { - let link: ContributionLink - beforeAll(async () => { - // activate account of admin Peter Lustig - await mutate({ - mutation: setPassword, - variables: { code: emailOptIn, password: 'Aa12345_' }, - }) - - // make Peter Lustig Admin - const peter = await User.findOneOrFail({ id: user[0].id }) - peter.isAdmin = new Date() - await peter.save() - - // date statement - const actualDate = new Date() - const futureDate = new Date() // Create a future day from the executed day - futureDate.setDate(futureDate.getDate() + 1) - - // factory logs in as Peter Lustig - link = await contributionLinkFactory(testEnv, { - name: 'Dokumenta 2022', - memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2022', - amount: 200, - validFrom: actualDate, - validTo: futureDate, - }) - resetToken() - await mutate({ - mutation: createUser, - variables: { ...variables, email: 'ein@besucher.de', redeemCode: 'CL-' + link.code }, - }) + let result: any + let link: ContributionLink + beforeAll(async () => { + // activate account of admin Peter Lustig + await mutate({ + mutation: setPassword, + variables: { code: emailOptIn, password: 'Aa12345_' }, }) + // make Peter Lustig Admin + const peter = await User.findOneOrFail({ id: user[0].id }) + peter.isAdmin = new Date() + await peter.save() + + // date statement + const actualDate = new Date() + const futureDate = new Date() // Create a future day from the executed day + futureDate.setDate(futureDate.getDate() + 1) + + // factory logs in as Peter Lustig + link = await contributionLinkFactory(testEnv, { + name: 'Dokumenta 2022', + memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2022', + amount: 100, + validFrom: actualDate, + validTo: futureDate, + }) + + resetToken() + + result = await mutate({ + mutation: createUser, + variables: { ...variables, email: 'ein@besucher.de', redeemCode: 'CL-' + link.code }, + }) + }) + + afterAll(async () => { + await cleanDB() + }) + + describe('contribution link', () => { it('sets the contribution link id', async () => { await expect(User.findOne({ email: 'ein@besucher.de' })).resolves.toEqual( expect.objectContaining({ @@ -296,7 +312,7 @@ describe('UserResolver', () => { expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.ACTIVATE_ACCOUNT, - userId: expect.any(Number), // as it is randomly generated + userId: user[0].id, }), ) }) @@ -305,32 +321,92 @@ describe('UserResolver', () => { expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.REDEEM_REGISTER, - userId: expect.any(Number), // as it is randomly generated + userId: result.data.createUser.id, + contributionId: link.id, }), ) }) }) describe('transaction link', () => { + let contribution: any + let bob: any + let peter: any + let transactionLink: TransactionLink + let newUser: any + + const bobData = { + email: 'bob@baumeister.de', + password: 'Aa12345_', + publisherId: 1234, + } + + const peterData = { + email: 'peter@lustig.de', + password: 'Aa12345_', + publisherId: 1234, + } + beforeAll(async () => { - await transactionLinkFactory(testEnv, { - email: 'peter@lustig.de', - amount: 19.99, - memo: `Kein Trick, keine Zauberrei, - bei Gradidio sei dabei!`, + await userFactory(testEnv, bobBaumeister) + await query({ query: login, variables: bobData }) + + // create contribution as user bob + contribution = await mutate({ + mutation: createContribution, + variables: { amount: 1000, memo: 'testing', creationDate: new Date().toISOString() }, }) - const transactionLink = await TransactionLink.findOneOrFail() - resetToken() - await mutate({ - mutation: createUser, - variables: { ...variables, email: 'neuer@user.de', redeemCode: transactionLink.code }, + // login as admin + await query({ query: login, variables: peterData }) + + // confirm the contribution + contribution = await mutate({ + mutation: confirmContribution, + variables: { id: contribution.data.createContribution.id }, }) + + // login as user bob + bob = await query({ query: login, variables: bobData }) + + // create transaction link + await transactionLinkFactory(testEnv, { + email: 'bob@baumeister.de', + amount: 19.99, + memo: `testing transaction link`, + }) + + transactionLink = await TransactionLink.findOneOrFail() + + resetToken() + + // create new user using transaction link of bob + newUser = await mutate({ + mutation: createUser, + variables: { + ...variables, + email: 'which@ever.de', + redeemCode: transactionLink.code, + }, + }) + + console.log(await User.find()) + console.log(await EventProtocol.find()) }) - it('sets the referrer id to Peter Lustigs id', () => { - expect(User.findOne({ email: 'neuer@user.de' })).resolves.toEqual( - expect.objectContaining({ referrerId: user[0].id }), + it('sets the referrer id to bob baumeister id', () => { + expect(User.findOne({ email: 'which@ever.de' })).resolves.toEqual( + expect.objectContaining({ referrerId: bob.data.login.id }), + ) + }) + + // THIS ONE FAILS WITHOUT CONSOLE LOGS + it('stores the redeem register event in the database', () => { + expect(EventProtocol.find()).resolves.toContainEqual( + expect.objectContaining({ + type: EventProtocolType.REDEEM_REGISTER, + userId: newUser.data.createUser.id, + }), ) }) }) From c822580c1a2789cea653503a688e722c412c8028 Mon Sep 17 00:00:00 2001 From: joseji Date: Wed, 21 Sep 2022 19:53:57 +0200 Subject: [PATCH 16/18] removed unused variable --- backend/src/graphql/resolver/UserResolver.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 08256a11a..6f3fd2d1d 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -331,7 +331,6 @@ describe('UserResolver', () => { describe('transaction link', () => { let contribution: any let bob: any - let peter: any let transactionLink: TransactionLink let newUser: any From f710fd9b4560ebff9bedaf38f1641f2b3d9b5fad Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 22 Sep 2022 11:19:32 +0200 Subject: [PATCH 17/18] fixed await for events redeem register --- backend/src/graphql/resolver/UserResolver.test.ts | 12 ++++-------- backend/src/graphql/resolver/UserResolver.ts | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 840e1ea4a..fd4fc6d09 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -389,20 +389,16 @@ describe('UserResolver', () => { redeemCode: transactionLink.code, }, }) - - console.log(await User.find()) - console.log(await EventProtocol.find()) }) - it('sets the referrer id to bob baumeister id', () => { - expect(User.findOne({ email: 'which@ever.de' })).resolves.toEqual( + it('sets the referrer id to bob baumeister id', async () => { + await expect(User.findOne({ email: 'which@ever.de' })).resolves.toEqual( expect.objectContaining({ referrerId: bob.data.login.id }), ) }) - // THIS ONE FAILS WITHOUT CONSOLE LOGS - it('stores the redeem register event in the database', () => { - expect(EventProtocol.find()).resolves.toContainEqual( + it('stores the redeem register event in the database', async () => { + await expect(EventProtocol.find()).resolves.toContainEqual( expect.objectContaining({ type: EventProtocolType.REDEEM_REGISTER, userId: newUser.data.createUser.id, diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index f2fd048fc..18cd8134b 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -494,10 +494,10 @@ export class UserResolver { if (redeemCode) { eventRedeemRegister.userId = dbUser.id - eventProtocol.writeEvent(event.setEventRedeemRegister(eventRedeemRegister)) + await eventProtocol.writeEvent(event.setEventRedeemRegister(eventRedeemRegister)) } else { eventRegister.userId = dbUser.id - eventProtocol.writeEvent(event.setEventRegister(eventRegister)) + await eventProtocol.writeEvent(event.setEventRegister(eventRegister)) } return new User(dbUser) From db21cf2e8d9e524d52a5c42f78b0b0ece09ed605 Mon Sep 17 00:00:00 2001 From: joseji Date: Thu, 22 Sep 2022 11:49:56 +0200 Subject: [PATCH 18/18] removed unused imports --- backend/src/graphql/resolver/UserResolver.test.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index fd4fc6d09..7ba74aff8 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -9,7 +9,6 @@ import { setPassword, forgotPassword, updateUserInfos, - createTransactionLink, createContribution, confirmContribution, } from '@/seeds/graphql/mutations' @@ -32,8 +31,6 @@ import { EventProtocol } from '@entity/EventProtocol' import { logger } from '@test/testSetup' import { validate as validateUUID, version as versionUUID } from 'uuid' import { peterLustig } from '@/seeds/users/peter-lustig' -import { creationFactory } from '@/seeds/factory/creation' -import { creations } from '@/seeds/creation' import { bobBaumeister } from '@/seeds/users/bob-baumeister' // import { klicktippSignIn } from '@/apis/KlicktippController'