Merge branch 'master' into fix-french-apostroph

This commit is contained in:
Hannes Heine 2023-03-28 00:21:54 +02:00 committed by GitHub
commit b475b17e0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 244 additions and 20 deletions

View File

@ -0,0 +1,23 @@
import { User as DbUser } from '@entity/User'
import { Contribution as DbContribution } from '@entity/Contribution'
import { ContributionMessage as DbContributionMessage } from '@entity/ContributionMessage'
import { Event as DbEvent } from '@entity/Event'
import { Event, EventType } from './Event'
export const EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE = async (
user: DbUser,
moderator: DbUser,
contribution: DbContribution,
contributionMessage: DbContributionMessage,
): Promise<DbEvent> =>
Event(
EventType.ADMIN_CONTRIBUTION_MESSAGE_CREATE,
user,
moderator,
null,
null,
contribution,
contributionMessage,
null,
null,
).save()

View File

@ -0,0 +1,27 @@
import Decimal from 'decimal.js-light'
import { User as DbUser } from '@entity/User'
import { Transaction as DbTransaction } from '@entity/Transaction'
import { Contribution as DbContribution } from '@entity/Contribution'
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
import { Event as DbEvent } from '@entity/Event'
import { Event, EventType } from './Event'
export const EVENT_CONTRIBUTION_LINK_REDEEM = async (
user: DbUser,
transaction: DbTransaction,
contribution: DbContribution,
contributionLink: DbContributionLink,
amount: Decimal,
): Promise<DbEvent> =>
Event(
EventType.CONTRIBUTION_LINK_REDEEM,
user,
user,
null,
transaction,
contribution,
null,
null,
contributionLink,
amount,
).save()

View File

@ -0,0 +1,22 @@
import { User as DbUser } from '@entity/User'
import { Contribution as DbContribution } from '@entity/Contribution'
import { ContributionMessage as DbContributionMessage } from '@entity/ContributionMessage'
import { Event as DbEvent } from '@entity/Event'
import { Event, EventType } from './Event'
export const EVENT_CONTRIBUTION_MESSAGE_CREATE = async (
user: DbUser,
contribution: DbContribution,
contributionMessage: DbContributionMessage,
): Promise<DbEvent> =>
Event(
EventType.CONTRIBUTION_MESSAGE_CREATE,
user,
user,
null,
null,
contribution,
contributionMessage,
null,
null,
).save()

View File

@ -0,0 +1,23 @@
import Decimal from 'decimal.js-light'
import { User as DbUser } from '@entity/User'
import { TransactionLink as DbTransactionLink } from '@entity/TransactionLink'
import { Event as DbEvent } from '@entity/Event'
import { Event, EventType } from './Event'
export const EVENT_TRANSACTION_LINK_CREATE = async (
user: DbUser,
transactionLink: DbTransactionLink,
amount: Decimal,
): Promise<DbEvent> =>
Event(
EventType.TRANSACTION_LINK_CREATE,
user,
user,
null,
null,
null,
null,
transactionLink,
null,
amount,
).save()

View File

@ -0,0 +1,19 @@
import { User as DbUser } from '@entity/User'
import { TransactionLink as DbTransactionLink } from '@entity/TransactionLink'
import { Event as DbEvent } from '@entity/Event'
import { Event, EventType } from './Event'
export const EVENT_TRANSACTION_LINK_DELETE = async (
user: DbUser,
transactionLink: DbTransactionLink,
): Promise<DbEvent> =>
Event(
EventType.TRANSACTION_LINK_DELETE,
user,
user,
null,
null,
null,
null,
transactionLink,
).save()

View File

@ -0,0 +1,24 @@
import Decimal from 'decimal.js-light'
import { User as DbUser } from '@entity/User'
import { TransactionLink as DbTransactionLink } from '@entity/TransactionLink'
import { Event as DbEvent } from '@entity/Event'
import { Event, EventType } from './Event'
export const EVENT_TRANSACTION_LINK_REDEEM = async (
user: DbUser,
senderUser: DbUser,
transactionLink: DbTransactionLink,
amount: Decimal,
): Promise<DbEvent> =>
Event(
EventType.TRANSACTION_LINK_REDEEM,
user,
user,
senderUser,
null,
null,
null,
transactionLink,
null,
amount,
).save()

