diff --git a/backend/src/schema/resolvers/moderation.js b/backend/src/schema/resolvers/moderation.js index e5e2c580c..072bbb700 100644 --- a/backend/src/schema/resolvers/moderation.js +++ b/backend/src/schema/resolvers/moderation.js @@ -17,7 +17,7 @@ export default { CASE WHEN decision.createdAt IS NULL THEN decision END).createdAt = toString(datetime()) - SET decision.disabled = true, decision.closed = false, decision.last = true + SET decision.disable = true, decision.closed = false, decision.last = true RETURN resource {.id} ` const session = driver.session() @@ -34,7 +34,7 @@ export default { const cypher = ` MATCH (resource {id: $resourceId})<-[decision:DECIDED]-(:User) SET resource.disabled = false - SET decision.disabled = false, decision.updatedAt = toString(datetime()) + SET decision.disable = false, decision.updatedAt = toString(datetime()) RETURN resource {.id} ` const session = driver.session() @@ -46,10 +46,13 @@ export default { if (!resource) return null return resource.id }, - decide: async (object, params, context, _resolveInfo) => { + decide: async (_object, params, context, _resolveInfo) => { let createdRelationshipWithNestedAttributes = null + // Wolle console.log('params: ', params) const { resourceId } = params - let { disabled, closed } = params + // Wolle console.log('resourceId: ', resourceId) + let { disable, closed } = params + // Wolle console.log('disable: ', disable) const { user: moderator, driver } = context const session = driver.session() @@ -76,7 +79,7 @@ export default { const [existingDecisionTxResult] = await existingDecisionWriteTxResultPromise if (!existingDecisionTxResult) { // no open decision, then create one - if (disabled === undefined) disabled = false // default for creation + if (disable === undefined) disable = false // default for creation if (closed === undefined) closed = false // default for creation cypherHeader = ` MATCH (moderator:User {id: $moderatorId}) @@ -93,8 +96,8 @@ export default { ` } else { // an open decision … - if (disabled === undefined) - disabled = existingDecisionTxResult.decision.properties.disabled // default set to existing + if (disable === undefined) + disable = existingDecisionTxResult.decision.properties.disable // default set to existing if (closed === undefined) closed = existingDecisionTxResult.decision.properties.closed // default set to existing // current moderator is not the same as old if (moderator.id !== existingDecisionTxResult.decisionModerator.id) { @@ -127,16 +130,18 @@ export default { CASE WHEN decision.createdAt IS NULL THEN decision END).createdAt = toString(datetime()) - SET decision.disabled = $disabled, decision.closed = $closed - SET resource.disabled = $disabled + SET decision.disable = $disable, decision.closed = $closed + SET resource.disabled = $disable RETURN decision, resource, moderator, labels(resource)[0] AS type ` + // Wolle console.log('cypher: ', cypher) + // console.log('disable: ', disable) const newDecisionWriteTxResultPromise = session.writeTransaction(async txc => { const decisionRelationshipTransactionResponse = await txc.run(cypher, { resourceId, moderatorId: moderator.id, - disabled, + disable, closed, }) return decisionRelationshipTransactionResponse.records.map(record => ({ diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 242a8c3fa..e29aa0ffd 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -8,11 +8,18 @@ const factory = Factory() const neode = getNeode() const driver = getDriver() -let query, mutate, authenticatedUser, variables, moderator, nonModerator +let query, + mutate, + authenticatedUser, + disableVariables, + // enableVariables, + resourceVariables, + moderator, + nonModerator -const disableMutation = gql` - mutation($id: ID!) { - decide(resourceId: $id, disabled: true, closed: false) { +const decideMutation = gql` + mutation($resourceId: ID!, $disable: Boolean, $closed: Boolean) { + decide(resourceId: $resourceId, disable: $disable, closed: $closed) { post { id } @@ -69,7 +76,19 @@ describe('moderate resources', () => { }) beforeEach(async () => { - variables = {} + resourceVariables = { + id: 'undefined-resource', + } + disableVariables = { + resourceId: 'undefined-resource', + disable: true, + closed: false, + } + // enableVariables = { + // resourceId: 'undefined-resource', + // disable: false, + // closed: false, + // } authenticatedUser = null moderator = await factory.create('User', { id: 'moderator-id', @@ -84,19 +103,17 @@ describe('moderate resources', () => { await factory.cleanDatabase() }) - describe('disable', () => { - beforeEach(() => { - variables = { - id: 'some-resource', - } - }) + describe('decide to disable', () => { describe('unauthenticated', () => { it('throws authorization error', async () => { - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) }) + describe('authenticated', () => { describe('non moderator', () => { beforeEach(async () => { @@ -108,8 +125,11 @@ describe('moderate resources', () => { }) authenticatedUser = await nonModerator.toJson() }) + it('throws authorization error', async () => { - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) @@ -122,14 +142,17 @@ describe('moderate resources', () => { describe('moderate a resource that is not a (Comment|Post|User) ', () => { beforeEach(async () => { - variables = { - id: 'sample-tag-id', + disableVariables = { + ...disableVariables, + resourceId: 'sample-tag-id', } await factory.create('Tag', { id: 'sample-tag-id' }) }) it('returns null', async () => { - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ data: { decide: null }, }) }) @@ -137,63 +160,102 @@ describe('moderate resources', () => { describe('moderate a comment', () => { beforeEach(async () => { - variables = {} + // Wolle variables = {} await factory.create('Comment', { id: 'comment-id', }) }) it('returns disabled resource id', async () => { - variables = { id: 'comment-id' } - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + disableVariables = { + ...disableVariables, + resourceId: 'comment-id', + } + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ data: { decide: { comment: { id: 'comment-id' } } }, errors: undefined, }) }) it('changes .decidedByModerator', async () => { - variables = { id: 'comment-id' } + resourceVariables = { + id: 'comment-id', + } + disableVariables = { + ...disableVariables, + resourceId: 'comment-id', + } const before = { data: { Comment: [{ id: 'comment-id', decidedByModerator: null }] } } const expected = { data: { Comment: [{ id: 'comment-id', decidedByModerator: { id: 'moderator-id' } }] }, } - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + await expect( + query({ query: commentQuery, variables: resourceVariables }), + ).resolves.toMatchObject(before) + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ data: { decide: { comment: { id: 'comment-id' } } }, }) - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + await expect( + query({ query: commentQuery, variables: resourceVariables }), + ).resolves.toMatchObject(expected) }) it('updates .disabled on comment', async () => { - variables = { id: 'comment-id' } + resourceVariables = { + id: 'comment-id', + } + disableVariables = { + ...disableVariables, + resourceId: 'comment-id', + } const before = { data: { Comment: [{ id: 'comment-id', disabled: false }] } } const expected = { data: { Comment: [{ id: 'comment-id', disabled: true }] } } - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + await expect( + query({ query: commentQuery, variables: resourceVariables }), + ).resolves.toMatchObject(before) + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ data: { decide: { comment: { id: 'comment-id' } } }, }) - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + await expect( + query({ query: commentQuery, variables: resourceVariables }), + ).resolves.toMatchObject(expected) }) }) describe('moderate a post', () => { beforeEach(async () => { - variables = {} await factory.create('Post', { id: 'sample-post-id', }) }) it('returns disabled resource id', async () => { - variables = { id: 'sample-post-id' } - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + disableVariables = { + ...disableVariables, + resourceId: 'sample-post-id', + } + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ data: { decide: { post: { id: 'sample-post-id' } } }, }) }) it('changes .decidedByModerator', async () => { - variables = { id: 'sample-post-id' } + resourceVariables = { + id: 'sample-post-id', + } + disableVariables = { + ...disableVariables, + resourceId: 'sample-post-id', + } const before = { data: { Post: [{ id: 'sample-post-id', decidedByModerator: null }] } } const expected = { data: { @@ -201,23 +263,41 @@ describe('moderate resources', () => { }, } - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + await expect( + query({ query: postQuery, variables: resourceVariables }), + ).resolves.toMatchObject(before) + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ data: { decide: { post: { id: 'sample-post-id' } } }, }) - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) + await expect( + query({ query: postQuery, variables: resourceVariables }), + ).resolves.toMatchObject(expected) }) it('updates .disabled on post', async () => { + resourceVariables = { + id: 'sample-post-id', + } + disableVariables = { + ...disableVariables, + resourceId: 'sample-post-id', + } const before = { data: { Post: [{ id: 'sample-post-id', disabled: false }] } } const expected = { data: { Post: [{ id: 'sample-post-id', disabled: true }] } } - variables = { id: 'sample-post-id' } - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(before) - await expect(mutate({ mutation: disableMutation, variables })).resolves.toMatchObject({ + await expect( + query({ query: postQuery, variables: resourceVariables }), + ).resolves.toMatchObject(before) + await expect( + mutate({ mutation: decideMutation, variables: disableVariables }), + ).resolves.toMatchObject({ data: { decide: { post: { id: 'sample-post-id' } } }, }) - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) + await expect( + query({ query: postQuery, variables: resourceVariables }), + ).resolves.toMatchObject(expected) }) }) }) @@ -227,8 +307,10 @@ describe('moderate resources', () => { describe('enable', () => { describe('unautenticated user', () => { it('throws authorization error', async () => { - variables = { id: 'sample-post-id' } - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + resourceVariables = { id: 'sample-post-id' } + await expect( + mutate({ mutation: enableMutation, variables: resourceVariables }), + ).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) @@ -245,9 +327,12 @@ describe('moderate resources', () => { }) authenticatedUser = await nonModerator.toJson() }) + it('throws authorization error', async () => { - variables = { id: 'sample-post-id' } - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + resourceVariables = { id: 'sample-post-id' } + await expect( + mutate({ mutation: enableMutation, variables: resourceVariables }), + ).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) @@ -257,6 +342,7 @@ describe('moderate resources', () => { beforeEach(async () => { authenticatedUser = await moderator.toJson() }) + describe('moderate a resource that is not a (Comment|Post|User) ', () => { beforeEach(async () => { await Promise.all([factory.create('Tag', { id: 'sample-tag-id' })]) @@ -273,15 +359,23 @@ describe('moderate resources', () => { describe('moderate a comment', () => { beforeEach(async () => { - variables = { id: 'comment-id' } + disableVariables = { + ...disableVariables, + resourceId: 'comment-id', + } + resourceVariables = { + id: 'comment-id', + } await factory.create('Comment', { id: 'comment-id', }) - await mutate({ mutation: disableMutation, variables }) + await mutate({ mutation: decideMutation, variables: disableVariables }) }) it('returns enabled resource id', async () => { - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + await expect( + mutate({ mutation: enableMutation, variables: resourceVariables }), + ).resolves.toMatchObject({ data: { enable: 'comment-id' }, errors: undefined, }) @@ -292,11 +386,15 @@ describe('moderate resources', () => { data: { Comment: [{ id: 'comment-id', decidedByModerator: { id: 'moderator-id' } }] }, errors: undefined, } - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + await expect( + mutate({ mutation: enableMutation, variables: resourceVariables }), + ).resolves.toMatchObject({ data: { enable: 'comment-id' }, errors: undefined, }) - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + await expect( + query({ query: commentQuery, variables: resourceVariables }), + ).resolves.toMatchObject(expected) }) it('updates .disabled on comment', async () => { @@ -305,25 +403,36 @@ describe('moderate resources', () => { errors: undefined, } - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + await expect( + mutate({ mutation: enableMutation, variables: resourceVariables }), + ).resolves.toMatchObject({ data: { enable: 'comment-id' }, errors: undefined, }) - await expect(query({ query: commentQuery, variables })).resolves.toMatchObject(expected) + await expect( + query({ query: commentQuery, variables: resourceVariables }), + ).resolves.toMatchObject(expected) }) }) describe('moderate a post', () => { beforeEach(async () => { - variables = { id: 'post-id' } + resourceVariables = { id: 'post-id' } + disableVariables = { + ...disableVariables, + resourceId: 'post-id', + } + resourceVariables = { + id: 'post-id', + } await factory.create('Post', { id: 'post-id', }) - await mutate({ mutation: disableMutation, variables }) + await mutate({ mutation: decideMutation, variables: disableVariables }) }) it('returns enabled resource id', async () => { - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: enableMutation, variables: resourceVariables })).resolves.toMatchObject({ data: { enable: 'post-id' }, errors: undefined, }) @@ -334,11 +443,11 @@ describe('moderate resources', () => { data: { Post: [{ id: 'post-id', decidedByModerator: { id: 'moderator-id' } }] }, errors: undefined, } - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: enableMutation, variables: resourceVariables })).resolves.toMatchObject({ data: { enable: 'post-id' }, errors: undefined, }) - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) + await expect(query({ query: postQuery, variables: resourceVariables })).resolves.toMatchObject(expected) }) it('updates .disabled on post', async () => { @@ -347,11 +456,11 @@ describe('moderate resources', () => { errors: undefined, } - await expect(mutate({ mutation: enableMutation, variables })).resolves.toMatchObject({ + await expect(mutate({ mutation: enableMutation, variables: resourceVariables })).resolves.toMatchObject({ data: { enable: 'post-id' }, errors: undefined, }) - await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected) + await expect(query({ query: postQuery, variables: resourceVariables })).resolves.toMatchObject(expected) }) }) }) diff --git a/backend/src/schema/types/type/DECIDED.gql b/backend/src/schema/types/type/DECIDED.gql index 073730403..d76534256 100644 --- a/backend/src/schema/types/type/DECIDED.gql +++ b/backend/src/schema/types/type/DECIDED.gql @@ -3,7 +3,7 @@ type DECIDED { updatedAt: String # reasonCategory: ReasonCategory # reasonDescription: String - disabled: Boolean! + disable: Boolean! closed: Boolean! # internal @@ -22,5 +22,5 @@ type DECIDED { } type Mutation { - decide(resourceId: ID!, disabled: Boolean, closed: Boolean): DECIDED + decide(resourceId: ID!, disable: Boolean, closed: Boolean): DECIDED } diff --git a/neo4j/change_disabled_relationship_to_decided_relationship.sh b/neo4j/change_disabled_relationship_to_decided_relationship.sh index baa147bcc..8fb3ac4b2 100755 --- a/neo4j/change_disabled_relationship_to_decided_relationship.sh +++ b/neo4j/change_disabled_relationship_to_decided_relationship.sh @@ -19,6 +19,6 @@ echo " MATCH (moderator:User)-[disabled:DISABLED]->(resource) DELETE disabled CREATE (moderator)-[decision:DECIDED]->(resource) -SET decision.createdAt = toString(datetime()), decision.disabled = true, decision.last = true, decision.closed = false +SET decision.createdAt = toString(datetime()), decision.disable = true, decision.last = true, decision.closed = false RETURN decision; " | cypher-shell