Merge pull request #3123 from gradido/fix-moderation-message-answer-question

fix(backend): moderation message are completely hidden from the user
This commit is contained in:
Hannes Heine 2023-07-06 08:55:04 +02:00 committed by GitHub
commit da94074457
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 46 deletions

View File

@ -4,10 +4,12 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Connection } from '@dbTools/typeorm'
import { Contribution as DbContribution } from '@entity/Contribution'
import { Event as DbEvent } from '@entity/Event'
import { ApolloServerTestClient } from 'apollo-server-testing'
import { GraphQLError } from 'graphql'
import { ContributionStatus } from '@enum/ContributionStatus'
import { cleanDB, resetToken, testEnvironment } from '@test/helpers'
import { logger, i18n as localization } from '@test/testSetup'
@ -168,6 +170,50 @@ describe('ContributionMessageResolver', () => {
})
})
describe('contribution message type MODERATOR', () => {
beforeAll(() => {
jest.clearAllMocks()
})
it('creates ContributionMessage', async () => {
await expect(
mutate({
mutation: adminCreateContributionMessage,
variables: {
contributionId: result.data.createContribution.id,
message: 'Internal moderator communication',
messageType: 'MODERATOR',
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
adminCreateContributionMessage: expect.objectContaining({
id: expect.any(Number),
message: 'Internal moderator communication',
type: 'MODERATOR',
userFirstName: 'Peter',
userLastName: 'Lustig',
}),
},
}),
)
})
it('does not call sendAddedContributionMessageEmail', () => {
expect(sendAddedContributionMessageEmail).not.toBeCalled()
})
it('does not change contribution status', async () => {
await expect(DbContribution.find()).resolves.toContainEqual(
expect.objectContaining({
id: result.data.createContribution.id,
contributionStatus: ContributionStatus.PENDING,
}),
)
})
})
describe('valid input', () => {
it('creates ContributionMessage', async () => {
await expect(
@ -205,6 +251,15 @@ describe('ContributionMessageResolver', () => {
})
})
it('changes contribution status', async () => {
await expect(DbContribution.find()).resolves.toContainEqual(
expect.objectContaining({
id: result.data.createContribution.id,
contributionStatus: ContributionStatus.IN_PROGRESS,
}),
)
})
it('stores the ADMIN_CONTRIBUTION_MESSAGE_CREATE event in the database', async () => {
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
@ -217,41 +272,6 @@ describe('ContributionMessageResolver', () => {
)
})
})
describe('contribution message type MODERATOR', () => {
beforeAll(() => {
jest.clearAllMocks()
})
it('creates ContributionMessage', async () => {
await expect(
mutate({
mutation: adminCreateContributionMessage,
variables: {
contributionId: result.data.createContribution.id,
message: 'Internal moderator communication',
messageType: 'MODERATOR',
},
}),
).resolves.toEqual(
expect.objectContaining({
data: {
adminCreateContributionMessage: expect.objectContaining({
id: expect.any(Number),
message: 'Internal moderator communication',
type: 'MODERATOR',
userFirstName: 'Peter',
userLastName: 'Lustig',
}),
},
}),
)
})
it("don't call sendAddedContributionMessageEmail", () => {
expect(sendAddedContributionMessageEmail).not.toBeCalled()
})
})
})
})

View File