View File

@ -45,13 +45,19 @@ export { EVENT_ADMIN_CONTRIBUTION_UPDATE } from './EVENT_ADMIN_CONTRIBUTION_UPDA
export { EVENT_ADMIN_CONTRIBUTION_LINK_CREATE } from './EVENT_ADMIN_CONTRIBUTION_LINK_CREATE' export { EVENT_ADMIN_CONTRIBUTION_LINK_CREATE } from './EVENT_ADMIN_CONTRIBUTION_LINK_CREATE'
export { EVENT_ADMIN_CONTRIBUTION_LINK_DELETE } from './EVENT_ADMIN_CONTRIBUTION_LINK_DELETE' export { EVENT_ADMIN_CONTRIBUTION_LINK_DELETE } from './EVENT_ADMIN_CONTRIBUTION_LINK_DELETE'
export { EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE } from './EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE' export { EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE } from './EVENT_ADMIN_CONTRIBUTION_LINK_UPDATE'
export { EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE } from './EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE'
export { EVENT_ADMIN_SEND_CONFIRMATION_EMAIL } from './EVENT_ADMIN_SEND_CONFIRMATION_EMAIL' export { EVENT_ADMIN_SEND_CONFIRMATION_EMAIL } from './EVENT_ADMIN_SEND_CONFIRMATION_EMAIL'
export { EVENT_CONTRIBUTION_CREATE } from './EVENT_CONTRIBUTION_CREATE' export { EVENT_CONTRIBUTION_CREATE } from './EVENT_CONTRIBUTION_CREATE'
export { EVENT_CONTRIBUTION_DELETE } from './EVENT_CONTRIBUTION_DELETE' export { EVENT_CONTRIBUTION_DELETE } from './EVENT_CONTRIBUTION_DELETE'
export { EVENT_CONTRIBUTION_UPDATE } from './EVENT_CONTRIBUTION_UPDATE' export { EVENT_CONTRIBUTION_UPDATE } from './EVENT_CONTRIBUTION_UPDATE'
export { EVENT_CONTRIBUTION_MESSAGE_CREATE } from './EVENT_CONTRIBUTION_MESSAGE_CREATE'
export { EVENT_CONTRIBUTION_LINK_REDEEM } from './EVENT_CONTRIBUTION_LINK_REDEEM'
export { EVENT_LOGIN } from './EVENT_LOGIN' export { EVENT_LOGIN } from './EVENT_LOGIN'
export { EVENT_REGISTER } from './EVENT_REGISTER' export { EVENT_REGISTER } from './EVENT_REGISTER'
export { EVENT_SEND_ACCOUNT_MULTIREGISTRATION_EMAIL } from './EVENT_SEND_ACCOUNT_MULTIREGISTRATION_EMAIL' export { EVENT_SEND_ACCOUNT_MULTIREGISTRATION_EMAIL } from './EVENT_SEND_ACCOUNT_MULTIREGISTRATION_EMAIL'
export { EVENT_SEND_CONFIRMATION_EMAIL } from './EVENT_SEND_CONFIRMATION_EMAIL' export { EVENT_SEND_CONFIRMATION_EMAIL } from './EVENT_SEND_CONFIRMATION_EMAIL'
export { EVENT_TRANSACTION_SEND } from './EVENT_TRANSACTION_SEND' export { EVENT_TRANSACTION_SEND } from './EVENT_TRANSACTION_SEND'
export { EVENT_TRANSACTION_RECEIVE } from './EVENT_TRANSACTION_RECEIVE' export { EVENT_TRANSACTION_RECEIVE } from './EVENT_TRANSACTION_RECEIVE'
export { EVENT_TRANSACTION_LINK_CREATE } from './EVENT_TRANSACTION_LINK_CREATE'
export { EVENT_TRANSACTION_LINK_DELETE } from './EVENT_TRANSACTION_LINK_DELETE'
export { EVENT_TRANSACTION_LINK_REDEEM } from './EVENT_TRANSACTION_LINK_REDEEM'

