From dc46f4e78c5d26af13871d4773e4c102c30238fe Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 14 Jun 2022 15:29:34 +0200 Subject: [PATCH] add update contribution link mutation --- backend/src/auth/RIGHTS.ts | 1 + .../graphql/resolver/AdminResolver.test.ts | 118 ++++++++++++++++++ backend/src/graphql/resolver/AdminResolver.ts | 33 +++++ backend/src/seeds/graphql/mutations.ts | 39 ++++++ 4 files changed, 191 insertions(+) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index f8fa38616..8ac2c78cc 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -40,4 +40,5 @@ export enum RIGHTS { CREATE_CONTRIBUTION_LINK = 'CREATE_CONTRIBUTION_LINK', LIST_CONTRIBUTION_LINKS = 'LIST_CONTRIBUTION_LINKS', DELETE_CONTRIBUTION_LINK = 'DELETE_CONTRIBUTION_LINK', + UPDATE_CONTRIBUTION_LINK = 'UPDATE_CONTRIBUTION_LINK', } diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index 32227f257..d08c52320 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -22,6 +22,7 @@ import { confirmPendingCreation, createContributionLink, deleteContributionLink, + updateContributionLink, } from '@/seeds/graphql/mutations' import { getPendingCreations, @@ -1631,6 +1632,27 @@ describe('AdminResolver', () => { }) }) + describe('updateContributionLink', () => { + it('returns an error', async () => { + await expect( + mutate({ + mutation: updateContributionLink, + variables: { + ...variables, + id: -1, + amount: new Decimal(400), + name: 'Dokumenta 2023', + memo: 'Danke für deine Teilnahme an der Dokumenta 2023', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + }) + describe('deleteContributionLink', () => { it('returns an error', async () => { await expect( @@ -1679,6 +1701,27 @@ describe('AdminResolver', () => { }) }) + describe('updateContributionLink', () => { + it('returns an error', async () => { + await expect( + mutate({ + mutation: updateContributionLink, + variables: { + ...variables, + id: -1, + amount: new Decimal(400), + name: 'Dokumenta 2023', + memo: 'Danke für deine Teilnahme an der Dokumenta 2023', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('401 Unauthorized')], + }), + ) + }) + }) + describe('deleteContributionLink', () => { it('returns an error', async () => { await expect( @@ -1786,6 +1829,81 @@ describe('AdminResolver', () => { }) }) + describe('updateContributionLink', () => { + describe('no valid id', () => { + it('returns an error', async () => { + await expect( + mutate({ + mutation: updateContributionLink, + variables: { + ...variables, + id: -1, + amount: new Decimal(400), + name: 'Dokumenta 2023', + memo: 'Danke für deine Teilnahme an der Dokumenta 2023', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + errors: [new GraphQLError('Contribution Link not found to given id.')], + }), + ) + }) + }) + + describe('valid id', () => { + let linkId: number + beforeAll(async () => { + const links = await query({ query: listContributionLinks }) + linkId = links.data.listContributionLinks.links[0].id + }) + + it('returns updated contribution link object', async () => { + await expect( + mutate({ + mutation: updateContributionLink, + variables: { + ...variables, + id: linkId, + amount: new Decimal(400), + name: 'Dokumenta 2023', + memo: 'Danke für deine Teilnahme an der Dokumenta 2023', + }, + }), + ).resolves.toEqual( + expect.objectContaining({ + data: { + updateContributionLink: { + id: linkId, + amount: '400', + code: expect.stringMatching(/^CL-[0-9a-f]{24,24}$/), + link: expect.any(String), + createdAt: expect.any(String), + name: 'Dokumenta 2023', + memo: 'Danke für deine Teilnahme an der Dokumenta 2023', + validFrom: expect.any(String), + validTo: expect.any(String), + maxAmountPerMonth: '200', + cycle: 'once', + maxPerCycle: 1, + }, + }, + }), + ) + }) + + it('updated the DB record', async () => { + await expect(DbContributionLink.findOne(linkId)).resolves.toEqual( + expect.objectContaining({ + id: linkId, + name: 'Dokumenta 2023', + memo: 'Danke für deine Teilnahme an der Dokumenta 2023', + }), + ) + }) + }) + }) + describe('deleteContributionLink', () => { describe('no valid id', () => { it('returns an error', async () => { diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 715d09d35..785a7de02 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -526,6 +526,39 @@ export class AdminResolver { const newContributionLink = await DbContributionLink.findOne({ id }, { withDeleted: true }) return newContributionLink ? newContributionLink.deletedAt : null } + + @Authorized([RIGHTS.UPDATE_CONTRIBUTION_LINK]) + @Mutation(() => ContributionLink) + async updateContributionLink( + @Args() + { + amount, + name, + memo, + cycle, + validFrom, + validTo, + maxAmountPerMonth, + maxPerCycle, + }: ContributionLinkArgs, + @Arg('id', () => Int) id: number, + ): Promise { + const dbContributionLink = await DbContributionLink.findOne(id) + if (!dbContributionLink) { + logger.error(`Contribution Link not found to given id: ${id}`) + throw new Error('Contribution Link not found to given id.') + } + dbContributionLink.amount = amount + dbContributionLink.name = name + dbContributionLink.memo = memo + dbContributionLink.cycle = cycle + if (validFrom) dbContributionLink.validFrom = new Date(validFrom) + if (validTo) dbContributionLink.validTo = new Date(validTo) + dbContributionLink.maxAmountPerMonth = maxAmountPerMonth + dbContributionLink.maxPerCycle = maxPerCycle + await dbContributionLink.save() + return new ContributionLink(dbContributionLink) + } } interface CreationMap { diff --git a/backend/src/seeds/graphql/mutations.ts b/backend/src/seeds/graphql/mutations.ts index 7c334796e..c0f0fa6e4 100644 --- a/backend/src/seeds/graphql/mutations.ts +++ b/backend/src/seeds/graphql/mutations.ts @@ -174,6 +174,45 @@ export const createContributionLink = gql` } ` +export const updateContributionLink = gql` + mutation ( + $amount: Decimal! + $name: String! + $memo: String! + $cycle: String! + $validFrom: String + $validTo: String + $maxAmountPerMonth: Decimal + $maxPerCycle: Int! = 1 + $id: Int! + ) { + updateContributionLink( + amount: $amount + name: $name + memo: $memo + cycle: $cycle + validFrom: $validFrom + validTo: $validTo + maxAmountPerMonth: $maxAmountPerMonth + maxPerCycle: $maxPerCycle + id: $id + ) { + id + amount + name + memo + code + link + createdAt + validFrom + validTo + maxAmountPerMonth + cycle + maxPerCycle + } + } +` + export const deleteContributionLink = gql` mutation ($id: Int!) { deleteContributionLink(id: $id)