From 33134c1d4f4b77aca26624f0a7fc7d592ab84bc8 Mon Sep 17 00:00:00 2001 From: aonomike Date: Tue, 24 Sep 2019 23:36:52 +0300 Subject: [PATCH 1/4] Refactor shout spec - Test unauthorized user path --- backend/src/schema/resolvers/shout.spec.js | 156 ++++----------------- 1 file changed, 29 insertions(+), 127 deletions(-) diff --git a/backend/src/schema/resolvers/shout.spec.js b/backend/src/schema/resolvers/shout.spec.js index 718a1e169..8cf6c6982 100644 --- a/backend/src/schema/resolvers/shout.spec.js +++ b/backend/src/schema/resolvers/shout.spec.js @@ -1,13 +1,13 @@ -import { GraphQLClient } from 'graphql-request' +import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' -import { host, login, gql } from '../../jest/helpers' -import { neode } from '../../bootstrap/neo4j' +import { gql } from '../../jest/helpers' +import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import createServer from '../../server' -let clientUser1, clientUser2 -let headersUser1, headersUser2 +let mutate, query, authenticatedUser, variables const factory = Factory() -const instance = neode() -const categoryIds = ['cat9'] +const instance = getNeode() +const driver = getDriver() const mutationShoutPost = gql` mutation($id: ID!) { @@ -28,132 +28,34 @@ const createPostMutation = gql` } } ` -const createPostVariables = { - id: 'p1234', - title: 'Post Title 1234', - content: 'Some Post Content 1234', - categoryIds, -} -beforeEach(async () => { - await factory.create('User', { - id: 'u1', - email: 'test@example.org', - password: '1234', +describe('shout and unshout posts', () => { + beforeAll(() => { + authenticatedUser = undefined + const { server } = createServer({ + context: () => { + return { + driver, + neode: instance, + user: authenticatedUser, + } + }, + }) + mutate = createTestClient(server).mutate + query = createTestClient(server).query }) - await factory.create('User', { - id: 'u2', - email: 'test2@example.org', - password: '1234', - }) - await instance.create('Category', { - id: 'cat9', - name: 'Democracy & Politics', - icon: 'university', - }) - headersUser1 = await login({ email: 'test@example.org', password: '1234' }) - headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) - clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) - clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) - await clientUser1.request(createPostMutation, createPostVariables) - await clientUser2.request(createPostMutation, { - id: 'p12345', - title: 'Post Title 12345', - content: 'Some Post Content 12345', - categoryIds, + afterEach(() => { + factory.cleanDatabase() }) -}) -afterEach(async () => { - await factory.cleanDatabase() -}) - -describe('shout', () => { - describe('shout foreign post', () => { - describe('unauthenticated shout', () => { + describe('shout', () => { + describe('unauthenticated', () => { it('throws authorization error', async () => { - const client = new GraphQLClient(host) - await expect(client.request(mutationShoutPost, { id: 'p1234' })).rejects.toThrow( - 'Not Authorised', - ) + variables = { id: 'post-to-shout-id' } + await expect(mutate({ mutation: mutationShoutPost, variables })).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + }) }) }) - - it('I shout a post of another user', async () => { - const res = await clientUser1.request(mutationShoutPost, { id: 'p12345' }) - const expected = { - shout: true, - } - expect(res).toMatchObject(expected) - - const { Post } = await clientUser1.request(gql` - query { - Post(id: "p12345") { - shoutedByCurrentUser - } - } - `) - const expected2 = { - shoutedByCurrentUser: true, - } - expect(Post[0]).toMatchObject(expected2) - }) - - it('I can`t shout my own post', async () => { - const res = await clientUser1.request(mutationShoutPost, { id: 'p1234' }) - const expected = { - shout: false, - } - expect(res).toMatchObject(expected) - - const { Post } = await clientUser1.request(gql` - query { - Post(id: "p1234") { - shoutedByCurrentUser - } - } - `) - const expected2 = { - shoutedByCurrentUser: false, - } - expect(Post[0]).toMatchObject(expected2) - }) - }) - - describe('unshout foreign post', () => { - describe('unauthenticated shout', () => { - it('throws authorization error', async () => { - // shout - await clientUser1.request(mutationShoutPost, { id: 'p12345' }) - // unshout - const client = new GraphQLClient(host) - await expect(client.request(mutationUnshoutPost, { id: 'p12345' })).rejects.toThrow( - 'Not Authorised', - ) - }) - }) - - it('I unshout a post of another user', async () => { - // shout - await clientUser1.request(mutationShoutPost, { id: 'p12345' }) - const expected = { - unshout: true, - } - // unshout - const res = await clientUser1.request(mutationUnshoutPost, { id: 'p12345' }) - expect(res).toMatchObject(expected) - - const { Post } = await clientUser1.request(gql` - query { - Post(id: "p12345") { - shoutedByCurrentUser - } - } - `) - const expected2 = { - shoutedByCurrentUser: false, - } - expect(Post[0]).toMatchObject(expected2) - }) }) }) From 4488008a2c8974ccbc674c6295a083a4b68e6f99 Mon Sep 17 00:00:00 2001 From: aonomike Date: Wed, 25 Sep 2019 01:11:18 +0300 Subject: [PATCH 2/4] Test shouting other user's and current user's post --- backend/src/schema/resolvers/shout.spec.js | 177 ++++++++++++++++++++- 1 file changed, 172 insertions(+), 5 deletions(-) diff --git a/backend/src/schema/resolvers/shout.spec.js b/backend/src/schema/resolvers/shout.spec.js index 8cf6c6982..d38b1bef8 100644 --- a/backend/src/schema/resolvers/shout.spec.js +++ b/backend/src/schema/resolvers/shout.spec.js @@ -19,12 +19,13 @@ const mutationUnshoutPost = gql` unshout(id: $id, type: Post) } ` -const createPostMutation = gql` - mutation($id: ID, $title: String!, $content: String!, $categoryIds: [ID]!) { - CreatePost(id: $id, title: $title, content: $content, categoryIds: $categoryIds) { +const queryPost = gql` + query($id: ID!) { + Post(id: $id) { id - title - content + shoutedBy { + id + } } } ` @@ -57,5 +58,171 @@ describe('shout and unshout posts', () => { }) }) }) + describe('authenticated', () => { + let currentUser, postAuthor + beforeEach(async () => { + currentUser = await factory.create('User', { + id: 'current-user-id', + name: 'Current User', + email: 'current.user@example.org', + password: '1234', + }) + + postAuthor = await factory.create('User', { + id: 'post-author-id', + name: 'Post Author', + email: 'post.author@example.org', + password: '1234', + }) + authenticatedUser = await currentUser.toJson() + await factory.create('Post', { + name: 'Other user post', + id: 'other-user-post-id', + author: postAuthor, + }) + await factory.create('Post', { + name: 'current user post', + id: 'current-user-post-id', + author: currentUser, + }) + variables = {} + }) + + it('post of another user', async () => { + variables = { id: 'other-user-post-id' } + await expect(mutate({ mutation: mutationShoutPost, variables })).resolves.toMatchObject({ + data: { shout: true }, + }) + await expect(query({ query: queryPost, variables })).resolves.toMatchObject({ + data: { Post: [{ id: 'other-user-post-id', shoutedBy: [{ id: 'current-user-id' }] }] }, + errors: undefined, + }) + }) + + it('my own post', async () => { + variables = { id: 'current-user-post-id' } + await expect(mutate({ mutation: mutationShoutPost, variables })).resolves.toMatchObject({ + data: { shout: false }, + }) + await expect(query({ query: queryPost, variables })).resolves.toMatchObject({ + data: { Post: [{ id: 'current-user-post-id', shoutedBy: [] }] }, + errors: undefined, + }) + }) + }) }) }) + +// let clientUser1, clientUser2 +// let headersUser1, headersUser2 +// const factory = Factory() +// const instance = neode() +// const categoryIds = ['cat9'] + +// const mutationShoutPost = gql` +// mutation($id: ID!) { +// shout(id: $id, type: Post) +// } +// ` +// const mutationUnshoutPost = gql` +// mutation($id: ID!) { +// unshout(id: $id, type: Post) +// } +// ` +// const createPostMutation = gql` +// mutation($id: ID, $title: String!, $content: String!, $categoryIds: [ID]!) { +// CreatePost(id: $id, title: $title, content: $content, categoryIds: $categoryIds) { +// id +// title +// content +// } +// } +// ` +// const createPostVariables = { +// id: 'p1234', +// title: 'Post Title 1234', +// content: 'Some Post Content 1234', +// categoryIds, +// } +// beforeEach(async () => { +// await factory.create('User', { +// id: 'u1', +// email: 'test@example.org', +// password: '1234', +// }) +// await factory.create('User', { +// id: 'u2', +// email: 'test2@example.org', +// password: '1234', +// }) +// await instance.create('Category', { +// id: 'cat9', +// name: 'Democracy & Politics', +// icon: 'university', +// }) +// headersUser1 = await login({ email: 'test@example.org', password: '1234' }) +// headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) +// clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) +// clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) + +// await clientUser1.request(createPostMutation, createPostVariables) +// await clientUser2.request(createPostMutation, { +// id: 'p12345', +// title: 'Post Title 12345', +// content: 'Some Post Content 12345', +// categoryIds, +// }) +// }) + +// afterEach(async () => { +// await factory.cleanDatabase() +// }) + +// describe('shout', () => { +// describe('shout foreign post', () => { +// describe('unauthenticated shout', () => { +// it('throws authorization error', async () => { +// const client = new GraphQLClient(host) +// await expect(client.request(mutationShoutPost, { id: 'p1234' })).rejects.toThrow( +// 'Not Authorised', +// ) +// }) +// }) + +// describe('unshout foreign post', () => { +// describe('unauthenticated shout', () => { +// it('throws authorization error', async () => { +// // shout +// await clientUser1.request(mutationShoutPost, { id: 'p12345' }) +// // unshout +// const client = new GraphQLClient(host) +// await expect(client.request(mutationUnshoutPost, { id: 'p12345' })).rejects.toThrow( +// 'Not Authorised', +// ) +// }) +// }) + +// it('I unshout a post of another user', async () => { +// // shout +// await clientUser1.request(mutationShoutPost, { id: 'p12345' }) +// const expected = { +// unshout: true, +// } +// // unshout +// const res = await clientUser1.request(mutationUnshoutPost, { id: 'p12345' }) +// expect(res).toMatchObject(expected) + +// const { Post } = await clientUser1.request(gql` +// query { +// Post(id: "p12345") { +// shoutedByCurrentUser +// } +// } +// `) +// const expected2 = { +// shoutedByCurrentUser: false, +// } +// expect(Post[0]).toMatchObject(expected2) +// }) +// }) +// }) From 53aa87ea3cd01b79abfe298fcacc070054a35d15 Mon Sep 17 00:00:00 2001 From: aonomike Date: Wed, 25 Sep 2019 21:44:47 +0300 Subject: [PATCH 3/4] Test Unshouting of a post - Tests passing individually but test suites failing --- backend/src/schema/resolvers/shout.spec.js | 174 +++++++-------------- 1 file changed, 55 insertions(+), 119 deletions(-) diff --git a/backend/src/schema/resolvers/shout.spec.js b/backend/src/schema/resolvers/shout.spec.js index d38b1bef8..031cdbc49 100644 --- a/backend/src/schema/resolvers/shout.spec.js +++ b/backend/src/schema/resolvers/shout.spec.js @@ -3,6 +3,7 @@ import Factory from '../../seed/factories' import { gql } from '../../jest/helpers' import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' +import expectExport from 'expect' let mutate, query, authenticatedUser, variables const factory = Factory() @@ -30,6 +31,7 @@ const queryPost = gql` } ` describe('shout and unshout posts', () => { + let currentUser, postAuthor beforeAll(() => { authenticatedUser = undefined const { server } = createServer({ @@ -53,13 +55,13 @@ describe('shout and unshout posts', () => { describe('unauthenticated', () => { it('throws authorization error', async () => { variables = { id: 'post-to-shout-id' } + authenticatedUser = undefined await expect(mutate({ mutation: mutationShoutPost, variables })).resolves.toMatchObject({ errors: [{ message: 'Not Authorised!' }], }) }) }) describe('authenticated', () => { - let currentUser, postAuthor beforeEach(async () => { currentUser = await factory.create('User', { id: 'current-user-id', @@ -77,7 +79,7 @@ describe('shout and unshout posts', () => { authenticatedUser = await currentUser.toJson() await factory.create('Post', { name: 'Other user post', - id: 'other-user-post-id', + id: 'another-user-post-id', author: postAuthor, }) await factory.create('Post', { @@ -88,13 +90,13 @@ describe('shout and unshout posts', () => { variables = {} }) - it('post of another user', async () => { - variables = { id: 'other-user-post-id' } + it("another user's post", async () => { + variables = { id: 'another-user-post-id' } await expect(mutate({ mutation: mutationShoutPost, variables })).resolves.toMatchObject({ data: { shout: true }, }) await expect(query({ query: queryPost, variables })).resolves.toMatchObject({ - data: { Post: [{ id: 'other-user-post-id', shoutedBy: [{ id: 'current-user-id' }] }] }, + data: { Post: [{ id: 'another-user-post-id', shoutedBy: [{ id: 'current-user-id' }] }] }, errors: undefined, }) }) @@ -111,118 +113,52 @@ describe('shout and unshout posts', () => { }) }) }) + describe('unshout', () => { + describe('unauthenticated', () => { + it('throws authorization error', async () => { + authenticatedUser = undefined + variables = { id: 'post-to-shout-id' } + await expect(mutate({ mutation: mutationUnshoutPost, variables })).resolves.toMatchObject({ + errors: [{ message: 'Not Authorised!' }], + }) + }) + }) + + describe('authenticated', () => { + beforeEach(async () => { + currentUser = await factory.create('User', { + id: 'current-user-id', + name: 'Current User', + email: 'current.user@example.org', + password: '1234', + }) + + postAuthor = await factory.create('User', { + id: 'post-author-id', + name: 'Post Author', + email: 'post.author@example.org', + password: '1234', + }) + authenticatedUser = await currentUser.toJson() + await factory.create('Post', { + name: 'Other user post', + id: 'another-user-post-id', + author: postAuthor, + }) + variables = {} + await mutate({ mutation: mutationShoutPost, variables: { id: 'another-user-post-id' } }) + }) + + it("another user's post", async () => { + variables = { id: 'another-user-post-id' } + await expect(mutate({ mutation: mutationUnshoutPost, variables })).resolves.toMatchObject({ + data: { unshout: true }, + }) + await expect(query({ query: queryPost, variables })).resolves.toMatchObject({ + data: { Post: [{ id: 'another-user-post-id', shoutedBy: [] }] }, + errors: undefined, + }) + }) + }) + }) }) - -// let clientUser1, clientUser2 -// let headersUser1, headersUser2 -// const factory = Factory() -// const instance = neode() -// const categoryIds = ['cat9'] - -// const mutationShoutPost = gql` -// mutation($id: ID!) { -// shout(id: $id, type: Post) -// } -// ` -// const mutationUnshoutPost = gql` -// mutation($id: ID!) { -// unshout(id: $id, type: Post) -// } -// ` -// const createPostMutation = gql` -// mutation($id: ID, $title: String!, $content: String!, $categoryIds: [ID]!) { -// CreatePost(id: $id, title: $title, content: $content, categoryIds: $categoryIds) { -// id -// title -// content -// } -// } -// ` -// const createPostVariables = { -// id: 'p1234', -// title: 'Post Title 1234', -// content: 'Some Post Content 1234', -// categoryIds, -// } -// beforeEach(async () => { -// await factory.create('User', { -// id: 'u1', -// email: 'test@example.org', -// password: '1234', -// }) -// await factory.create('User', { -// id: 'u2', -// email: 'test2@example.org', -// password: '1234', -// }) -// await instance.create('Category', { -// id: 'cat9', -// name: 'Democracy & Politics', -// icon: 'university', -// }) -// headersUser1 = await login({ email: 'test@example.org', password: '1234' }) -// headersUser2 = await login({ email: 'test2@example.org', password: '1234' }) -// clientUser1 = new GraphQLClient(host, { headers: headersUser1 }) -// clientUser2 = new GraphQLClient(host, { headers: headersUser2 }) - -// await clientUser1.request(createPostMutation, createPostVariables) -// await clientUser2.request(createPostMutation, { -// id: 'p12345', -// title: 'Post Title 12345', -// content: 'Some Post Content 12345', -// categoryIds, -// }) -// }) - -// afterEach(async () => { -// await factory.cleanDatabase() -// }) - -// describe('shout', () => { -// describe('shout foreign post', () => { -// describe('unauthenticated shout', () => { -// it('throws authorization error', async () => { -// const client = new GraphQLClient(host) -// await expect(client.request(mutationShoutPost, { id: 'p1234' })).rejects.toThrow( -// 'Not Authorised', -// ) -// }) -// }) - -// describe('unshout foreign post', () => { -// describe('unauthenticated shout', () => { -// it('throws authorization error', async () => { -// // shout -// await clientUser1.request(mutationShoutPost, { id: 'p12345' }) -// // unshout -// const client = new GraphQLClient(host) -// await expect(client.request(mutationUnshoutPost, { id: 'p12345' })).rejects.toThrow( -// 'Not Authorised', -// ) -// }) -// }) - -// it('I unshout a post of another user', async () => { -// // shout -// await clientUser1.request(mutationShoutPost, { id: 'p12345' }) -// const expected = { -// unshout: true, -// } -// // unshout -// const res = await clientUser1.request(mutationUnshoutPost, { id: 'p12345' }) -// expect(res).toMatchObject(expected) - -// const { Post } = await clientUser1.request(gql` -// query { -// Post(id: "p12345") { -// shoutedByCurrentUser -// } -// } -// `) -// const expected2 = { -// shoutedByCurrentUser: false, -// } -// expect(Post[0]).toMatchObject(expected2) -// }) -// }) -// }) From c427cb2b97f07e623ba96c51f8fddd1c1f941821 Mon Sep 17 00:00:00 2001 From: aonomike Date: Sat, 28 Sep 2019 00:31:08 +0300 Subject: [PATCH 4/4] refactor the naming of variables --- backend/src/schema/resolvers/shout.spec.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/backend/src/schema/resolvers/shout.spec.js b/backend/src/schema/resolvers/shout.spec.js index 031cdbc49..e39ac2e24 100644 --- a/backend/src/schema/resolvers/shout.spec.js +++ b/backend/src/schema/resolvers/shout.spec.js @@ -3,7 +3,6 @@ import Factory from '../../seed/factories' import { gql } from '../../jest/helpers' import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' -import expectExport from 'expect' let mutate, query, authenticatedUser, variables const factory = Factory() @@ -30,6 +29,7 @@ const queryPost = gql` } } ` + describe('shout and unshout posts', () => { let currentUser, postAuthor beforeAll(() => { @@ -46,7 +46,6 @@ describe('shout and unshout posts', () => { mutate = createTestClient(server).mutate query = createTestClient(server).query }) - afterEach(() => { factory.cleanDatabase() }) @@ -134,28 +133,31 @@ describe('shout and unshout posts', () => { }) postAuthor = await factory.create('User', { - id: 'post-author-id', - name: 'Post Author', - email: 'post.author@example.org', + id: 'id-of-another-user', + name: 'Another User', + email: 'another.user@example.org', password: '1234', }) authenticatedUser = await currentUser.toJson() await factory.create('Post', { - name: 'Other user post', - id: 'another-user-post-id', + name: 'Posted By Another User', + id: 'posted-by-another-user', author: postAuthor, }) + await mutate({ + mutation: mutationShoutPost, + variables: { id: 'posted-by-another-user' }, + }) variables = {} - await mutate({ mutation: mutationShoutPost, variables: { id: 'another-user-post-id' } }) }) it("another user's post", async () => { - variables = { id: 'another-user-post-id' } + variables = { id: 'posted-by-another-user' } await expect(mutate({ mutation: mutationUnshoutPost, variables })).resolves.toMatchObject({ data: { unshout: true }, }) await expect(query({ query: queryPost, variables })).resolves.toMatchObject({ - data: { Post: [{ id: 'another-user-post-id', shoutedBy: [] }] }, + data: { Post: [{ id: 'posted-by-another-user', shoutedBy: [] }] }, errors: undefined, }) })