View File

@ -9,10 +9,13 @@ export enum EventType {
ADMIN_CONTRIBUTION_LINK_CREATE = 'ADMIN_CONTRIBUTION_LINK_CREATE', ADMIN_CONTRIBUTION_LINK_CREATE = 'ADMIN_CONTRIBUTION_LINK_CREATE',
ADMIN_CONTRIBUTION_LINK_DELETE = 'ADMIN_CONTRIBUTION_LINK_DELETE', ADMIN_CONTRIBUTION_LINK_DELETE = 'ADMIN_CONTRIBUTION_LINK_DELETE',
ADMIN_CONTRIBUTION_LINK_UPDATE = 'ADMIN_CONTRIBUTION_LINK_UPDATE', ADMIN_CONTRIBUTION_LINK_UPDATE = 'ADMIN_CONTRIBUTION_LINK_UPDATE',
ADMIN_CONTRIBUTION_MESSAGE_CREATE = 'ADMIN_CONTRIBUTION_MESSAGE_CREATE',
ADMIN_SEND_CONFIRMATION_EMAIL = 'ADMIN_SEND_CONFIRMATION_EMAIL', ADMIN_SEND_CONFIRMATION_EMAIL = 'ADMIN_SEND_CONFIRMATION_EMAIL',
CONTRIBUTION_CREATE = 'CONTRIBUTION_CREATE', CONTRIBUTION_CREATE = 'CONTRIBUTION_CREATE',
CONTRIBUTION_DELETE = 'CONTRIBUTION_DELETE', CONTRIBUTION_DELETE = 'CONTRIBUTION_DELETE',
CONTRIBUTION_UPDATE = 'CONTRIBUTION_UPDATE', CONTRIBUTION_UPDATE = 'CONTRIBUTION_UPDATE',
CONTRIBUTION_MESSAGE_CREATE = 'CONTRIBUTION_MESSAGE_CREATE',
CONTRIBUTION_LINK_REDEEM = 'CONTRIBUTION_LINK_REDEEM',
LOGIN = 'LOGIN', LOGIN = 'LOGIN',
REGISTER = 'REGISTER', REGISTER = 'REGISTER',
REDEEM_REGISTER = 'REDEEM_REGISTER', REDEEM_REGISTER = 'REDEEM_REGISTER',
@ -20,6 +23,9 @@ export enum EventType {
SEND_CONFIRMATION_EMAIL = 'SEND_CONFIRMATION_EMAIL', SEND_CONFIRMATION_EMAIL = 'SEND_CONFIRMATION_EMAIL',
TRANSACTION_SEND = 'TRANSACTION_SEND', TRANSACTION_SEND = 'TRANSACTION_SEND',
TRANSACTION_RECEIVE = 'TRANSACTION_RECEIVE', TRANSACTION_RECEIVE = 'TRANSACTION_RECEIVE',
TRANSACTION_LINK_CREATE = 'TRANSACTION_LINK_CREATE',
TRANSACTION_LINK_DELETE = 'TRANSACTION_LINK_DELETE',
TRANSACTION_LINK_REDEEM = 'TRANSACTION_LINK_REDEEM',
// VISIT_GRADIDO = 'VISIT_GRADIDO', // VISIT_GRADIDO = 'VISIT_GRADIDO',
// VERIFY_REDEEM = 'VERIFY_REDEEM', // VERIFY_REDEEM = 'VERIFY_REDEEM',
// INACTIVE_ACCOUNT = 'INACTIVE_ACCOUNT', // INACTIVE_ACCOUNT = 'INACTIVE_ACCOUNT',

View File

@ -20,6 +20,8 @@ import { userFactory } from '@/seeds/factory/user'
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg' import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
import { peterLustig } from '@/seeds/users/peter-lustig' import { peterLustig } from '@/seeds/users/peter-lustig'
import { sendAddedContributionMessageEmail } from '@/emails/sendEmailVariants' import { sendAddedContributionMessageEmail } from '@/emails/sendEmailVariants'
import { EventType } from '@/event/Event'
import { Event as DbEvent } from '@entity/Event'
jest.mock('@/emails/sendEmailVariants', () => { jest.mock('@/emails/sendEmailVariants', () => {
const originalModule = jest.requireActual('@/emails/sendEmailVariants') const originalModule = jest.requireActual('@/emails/sendEmailVariants')
@ -197,6 +199,18 @@ describe('ContributionMessageResolver', () => {
contributionMemo: 'Test env contribution', contributionMemo: 'Test env contribution',
}) })
}) })
it('stores the ADMIN_CONTRIBUTION_MESSAGE_CREATE event in the database', async () => {
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.ADMIN_CONTRIBUTION_MESSAGE_CREATE,
affectedUserId: expect.any(Number),
actingUserId: expect.any(Number),
involvedContributionId: result.data.createContribution.id,
involvedContributionMessageId: expect.any(Number),
}),
)
})
}) })
}) })
}) })
@ -322,6 +336,18 @@ describe('ContributionMessageResolver', () => {
}), }),
) )
}) })
it('stores the CONTRIBUTION_MESSAGE_CREATE event in the database', async () => {
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.CONTRIBUTION_MESSAGE_CREATE,
affectedUserId: expect.any(Number),
actingUserId: expect.any(Number),
involvedContributionId: result.data.createContribution.id,
involvedContributionMessageId: expect.any(Number),
}),
)
})
}) })
}) })
}) })

