diff --git a/backend/src/schema/resolvers/users.spec.js b/backend/src/schema/resolvers/users.spec.js index 1a2093f49..ebcd2e3cb 100644 --- a/backend/src/schema/resolvers/users.spec.js +++ b/backend/src/schema/resolvers/users.spec.js @@ -244,7 +244,435 @@ describe('UpdateUser', () => { }) }) -describe('DeleteUser', () => { +describe('DeleteUser as another user', () => { + const deleteUserMutation = gql` + mutation($id: ID!, $resource: [Deletable]) { + DeleteUser(id: $id, resource: $resource) { + id + name + about + deleted + contributions { + id + content + contentExcerpt + deleted + comments { + id + content + contentExcerpt + deleted + } + } + comments { + id + content + contentExcerpt + deleted + } + } + } + ` + beforeEach(async () => { + variables = { id: ' u343', resource: [] } + + user = await Factory.build('user', { + name: 'My name should be deleted', + about: 'along with my about', + id: 'u343', + }) + }) + + beforeEach(async () => { + const anotherUser = await Factory.build( + 'user', + { + role: 'user', + }, + { + email: 'user@example.org', + password: '1234', + }, + ) + + authenticatedUser = await anotherUser.toJson() + }) + + it('a user has no authorization to delete another user accounts', async () => { + const { errors } = await mutate({ mutation: deleteUserMutation, variables }) + expect(errors[0]).toHaveProperty('message', 'Not Authorised!') + }) +}) + +describe('DeleteUser as moderator', () => { + const deleteUserMutation = gql` + mutation($id: ID!, $resource: [Deletable]) { + DeleteUser(id: $id, resource: $resource) { + id + name + about + deleted + contributions { + id + content + contentExcerpt + deleted + comments { + id + content + contentExcerpt + deleted + } + } + comments { + id + content + contentExcerpt + deleted + } + } + } + ` + beforeEach(async () => { + variables = { id: ' u343', resource: [] } + + user = await Factory.build('user', { + name: 'My name should be deleted', + about: 'along with my about', + id: 'u343', + }) + }) + + beforeEach(async () => { + const moderator = await Factory.build( + 'user', + { + role: 'moderator', + }, + { + email: 'moderator@example.org', + password: '1234', + }, + ) + + authenticatedUser = await moderator.toJson() + }) + + it('moderator is not allowed to delete other user accounts', async () => { + const { errors } = await mutate({ mutation: deleteUserMutation, variables }) + expect(errors[0]).toHaveProperty('message', 'Not Authorised!') + }) +}) + +describe('DeleteUser as Admin', () => { + const deleteUserMutation = gql` + mutation($id: ID!, $resource: [Deletable]) { + DeleteUser(id: $id, resource: $resource) { + id + name + about + deleted + contributions { + id + content + contentExcerpt + deleted + comments { + id + content + contentExcerpt + deleted + } + } + comments { + id + content + contentExcerpt + deleted + } + } + } + ` + beforeEach(async () => { + variables = { id: ' u343', resource: [] } + + user = await Factory.build('user', { + name: 'My name should be deleted', + about: 'along with my about', + id: 'u343', + }) + }) + + describe('authenticated as Admin', () => { + beforeEach(async () => { + const admin = await Factory.build( + 'user', + { + role: 'admin', + }, + { + email: 'admin@example.org', + password: '1234', + }, + ) + authenticatedUser = await admin.toJson() + }) + + describe('deleting a user account', () => { + beforeEach(() => { + variables = { ...variables, id: 'u343' } + }) + + describe('given posts and comments', () => { + beforeEach(async () => { + await Factory.build('category', { + id: 'cat9', + name: 'Democracy & Politics', + icon: 'university', + }) + await Factory.build( + 'post', + { + id: 'p139', + content: 'Post by user u343', + }, + { + author: user, + categoryIds, + }, + ) + await Factory.build( + 'comment', + { + id: 'c155', + content: 'Comment by user u343', + }, + { + author: user, + }, + ) + await Factory.build( + 'comment', + { + id: 'c156', + content: "A comment by someone else on user u343's post", + }, + { + postId: 'p139', + }, + ) + }) + + it("deletes account, but doesn't delete posts or comments by default", async () => { + const expectedResponse = { + data: { + DeleteUser: { + id: 'u343', + name: 'UNAVAILABLE', + about: 'UNAVAILABLE', + deleted: true, + contributions: [ + { + id: 'p139', + content: 'Post by user u343', + contentExcerpt: 'Post by user u343', + deleted: false, + comments: [ + { + id: 'c156', + content: "A comment by someone else on user u343's post", + contentExcerpt: "A comment by someone else on user u343's post", + deleted: false, + }, + ], + }, + ], + comments: [ + { + id: 'c155', + content: 'Comment by user u343', + contentExcerpt: 'Comment by user u343', + deleted: false, + }, + ], + }, + }, + errors: undefined, + } + await expect(mutate({ mutation: deleteUserMutation, variables })).resolves.toMatchObject( + expectedResponse, + ) + }) + + describe('deletion of all post requested', () => { + beforeEach(() => { + variables = { ...variables, resource: ['Post'] } + }) + + describe("marks user's posts as deleted", () => { + it('on request', async () => { + const expectedResponse = { + data: { + DeleteUser: { + id: 'u343', + name: 'UNAVAILABLE', + about: 'UNAVAILABLE', + deleted: true, + contributions: [ + { + id: 'p139', + content: 'UNAVAILABLE', + contentExcerpt: 'UNAVAILABLE', + deleted: true, + comments: [ + { + id: 'c156', + content: 'UNAVAILABLE', + contentExcerpt: 'UNAVAILABLE', + deleted: true, + }, + ], + }, + ], + comments: [ + { + id: 'c155', + content: 'Comment by user u343', + contentExcerpt: 'Comment by user u343', + deleted: false, + }, + ], + }, + }, + errors: undefined, + } + await expect( + mutate({ mutation: deleteUserMutation, variables }), + ).resolves.toMatchObject(expectedResponse) + }) + }) + }) + + describe('deletion of all comments requested', () => { + beforeEach(() => { + variables = { ...variables, resource: ['Comment'] } + }) + + it('marks comments as deleted', async () => { + const expectedResponse = { + data: { + DeleteUser: { + id: 'u343', + name: 'UNAVAILABLE', + about: 'UNAVAILABLE', + deleted: true, + contributions: [ + { + id: 'p139', + content: 'Post by user u343', + contentExcerpt: 'Post by user u343', + deleted: false, + comments: [ + { + id: 'c156', + content: "A comment by someone else on user u343's post", + contentExcerpt: "A comment by someone else on user u343's post", + deleted: false, + }, + ], + }, + ], + comments: [ + { + id: 'c155', + content: 'UNAVAILABLE', + contentExcerpt: 'UNAVAILABLE', + deleted: true, + }, + ], + }, + }, + errors: undefined, + } + await expect( + mutate({ mutation: deleteUserMutation, variables }), + ).resolves.toMatchObject(expectedResponse) + }) + }) + + describe('deletion of all posts and comments requested', () => { + beforeEach(() => { + variables = { ...variables, resource: ['Post', 'Comment'] } + }) + + it('marks posts and comments as deleted', async () => { + const expectedResponse = { + data: { + DeleteUser: { + id: 'u343', + name: 'UNAVAILABLE', + about: 'UNAVAILABLE', + deleted: true, + contributions: [ + { + id: 'p139', + content: 'UNAVAILABLE', + contentExcerpt: 'UNAVAILABLE', + deleted: true, + comments: [ + { + id: 'c156', + content: 'UNAVAILABLE', + contentExcerpt: 'UNAVAILABLE', + deleted: true, + }, + ], + }, + ], + comments: [ + { + id: 'c155', + content: 'UNAVAILABLE', + contentExcerpt: 'UNAVAILABLE', + deleted: true, + }, + ], + }, + }, + errors: undefined, + } + await expect( + mutate({ mutation: deleteUserMutation, variables }), + ).resolves.toMatchObject(expectedResponse) + }) + }) + }) + + describe('connected `EmailAddress` nodes', () => { + it('will be removed completely', async () => { + await expect(neode.all('EmailAddress')).resolves.toHaveLength(2) + await mutate({ mutation: deleteUserMutation, variables }) + await expect(neode.all('EmailAddress')).resolves.toHaveLength(1) + }) + }) + + describe('connected `SocialMedia` nodes', () => { + beforeEach(async () => { + const socialMedia = await Factory.build('socialMedia') + await socialMedia.relateTo(user, 'ownedBy') + }) + + it('will be removed completely', async () => { + await expect(neode.all('SocialMedia')).resolves.toHaveLength(1) + await mutate({ mutation: deleteUserMutation, variables }) + await expect(neode.all('SocialMedia')).resolves.toHaveLength(0) + }) + }) + }) + }) +}) + +describe('DeleteUser I myself', () => { const deleteUserMutation = gql` mutation($id: ID!, $resource: [Deletable]) { DeleteUser(id: $id, resource: $resource) { @@ -568,456 +996,3 @@ describe('DeleteUser', () => { }) }) }) - - - -describe('DeleteUser as another user', () => { - const deleteUserMutation = gql` - mutation($id: ID!, $resource: [Deletable]) { - DeleteUser(id: $id, resource: $resource) { - id - name - about - deleted - contributions { - id - content - contentExcerpt - deleted - comments { - id - content - contentExcerpt - deleted - } - } - comments { - id - content - contentExcerpt - deleted - } - } - } -` -beforeEach(async () => { - variables = { id: ' u343', resource: [] } - - user = await Factory.build('user', { - name: 'My name should be deleted', - about: 'along with my about', - id: 'u343', - }) - -}) - - beforeEach(async () => { - - - const anotherUser = await Factory.build( - 'user', - { - role: 'user', - }, - { - email: 'user@example.org', - password: '1234', - }, - ) - - authenticatedUser = await anotherUser.toJson() - }) - - it('a user has no authorization to delete another user accounts', async () => { - const { errors } = await mutate({ mutation: deleteUserMutation, variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorised!') - }) -}) - - - - -describe('DeleteUser as moderator', () => { - const deleteUserMutation = gql` - mutation($id: ID!, $resource: [Deletable]) { - DeleteUser(id: $id, resource: $resource) { - id - name - about - deleted - contributions { - id - content - contentExcerpt - deleted - comments { - id - content - contentExcerpt - deleted - } - } - comments { - id - content - contentExcerpt - deleted - } - } - } -` -beforeEach(async () => { - variables = { id: ' u343', resource: [] } - - user = await Factory.build('user', { - name: 'My name should be deleted', - about: 'along with my about', - id: 'u343', - }) - -}) - -beforeEach(async () => { - - - const moderator = await Factory.build( - 'user', - { - role: 'moderator', - }, - { - email: 'moderator@example.org', - password: '1234', - }, - ) - - - authenticatedUser = await moderator.toJson() -}) - -it('moderator is not allowed to delete other user accounts', async () => { - const { errors } = await mutate({ mutation: deleteUserMutation, variables }) - expect(errors[0]).toHaveProperty('message', 'Not Authorised!') -}) - - - -}) - - - - - - -describe('DeleteUser as Admin', () => { - const deleteUserMutation = gql` - mutation($id: ID!, $resource: [Deletable]) { - DeleteUser(id: $id, resource: $resource) { - id - name - about - deleted - contributions { - id - content - contentExcerpt - deleted - comments { - id - content - contentExcerpt - deleted - } - } - comments { - id - content - contentExcerpt - deleted - } - } - } - ` - beforeEach(async () => { - variables = { id: ' u343', resource: [] } - - user = await Factory.build('user', { - name: 'My name should be deleted', - about: 'along with my about', - id: 'u343', - }) - - }) - - - - - describe('authenticated as Admin', () => { - beforeEach(async () => { - const admin = await Factory.build( - 'user', - { - role: 'admin', - }, - { - email: 'admin@example.org', - password: '1234', - }, - ) - authenticatedUser = await admin.toJson() - }) - - - describe('deleting a user account', () => { - beforeEach(() => { - variables = { ...variables, id: 'u343' } - }) - - describe('given posts and comments', () => { - beforeEach(async () => { - await Factory.build('category', { - id: 'cat9', - name: 'Democracy & Politics', - icon: 'university', - }) - await Factory.build( - 'post', - { - id: 'p139', - content: 'Post by user u343', - }, - { - author: user, - categoryIds, - }, - ) - await Factory.build( - 'comment', - { - id: 'c155', - content: 'Comment by user u343', - }, - { - author: user, - }, - ) - await Factory.build( - 'comment', - { - id: 'c156', - content: "A comment by someone else on user u343's post", - }, - { - postId: 'p139', - }, - ) - }) - - it("deletes account, but doesn't delete posts or comments by default", async () => { - const expectedResponse = { - data: { - DeleteUser: { - id: 'u343', - name: 'UNAVAILABLE', - about: 'UNAVAILABLE', - deleted: true, - contributions: [ - { - id: 'p139', - content: 'Post by user u343', - contentExcerpt: 'Post by user u343', - deleted: false, - comments: [ - { - id: 'c156', - content: "A comment by someone else on user u343's post", - contentExcerpt: "A comment by someone else on user u343's post", - deleted: false, - }, - ], - }, - ], - comments: [ - { - id: 'c155', - content: 'Comment by user u343', - contentExcerpt: 'Comment by user u343', - deleted: false, - }, - ], - }, - }, - errors: undefined, - } - await expect(mutate({ mutation: deleteUserMutation, variables })).resolves.toMatchObject( - expectedResponse, - ) - }) - - describe('deletion of all post requested', () => { - beforeEach(() => { - variables = { ...variables, resource: ['Post'] } - }) - - describe("marks user's posts as deleted", () => { - it('posts on request', async () => { - const expectedResponse = { - data: { - DeleteUser: { - id: 'u343', - name: 'UNAVAILABLE', - about: 'UNAVAILABLE', - deleted: true, - contributions: [ - { - id: 'p139', - content: 'UNAVAILABLE', - contentExcerpt: 'UNAVAILABLE', - deleted: true, - comments: [ - { - id: 'c156', - content: 'UNAVAILABLE', - contentExcerpt: 'UNAVAILABLE', - deleted: true, - }, - ], - }, - ], - comments: [ - { - id: 'c155', - content: 'Comment by user u343', - contentExcerpt: 'Comment by user u343', - deleted: false, - }, - ], - }, - }, - errors: undefined, - } - await expect( - mutate({ mutation: deleteUserMutation, variables }), - ).resolves.toMatchObject(expectedResponse) - }) - }) - }) - - describe('deletion of all comments requested', () => { - beforeEach(() => { - variables = { ...variables, resource: ['Comment'] } - }) - - it('marks comments as deleted', async () => { - const expectedResponse = { - data: { - DeleteUser: { - id: 'u343', - name: 'UNAVAILABLE', - about: 'UNAVAILABLE', - deleted: true, - contributions: [ - { - id: 'p139', - content: 'Post by user u343', - contentExcerpt: 'Post by user u343', - deleted: false, - comments: [ - { - id: 'c156', - content: "A comment by someone else on user u343's post", - contentExcerpt: "A comment by someone else on user u343's post", - deleted: false, - }, - ], - }, - ], - comments: [ - { - id: 'c155', - content: 'UNAVAILABLE', - contentExcerpt: 'UNAVAILABLE', - deleted: true, - }, - ], - }, - }, - errors: undefined, - } - await expect( - mutate({ mutation: deleteUserMutation, variables }), - ).resolves.toMatchObject(expectedResponse) - }) - }) - - describe('deletion of all post and comments requested', () => { - beforeEach(() => { - variables = { ...variables, resource: ['Post', 'Comment'] } - }) - - it('marks posts and comments as deleted', async () => { - const expectedResponse = { - data: { - DeleteUser: { - id: 'u343', - name: 'UNAVAILABLE', - about: 'UNAVAILABLE', - deleted: true, - contributions: [ - { - id: 'p139', - content: 'UNAVAILABLE', - contentExcerpt: 'UNAVAILABLE', - deleted: true, - comments: [ - { - id: 'c156', - content: 'UNAVAILABLE', - contentExcerpt: 'UNAVAILABLE', - deleted: true, - }, - ], - }, - ], - comments: [ - { - id: 'c155', - content: 'UNAVAILABLE', - contentExcerpt: 'UNAVAILABLE', - deleted: true, - }, - ], - }, - }, - errors: undefined, - } - await expect( - mutate({ mutation: deleteUserMutation, variables }), - ).resolves.toMatchObject(expectedResponse) - }) - }) - }) - - describe('connected `EmailAddress` nodes', () => { - it('will be removed completely', async () => { - await expect(neode.all('EmailAddress')).resolves.toHaveLength(2) - await mutate({ mutation: deleteUserMutation, variables }) - await expect(neode.all('EmailAddress')).resolves.toHaveLength(1) - }) - }) - - describe('connected `SocialMedia` nodes', () => { - beforeEach(async () => { - const socialMedia = await Factory.build('socialMedia') - await socialMedia.relateTo(user, 'ownedBy') - }) - - it('will be removed completely', async () => { - await expect(neode.all('SocialMedia')).resolves.toHaveLength(1) - await mutate({ mutation: deleteUserMutation, variables }) - await expect(neode.all('SocialMedia')).resolves.toHaveLength(0) - }) - }) - }) - }) -})