diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 755ddabf8..10dc98845 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -152,6 +152,7 @@ export default shield( User: { email: or(isMyOwn, isAdmin), }, + Report: isModerator, }, { debug, diff --git a/backend/src/middleware/permissionsMiddleware.spec.js b/backend/src/middleware/permissionsMiddleware.spec.js index 3c307348d..775533867 100644 --- a/backend/src/middleware/permissionsMiddleware.spec.js +++ b/backend/src/middleware/permissionsMiddleware.spec.js @@ -9,14 +9,6 @@ const driver = getDriver() let query, authenticatedUser, owner, anotherRegularUser, administrator, variables, moderator -const userQuery = gql` - query($name: String) { - User(name: $name) { - email - } - } -` - describe('authorization', () => { beforeAll(async () => { await cleanDatabase() @@ -30,7 +22,11 @@ describe('authorization', () => { query = createTestClient(server).query }) - describe('given two existing users', () => { + afterEach(async () => { + await cleanDatabase() + }) + + describe('given an owner, an other user, an admin, a moderator', () => { beforeEach(async () => { ;[owner, anotherRegularUser, administrator, moderator] = await Promise.all([ Factory.build( @@ -79,15 +75,20 @@ describe('authorization', () => { variables = {} }) - afterEach(async () => { - await cleanDatabase() - }) - describe('access email address', () => { + const userQuery = gql` + query($name: String) { + User(name: $name) { + email + } + } + ` + describe('unauthenticated', () => { beforeEach(() => { authenticatedUser = null }) + it("throws an error and does not expose the owner's email address", async () => { await expect( query({ query: userQuery, variables: { name: 'Owner' } }), @@ -143,7 +144,7 @@ describe('authorization', () => { }) }) - describe('administrator', () => { + describe('as an administrator', () => { beforeEach(async () => { authenticatedUser = await administrator.toJson() }) diff --git a/backend/src/middleware/validation/validationMiddleware.spec.js b/backend/src/middleware/validation/validationMiddleware.spec.js index b2c669369..74a343eeb 100644 --- a/backend/src/middleware/validation/validationMiddleware.spec.js +++ b/backend/src/middleware/validation/validationMiddleware.spec.js @@ -58,7 +58,7 @@ const reportMutation = gql` reasonCategory: $reasonCategory reasonDescription: $reasonDescription ) { - id + reportId } } ` diff --git a/backend/src/schema/resolvers/moderation.js b/backend/src/schema/resolvers/moderation.js index 4bdf82d50..07054d3a3 100644 --- a/backend/src/schema/resolvers/moderation.js +++ b/backend/src/schema/resolvers/moderation.js @@ -1,20 +1,10 @@ -const transformReturnType = record => { - return { - ...record.get('review').properties, - report: record.get('report').properties, - resource: { - __typename: record.get('type'), - ...record.get('resource').properties, - }, - } -} +import log from './helpers/databaseLogger' export default { Mutation: { review: async (_object, params, context, _resolveInfo) => { const { user: moderator, driver } = context - let createdRelationshipWithNestedAttributes = null // return value const session = driver.session() try { const cypher = ` @@ -25,10 +15,11 @@ export default { ON CREATE SET review.createdAt = $dateTime, review.updatedAt = review.createdAt ON MATCH SET review.updatedAt = $dateTime SET review.disable = $params.disable - SET report.updatedAt = $dateTime, report.closed = $params.closed - SET resource.disabled = review.disable + SET report.updatedAt = $dateTime, report.disable = review.disable, report.closed = $params.closed + SET resource.disabled = report.disable - RETURN review, report, resource, labels(resource)[0] AS type + WITH review, report, resource {.*, __typename: labels(resource)[0]} AS finalResource + RETURN review {.*, report: properties(report), resource: properties(finalResource)} ` const reviewWriteTxResultPromise = session.writeTransaction(async txc => { const reviewTransactionResponse = await txc.run(cypher, { @@ -36,16 +27,14 @@ export default { moderatorId: moderator.id, dateTime: new Date().toISOString(), }) - return reviewTransactionResponse.records.map(transformReturnType) + log(reviewTransactionResponse) + return reviewTransactionResponse.records.map(record => record.get('review')) }) - const txResult = await reviewWriteTxResultPromise - if (!txResult[0]) return null - createdRelationshipWithNestedAttributes = txResult[0] + const [reviewed] = await reviewWriteTxResultPromise + return reviewed || null } finally { session.close() } - - return createdRelationshipWithNestedAttributes }, }, } diff --git a/backend/src/schema/resolvers/reports.js b/backend/src/schema/resolvers/reports.js index 0565c4d8a..f7a2addc4 100644 --- a/backend/src/schema/resolvers/reports.js +++ b/backend/src/schema/resolvers/reports.js @@ -1,23 +1,13 @@ import log from './helpers/databaseLogger' -const transformReturnType = record => { - return { - ...record.get('report').properties, - resource: { - __typename: record.get('type'), - ...record.get('resource').properties, - }, - } -} - export default { Mutation: { fileReport: async (_parent, params, context, _resolveInfo) => { const { resourceId, reasonCategory, reasonDescription } = params const { driver, user } = context const session = driver.session() - const reportWriteTxResultPromise = session.writeTransaction(async transaction => { - const reportTransactionResponse = await transaction.run( + const fileReportWriteTxResultPromise = session.writeTransaction(async transaction => { + const fileReportTransactionResponse = await transaction.run( ` MATCH (submitter:User {id: $submitterId}) MATCH (resource {id: $resourceId}) @@ -27,7 +17,8 @@ export default { WITH submitter, resource, report CREATE (report)<-[filed:FILED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter) - RETURN report, resource, labels(resource)[0] AS type + WITH filed, report, resource {.*, __typename: labels(resource)[0]} AS finalResource + RETURN filed {.*, reportId: report.id, resource: properties(finalResource)} AS filedReport `, { resourceId, @@ -37,13 +28,12 @@ export default { reasonDescription, }, ) - log(reportTransactionResponse) - return reportTransactionResponse.records.map(transformReturnType) + log(fileReportTransactionResponse) + return fileReportTransactionResponse.records.map(record => record.get('filedReport')) }) try { - const [createdRelationshipWithNestedAttributes] = await reportWriteTxResultPromise - if (!createdRelationshipWithNestedAttributes) return null - return createdRelationshipWithNestedAttributes + const [filedReport] = await fileReportWriteTxResultPromise + return filedReport || null } finally { session.close() } @@ -76,14 +66,24 @@ export default { filterClause = '' } - if (params.closed) filterClause = 'AND report.closed = true' + switch (params.closed) { + case true: + filterClause = 'AND report.closed = true' + break + case false: + filterClause = 'AND report.closed = false' + break + default: + break + } const offset = params.offset && typeof params.offset === 'number' ? `SKIP ${params.offset}` : '' const limit = params.first && typeof params.first === 'number' ? `LIMIT ${params.first}` : '' - const reportReadTxPromise = session.readTransaction(async transaction => { - const allReportsTransactionResponse = await transaction.run( + const reportsReadTxPromise = session.readTransaction(async transaction => { + const reportsTransactionResponse = await transaction.run( + // !!! this Cypher query returns multiple reports on the same resource! i will create an issue for refactoring (bug fixing) ` MATCH (report:Report)-[:BELONGS_TO]->(resource) WHERE (resource:User OR resource:Post OR resource:Comment) @@ -101,11 +101,11 @@ export default { ${offset} ${limit} `, ) - log(allReportsTransactionResponse) - return allReportsTransactionResponse.records.map(record => record.get('report')) + log(reportsTransactionResponse) + return reportsTransactionResponse.records.map(record => record.get('report')) }) try { - const reports = await reportReadTxPromise + const reports = await reportsReadTxPromise return reports } finally { session.close() diff --git a/backend/src/schema/resolvers/reports.spec.js b/backend/src/schema/resolvers/reports.spec.js index 0e690c19e..5e1156f0c 100644 --- a/backend/src/schema/resolvers/reports.spec.js +++ b/backend/src/schema/resolvers/reports.spec.js @@ -10,18 +10,17 @@ const driver = getDriver() describe('file a report on a resource', () => { let authenticatedUser, currentUser, mutate, query, moderator, abusiveUser, otherReportingUser const categoryIds = ['cat9'] - const reportMutation = gql` + const fileReportMutation = gql` mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { fileReport( resourceId: $resourceId reasonCategory: $reasonCategory reasonDescription: $reasonDescription ) { - id createdAt - updatedAt - closed - rule + reasonCategory + reasonDescription + reportId resource { __typename ... on User { @@ -34,6 +33,35 @@ describe('file a report on a resource', () => { content } } + } + } + ` + const variables = { + resourceId: 'invalid', + reasonCategory: 'other', + reasonDescription: 'Violates code of conduct !!!', + } + const reportsQuery = gql` + query($closed: Boolean) { + reports(orderBy: createdAt_desc, closed: $closed) { + id + createdAt + updatedAt + rule + disable + closed + resource { + __typename + ... on User { + id + } + ... on Post { + id + } + ... on Comment { + id + } + } filed { submitter { id @@ -45,11 +73,31 @@ describe('file a report on a resource', () => { } } ` - const variables = { - resourceId: 'whatever', - reasonCategory: 'other', - reasonDescription: 'Violates code of conduct !!!', - } + const reviewMutation = gql` + mutation($resourceId: ID!, $disable: Boolean, $closed: Boolean) { + review(resourceId: $resourceId, disable: $disable, closed: $closed) { + createdAt + resource { + __typename + ... on User { + id + disabled + } + ... on Post { + id + disabled + } + ... on Comment { + id + disabled + } + } + report { + disable + } + } + } + ` beforeAll(async () => { await cleanDatabase() @@ -74,7 +122,7 @@ describe('file a report on a resource', () => { describe('unauthenticated', () => { it('throws authorization error', async () => { authenticatedUser = null - await expect(mutate({ mutation: reportMutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: fileReportMutation, variables })).resolves.toMatchObject({ data: { fileReport: null }, errors: [{ message: 'Not Authorised!' }], }) @@ -94,6 +142,17 @@ describe('file a report on a resource', () => { password: '1234', }, ) + moderator = await Factory.build( + 'user', + { + id: 'moderator-id', + role: 'moderator', + }, + { + email: 'moderator@example.org', + password: '1234', + }, + ) otherReportingUser = await Factory.build( 'user', { @@ -127,7 +186,7 @@ describe('file a report on a resource', () => { describe('invalid resource id', () => { it('returns null', async () => { - await expect(mutate({ mutation: reportMutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: fileReportMutation, variables })).resolves.toMatchObject({ data: { fileReport: null }, errors: undefined, }) @@ -139,47 +198,112 @@ describe('file a report on a resource', () => { it('which belongs to resource', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, }), ).resolves.toMatchObject({ data: { fileReport: { - id: expect.any(String), + reportId: expect.any(String), + resource: { + name: 'abusive-user', + }, }, }, errors: undefined, }) }) - it('creates only one report for multiple reports on the same resource', async () => { + it('only one report for multiple reports on the same resource', async () => { const firstReport = await mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, }) authenticatedUser = await otherReportingUser.toJson() const secondReport = await mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, }) - expect(firstReport.data.fileReport.id).toEqual(secondReport.data.fileReport.id) + + expect(firstReport.data.fileReport.reportId).toEqual( + secondReport.data.fileReport.reportId, + ) }) - it('returns the rule for how the report was decided', async () => { - await expect( - mutate({ - mutation: reportMutation, + describe('report properties are set correctly', () => { + const reportsCypherQuery = + 'MATCH (resource:User {id: $resourceId})<-[:BELONGS_TO]-(report:Report {closed: false})<-[filed:FILED]-(user:User {id: $currentUserId}) RETURN report' + + it('with the rule for how the report will be decided', async () => { + await mutate({ + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, - }), - ).resolves.toMatchObject({ - data: { - fileReport: { - rule: 'latestReviewUpdatedAtRules', - }, - }, - errors: undefined, + }) + + const reportsCypherQueryResponse = await instance.cypher(reportsCypherQuery, { + resourceId: 'abusive-user-id', + currentUserId: authenticatedUser.id, + }) + expect(reportsCypherQueryResponse.records).toHaveLength(1) + const [reportProperties] = reportsCypherQueryResponse.records.map( + record => record.get('report').properties, + ) + expect(reportProperties).toMatchObject({ rule: 'latestReviewUpdatedAtRules' }) + }) + + describe('with overtaken disabled from resource in disable property', () => { + it('disable is false', async () => { + await mutate({ + mutation: fileReportMutation, + variables: { ...variables, resourceId: 'abusive-user-id' }, + }) + + const reportsCypherQueryResponse = await instance.cypher(reportsCypherQuery, { + resourceId: 'abusive-user-id', + currentUserId: authenticatedUser.id, + }) + expect(reportsCypherQueryResponse.records).toHaveLength(1) + const [reportProperties] = reportsCypherQueryResponse.records.map( + record => record.get('report').properties, + ) + expect(reportProperties).toMatchObject({ disable: false }) + }) + + it('disable is true', async () => { + // first time filling a report to enable a moderator the disable the resource + await mutate({ + mutation: fileReportMutation, + variables: { ...variables, resourceId: 'abusive-user-id' }, + }) + authenticatedUser = await moderator.toJson() + await mutate({ + mutation: reviewMutation, + variables: { + resourceId: 'abusive-user-id', + disable: true, + closed: true, + }, + }) + authenticatedUser = await currentUser.toJson() + // second time filling a report to see if the "disable is true" of the resource is overtaken + await mutate({ + mutation: fileReportMutation, + variables: { ...variables, resourceId: 'abusive-user-id' }, + }) + + const reportsCypherQueryResponse = await instance.cypher(reportsCypherQuery, { + resourceId: 'abusive-user-id', + currentUserId: authenticatedUser.id, + }) + expect(reportsCypherQueryResponse.records).toHaveLength(1) + const [reportProperties] = reportsCypherQueryResponse.records.map( + record => record.get('report').properties, + ) + expect(reportProperties).toMatchObject({ disable: true }) + }) }) }) + it.todo('creates multiple filed reports') }) @@ -187,7 +311,7 @@ describe('file a report on a resource', () => { it('returns __typename "User"', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, }), ).resolves.toMatchObject({ @@ -205,7 +329,7 @@ describe('file a report on a resource', () => { it('returns user attribute info', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, }), ).resolves.toMatchObject({ @@ -221,32 +345,10 @@ describe('file a report on a resource', () => { }) }) - it('returns the submitter', async () => { + it('returns a createdAt', async () => { await expect( mutate({ - mutation: reportMutation, - variables: { ...variables, resourceId: 'abusive-user-id' }, - }), - ).resolves.toMatchObject({ - data: { - fileReport: { - filed: [ - { - submitter: { - id: 'current-user-id', - }, - }, - ], - }, - }, - errors: undefined, - }) - }) - - it('returns a date', async () => { - await expect( - mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, }), ).resolves.toMatchObject({ @@ -262,7 +364,7 @@ describe('file a report on a resource', () => { it('returns the reason category', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id', @@ -272,11 +374,7 @@ describe('file a report on a resource', () => { ).resolves.toMatchObject({ data: { fileReport: { - filed: [ - { - reasonCategory: 'criminal_behavior_violation_german_law', - }, - ], + reasonCategory: 'criminal_behavior_violation_german_law', }, }, errors: undefined, @@ -286,7 +384,7 @@ describe('file a report on a resource', () => { it('gives an error if the reason category is not in enum "ReasonCategory"', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id', @@ -307,7 +405,7 @@ describe('file a report on a resource', () => { it('returns the reason description', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id', @@ -317,11 +415,7 @@ describe('file a report on a resource', () => { ).resolves.toMatchObject({ data: { fileReport: { - filed: [ - { - reasonDescription: 'My reason!', - }, - ], + reasonDescription: 'My reason!', }, }, errors: undefined, @@ -331,7 +425,7 @@ describe('file a report on a resource', () => { it('sanitizes the reason description', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'abusive-user-id', @@ -341,11 +435,7 @@ describe('file a report on a resource', () => { ).resolves.toMatchObject({ data: { fileReport: { - filed: [ - { - reasonDescription: 'My reason !', - }, - ], + reasonDescription: 'My reason !', }, }, errors: undefined, @@ -371,7 +461,7 @@ describe('file a report on a resource', () => { it('returns type "Post"', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'post-to-report-id', @@ -392,7 +482,7 @@ describe('file a report on a resource', () => { it('returns resource in post attribute', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'post-to-report-id', @@ -442,7 +532,7 @@ describe('file a report on a resource', () => { it('returns type "Comment"', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'comment-to-report-id', @@ -463,7 +553,7 @@ describe('file a report on a resource', () => { it('returns resource in comment attribute', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'comment-to-report-id', @@ -493,7 +583,7 @@ describe('file a report on a resource', () => { it('returns null', async () => { await expect( mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { ...variables, resourceId: 'tag-to-report-id', @@ -510,37 +600,6 @@ describe('file a report on a resource', () => { }) describe('query for reported resource', () => { - const reportsQuery = gql` - query { - reports(orderBy: createdAt_desc) { - id - createdAt - updatedAt - closed - resource { - __typename - ... on User { - id - } - ... on Post { - id - } - ... on Comment { - id - } - } - filed { - submitter { - id - } - createdAt - reasonCategory - reasonDescription - } - } - } - ` - beforeEach(async () => { authenticatedUser = null moderator = await Factory.build( @@ -632,7 +691,7 @@ describe('file a report on a resource', () => { authenticatedUser = await currentUser.toJson() await Promise.all([ mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { resourceId: 'abusive-post-1', reasonCategory: 'other', @@ -640,7 +699,7 @@ describe('file a report on a resource', () => { }, }), mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { resourceId: 'abusive-comment-1', reasonCategory: 'discrimination_etc', @@ -648,7 +707,7 @@ describe('file a report on a resource', () => { }, }), mutate({ - mutation: reportMutation, + mutation: fileReportMutation, variables: { resourceId: 'abusive-user-1', reasonCategory: 'doxing', diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index cbdc683e8..a1b68e20d 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -251,12 +251,12 @@ export default { boolean: { followedByCurrentUser: 'MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', + isBlocked: + 'MATCH (this)<-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', blocked: 'MATCH (this)-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', isMuted: 'MATCH (this)<-[:MUTED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', - isBlocked: - 'MATCH (this)<-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', }, count: { contributionsCount: diff --git a/backend/src/schema/types/type/FILED.gql b/backend/src/schema/types/type/FILED.gql index cdce62116..85eca951e 100644 --- a/backend/src/schema/types/type/FILED.gql +++ b/backend/src/schema/types/type/FILED.gql @@ -16,3 +16,15 @@ enum ReasonCategory { advert_products_services_commercial criminal_behavior_violation_german_law } + +type FiledReport { + createdAt: String! + reasonCategory: ReasonCategory! + reasonDescription: String! + reportId: ID! + resource: ReportedResource! +} + +type Mutation { + fileReport(resourceId: ID!, reasonCategory: ReasonCategory!, reasonDescription: String!): FiledReport +} \ No newline at end of file diff --git a/backend/src/schema/types/type/REVIEWED.gql b/backend/src/schema/types/type/REVIEWED.gql index aea005abe..086d73815 100644 --- a/backend/src/schema/types/type/REVIEWED.gql +++ b/backend/src/schema/types/type/REVIEWED.gql @@ -4,7 +4,6 @@ type REVIEWED { disable: Boolean! closed: Boolean! report: Report - # @cypher(statement: "MATCH (report:Report)<-[this:REVIEWED]-(:User) RETURN report") moderator: User resource: ReviewedResource } diff --git a/backend/src/schema/types/type/Report.gql b/backend/src/schema/types/type/Report.gql index ad0015d01..9a4a48c4b 100644 --- a/backend/src/schema/types/type/Report.gql +++ b/backend/src/schema/types/type/Report.gql @@ -5,9 +5,9 @@ type Report { rule: ReportRule! disable: Boolean! closed: Boolean! - filed: [FILED] + filed: [FILED]! reviewed: [REVIEWED]! - resource: ReportedResource + resource: ReportedResource! } union ReportedResource = User | Post | Comment @@ -16,10 +16,6 @@ enum ReportRule { latestReviewUpdatedAtRules } -type Mutation { - fileReport(resourceId: ID!, reasonCategory: ReasonCategory!, reasonDescription: String!): Report -} - type Query { reports(orderBy: ReportOrdering, first: Int, offset: Int, reviewed: Boolean, closed: Boolean): [Report] } diff --git a/backend/src/schema/types/type/User.gql b/backend/src/schema/types/type/User.gql index baefc9d29..948d8e7d3 100644 --- a/backend/src/schema/types/type/User.gql +++ b/backend/src/schema/types/type/User.gql @@ -64,10 +64,11 @@ type User { # Is the currently logged in user following that user? followedByCurrentUser: Boolean! @cypher( statement: """ - MATCH (this)<-[: FOLLOWS]-(u: User { id: $cypherParams.currentUserId}) + MATCH (this)<-[:FOLLOWS]-(u:User { id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1 """ ) + isBlocked: Boolean! @cypher( statement: """ MATCH (this)<-[:BLOCKED]-(user:User {id: $cypherParams.currentUserId}) diff --git a/cypress/integration/common/report.js b/cypress/integration/common/report.js index fe7a31363..e85bd9662 100644 --- a/cypress/integration/common/report.js +++ b/cypress/integration/common/report.js @@ -139,7 +139,7 @@ Given('somebody reported the following posts:', table => { .authenticateAs(submitter) .mutate(gql`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { fileReport(resourceId: $resourceId, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription) { - id + reportId } }`, { resourceId, diff --git a/webapp/components/features/ReportList/ReportList.vue b/webapp/components/features/ReportList/ReportList.vue index c4a17bd26..a6b1d9f5b 100644 --- a/webapp/components/features/ReportList/ReportList.vue +++ b/webapp/components/features/ReportList/ReportList.vue @@ -44,13 +44,22 @@ export default { computed: { filterOptions() { return [ - { label: this.$t('moderation.reports.filterLabel.all'), value: { reviewed: null } }, + { + label: this.$t('moderation.reports.filterLabel.all'), + value: { reviewed: null, closed: null }, + }, { label: this.$t('moderation.reports.filterLabel.unreviewed'), - value: { reviewed: false }, + value: { reviewed: false, closed: false }, + }, + { + label: this.$t('moderation.reports.filterLabel.reviewed'), + value: { reviewed: true, closed: false }, + }, + { + label: this.$t('moderation.reports.filterLabel.closed'), + value: { reviewed: null, closed: true }, }, - { label: this.$t('moderation.reports.filterLabel.reviewed'), value: { reviewed: true } }, - { label: this.$t('moderation.reports.filterLabel.closed'), value: { closed: true } }, ] }, modalData() { @@ -108,13 +117,8 @@ export default { filter(option) { this.selected = option.label this.offset = 0 - if (option.value.closed) { - this.closed = option.value.closed - this.reviewed = null - return - } - this.closed = null this.reviewed = option.value.reviewed + this.closed = option.value.closed }, async confirmCallback(resource) { const { disabled: disable, id: resourceId } = resource diff --git a/webapp/components/features/ReportsTable/ReportsTable.vue b/webapp/components/features/ReportsTable/ReportsTable.vue index 512c04ea8..3892c0b12 100644 --- a/webapp/components/features/ReportsTable/ReportsTable.vue +++ b/webapp/components/features/ReportsTable/ReportsTable.vue @@ -24,11 +24,8 @@ diff --git a/webapp/graphql/Moderation.js b/webapp/graphql/Moderation.js index c63df921e..f4796d080 100644 --- a/webapp/graphql/Moderation.js +++ b/webapp/graphql/Moderation.js @@ -100,7 +100,7 @@ export const reportMutation = () => { reasonCategory: $reasonCategory reasonDescription: $reasonDescription ) { - id + reportId } } `