Skip to content

Commit

Permalink
feat(report-comment): auto collapse comment conditionally when submit…
Browse files Browse the repository at this point in the history
  • Loading branch information
gary02 committed May 15, 2024
1 parent 4558bc3 commit b8ddcbb
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 12 deletions.
117 changes: 105 additions & 12 deletions src/connectors/__test__/systemService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import type { Connections, Asset } from 'definitions'

import { v4 } from 'uuid'

import { NODE_TYPES } from 'common/enums'
import { SystemService } from 'connectors'
import { NODE_TYPES, COMMENT_TYPE, COMMENT_STATE } from 'common/enums'
import { SystemService, AtomService } from 'connectors'

import { genConnections, closeConnections } from './utils'

Expand All @@ -19,11 +19,13 @@ const assetValidation = {

let connections: Connections
let systemService: SystemService
let atomService: AtomService

beforeAll(async () => {
connections = await genConnections()
systemService = new SystemService(connections)
}, 50000)
atomService = new AtomService(connections)
}, 30000)

afterAll(async () => {
await closeConnections(connections)
Expand Down Expand Up @@ -77,14 +79,105 @@ test('copy asset map', async () => {
await systemService.copyAssetMapEntities({ source, target })
})

test('submit report', async () => {
const report = await systemService.submitReport({
targetType: NODE_TYPES.Article,
targetId: '1',
reporterId: '1',
reason: 'other',
describe('report', () => {
test('submit report', async () => {
const report = await systemService.submitReport({
targetType: NODE_TYPES.Article,
targetId: '1',
reporterId: '1',
reason: 'other',
})
expect(report.id).toBeDefined()
expect(report.articleId).not.toBeNull()
expect(report.commentId).toBeNull()
})
test('collapse comment if more than 3 different users report it', async () => {
const commentId = '1'
const comment = await atomService.findUnique({
table: 'comment',
where: { id: commentId },
})
expect(comment.type).toBe(COMMENT_TYPE.article)
expect(comment.state).toBe(COMMENT_STATE.active)

// only 2 reports, comment should not be collapsed

await systemService.submitReport({
targetType: NODE_TYPES.Comment,
targetId: commentId,
reporterId: '2',
reason: 'other',
})
await systemService.submitReport({
targetType: NODE_TYPES.Comment,
targetId: commentId,
reporterId: '3',
reason: 'other',
})

const commentAfter2Reports = await atomService.findUnique({
table: 'comment',
where: { id: commentId },
})
expect(commentAfter2Reports.state).toBe(COMMENT_STATE.active)

// only 3 reports from 2 different users, comment should not be collapsed

await systemService.submitReport({
targetType: NODE_TYPES.Comment,
targetId: commentId,
reporterId: '3',
reason: 'other',
})

const commentAfter3Reports = await atomService.findUnique({
table: 'comment',
where: { id: commentId },
})
expect(commentAfter3Reports.state).toBe(COMMENT_STATE.active)

// 4 reports from 3 different users, comment should be collapsed

await systemService.submitReport({
targetType: NODE_TYPES.Comment,
targetId: commentId,
reporterId: '4',
reason: 'other',
})

const commentAfter4Reports = await atomService.findUnique({
table: 'comment',
where: { id: commentId },
})
expect(commentAfter4Reports.state).toBe(COMMENT_STATE.collapsed)
})

test('collapse comment if article author report it', async () => {
const commentId = '2'
const comment = await atomService.findUnique({
table: 'comment',
where: { id: commentId },
})
expect(comment.type).toBe(COMMENT_TYPE.article)
expect(comment.state).toBe(COMMENT_STATE.active)

const { authorId } = await atomService.findUnique({
table: 'article',
where: { id: comment.targetId },
})

await systemService.submitReport({
targetType: NODE_TYPES.Comment,
targetId: commentId,
reporterId: authorId,
reason: 'other',
})

const commentAfterReport = await atomService.findUnique({
table: 'comment',
where: { id: commentId },
})

expect(commentAfterReport.state).toBe(COMMENT_STATE.collapsed)
})
expect(report.id).toBeDefined()
expect(report.articleId).not.toBeNull()
expect(report.commentId).toBeNull()
})
72 changes: 72 additions & 0 deletions src/connectors/systemService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
} from 'definitions'
import type { Knex } from 'knex'

import { invalidateFQC } from '@matters/apollo-response-cache'
import { v4 } from 'uuid'

import {
Expand All @@ -23,6 +24,8 @@ import {
USER_ROLE,
FEATURE_NAME,
FEATURE_FLAG,
COMMENT_STATE,
COMMENT_TYPE,
NODE_TYPES,
} from 'common/enums'
import { getLogger } from 'common/logger'
Expand Down Expand Up @@ -475,6 +478,13 @@ export class SystemService extends BaseService<BaseDBSchema> {
return updateItem
}

/**
* Create a report of target.
*
* @remarks
* The target could be an article or a comment.
* When the target is a comment, collapse the comment base on reports amount and reporters.
*/
public submitReport = async ({
targetType,
targetId,
Expand Down Expand Up @@ -503,7 +513,69 @@ export class SystemService extends BaseService<BaseDBSchema> {
reason,
})
.returning('*')

await this.tryCollapseComment(targetId)

Check warning on line 517 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L517

Added line #L517 was not covered by tests

return ret[0]
}
}

/**
* Collapse the article comment if its reports are created by more than 3 different users or 1 article author
*
* @returns true if the comment is collapsed, otherwise false
*
*/
private tryCollapseComment = async (commentId: string): Promise<boolean> => {
const comment = await this.models.findUnique({

Check warning on line 530 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L530

Added line #L530 was not covered by tests
table: 'comment',
where: { id: commentId },
})

if (
!comment ||
comment.state === COMMENT_STATE.collapsed ||
comment.type !== COMMENT_TYPE.article

Check warning on line 538 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L537-L538

Added lines #L537 - L538 were not covered by tests
) {
return false

Check warning on line 540 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L540

Added line #L540 was not covered by tests
}

const reports = await this.knex<Report>('report')

Check warning on line 543 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L543

Added line #L543 was not covered by tests
.select(['id', 'reporterId'])
.distinctOn('reporterId')
.where({ commentId })

if (reports.length >= 3) {
await this.models.update({

Check warning on line 549 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L549

Added line #L549 was not covered by tests
table: 'comment',
where: { id: commentId },
data: { state: COMMENT_STATE.collapsed },
})
await invalidateFQC({

Check warning on line 554 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L554

Added line #L554 was not covered by tests
node: { id: commentId, type: NODE_TYPES.Comment },
redis: this.redis,
})
return true

Check warning on line 558 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L558

Added line #L558 was not covered by tests
}

const { authorId } = await this.models.findUnique({

Check warning on line 561 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L561

Added line #L561 was not covered by tests
table: 'article',
where: { id: comment.targetId },
})

if (authorId && reports.find((r) => r.reporterId === authorId)) {
await this.models.update({

Check warning on line 567 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L567

Added line #L567 was not covered by tests
table: 'comment',
where: { id: commentId },
data: { state: COMMENT_STATE.collapsed },
})
await invalidateFQC({

Check warning on line 572 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L572

Added line #L572 was not covered by tests
node: { id: commentId, type: NODE_TYPES.Comment },
redis: this.redis,
})
return true

Check warning on line 576 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L576

Added line #L576 was not covered by tests
}

return false

Check warning on line 579 in src/connectors/systemService.ts

View check run for this annotation

Codecov / codecov/patch

src/connectors/systemService.ts#L579

Added line #L579 was not covered by tests
}
}

0 comments on commit b8ddcbb

Please sign in to comment.