View File

@ -4,7 +4,8 @@ import { getConnection } from '@dbTools/typeorm'
import { ContributionMessage as DbContributionMessage } from '@entity/ContributionMessage' import { ContributionMessage as DbContributionMessage } from '@entity/ContributionMessage'
import { Contribution as DbContribution } from '@entity/Contribution' import { Contribution as DbContribution } from '@entity/Contribution'
import { UserContact } from '@entity/UserContact' import { UserContact as DbUserContact } from '@entity/UserContact'
import { User as DbUser } from '@entity/User'
import { ContributionMessage, ContributionMessageListResult } from '@model/ContributionMessage' import { ContributionMessage, ContributionMessageListResult } from '@model/ContributionMessage'
import ContributionMessageArgs from '@arg/ContributionMessageArgs' import ContributionMessageArgs from '@arg/ContributionMessageArgs'
@ -17,6 +18,10 @@ import { RIGHTS } from '@/auth/RIGHTS'
import { Context, getUser } from '@/server/context' import { Context, getUser } from '@/server/context'
import { sendAddedContributionMessageEmail } from '@/emails/sendEmailVariants' import { sendAddedContributionMessageEmail } from '@/emails/sendEmailVariants'
import LogError from '@/server/LogError' import LogError from '@/server/LogError'
import {
EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE,
EVENT_CONTRIBUTION_MESSAGE_CREATE,
} from '@/event/Event'
@Resolver() @Resolver()
export class ContributionMessageResolver { export class ContributionMessageResolver {
@ -57,6 +62,11 @@ export class ContributionMessageResolver {
await queryRunner.manager.update(DbContribution, { id: contributionId }, contribution) await queryRunner.manager.update(DbContribution, { id: contributionId }, contribution)
} }
await queryRunner.commitTransaction() await queryRunner.commitTransaction()
await EVENT_CONTRIBUTION_MESSAGE_CREATE(
user,
{ id: contributionMessage.contributionId } as DbContribution,
contributionMessage,
)
} catch (e) { } catch (e) {
await queryRunner.rollbackTransaction() await queryRunner.rollbackTransaction()
throw new LogError(`ContributionMessage was not sent successfully: ${e}`, e) throw new LogError(`ContributionMessage was not sent successfully: ${e}`, e)
@ -98,7 +108,7 @@ export class ContributionMessageResolver {
@Args() { contributionId, message }: ContributionMessageArgs, @Args() { contributionId, message }: ContributionMessageArgs,
@Ctx() context: Context, @Ctx() context: Context,
): Promise<ContributionMessage> { ): Promise<ContributionMessage> {
const user = getUser(context) const moderator = getUser(context)
const queryRunner = getConnection().createQueryRunner() const queryRunner = getConnection().createQueryRunner()
await queryRunner.connect() await queryRunner.connect()
@ -112,18 +122,18 @@ export class ContributionMessageResolver {
if (!contribution) { if (!contribution) {
throw new LogError('Contribution not found', contributionId) throw new LogError('Contribution not found', contributionId)
} }
if (contribution.userId === user.id) { if (contribution.userId === moderator.id) {
throw new LogError('Admin can not answer on his own contribution', contributionId) throw new LogError('Admin can not answer on his own contribution', contributionId)
} }
if (!contribution.user.emailContact) { if (!contribution.user.emailContact) {
contribution.user.emailContact = await UserContact.findOneOrFail({ contribution.user.emailContact = await DbUserContact.findOneOrFail({
where: { id: contribution.user.emailId }, where: { id: contribution.user.emailId },
}) })
} }
contributionMessage.contributionId = contributionId contributionMessage.contributionId = contributionId
contributionMessage.createdAt = new Date() contributionMessage.createdAt = new Date()
contributionMessage.message = message contributionMessage.message = message
contributionMessage.userId = user.id contributionMessage.userId = moderator.id
contributionMessage.type = ContributionMessageType.DIALOG contributionMessage.type = ContributionMessageType.DIALOG
contributionMessage.isModerator = true contributionMessage.isModerator = true
await queryRunner.manager.insert(DbContributionMessage, contributionMessage) await queryRunner.manager.insert(DbContributionMessage, contributionMessage)
@ -142,17 +152,23 @@ export class ContributionMessageResolver {
lastName: contribution.user.lastName, lastName: contribution.user.lastName,
email: contribution.user.emailContact.email, email: contribution.user.emailContact.email,
language: contribution.user.language, language: contribution.user.language,
senderFirstName: user.firstName, senderFirstName: moderator.firstName,
senderLastName: user.lastName, senderLastName: moderator.lastName,
contributionMemo: contribution.memo, contributionMemo: contribution.memo,
}) })
await queryRunner.commitTransaction() await queryRunner.commitTransaction()
await EVENT_ADMIN_CONTRIBUTION_MESSAGE_CREATE(
{ id: contribution.userId } as DbUser,
moderator,
contribution,
contributionMessage,
)
} catch (e) { } catch (e) {
await queryRunner.rollbackTransaction() await queryRunner.rollbackTransaction()
throw new LogError(`ContributionMessage was not sent successfully: ${e}`, e) throw new LogError(`ContributionMessage was not sent successfully: ${e}`, e)
} finally { } finally {
await queryRunner.release() await queryRunner.release()
} }
return new ContributionMessage(contributionMessage, user) return new ContributionMessage(contributionMessage, moderator)
} }
} }

