diff --git a/packages/api/src/entity/reports/abuse_report.ts b/packages/api/src/entity/reports/abuse_report.ts index 6f68b1982..a38b0b939 100644 --- a/packages/api/src/entity/reports/abuse_report.ts +++ b/packages/api/src/entity/reports/abuse_report.ts @@ -1,9 +1,9 @@ import { - Entity, BaseEntity, Column, - PrimaryGeneratedColumn, CreateDateColumn, + Entity, + PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm' import { ReportType } from '../../generated/graphql' @@ -14,7 +14,7 @@ export class AbuseReport extends BaseEntity { id?: string @Column('text') - pageId!: string + pageId?: string @Column('text') sharedBy!: string @@ -36,4 +36,7 @@ export class AbuseReport extends BaseEntity { @UpdateDateColumn() updatedAt?: Date + + @Column('text') + elasticPageId?: string } diff --git a/packages/api/src/entity/reports/content_display_report.ts b/packages/api/src/entity/reports/content_display_report.ts index fe59e535d..d5396d010 100644 --- a/packages/api/src/entity/reports/content_display_report.ts +++ b/packages/api/src/entity/reports/content_display_report.ts @@ -1,9 +1,9 @@ import { - Entity, BaseEntity, Column, - PrimaryGeneratedColumn, CreateDateColumn, + Entity, + PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm' @@ -16,7 +16,7 @@ export class ContentDisplayReport extends BaseEntity { userId!: string @Column('text') - pageId!: string + pageId?: string @Column('text') content!: string @@ -35,4 +35,7 @@ export class ContentDisplayReport extends BaseEntity { @UpdateDateColumn() updatedAt?: Date + + @Column('text') + elasticPageId?: string } diff --git a/packages/api/src/resolvers/report/index.ts b/packages/api/src/resolvers/report/index.ts index 264fd59d9..f38b7b5c2 100644 --- a/packages/api/src/resolvers/report/index.ts +++ b/packages/api/src/resolvers/report/index.ts @@ -45,7 +45,7 @@ export const reportItemResolver: ResolverFn< const uid = ctx.claims?.uid || '' const value = { sharedBy: uid, reportedBy: uid, ...args.input } - const report = await saveAbuseReport(ctx.kx, uid, value) + const report = await saveAbuseReport(uid, value) const message = report ? SUCCESS_MESSAGE : FAILURE_MESSAGE return { message: message, @@ -58,7 +58,7 @@ export const reportItemResolver: ResolverFn< message: FAILURE_MESSAGE, } } - const report = await saveContentDisplayReport(ctx.kx, uid, args.input) + const report = await saveContentDisplayReport(uid, args.input) const message = report ? SUCCESS_MESSAGE : FAILURE_MESSAGE return { message: message, diff --git a/packages/api/src/services/reports.ts b/packages/api/src/services/reports.ts index 7cad6226e..f58e7e74b 100644 --- a/packages/api/src/services/reports.ts +++ b/packages/api/src/services/reports.ts @@ -1,22 +1,19 @@ import { getRepository } from 'typeorm' import { ReportItemInput, ReportType } from '../generated/graphql' import { ContentDisplayReport } from '../entity/reports/content_display_report' -import ArticleModel from '../datalayer/article' -import Knex from 'knex' import { AbuseReport } from '../entity/reports/abuse_report' +import { getPageById } from '../elastic' export const saveContentDisplayReport = async ( - kx: Knex, uid: string, input: ReportItemInput ): Promise => { const repo = getRepository(ContentDisplayReport) - const am = new ArticleModel(kx) - const article = await am.get(input.pageId) + const page = await getPageById(input.pageId) - if (!article) { - console.log('unable to submit report, article not found', input) + if (!page) { + console.log('unable to submit report, page not found', input) return false } @@ -26,10 +23,10 @@ export const saveContentDisplayReport = async ( const result = await repo .create({ userId: uid, - pageId: input.pageId, - content: article.content, - originalHtml: article.originalHtml || undefined, - originalUrl: article.url, + elasticPageId: input.pageId, + content: page.content, + originalHtml: page.originalHtml || undefined, + originalUrl: page.url, reportComment: input.reportComment, }) .save() @@ -38,17 +35,15 @@ export const saveContentDisplayReport = async ( } export const saveAbuseReport = async ( - kx: Knex, uid: string, input: ReportItemInput ): Promise => { const repo = getRepository(AbuseReport) - const am = new ArticleModel(kx) - const article = await am.get(input.pageId) + const page = await getPageById(input.pageId) - if (!article) { - console.log('unable to submit report, article not found', input) + if (!page) { + console.log('unable to submit report, page not found', input) return false } @@ -64,7 +59,7 @@ export const saveAbuseReport = async ( .create({ reportedBy: uid, sharedBy: input.sharedBy, - pageId: input.pageId, + elasticPageId: input.pageId, itemUrl: input.itemUrl, reportTypes: [ReportType.Abusive], reportComment: input.reportComment, diff --git a/packages/api/test/resolvers/report.test.ts b/packages/api/test/resolvers/report.test.ts new file mode 100644 index 000000000..148eb3566 --- /dev/null +++ b/packages/api/test/resolvers/report.test.ts @@ -0,0 +1,80 @@ +import { User } from '../../src/entity/user' +import { Page } from '../../src/elastic/types' +import { createTestUser, deleteTestUser } from '../db' +import { createTestElasticPage, graphqlRequest, request } from '../util' +import { ReportType } from '../../src/generated/graphql' +import { getRepository } from 'typeorm' +import { ContentDisplayReport } from '../../src/entity/reports/content_display_report' +import { expect } from 'chai' + +describe('Report API', () => { + const username = 'fakeUser' + + let user: User + let authToken: string + let page: Page + + before(async () => { + // create test user and login + user = await createTestUser(username) + const res = await request + .post('/local/debug/fake-user-login') + .send({ fakeEmail: user.email }) + + authToken = res.body.authToken + + // create a page + page = await createTestElasticPage(user) + }) + + after(async () => { + // clean up + await deleteTestUser(username) + }) + + describe('reportItem', () => { + let pageId: string + let reportTypes: ReportType[] + let query: string + + beforeEach(() => { + query = ` + mutation { + reportItem( + input: { + pageId: "${pageId}", + itemUrl: "test url" + reportTypes: [${reportTypes}], + reportComment: "test comment" + } + ) { + message + } + } + ` + }) + + context('when page exists and report is content display', () => { + before(() => { + pageId = page.id + reportTypes = [ReportType.ContentDisplay] + }) + + after(async () => { + await getRepository(ContentDisplayReport).delete({ + elasticPageId: pageId, + }) + }) + + it('should report an item', async () => { + await graphqlRequest(query, authToken).expect(200) + + expect( + await getRepository(ContentDisplayReport).find({ + elasticPageId: pageId, + }) + ).to.exist + }) + }) + }) +}) diff --git a/packages/db/migrations/0076.do.drop_not_null_on_page_id.sql b/packages/db/migrations/0076.do.drop_not_null_on_page_id.sql new file mode 100755 index 000000000..662df1f9f --- /dev/null +++ b/packages/db/migrations/0076.do.drop_not_null_on_page_id.sql @@ -0,0 +1,10 @@ +-- Type: DO +-- Name: drop_not_null_on_page_id +-- Description: Drop not null constraint on page_id in content_display_report table + +BEGIN; + +ALTER TABLE omnivore.content_display_report ALTER COLUMN page_id DROP NOT NULL; +ALTER TABLE omnivore.abuse_report ALTER COLUMN page_id DROP NOT NULL; + +COMMIT; diff --git a/packages/db/migrations/0076.undo.drop_not_null_on_page_id.sql b/packages/db/migrations/0076.undo.drop_not_null_on_page_id.sql new file mode 100755 index 000000000..136006069 --- /dev/null +++ b/packages/db/migrations/0076.undo.drop_not_null_on_page_id.sql @@ -0,0 +1,10 @@ +-- Type: UNDO +-- Name: drop_not_null_on_page_id +-- Description: Drop not null constraint on page_id in content_display_report table + +BEGIN; + +ALTER TABLE omnivore.content_display_report ALTER COLUMN page_id SET NOT NULL; +ALTER TABLE omnivore.abuse_report ALTER COLUMN page_id SET NOT NULL; + +COMMIT;