mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into refactor-find-contribtiions
This commit is contained in:
commit
4bcc0e19e8
@ -22,10 +22,12 @@ import {
|
|||||||
createContribution,
|
createContribution,
|
||||||
updateContribution,
|
updateContribution,
|
||||||
createTransactionLink,
|
createTransactionLink,
|
||||||
|
confirmContribution,
|
||||||
} from '@/seeds/graphql/mutations'
|
} from '@/seeds/graphql/mutations'
|
||||||
import { listTransactionLinksAdmin } from '@/seeds/graphql/queries'
|
import { listTransactionLinksAdmin } from '@/seeds/graphql/queries'
|
||||||
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
|
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
|
||||||
import { User } from '@entity/User'
|
import { User } from '@entity/User'
|
||||||
|
import { Transaction } from '@entity/Transaction'
|
||||||
import { UnconfirmedContribution } from '@model/UnconfirmedContribution'
|
import { UnconfirmedContribution } from '@model/UnconfirmedContribution'
|
||||||
import Decimal from 'decimal.js-light'
|
import Decimal from 'decimal.js-light'
|
||||||
import { GraphQLError } from 'graphql'
|
import { GraphQLError } from 'graphql'
|
||||||
@ -142,6 +144,8 @@ describe('TransactionLinkResolver', () => {
|
|||||||
resetToken()
|
resetToken()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let contributionId: number
|
||||||
|
|
||||||
describe('unauthenticated', () => {
|
describe('unauthenticated', () => {
|
||||||
it('throws an error', async () => {
|
it('throws an error', async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
@ -311,7 +315,6 @@ describe('TransactionLinkResolver', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: have this test separated into a transactionLink and a contributionLink part
|
|
||||||
describe('redeem daily Contribution Link', () => {
|
describe('redeem daily Contribution Link', () => {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
let contributionLink: DbContributionLink | undefined
|
let contributionLink: DbContributionLink | undefined
|
||||||
@ -337,6 +340,10 @@ describe('TransactionLinkResolver', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await resetEntity(Transaction)
|
||||||
|
})
|
||||||
|
|
||||||
it('has a daily contribution link in the database', async () => {
|
it('has a daily contribution link in the database', async () => {
|
||||||
const cls = await DbContributionLink.find()
|
const cls = await DbContributionLink.find()
|
||||||
expect(cls).toHaveLength(1)
|
expect(cls).toHaveLength(1)
|
||||||
@ -378,6 +385,7 @@ describe('TransactionLinkResolver', () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
contribution = result.data.createContribution
|
contribution = result.data.createContribution
|
||||||
|
contributionId = result.data.createContribution.id
|
||||||
})
|
})
|
||||||
|
|
||||||
it('does not allow the user to redeem the contribution link', async () => {
|
it('does not allow the user to redeem the contribution link', async () => {
|
||||||
@ -513,6 +521,92 @@ describe('TransactionLinkResolver', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('transaction link', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('link does not exits', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
await mutate({
|
||||||
|
mutation: login,
|
||||||
|
variables: { email: 'bibi@bloxberg.de', password: 'Aa12345_' },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws and logs the error', async () => {
|
||||||
|
await expect(
|
||||||
|
mutate({
|
||||||
|
mutation: redeemTransactionLink,
|
||||||
|
variables: {
|
||||||
|
code: 'not-valid',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).resolves.toMatchObject({
|
||||||
|
errors: [new GraphQLError('Transaction link not found')],
|
||||||
|
})
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -285,12 +285,20 @@ export class TransactionLinkResolver {
|
|||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const transactionLink = await DbTransactionLink.findOneOrFail({ code })
|
const transactionLink = await DbTransactionLink.findOne({ code })
|
||||||
const linkedUser = await DbUser.findOneOrFail(
|
if (!transactionLink) {
|
||||||
|
throw new LogError('Transaction link not found', code)
|
||||||
|
}
|
||||||
|
|
||||||
|
const linkedUser = await DbUser.findOne(
|
||||||
{ id: transactionLink.userId },
|
{ id: transactionLink.userId },
|
||||||
{ relations: ['emailContact'] },
|
{ relations: ['emailContact'] },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!linkedUser) {
|
||||||
|
throw new LogError('Linked user not found for given link', transactionLink.userId)
|
||||||
|
}
|
||||||
|
|
||||||
if (user.id === linkedUser.id) {
|
if (user.id === linkedUser.id) {
|
||||||
throw new LogError('Cannot redeem own transaction link', user.id)
|
throw new LogError('Cannot redeem own transaction link', user.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -191,4 +191,50 @@ describe('semaphore', () => {
|
|||||||
await expect(confirmBibisContribution).resolves.toMatchObject({ errors: undefined })
|
await expect(confirmBibisContribution).resolves.toMatchObject({ errors: undefined })
|
||||||
await expect(confirmBobsContribution).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,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -89,6 +89,12 @@ export const createTransactionLink = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
export const deleteTransactionLink = gql`
|
||||||
|
mutation ($id: Int!) {
|
||||||
|
deleteTransactionLink(id: $id)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
// from admin interface
|
// from admin interface
|
||||||
|
|
||||||
export const adminCreateContribution = gql`
|
export const adminCreateContribution = gql`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user