@ -158,16 +158,18 @@ export class ContributionMessageResolver {
contributionMessage.isModerator = true
await queryRunner.manager.insert(DbContributionMessage, contributionMessage)
if (
contribution.contributionStatus === ContributionStatus.DELETED ||
contribution.contributionStatus === ContributionStatus.DENIED ||
contribution.contributionStatus === ContributionStatus.PENDING
) {
contribution.contributionStatus = ContributionStatus.IN_PROGRESS
await queryRunner.manager.update(DbContribution, { id: contributionId }, contribution)
}
if (messageType !== ContributionMessageType.MODERATOR) {
// change status (does not apply to moderator messages)
if (
contribution.contributionStatus === ContributionStatus.DELETED ||
contribution.contributionStatus === ContributionStatus.DENIED ||
contribution.contributionStatus === ContributionStatus.PENDING
) {
contribution.contributionStatus = ContributionStatus.IN_PROGRESS
await queryRunner.manager.update(DbContribution, { id: contributionId }, contribution)
}
// send email (never for moderator messages)
void sendAddedContributionMessageEmail({
firstName: contribution.user.firstName,
lastName: contribution.user.lastName,

View File

@ -11,6 +11,7 @@ import { ApolloServerTestClient } from 'apollo-server-testing'
import { Decimal } from 'decimal.js-light'
import { GraphQLError } from 'graphql'
import { ContributionMessageType } from '@enum/ContributionMessageType'
import { ContributionStatus } from '@enum/ContributionStatus'
import { Order } from '@enum/Order'
import {
@ -153,6 +154,14 @@ describe('ContributionResolver', () => {
message: 'Test message to IN_PROGRESS contribution',
},
})
await mutate({
mutation: adminCreateContributionMessage,
variables: {
contributionId: pendingContribution.data.createContribution.id,
message: 'Test moderator message',
messageType: ContributionMessageType.MODERATOR,
},
})
await mutate({
mutation: logout,
})
@ -1043,31 +1052,37 @@ describe('ContributionResolver', () => {
amount: '100',
id: contributionToConfirm.data.createContribution.id,
memo: 'Test contribution to confirm',
messagesCount: 0,
}),
expect.objectContaining({
id: pendingContribution.data.createContribution.id,
memo: 'Test PENDING contribution update',
amount: '10',
messagesCount: 1,
}),
expect.objectContaining({
id: contributionToDeny.data.createContribution.id,
memo: 'Test contribution to deny',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: contributionToDelete.data.createContribution.id,
memo: 'Test contribution to delete',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: inProgressContribution.data.createContribution.id,
memo: 'Test IN_PROGRESS contribution',
amount: '100',
messagesCount: 1,
}),
expect.objectContaining({
id: bibiCreatedContribution.id,
memo: 'Herzlich Willkommen bei Gradido!',
amount: '1000',
messagesCount: 0,
}),
]),
})
@ -1099,24 +1114,28 @@ describe('ContributionResolver', () => {
status: 'PENDING',
memo: 'Test PENDING contribution update',
amount: '10',
messagesCount: 1,
}),
expect.objectContaining({
id: contributionToDeny.data.createContribution.id,
status: 'DENIED',
memo: 'Test contribution to deny',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: contributionToDelete.data.createContribution.id,
status: 'DELETED',
memo: 'Test contribution to delete',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: inProgressContribution.data.createContribution.id,
status: 'IN_PROGRESS',
memo: 'Test IN_PROGRESS contribution',
amount: '100',
messagesCount: 1,
}),
]),
})
@ -1230,42 +1249,49 @@ describe('ContributionResolver', () => {
status: 'CONFIRMED',
id: contributionToConfirm.data.createContribution.id,
memo: 'Test contribution to confirm',
messagesCount: 0,
}),
expect.objectContaining({
id: pendingContribution.data.createContribution.id,
status: 'PENDING',
memo: 'Test PENDING contribution update',
amount: '10',
messagesCount: 0,
}),
expect.objectContaining({
id: contributionToDeny.data.createContribution.id,
status: 'DENIED',
memo: 'Test contribution to deny',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: inProgressContribution.data.createContribution.id,
status: 'IN_PROGRESS',
memo: 'Test IN_PROGRESS contribution',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: bibiCreatedContribution.id,
status: 'CONFIRMED',
memo: 'Herzlich Willkommen bei Gradido!',
amount: '1000',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'CONFIRMED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'DENIED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
]),
})
@ -1295,42 +1321,49 @@ describe('ContributionResolver', () => {
status: 'CONFIRMED',
id: contributionToConfirm.data.createContribution.id,
memo: 'Test contribution to confirm',
messagesCount: 0,
}),
expect.objectContaining({
id: pendingContribution.data.createContribution.id,
status: 'PENDING',
memo: 'Test PENDING contribution update',
amount: '10',
messagesCount: 0,
}),
expect.objectContaining({
id: contributionToDeny.data.createContribution.id,
status: 'DENIED',
memo: 'Test contribution to deny',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: inProgressContribution.data.createContribution.id,
status: 'IN_PROGRESS',
memo: 'Test IN_PROGRESS contribution',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: bibiCreatedContribution.id,
status: 'CONFIRMED',
memo: 'Herzlich Willkommen bei Gradido!',
amount: '1000',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'CONFIRMED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'DENIED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
]),
})
@ -1360,42 +1393,49 @@ describe('ContributionResolver', () => {
status: 'CONFIRMED',
id: contributionToConfirm.data.createContribution.id,
memo: 'Test contribution to confirm',
messagesCount: 0,
}),
expect.objectContaining({
id: pendingContribution.data.createContribution.id,
status: 'PENDING',
memo: 'Test PENDING contribution update',
amount: '10',
messagesCount: 0,
}),
expect.objectContaining({
id: contributionToDeny.data.createContribution.id,
status: 'DENIED',
memo: 'Test contribution to deny',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: inProgressContribution.data.createContribution.id,
status: 'IN_PROGRESS',
memo: 'Test IN_PROGRESS contribution',
amount: '100',
messagesCount: 0,
}),
expect.objectContaining({
id: bibiCreatedContribution.id,
status: 'CONFIRMED',
memo: 'Herzlich Willkommen bei Gradido!',
amount: '1000',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'CONFIRMED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'DENIED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
]),
})
@ -1422,18 +1462,21 @@ describe('ContributionResolver', () => {
status: 'CONFIRMED',
id: contributionToConfirm.data.createContribution.id,
memo: 'Test contribution to confirm',
messagesCount: 0,
}),
expect.objectContaining({
id: bibiCreatedContribution.id,
status: 'CONFIRMED',
memo: 'Herzlich Willkommen bei Gradido!',
amount: '1000',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'CONFIRMED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
expect.not.objectContaining({
status: 'PENDING',
@ -1484,6 +1527,7 @@ describe('ContributionResolver', () => {
status: 'PENDING',
memo: 'Test PENDING contribution update',
amount: '10',
messagesCount: 0,
}),
]),
})
@ -1522,6 +1566,7 @@ describe('ContributionResolver', () => {
status: 'IN_PROGRESS',
memo: 'Test IN_PROGRESS contribution',
amount: '100',
messagesCount: 0,
}),
]),
})
@ -1554,6 +1599,7 @@ describe('ContributionResolver', () => {
status: 'DENIED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
expect.not.objectContaining({
status: 'CONFIRMED',
@ -1611,24 +1657,28 @@ describe('ContributionResolver', () => {
status: 'CONFIRMED',
id: contributionToConfirm.data.createContribution.id,
memo: 'Test contribution to confirm',
messagesCount: 0,
}),
expect.objectContaining({
id: pendingContribution.data.createContribution.id,
status: 'PENDING',
memo: 'Test PENDING contribution update',
amount: '10',
messagesCount: 0,
}),
expect.objectContaining({
id: bibiCreatedContribution.id,
status: 'CONFIRMED',
memo: 'Herzlich Willkommen bei Gradido!',
amount: '1000',
messagesCount: 0,
}),
expect.objectContaining({
id: expect.any(Number),
status: 'CONFIRMED',
memo: 'Whatever contribution',
amount: '166',
messagesCount: 0,
}),
expect.not.objectContaining({
status: 'DENIED',
@ -2825,7 +2875,7 @@ describe('ContributionResolver', () => {
id: expect.any(Number),
lastName: 'Bloxberg',
memo: 'Test PENDING contribution update',
messagesCount: 1,
messagesCount: 2,
status: 'PENDING',
}),
expect.objectContaining({

View File

@ -142,9 +142,16 @@ export class ContributionResolver {
userId: user.id,
statusFilter,
})
return new ContributionListResult(
count,
dbContributions.map((contribution) => new Contribution(contribution, user)),
dbContributions.map((contribution) => {
// filter out moderator messages for this call
contribution.messages = contribution.messages?.filter(
(m) => m.type !== ContributionMessageType.MODERATOR,
)
return new Contribution(contribution, user)
}),
)
}