store contribution link id on user when regsitered with contribution link code

This commit is contained in:
Moriz Wahl 2022-06-16 10:44:17 +02:00
parent b493fd4231
commit 409e44f679
3 changed files with 91 additions and 7 deletions

View File

@ -13,6 +13,10 @@ import CONFIG from '@/config'
import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail' import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail'
import { printTimeDuration, activationLink } from './UserResolver' 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' import { logger } from '@test/testSetup'
@ -69,6 +73,7 @@ describe('UserResolver', () => {
let result: any let result: any
let emailOptIn: string let emailOptIn: string
let user: User[]
beforeAll(async () => { beforeAll(async () => {
jest.clearAllMocks() jest.clearAllMocks()
@ -86,7 +91,6 @@ describe('UserResolver', () => {
}) })
describe('valid input data', () => { describe('valid input data', () => {
let user: User[]
let loginEmailOptIn: LoginEmailOptIn[] let loginEmailOptIn: LoginEmailOptIn[]
beforeAll(async () => { beforeAll(async () => {
user = await User.find() user = await User.find()
@ -114,6 +118,7 @@ describe('UserResolver', () => {
deletedAt: null, deletedAt: null,
publisherId: 1234, publisherId: 1234,
referrerId: null, 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', () => { describe('setPassword', () => {

View File

@ -8,6 +8,7 @@ import CONFIG from '@/config'
import { User } from '@model/User' import { User } from '@model/User'
import { User as DbUser } from '@entity/User' import { User as DbUser } from '@entity/User'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { ContributionLink as dbContributionLink } from '@entity/ContributionLink'
import { encode } from '@/auth/JWT' import { encode } from '@/auth/JWT'
import CreateUserArgs from '@arg/CreateUserArgs' import CreateUserArgs from '@arg/CreateUserArgs'
import UnsecureLoginArgs from '@arg/UnsecureLoginArgs' import UnsecureLoginArgs from '@arg/UnsecureLoginArgs'
@ -349,10 +350,20 @@ export class UserResolver {
dbUser.passphrase = passphrase.join(' ') dbUser.passphrase = passphrase.join(' ')
logger.debug('new dbUser=' + dbUser) logger.debug('new dbUser=' + dbUser)
if (redeemCode) { if (redeemCode) {
const transactionLink = await dbTransactionLink.findOne({ code: redeemCode }) if (redeemCode.match(/^CL-/)) {
logger.info('redeemCode found transactionLink=' + transactionLink) const contributionLink = await dbContributionLink.findOne({
if (transactionLink) { code: redeemCode.replace('CL-', ''),
dbUser.referrerId = transactionLink.userId })
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 // TODO this field has no null allowed unlike the loginServer table

View File

@ -1,12 +1,13 @@
import { ApolloServerTestClient } from 'apollo-server-testing' import { ApolloServerTestClient } from 'apollo-server-testing'
import { createContributionLink } from '@/seeds/graphql/mutations' import { createContributionLink } from '@/seeds/graphql/mutations'
import { login } from '@/seeds/graphql/queries' import { login } from '@/seeds/graphql/queries'
import { ContributionLink } from '@model/ContributionLink'
import { ContributionLinkInterface } from '@/seeds/contributionLink/ContributionLinkInterface' import { ContributionLinkInterface } from '@/seeds/contributionLink/ContributionLinkInterface'
export const contributionLinkFactory = async ( export const contributionLinkFactory = async (
client: ApolloServerTestClient, client: ApolloServerTestClient,
contributionLink: ContributionLinkInterface, contributionLink: ContributionLinkInterface,
): Promise<void> => { ): Promise<ContributionLink> => {
const { mutate, query } = client const { mutate, query } = client
// login as admin // login as admin
@ -23,5 +24,6 @@ export const contributionLinkFactory = async (
validTo: contributionLink.validTo ? contributionLink.validTo.toISOString() : undefined, validTo: contributionLink.validTo ? contributionLink.validTo.toISOString() : undefined,
} }
await mutate({ mutation: createContributionLink, variables }) const result = await mutate({ mutation: createContributionLink, variables })
return result.data.createContributionLink
} }