test createContributionLink

This commit is contained in:
Moriz Wahl 2022-06-14 10:43:03 +02:00
parent 9a88db2b8f
commit f258f63ee7
5 changed files with 168 additions and 6 deletions

View File

@ -15,11 +15,11 @@ export default class ContributionLinkArgs {
@Field(() => String) @Field(() => String)
cycle: string cycle: string
@Field(() => Date, { nullable: true }) @Field(() => String, { nullable: true })
validFrom?: Date | null validFrom?: string | null
@Field(() => Date, { nullable: true }) @Field(() => String, { nullable: true })
validTo?: Date | null validTo?: string | null
@Field(() => Decimal, { nullable: true }) @Field(() => Decimal, { nullable: true })
maxAmountPerMonth: Decimal | null maxAmountPerMonth: Decimal | null

View File

@ -1,6 +1,7 @@
import { ObjectType, Field, Int } from 'type-graphql' import { ObjectType, Field, Int } from 'type-graphql'
import Decimal from 'decimal.js-light' import Decimal from 'decimal.js-light'
import { ContributionLink as dbContributionLink } from '@entity/ContributionLink' import { ContributionLink as dbContributionLink } from '@entity/ContributionLink'
import CONFIG from '@/config'
@ObjectType() @ObjectType()
export class ContributionLink { export class ContributionLink {
@ -16,6 +17,8 @@ export class ContributionLink {
this.maxAmountPerMonth = contributionLink.maxAmountPerMonth this.maxAmountPerMonth = contributionLink.maxAmountPerMonth
this.cycle = contributionLink.cycle this.cycle = contributionLink.cycle
this.maxPerCycle = contributionLink.maxPerCycle this.maxPerCycle = contributionLink.maxPerCycle
this.code = 'CL-' + contributionLink.code
this.link = CONFIG.COMMUNITY_REDEEM_URL.replace(/{code}/g, this.code)
} }
@Field(() => Number) @Field(() => Number)
@ -33,6 +36,9 @@ export class ContributionLink {
@Field(() => String) @Field(() => String)
code: string code: string
@Field(() => String)
link: string
@Field(() => Date) @Field(() => Date)
createdAt: Date createdAt: Date

View File

@ -20,6 +20,7 @@ import {
updatePendingCreation, updatePendingCreation,
deletePendingCreation, deletePendingCreation,
confirmPendingCreation, confirmPendingCreation,
createContributionLink,
} from '@/seeds/graphql/mutations' } from '@/seeds/graphql/mutations'
import { import {
getPendingCreations, getPendingCreations,
@ -34,6 +35,7 @@ import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
import Decimal from 'decimal.js-light' import Decimal from 'decimal.js-light'
import { AdminPendingCreation } from '@entity/AdminPendingCreation' import { AdminPendingCreation } from '@entity/AdminPendingCreation'
import { Transaction as DbTransaction } from '@entity/Transaction' import { Transaction as DbTransaction } from '@entity/Transaction'
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
// mock account activation email to avoid console spam // mock account activation email to avoid console spam
jest.mock('@/mailer/sendAccountActivationEmail', () => { jest.mock('@/mailer/sendAccountActivationEmail', () => {
@ -1593,4 +1595,120 @@ describe('AdminResolver', () => {
}) })
}) })
}) })
describe('Contribution Links', () => {
const variables = {
amount: new Decimal(200),
name: 'Dokumenta 2022',
memo: 'Danke für deine Teilnahme an der Dokumenta 2022',
cycle: 'once',
validFrom: new Date(2022, 5, 18).toISOString(),
validTo: new Date(2022, 7, 14).toISOString(),
maxAmountPerMonth: new Decimal(200),
maxPerCycle: 1,
}
describe('unauthenticated', () => {
describe('createContributionLink', () => {
it.only('returns an error', async () => {
await expect(mutate({ mutation: createContributionLink, variables })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
})
describe('authenticated', () => {
describe('without admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, bibiBloxberg)
await query({
query: login,
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('createContributionLink', () => {
it.only('returns an error', async () => {
await expect(mutate({ mutation: createContributionLink, variables })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
)
})
})
})
describe('with admin rights', () => {
beforeAll(async () => {
user = await userFactory(testEnv, peterLustig)
await query({
query: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
})
afterAll(async () => {
await cleanDB()
resetToken()
})
describe('createContributionLink', () => {
it.only('returns a contribution link object', async () => {
await expect(mutate({ mutation: createContributionLink, variables })).resolves.toEqual(
expect.objectContaining({
data: {
createContributionLink: expect.objectContaining({
amount: '200',
code: expect.stringMatching(/^CL-[0-9a-f]{24,24}$/),
link: expect.any(String),
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,
}),
},
}),
)
})
it.only('has a contribution link stored in db', async () => {
const cls = await DbContributionLink.find()
expect(cls).toHaveLength(1)
expect(cls[0]).toEqual(
expect.objectContaining({
id: expect.any(Number),
name: 'Dokumenta 2022',
memo: 'Danke für deine Teilnahme an der Dokumenta 2022',
validFrom: new Date('2022-06-18T00:00:00.000Z'),
validTo: new Date('2022-08-14T00:00:00.000Z'),
cycle: 'once',
maxPerCycle: 1,
totalMaxCountOfContribution: null,
maxAccountBalance: null,
minGapHours: null,
createdAt: expect.any(Date),
deletedAt: null,
code: expect.stringMatching(/^[0-9a-f]{24,24}$/),
linkEnabled: true,
// amount: '200',
// maxAmountPerMonth: '200',
}),
)
})
})
})
})
})
}) })

View File

@ -42,6 +42,7 @@ import { Order } from '@enum/Order'
import { communityUser } from '@/util/communityUser' import { communityUser } from '@/util/communityUser'
import { checkOptInCode, activationLink, printTimeDuration } from './UserResolver' import { checkOptInCode, activationLink, printTimeDuration } from './UserResolver'
import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
import { transactionLinkCode as contributionLinkCode } from './TransactionLinkResolver'
import CONFIG from '@/config' import CONFIG from '@/config'
// const EMAIL_OPT_IN_REGISTER = 1 // const EMAIL_OPT_IN_REGISTER = 1
@ -484,9 +485,10 @@ export class AdminResolver {
dbContributionLink.name = name dbContributionLink.name = name
dbContributionLink.memo = memo dbContributionLink.memo = memo
dbContributionLink.createdAt = new Date() dbContributionLink.createdAt = new Date()
dbContributionLink.code = contributionLinkCode(dbContributionLink.createdAt)
dbContributionLink.cycle = cycle dbContributionLink.cycle = cycle
if (validFrom) dbContributionLink.validFrom = validFrom if (validFrom) dbContributionLink.validFrom = new Date(validFrom)
if (validTo) dbContributionLink.validTo = validTo if (validTo) dbContributionLink.validTo = new Date(validTo)
dbContributionLink.maxAmountPerMonth = maxAmountPerMonth dbContributionLink.maxAmountPerMonth = maxAmountPerMonth
dbContributionLink.maxPerCycle = maxPerCycle dbContributionLink.maxPerCycle = maxPerCycle
dbContributionLink.save() dbContributionLink.save()

View File

@ -137,3 +137,39 @@ export const deletePendingCreation = gql`
deletePendingCreation(id: $id) deletePendingCreation(id: $id)
} }
` `
export const createContributionLink = gql`
mutation (
$amount: Decimal!
$name: String!
$memo: String!
$cycle: String!
$validFrom: String
$validTo: String
$maxAmountPerMonth: Decimal
$maxPerCycle: Int! = 1
) {
createContributionLink(
amount: $amount
name: $name
memo: $memo
cycle: $cycle
validFrom: $validFrom
validTo: $validTo
maxAmountPerMonth: $maxAmountPerMonth
maxPerCycle: $maxPerCycle
) {
amount
name
memo
code
link
createdAt
validFrom
validTo
maxAmountPerMonth
cycle
maxPerCycle
}
}
`