From a49251205f479edc46d621599c9811d7f6b3063a Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 7 Mar 2023 16:24:17 +0100 Subject: [PATCH] test double redeem of transaction link --- .../resolver/TransactionLinkResolver.test.ts | 66 +++++++++++++++++++ .../src/graphql/resolver/semaphore.test.ts | 46 +++++++++++++ backend/src/seeds/graphql/mutations.ts | 6 ++ 3 files changed, 118 insertions(+) diff --git a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts index b4e49cfe0..5c03c722b 100644 --- a/backend/src/graphql/resolver/TransactionLinkResolver.test.ts +++ b/backend/src/graphql/resolver/TransactionLinkResolver.test.ts @@ -17,10 +17,12 @@ import { createContribution, updateContribution, createTransactionLink, + confirmContribution, } from '@/seeds/graphql/mutations' import { listTransactionLinksAdmin } from '@/seeds/graphql/queries' import { ContributionLink as DbContributionLink } from '@entity/ContributionLink' import { User } from '@entity/User' +import { Transaction } from '@entity/Transaction' import { UnconfirmedContribution } from '@model/UnconfirmedContribution' import Decimal from 'decimal.js-light' import { GraphQLError } from 'graphql' @@ -137,6 +139,8 @@ describe('TransactionLinkResolver', () => { resetToken() }) + let contributionId: number + describe('unauthenticated', () => { it('throws an error', async () => { jest.clearAllMocks() @@ -331,6 +335,10 @@ describe('TransactionLinkResolver', () => { }) }) + afterAll(async () => { + await resetEntity(Transaction) + }) + it('has a daily contribution link in the database', async () => { const cls = await DbContributionLink.find() expect(cls).toHaveLength(1) @@ -372,6 +380,7 @@ describe('TransactionLinkResolver', () => { }, }) contribution = result.data.createContribution + contributionId = result.data.createContribution.id }) it('does not allow the user to redeem the contribution link', async () => { @@ -535,6 +544,63 @@ describe('TransactionLinkResolver', () => { expect(logger.error).toBeCalledWith('Transaction link not found', 'not-valid') }) }) + + describe('link exists', () => { + let myCode: string + + beforeAll(async () => { + await mutate({ + mutation: login, + variables: { email: 'peter@lustig.de', password: 'Aa12345_' }, + }) + await mutate({ + mutation: confirmContribution, + variables: { id: contributionId }, + }) + await mutate({ + mutation: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + const { + data: { + createTransactionLink: { code }, + }, + } = await mutate({ + mutation: createTransactionLink, + variables: { + amount: 200, + memo: 'This is a transaction link from bibi', + }, + }) + myCode = code + }) + + describe('own link', () => { + beforeAll(async () => { + await mutate({ + mutation: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + }) + + it('throws and logs an error', async () => { + await expect( + mutate({ + mutation: redeemTransactionLink, + variables: { + code: myCode, + }, + }), + ).resolves.toMatchObject({ + errors: [new GraphQLError('Cannot redeem own transaction link')], + }) + expect(logger.error).toBeCalledWith( + 'Cannot redeem own transaction link', + expect.any(Number), + ) + }) + }) + }) }) }) }) diff --git a/backend/src/graphql/resolver/semaphore.test.ts b/backend/src/graphql/resolver/semaphore.test.ts index e334910f1..740a899f3 100644 --- a/backend/src/graphql/resolver/semaphore.test.ts +++ b/backend/src/graphql/resolver/semaphore.test.ts @@ -187,4 +187,50 @@ describe('semaphore', () => { await expect(confirmBibisContribution).resolves.toMatchObject({ errors: undefined }) await expect(confirmBobsContribution).resolves.toMatchObject({ errors: undefined }) }) + + describe('redeem transaction link twice', () => { + let myCode: string + + beforeAll(async () => { + await mutate({ + mutation: login, + variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' }, + }) + const { + data: { createTransactionLink: bibisLink }, + } = await mutate({ + mutation: createTransactionLink, + variables: { + amount: 20, + memo: 'Bibis Link', + }, + }) + myCode = bibisLink.code + await mutate({ + mutation: login, + variables: { email: 'bob@baumeister.de', password: 'Aa12345_' }, + }) + }) + + it('does not throw, but should', async () => { + const redeem1 = mutate({ + mutation: redeemTransactionLink, + variables: { + code: myCode, + }, + }) + const redeem2 = mutate({ + mutation: redeemTransactionLink, + variables: { + code: myCode, + }, + }) + await expect(redeem1).resolves.toMatchObject({ + errors: undefined, + }) + await expect(redeem2).resolves.toMatchObject({ + errors: undefined, + }) + }) + }) }) diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 79684d378..d9c293a0f 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -89,6 +89,12 @@ export const createTransactionLink = gql` } ` +export const deleteTransactionLink = gql` + mutation ($id: Int!) { + deleteTransactionLink(id: $id) + } +` + // from admin interface export const adminCreateContribution = gql`