From 409e44f6790063abb8c8a4217eb7df89c64ada1e Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Thu, 16 Jun 2022 10:44:17 +0200 Subject: [PATCH] store contribution link id on user when regsitered with contribution link code --- .../src/graphql/resolver/UserResolver.test.ts | 73 ++++++++++++++++++- backend/src/graphql/resolver/UserResolver.ts | 19 ++++- backend/src/seeds/factory/contributionLink.ts | 6 +- 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 78b630834..48fe667a9 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -13,6 +13,10 @@ import CONFIG from '@/config' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail' import { printTimeDuration, activationLink } from './UserResolver' +import { contributionLinkFactory } from '@/seeds/factory/contributionLink' +// import { transactionLinkFactory } from '@/seeds/factory/transactionLink' +import { ContributionLink } from '@model/ContributionLink' +// import { TransactionLink } from '@entity/TransactionLink' import { logger } from '@test/testSetup' @@ -69,6 +73,7 @@ describe('UserResolver', () => { let result: any let emailOptIn: string + let user: User[] beforeAll(async () => { jest.clearAllMocks() @@ -86,7 +91,6 @@ describe('UserResolver', () => { }) describe('valid input data', () => { - let user: User[] let loginEmailOptIn: LoginEmailOptIn[] beforeAll(async () => { user = await User.find() @@ -114,6 +118,7 @@ describe('UserResolver', () => { deletedAt: null, publisherId: 1234, referrerId: null, + contributionLinkId: null, }, ]) }) @@ -195,6 +200,72 @@ 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() + // 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), + }) + resetToken() + await mutate({ + mutation: createUser, + variables: { ...variables, email: 'ein@besucher.de', redeemCode: 'CL-' + link.code }, + }) + }) + + it('sets the contribution link id', async () => { + await expect(User.findOne({ email: 'ein@besucher.de' })).resolves.toEqual( + expect.objectContaining({ + contributionLinkId: link.id, + }), + ) + }) + }) + + /* A transaction link requires GDD on account + describe('transaction link', () => { + let code: string + beforeAll(async () => { + // factory logs in as Peter Lustig + 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', async () => { + await expect(User.findOne({ email: 'neuer@user.de' })).resolves.toEqual(expect.objectContaining({ + referrerId: user[0].id, + })) + }) + }) + + */ + }) }) describe('setPassword', () => { diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 9b42d76b5..224834f17 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -8,6 +8,7 @@ import CONFIG from '@/config' import { User } from '@model/User' import { User as DbUser } from '@entity/User' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' +import { ContributionLink as dbContributionLink } from '@entity/ContributionLink' import { encode } from '@/auth/JWT' import CreateUserArgs from '@arg/CreateUserArgs' import UnsecureLoginArgs from '@arg/UnsecureLoginArgs' @@ -349,10 +350,20 @@ export class UserResolver { dbUser.passphrase = passphrase.join(' ') logger.debug('new dbUser=' + dbUser) if (redeemCode) { - const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) - logger.info('redeemCode found transactionLink=' + transactionLink) - if (transactionLink) { - dbUser.referrerId = transactionLink.userId + if (redeemCode.match(/^CL-/)) { + const contributionLink = await dbContributionLink.findOne({ + code: redeemCode.replace('CL-', ''), + }) + logger.info('redeemCode found contributionLink=' + contributionLink) + if (contributionLink) { + dbUser.contributionLinkId = contributionLink.id + } + } else { + const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) + logger.info('redeemCode found transactionLink=' + transactionLink) + if (transactionLink) { + dbUser.referrerId = transactionLink.userId + } } } // TODO this field has no null allowed unlike the loginServer table diff --git a/backend/src/seeds/factory/contributionLink.ts b/backend/src/seeds/factory/contributionLink.ts index 7e34b9d20..5c83b6ad3 100644 --- a/backend/src/seeds/factory/contributionLink.ts +++ b/backend/src/seeds/factory/contributionLink.ts @@ -1,12 +1,13 @@ import { ApolloServerTestClient } from 'apollo-server-testing' import { createContributionLink } from '@/seeds/graphql/mutations' import { login } from '@/seeds/graphql/queries' +import { ContributionLink } from '@model/ContributionLink' import { ContributionLinkInterface } from '@/seeds/contributionLink/ContributionLinkInterface' export const contributionLinkFactory = async ( client: ApolloServerTestClient, contributionLink: ContributionLinkInterface, -): Promise => { +): Promise => { const { mutate, query } = client // login as admin @@ -23,5 +24,6 @@ export const contributionLinkFactory = async ( validTo: contributionLink.validTo ? contributionLink.validTo.toISOString() : undefined, } - await mutate({ mutation: createContributionLink, variables }) + const result = await mutate({ mutation: createContributionLink, variables }) + return result.data.createContributionLink }