Refactor tests/resolvers

- we were making multiple http requests to report resources in this
test, now we are bypassing these requests by setting the database up to
how we want to test, then testing what we want in isolation.
- also added tests for closing a report
- favor union for returning resource
- simplify review mutation
This commit is contained in:
mattwr18 2019-11-27 17:35:30 +01:00
parent 3a05844356
commit d18d9228b0
3 changed files with 452 additions and 382 deletions

View File

@ -1,94 +1,45 @@
const transformReturnType = record => {
return {
...record.get('review').properties,
report: record.get('report').properties,
to: {
__typename: record.get('type'),
...record.get('resource').properties,
},
}
}
export default {
Mutation: {
review: async (_object, params, context, _resolveInfo) => {
const { resourceId } = params
let { disable, closed } = params
disable = disable === undefined ? null : disable
closed = closed === undefined ? null : closed
const { user: moderator, driver } = context
let createdRelationshipWithNestedAttributes = null // return value
const session = driver.session()
try {
const cypher = `
MATCH (resource {id: $params.resourceId})<-[:BELONGS_TO]-(report:Report {closed: false})
MATCH (moderator:User {id: $moderatorId})
MATCH (resource {id: $resourceId})
WHERE resource:User OR resource:Post OR resource:Comment
// no open report, create one, update existing
MERGE (resource)<-[:BELONGS_TO]-(report:Report {closed: false})
ON CREATE SET report.id = randomUUID(), report.createdAt = $dateTime, report.updatedAt = report.createdAt, report.rule = 'latestReviewUpdatedAtRules', report.disable = resource.disabled, report.closed = false
ON MATCH SET report.updatedAt = $dateTime
// report.disable and report.closed are set after setting them in review
// Create review on report
WITH moderator, resource, report
MERGE (report)<-[review:REVIEWED]-(moderator)
ON CREATE SET review.createdAt = $dateTime, review.updatedAt = review.createdAt,
review.disable = CASE WHEN $disable IS NULL
THEN report.disable
ELSE $disable END,
review.closed = CASE WHEN $closed IS NULL
THEN report.closed
ELSE $closed END
ON MATCH SET
review.updatedAt = $dateTime,
review.disable = CASE WHEN $disable IS NULL
THEN review.disable
ELSE $disable END,
review.closed = CASE WHEN $closed IS NULL
THEN review.closed
ELSE $closed END
SET report.disable = review.disable, report.closed = review.closed
MERGE (report)<-[review:REVIEWED { disable: $params.disable, closed: $params.closed }]-(moderator)
ON CREATE SET review.createdAt = $dateTime, review.updatedAt = review.createdAt
ON MATCH SET review.updatedAt = $dateTime
SET report.updatedAt = $dateTime, report.closed = review.closed
SET resource.disabled = review.disable
RETURN moderator, review, report, resource, labels(resource)[0] AS type
RETURN review, report, resource, labels(resource)[0] AS type
`
const mutateDecisionWriteTxResultPromise = session.writeTransaction(async txc => {
const mutateDecisionTransactionResponse = await txc.run(cypher, {
resourceId,
const reviewWriteTxResultPromise = session.writeTransaction(async txc => {
const reviewTransactionResponse = await txc.run(cypher, {
params,
moderatorId: moderator.id,
dateTime: new Date().toISOString(),
disable,
closed,
})
return mutateDecisionTransactionResponse.records.map(record => ({
moderator: record.get('moderator'),
review: record.get('review'),
report: record.get('report'),
resource: record.get('resource'),
type: record.get('type'),
}))
return reviewTransactionResponse.records.map(transformReturnType)
})
const txResult = await mutateDecisionWriteTxResultPromise
const txResult = await reviewWriteTxResultPromise
if (!txResult[0]) return null
const { moderator: moderatorInResult, review, report, resource, type } = txResult[0]
createdRelationshipWithNestedAttributes = {
...review.properties,
reportId: report.properties.id,
reportCreatedAt: report.properties.createdAt,
reportUpdatedAt: report.properties.updatedAt,
reportDisable: report.properties.disable,
reportClosed: report.properties.closed,
moderator: moderatorInResult.properties,
type,
post: null,
comment: null,
user: null,
}
switch (type) {
case 'Post':
createdRelationshipWithNestedAttributes.post = resource.properties
break
case 'Comment':
createdRelationshipWithNestedAttributes.comment = resource.properties
break
case 'User':
createdRelationshipWithNestedAttributes.user = resource.properties
break
}
createdRelationshipWithNestedAttributes = txResult[0]
} finally {
session.close()
}

View File

@ -8,63 +8,50 @@ const factory = Factory()
const neode = getNeode()
const driver = getDriver()
let query,
mutate,
let mutate,
authenticatedUser,
disableVariables,
enableVariables,
resourceVariables,
moderator,
nonModerator
nonModerator,
closeReportVariables
const reportMutation = gql`
mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) {
fileReport(
resourceId: $resourceId
reasonCategory: $reasonCategory
reasonDescription: $reasonDescription
) {
type
}
}
`
const reviewMutation = gql`
mutation($resourceId: ID!, $disable: Boolean, $closed: Boolean) {
review(resourceId: $resourceId, disable: $disable, closed: $closed) {
post {
id
createdAt
updatedAt
to {
__typename
... on User {
id
disabled
}
... on Post {
id
disabled
}
... on Comment {
id
disabled
}
}
comment {
id
}
}
}
`
const commentQuery = gql`
query($id: ID!) {
Comment(id: $id) {
id
disabled
reviewedByModerator {
id
}
}
}
`
const postQuery = gql`
query($id: ID) {
Post(id: $id) {
id
disabled
reviewedByModerator {
report {
id
createdAt
updatedAt
closed
reviewedByModerator {
id
}
}
}
}
`
describe('moderate resources', () => {
beforeAll(() => {
beforeAll(async () => {
await factory.cleanDatabase()
authenticatedUser = undefined
const { server } = createServer({
context: () => {
@ -76,13 +63,9 @@ describe('moderate resources', () => {
},
})
mutate = createTestClient(server).mutate
query = createTestClient(server).query
})
beforeEach(async () => {
resourceVariables = {
id: 'undefined-resource',
}
disableVariables = {
resourceId: 'undefined-resource',
disable: true,
@ -101,12 +84,81 @@ describe('moderate resources', () => {
password: '1234',
role: 'moderator',
})
nonModerator = await factory.create('User', {
id: 'non-moderator',
name: 'Non Moderator',
email: 'non.moderator@example.org',
password: '1234',
})
})
afterEach(async () => {
await factory.cleanDatabase()
})
describe('review to close report, leaving resource enabled', () => {
describe('unauthenticated', () => {
it('throws authorization error', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
errors: [{ message: 'Not Authorised!' }],
})
})
})
describe('authenticated', () => {
beforeEach(async () => {
authenticatedUser = await nonModerator.toJson()
})
it('non-moderator receives an authorization error', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
errors: [{ message: 'Not Authorised!' }],
})
})
})
describe('moderator', () => {
beforeEach(async () => {
authenticatedUser = await moderator.toJson()
const questionablePost = await factory.create('Post', {
id: 'should-i-be-disabled',
})
const reportAgainstQuestionablePost = await factory.create('Report')
await Promise.all([
reportAgainstQuestionablePost.relateTo(nonModerator, 'filed', {
resourceId: 'should-i-be-disabled',
reasonCategory: 'doxing',
reasonDescription: "This shouldn't be shown to anybody else! It's my private thing!",
}),
reportAgainstQuestionablePost.relateTo(questionablePost, 'belongsTo'),
])
closeReportVariables = {
resourceId: 'should-i-be-disabled',
disable: false,
closed: true,
}
})
it('report can be closed without disabling resource', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: closeReportVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'Post', id: 'should-i-be-disabled', disabled: false },
report: { id: expect.any(String), closed: true },
},
},
errors: undefined,
})
})
})
})
describe('review to disable', () => {
describe('unauthenticated', () => {
it('throws authorization error', async () => {
@ -119,218 +171,256 @@ describe('moderate resources', () => {
})
describe('authenticated', () => {
describe('non moderator', () => {
beforeEach(async () => {
authenticatedUser = await nonModerator.toJson()
})
it('non-moderator receives an authorization error', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
errors: [{ message: 'Not Authorised!' }],
})
})
})
describe('moderator', () => {
beforeEach(async () => {
authenticatedUser = await moderator.toJson()
})
describe('review of a resource that is not a (Comment|Post|User) ', () => {
beforeEach(async () => {
nonModerator = await factory.create('User', {
id: 'non-moderator',
name: 'Non Moderator',
email: 'non.moderator@example.org',
password: '1234',
})
authenticatedUser = await nonModerator.toJson()
disableVariables = {
...disableVariables,
resourceId: 'tag-id',
}
await factory.create('Tag', { id: 'tag-id' })
})
it('throws authorization error', async () => {
it('returns null', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
errors: [{ message: 'Not Authorised!' }],
data: { review: null },
})
})
})
describe('moderator', () => {
describe('moderate a comment', () => {
beforeEach(async () => {
authenticatedUser = await moderator.toJson()
const trollingComment = await factory.create('Comment', {
id: 'comment-id',
})
const reportAgainstTrollingComment = await factory.create('Report')
await Promise.all([
reportAgainstTrollingComment.relateTo(nonModerator, 'filed', {
resourceId: 'comment-id',
reasonCategory: 'other',
reasonDescription: 'This comment is bigoted',
}),
reportAgainstTrollingComment.relateTo(trollingComment, 'belongsTo'),
])
disableVariables = {
...disableVariables,
resourceId: 'comment-id',
}
})
describe('moderate a resource that is not a (Comment|Post|User) ', () => {
beforeEach(async () => {
disableVariables = {
...disableVariables,
resourceId: 'sample-tag-id',
}
await factory.create('Tag', { id: 'sample-tag-id' })
})
it('returns null', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: null },
})
it('returns disabled resource id', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { to: { __typename: 'Comment', id: 'comment-id' } } },
errors: undefined,
})
})
describe('moderate a comment', () => {
beforeEach(async () => {
await factory.create('Comment', {
id: 'comment-id',
})
await mutate({
mutation: reportMutation,
variables: {
resourceId: 'comment-id',
reasonCategory: 'discrimination_etc',
reasonDescription: 'I am what I am !!!',
it('returns .reviewedByModerator', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'Comment', id: 'comment-id' },
report: { id: expect.any(String), reviewedByModerator: { id: 'moderator-id' } },
},
})
})
it('returns disabled resource id', async () => {
disableVariables = {
...disableVariables,
resourceId: 'comment-id',
}
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { comment: { id: 'comment-id' } } },
errors: undefined,
})
})
it('changes .reviewedByModerator', async () => {
resourceVariables = {
id: 'comment-id',
}
disableVariables = {
...disableVariables,
resourceId: 'comment-id',
}
const before = { data: { Comment: [{ id: 'comment-id', reviewedByModerator: null }] } }
const expected = {
data: {
Comment: [{ id: 'comment-id', reviewedByModerator: { id: 'moderator-id' } }],
},
}
await expect(
query({ query: commentQuery, variables: resourceVariables }),
).resolves.toMatchObject(before)
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { comment: { id: 'comment-id' } } },
})
await expect(
query({ query: commentQuery, variables: resourceVariables }),
).resolves.toMatchObject(expected)
})
it('updates .disabled on comment', async () => {
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: resourceVariables }),
).resolves.toMatchObject(before)
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { comment: { id: 'comment-id' } } },
})
await expect(
query({ query: commentQuery, variables: resourceVariables }),
).resolves.toMatchObject(expected)
},
})
})
describe('moderate a post', () => {
beforeEach(async () => {
await factory.create('Post', {
id: 'sample-post-id',
})
await mutate({
mutation: reportMutation,
variables: {
resourceId: 'sample-post-id',
reasonCategory: 'discrimination_etc',
reasonDescription: 'I am what I am !!!',
it('updates .disabled on comment', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { to: { __typename: 'Comment', id: 'comment-id', disabled: true } } },
})
})
it('can be closed with one review', async () => {
closeReportVariables = {
...disableVariables,
closed: true,
}
await expect(
mutate({ mutation: reviewMutation, variables: closeReportVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'Comment', id: 'comment-id' },
report: { id: expect.any(String), closed: true },
},
})
},
})
})
})
it('returns disabled resource id', async () => {
disableVariables = {
...disableVariables,
resourceId: 'sample-post-id',
}
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { post: { id: 'sample-post-id' } } },
})
describe('moderate a post', () => {
beforeEach(async () => {
const trollingPost = await factory.create('Post', {
id: 'post-id',
})
const reportAgainstTrollingPost = await factory.create('Report')
await Promise.all([
reportAgainstTrollingPost.relateTo(nonModerator, 'filed', {
resourceId: 'post-id',
reasonCategory: 'doxing',
reasonDescription: "This shouldn't be shown to anybody else! It's my private thing!",
}),
reportAgainstTrollingPost.relateTo(trollingPost, 'belongsTo'),
])
disableVariables = {
...disableVariables,
resourceId: 'post-id',
}
})
it('changes .reviewedByModerator', async () => {
resourceVariables = {
id: 'sample-post-id',
}
disableVariables = {
...disableVariables,
resourceId: 'sample-post-id',
}
const before = { data: { Post: [{ id: 'sample-post-id', reviewedByModerator: null }] } }
const expected = {
data: {
Post: [{ id: 'sample-post-id', reviewedByModerator: { id: 'moderator-id' } }],
it('returns disabled resource id', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'Post', id: 'post-id' },
},
}
await expect(
query({ query: postQuery, variables: resourceVariables }),
).resolves.toMatchObject(before)
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { post: { id: 'sample-post-id' } } },
})
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 }] } }
it('returns .reviewedByModerator', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'Post', id: 'post-id' },
report: { id: expect.any(String), reviewedByModerator: { id: 'moderator-id' } },
},
},
})
})
await expect(
query({ query: postQuery, variables: resourceVariables }),
).resolves.toMatchObject(before)
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { post: { id: 'sample-post-id' } } },
})
await expect(
query({ query: postQuery, variables: resourceVariables }),
).resolves.toMatchObject(expected)
it('updates .disabled on post', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { to: { __typename: 'Post', id: 'post-id', disabled: true } } },
})
})
it('can be closed with one review', async () => {
closeReportVariables = {
...disableVariables,
closed: true,
}
await expect(
mutate({ mutation: reviewMutation, variables: closeReportVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'Post', id: 'post-id' },
report: { id: expect.any(String), closed: true },
},
},
})
})
})
describe('moderate a user', () => {
beforeEach(async () => {
const troll = await factory.create('User', {
id: 'user-id',
})
const reportAgainstTroll = await factory.create('Report')
await Promise.all([
reportAgainstTroll.relateTo(nonModerator, 'filed', {
resourceId: 'user-id',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
}),
reportAgainstTroll.relateTo(troll, 'belongsTo'),
])
disableVariables = {
...disableVariables,
resourceId: 'user-id',
}
})
it('returns disabled resource id', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { to: { __typename: 'User', id: 'user-id' } } },
})
})
it('returns .reviewedByModerator', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'User', id: 'user-id' },
report: { id: expect.any(String), reviewedByModerator: { id: 'moderator-id' } },
},
},
})
})
it('updates .disabled on user', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: disableVariables }),
).resolves.toMatchObject({
data: { review: { to: { __typename: 'User', id: 'user-id', disabled: true } } },
})
})
it('can be closed with one review', async () => {
closeReportVariables = {
...disableVariables,
closed: true,
}
await expect(
mutate({ mutation: reviewMutation, variables: closeReportVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'User', id: 'user-id' },
report: { id: expect.any(String), closed: true },
},
},
})
})
})
})
})
describe('enable', () => {
describe('review to re-enable after disabled', () => {
describe('unautenticated user', () => {
it('throws authorization error', async () => {
enableVariables = {
...enableVariables,
resourceId: 'sample-post-id',
resourceId: 'post-id',
}
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
@ -343,19 +433,13 @@ describe('moderate resources', () => {
describe('authenticated user', () => {
describe('non moderator', () => {
beforeEach(async () => {
nonModerator = await factory.create('User', {
id: 'non-moderator',
name: 'Non Moderator',
email: 'non.moderator@example.org',
password: '1234',
})
authenticatedUser = await nonModerator.toJson()
})
it('throws authorization error', async () => {
enableVariables = {
...enableVariables,
resourceId: 'sample-post-id',
resourceId: 'post-id',
}
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
@ -372,13 +456,13 @@ describe('moderate resources', () => {
describe('moderate a resource that is not a (Comment|Post|User) ', () => {
beforeEach(async () => {
await Promise.all([factory.create('Tag', { id: 'sample-tag-id' })])
await Promise.all([factory.create('Tag', { id: 'tag-id' })])
})
it('returns null', async () => {
enableVariables = {
...enableVariables,
resourceId: 'sample-tag-id',
resourceId: 'tag-id',
}
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
@ -390,132 +474,175 @@ describe('moderate resources', () => {
describe('moderate a comment', () => {
beforeEach(async () => {
resourceVariables = {
const trollingComment = await factory.create('Comment', {
id: 'comment-id',
}
disableVariables = {
...disableVariables,
resourceId: 'comment-id',
}
})
const reportAgainstTrollingComment = await factory.create('Report')
await Promise.all([
reportAgainstTrollingComment.relateTo(nonModerator, 'filed', {
resourceId: 'comment-id',
reasonCategory: 'other',
reasonDescription: 'This comment is bigoted',
}),
reportAgainstTrollingComment.relateTo(trollingComment, 'belongsTo'),
])
await Promise.all([
reportAgainstTrollingComment.relateTo(moderator, 'reviewed', {
...disableVariables,
resourceId: 'comment-id',
}),
trollingComment.update({ disabled: true, updatedAt: new Date().toISOString() }),
])
enableVariables = {
...enableVariables,
resourceId: 'comment-id',
}
await factory.create('Comment', {
id: 'comment-id',
})
await mutate({
mutation: reportMutation,
variables: {
resourceId: 'comment-id',
reasonCategory: 'discrimination_etc',
reasonDescription: 'I am what I am !!!',
},
})
await mutate({ mutation: reviewMutation, variables: disableVariables })
})
it('returns enabled resource id', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { comment: { id: 'comment-id' } } },
data: { review: { to: { __typename: 'Comment', id: 'comment-id' } } },
})
})
it('changes .reviewedByModerator', async () => {
const expected = {
data: {
Comment: [{ id: 'comment-id', reviewedByModerator: { id: 'moderator-id' } }],
},
}
it('returns .reviewedByModerator', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { comment: { id: 'comment-id' } } },
data: {
review: {
to: { __typename: 'Comment', id: 'comment-id' },
report: { id: expect.any(String), reviewedByModerator: { id: 'moderator-id' } },
},
},
})
await expect(
query({ query: commentQuery, variables: resourceVariables }),
).resolves.toMatchObject(expected)
})
it('updates .disabled on comment', async () => {
const expected = {
data: { Comment: [{ id: 'comment-id', disabled: false }] },
}
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { comment: { id: 'comment-id' } } },
data: {
review: { to: { __typename: 'Comment', id: 'comment-id', disabled: false } },
},
})
await expect(
query({ query: commentQuery, variables: resourceVariables }),
).resolves.toMatchObject(expected)
})
})
describe('moderate a post', () => {
beforeEach(async () => {
resourceVariables = { id: 'post-id' }
disableVariables = {
...disableVariables,
resourceId: 'post-id',
}
const trollingPost = await factory.create('Post', {
id: 'post-id',
})
const reportAgainstTrollingPost = await factory.create('Report')
await Promise.all([
reportAgainstTrollingPost.relateTo(nonModerator, 'filed', {
resourceId: 'post-id',
reasonCategory: 'doxing',
reasonDescription:
"This shouldn't be shown to anybody else! It's my private thing!",
}),
reportAgainstTrollingPost.relateTo(trollingPost, 'belongsTo'),
])
await Promise.all([
reportAgainstTrollingPost.relateTo(moderator, 'reviewed', {
...disableVariables,
resourceId: 'comment-id',
}),
trollingPost.update({ disabled: true, updatedAt: new Date().toISOString() }),
])
enableVariables = {
...enableVariables,
resourceId: 'post-id',
}
await factory.create('Post', {
id: 'post-id',
})
await mutate({
mutation: reportMutation,
variables: {
resourceId: 'post-id',
reasonCategory: 'discrimination_etc',
reasonDescription: 'I am what I am !!!',
},
})
await mutate({ mutation: reviewMutation, variables: disableVariables })
})
it('returns enabled resource id', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { post: { id: 'post-id' } } },
data: { review: { to: { __typename: 'Post', id: 'post-id' } } },
})
})
it('changes .reviewedByModerator', async () => {
const expected = {
data: { Post: [{ id: 'post-id', reviewedByModerator: { id: 'moderator-id' } }] },
}
it('returns .reviewedByModerator', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { post: { id: 'post-id' } } },
data: {
review: {
to: { __typename: 'Post', id: 'post-id' },
report: { id: expect.any(String), reviewedByModerator: { id: 'moderator-id' } },
},
},
})
await expect(
query({ query: postQuery, variables: resourceVariables }),
).resolves.toMatchObject(expected)
})
it('updates .disabled on post', async () => {
const expected = {
data: { Post: [{ id: 'post-id', disabled: false }] },
}
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { post: { id: 'post-id' } } },
data: { review: { to: { __typename: 'Post', id: 'post-id', disabled: false } } },
})
})
})
describe('moderate a user', () => {
beforeEach(async () => {
const troll = await factory.create('User', {
id: 'user-id',
})
const reportAgainstTroll = await factory.create('Report')
await Promise.all([
reportAgainstTroll.relateTo(nonModerator, 'filed', {
resourceId: 'user-id',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
}),
reportAgainstTroll.relateTo(troll, 'belongsTo'),
])
await Promise.all([
reportAgainstTroll.relateTo(moderator, 'reviewed', {
...disableVariables,
resourceId: 'comment-id',
}),
troll.update({ disabled: true, updatedAt: new Date().toISOString() }),
])
enableVariables = {
...enableVariables,
resourceId: 'user-id',
}
})
it('returns enabled resource id', async () => {
await expect(
query({ query: postQuery, variables: resourceVariables }),
).resolves.toMatchObject(expected)
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { to: { __typename: 'User', id: 'user-id' } } },
})
})
it('returns .reviewedByModerator', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: {
review: {
to: { __typename: 'User', id: 'user-id' },
report: { id: expect.any(String), reviewedByModerator: { id: 'moderator-id' } },
},
},
})
})
it('updates .disabled on user', async () => {
await expect(
mutate({ mutation: reviewMutation, variables: enableVariables }),
).resolves.toMatchObject({
data: { review: { to: { __typename: 'User', id: 'user-id', disabled: false } } },
})
})
})
})

View File

@ -1,23 +1,15 @@
type REVIEWED {
createdAt: String!
updatedAt: String!
# reasonCategory: ReasonCategory
# reasonDescription: String
disable: Boolean!
closed: Boolean!
reportId: ID!
reportCreatedAt: String!
reportUpdatedAt: String!
reportDisable: Boolean!
reportClosed: Boolean!
report: Report
# @cypher(statement: "MATCH (report:Report)<-[this:REVIEWED]-(:User) RETURN report")
moderator: User
type: String
user: User
post: Post
comment: Comment
to: ReviewedResource
}
union ReviewedResource = User | Post | Comment
type Mutation {
review(resourceId: ID!, disable: Boolean, closed: Boolean): REVIEWED