View File

@ -2545,7 +2545,7 @@ describe('ContributionResolver', () => {
) )
}) })
it('stores the CONTRIBUTION_CONFIRM event in the database', async () => { it('stores the ADMIN_CONTRIBUTION_CONFIRM event in the database', async () => {
await expect(DbEvent.find()).resolves.toContainEqual( await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({ expect.objectContaining({
type: EventType.ADMIN_CONTRIBUTION_CONFIRM, type: EventType.ADMIN_CONTRIBUTION_CONFIRM,

View File

@ -90,7 +90,6 @@ export class ContributionResolver {
logger.trace('contribution to save', contribution) logger.trace('contribution to save', contribution)
await DbContribution.save(contribution) await DbContribution.save(contribution)
await EVENT_CONTRIBUTION_CREATE(user, contribution, amount) await EVENT_CONTRIBUTION_CREATE(user, contribution, amount)
return new UnconfirmedContribution(contribution, user, creations) return new UnconfirmedContribution(contribution, user, creations)
@ -118,7 +117,6 @@ export class ContributionResolver {
contribution.deletedBy = user.id contribution.deletedBy = user.id
contribution.deletedAt = new Date() contribution.deletedAt = new Date()
await contribution.save() await contribution.save()
await EVENT_CONTRIBUTION_DELETE(user, contribution, contribution.amount) await EVENT_CONTRIBUTION_DELETE(user, contribution, contribution.amount)
const res = await contribution.softRemove() const res = await contribution.softRemove()
@ -299,11 +297,8 @@ export class ContributionResolver {
contribution.moderatorId = moderator.id contribution.moderatorId = moderator.id
contribution.contributionType = ContributionType.ADMIN contribution.contributionType = ContributionType.ADMIN
contribution.contributionStatus = ContributionStatus.PENDING contribution.contributionStatus = ContributionStatus.PENDING
logger.trace('contribution to save', contribution) logger.trace('contribution to save', contribution)
await DbContribution.save(contribution) await DbContribution.save(contribution)
await EVENT_ADMIN_CONTRIBUTION_CREATE(emailContact.user, moderator, contribution, amount) await EVENT_ADMIN_CONTRIBUTION_CREATE(emailContact.user, moderator, contribution, amount)
return getUserCreation(emailContact.userId, clientTimezoneOffset) return getUserCreation(emailContact.userId, clientTimezoneOffset)
@ -369,9 +364,7 @@ export class ContributionResolver {
result.amount = amount result.amount = amount
result.memo = contributionToUpdate.memo result.memo = contributionToUpdate.memo
result.date = contributionToUpdate.contributionDate result.date = contributionToUpdate.contributionDate
result.creation = await getUserCreation(emailContact.user.id, clientTimezoneOffset) result.creation = await getUserCreation(emailContact.user.id, clientTimezoneOffset)
await EVENT_ADMIN_CONTRIBUTION_UPDATE( await EVENT_ADMIN_CONTRIBUTION_UPDATE(
emailContact.user, emailContact.user,
moderator, moderator,
@ -436,7 +429,6 @@ export class ContributionResolver {
contribution.deletedBy = moderator.id contribution.deletedBy = moderator.id
await contribution.save() await contribution.save()
const res = await contribution.softRemove() const res = await contribution.softRemove()
await EVENT_ADMIN_CONTRIBUTION_DELETE( await EVENT_ADMIN_CONTRIBUTION_DELETE(
{ id: contribution.userId } as DbUser, { id: contribution.userId } as DbUser,
moderator, moderator,
@ -554,7 +546,6 @@ export class ContributionResolver {
} finally { } finally {
await queryRunner.release() await queryRunner.release()
} }
await EVENT_ADMIN_CONTRIBUTION_CONFIRM(user, moderatorUser, contribution, contribution.amount) await EVENT_ADMIN_CONTRIBUTION_CONFIRM(user, moderatorUser, contribution, contribution.amount)
} finally { } finally {
releaseLock() releaseLock()
@ -613,7 +604,6 @@ export class ContributionResolver {
contributionToUpdate.deniedBy = moderator.id contributionToUpdate.deniedBy = moderator.id
contributionToUpdate.deniedAt = new Date() contributionToUpdate.deniedAt = new Date()
const res = await contributionToUpdate.save() const res = await contributionToUpdate.save()
await EVENT_ADMIN_CONTRIBUTION_DENY( await EVENT_ADMIN_CONTRIBUTION_DENY(
user, user,
moderator, moderator,

View File

@ -33,6 +33,9 @@ import Decimal from 'decimal.js-light'
import { GraphQLError } from 'graphql' import { GraphQLError } from 'graphql'
import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK' import { TRANSACTIONS_LOCK } from '@/util/TRANSACTIONS_LOCK'
import { logger } from '@test/testSetup' import { logger } from '@test/testSetup'
import { EventType } from '@/event/Event'
import { Event as DbEvent } from '@entity/Event'
import { UserContact } from '@entity/UserContact'
// mock semaphore to allow use fake timers // mock semaphore to allow use fake timers
jest.mock('@/util/TRANSACTIONS_LOCK') jest.mock('@/util/TRANSACTIONS_LOCK')
@ -445,6 +448,24 @@ describe('TransactionLinkResolver', () => {
}) })
}) })
it('stores the CONTRIBUTION_LINK_REDEEM event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.CONTRIBUTION_LINK_REDEEM,
affectedUserId: userConatct.user.id,
actingUserId: userConatct.user.id,
involvedTransactionId: expect.any(Number),
involvedContributionId: expect.any(Number),
involvedContributionLinkId: contributionLink?.id,
amount: contributionLink?.amount,
}),
)
})
it('does not allow the user to redeem the contribution link a second time on the same day', async () => { it('does not allow the user to redeem the contribution link a second time on the same day', async () => {
jest.clearAllMocks() jest.clearAllMocks()
await expect( await expect(

View File

@ -35,6 +35,12 @@ import LogError from '@/server/LogError'
import { getLastTransaction } from './util/getLastTransaction' import { getLastTransaction } from './util/getLastTransaction'
import transactionLinkList from './util/transactionLinkList' import transactionLinkList from './util/transactionLinkList'
import {
EVENT_CONTRIBUTION_LINK_REDEEM,
EVENT_TRANSACTION_LINK_CREATE,
EVENT_TRANSACTION_LINK_DELETE,
EVENT_TRANSACTION_LINK_REDEEM,
} from '@/event/Event'
// TODO: do not export, test it inside the resolver // TODO: do not export, test it inside the resolver
export const transactionLinkCode = (date: Date): string => { export const transactionLinkCode = (date: Date): string => {
@ -89,6 +95,7 @@ export class TransactionLinkResolver {
await DbTransactionLink.save(transactionLink).catch((e) => { await DbTransactionLink.save(transactionLink).catch((e) => {
throw new LogError('Unable to save transaction link', e) throw new LogError('Unable to save transaction link', e)
}) })
await EVENT_TRANSACTION_LINK_CREATE(user, transactionLink, amount)
return new TransactionLink(transactionLink, new User(user)) return new TransactionLink(transactionLink, new User(user))
} }
@ -122,6 +129,8 @@ export class TransactionLinkResolver {
throw new LogError('Transaction link could not be deleted', e) throw new LogError('Transaction link could not be deleted', e)
}) })
await EVENT_TRANSACTION_LINK_DELETE(user, transactionLink)
return true return true
} }
@ -272,7 +281,13 @@ export class TransactionLinkResolver {
await queryRunner.manager.update(DbContribution, { id: contribution.id }, contribution) await queryRunner.manager.update(DbContribution, { id: contribution.id }, contribution)
await queryRunner.commitTransaction() await queryRunner.commitTransaction()
logger.info('creation from contribution link commited successfuly.') await EVENT_CONTRIBUTION_LINK_REDEEM(
user,
transaction,
contribution,
contributionLink,
contributionLink.amount,
)
} catch (e) { } catch (e) {
await queryRunner.rollbackTransaction() await queryRunner.rollbackTransaction()
throw new LogError('Creation from contribution link was not successful', e) throw new LogError('Creation from contribution link was not successful', e)
@ -321,6 +336,12 @@ export class TransactionLinkResolver {
user, user,
transactionLink, transactionLink,
) )
await EVENT_TRANSACTION_LINK_REDEEM(
user,
{ id: transactionLink.userId } as DbUser,
transactionLink,
transactionLink.amount,
)
return true return true
} }