From 9262fbb44ffa53e3d89c0ecab8a8e625b015a7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 8 Jan 2019 14:57:13 +0100 Subject: [PATCH 01/18] Start a test server only once. This keeps our tests small. It is quite a headache though, because of an issue with jest and with transpiling. For reasons that I don't understand running `yarn run test:jest` sometimes complains about open handles. I would love to hear how to make our build more reliable. --- README.md | 9 +++++ package.json | 6 ++-- ...-schema.test.js => graphql-schema.spec.js} | 17 +--------- src/jest/globalSetup.js | 1 + src/jest/globalTeardown.js | 1 + src/jest/hooks.js | 16 +++++++++ src/middleware/permissionsMiddleware.spec.js | 33 +++++++++++++++++++ src/middleware/permissionsMiddleware.test.js | 15 --------- 8 files changed, 65 insertions(+), 33 deletions(-) rename src/{graphql-schema.test.js => graphql-schema.spec.js} (85%) create mode 100644 src/jest/globalSetup.js create mode 100644 src/jest/globalTeardown.js create mode 100644 src/jest/hooks.js create mode 100644 src/middleware/permissionsMiddleware.spec.js delete mode 100644 src/middleware/permissionsMiddleware.test.js diff --git a/README.md b/README.md index da8758334..eb814d1f0 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,15 @@ npm run db:reset **Beware**: We have no multiple database setup at the moment. We clean the database after each test, running the tests will wipe out all your data! +First build `server.js`: +```bash +yarn run build +# -or- +npm run build +``` +The additional build step will become obsolete, as soon as [jest transforms global setup teardown modules](https://github.com/facebook/jest/issues/5164). + +Now run the tests: ```bash yarn run test # -or- diff --git a/package.json b/package.json index 9d83da85b..0b624efee 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", - "test:cmd:jest": "jest --forceExit", + "test:cmd:jest": "jest --forceExit --detectOpenHandles", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", @@ -25,7 +25,9 @@ "license": "MIT", "jest": { "verbose": true, - "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ] + "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ], + "globalSetup": "/src/jest/globalSetup", + "globalTeardown": "/src/jest/globalTeardown" }, "dependencies": { "apollo-cache-inmemory": "~1.3.11", diff --git a/src/graphql-schema.test.js b/src/graphql-schema.spec.js similarity index 85% rename from src/graphql-schema.test.js rename to src/graphql-schema.spec.js index a58fb3599..a9ea1108a 100644 --- a/src/graphql-schema.test.js +++ b/src/graphql-schema.spec.js @@ -1,23 +1,8 @@ import { request } from 'graphql-request' -import createServer from './server' -import mocks from './mocks' import { create, cleanDatabase } from './seed/factories' import jwt from 'jsonwebtoken' -let getHost -let app -let port - -beforeEach(async () => { - const server = createServer({ mocks }) - app = await server.start({ port: 0 }) - port = app.address().port - getHost = () => `http://127.0.0.1:${port}` -}) - -afterEach(async () => { - await app.close() -}) +let getHost = () => 'http://127.0.0.1:3123' describe('login', () => { const mutation = (params) => { diff --git a/src/jest/globalSetup.js b/src/jest/globalSetup.js new file mode 100644 index 000000000..e2bfa24a5 --- /dev/null +++ b/src/jest/globalSetup.js @@ -0,0 +1 @@ +module.exports = require('./hooks').setup diff --git a/src/jest/globalTeardown.js b/src/jest/globalTeardown.js new file mode 100644 index 000000000..944503234 --- /dev/null +++ b/src/jest/globalTeardown.js @@ -0,0 +1 @@ +module.exports = require('./hooks').teardown diff --git a/src/jest/hooks.js b/src/jest/hooks.js new file mode 100644 index 000000000..d5bcf2f2e --- /dev/null +++ b/src/jest/hooks.js @@ -0,0 +1,16 @@ +const createServer = require('../../dist/server.js').default +let app + +const setup = async function () { + const server = createServer() + app = await server.start({ port: 3123 }) +} + +const teardown = async function () { + await app.close() +} + +module.exports = { + setup, + teardown +} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js new file mode 100644 index 000000000..fb612bb91 --- /dev/null +++ b/src/middleware/permissionsMiddleware.spec.js @@ -0,0 +1,33 @@ +import { request } from 'graphql-request' +import createServer from '../server' +import mocks from '../mocks' +import { create, cleanDatabase } from '../seed/factories' +import generateJwt from '../jwt/generateToken' + +describe('authorization', () => { + describe('given an existing user', () => { + + describe('logged in', () => { + let jwt + beforeEach(() => { + // jwt = generateJwt(user) + }) + + describe('query own user profile', () => { + const mutation = (params) => { + const { email, password } = params + return `{ + User(email: "${email}") { + name + } + }` + } + + it('returns the owner\'s email address', async () => { + // const data = await request(getHost(), mutation({ email: 'test@example.org' })) + console.log('it runs') + }) + }) + }) + }) +}) diff --git a/src/middleware/permissionsMiddleware.test.js b/src/middleware/permissionsMiddleware.test.js deleted file mode 100644 index 3cf808e39..000000000 --- a/src/middleware/permissionsMiddleware.test.js +++ /dev/null @@ -1,15 +0,0 @@ -describe('query', () => { - describe('statistics', () => { - describe('authenticated user', () => { - describe('read', () => { - xit('is forbidden', () => {}) - }) - }) - - describe('admin', () => { - describe('read', () => { - xit('is permitted', () => {}) - }) - }) - }) -}) From 0893d3740e77f5fe1aa7dbfd06437d94e2347e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Wed, 9 Jan 2019 18:56:57 +0100 Subject: [PATCH 02/18] Try to expose bug #106 It does not work as we have PERMISSIONS=disabled also in the server we're trying to test. --- src/graphql-schema.spec.js | 9 ++-- src/jest/helpers.js | 15 ++++++ src/middleware/permissionsMiddleware.spec.js | 49 ++++++++++++++------ src/seed/factories/index.js | 8 ++-- 4 files changed, 57 insertions(+), 24 deletions(-) create mode 100644 src/jest/helpers.js diff --git a/src/graphql-schema.spec.js b/src/graphql-schema.spec.js index a9ea1108a..69073444c 100644 --- a/src/graphql-schema.spec.js +++ b/src/graphql-schema.spec.js @@ -1,8 +1,7 @@ import { request } from 'graphql-request' import { create, cleanDatabase } from './seed/factories' import jwt from 'jsonwebtoken' - -let getHost = () => 'http://127.0.0.1:3123' +import { host } from './jest/helpers' describe('login', () => { const mutation = (params) => { @@ -30,7 +29,7 @@ describe('login', () => { describe('asking for a `token`', () => { describe('with valid email/password combination', () => { it('responds with a JWT token', async () => { - const data = await request(getHost(), mutation({ email: 'test@example.org', password: '1234' })) + const data = await request(host, mutation({ email: 'test@example.org', password: '1234' })) const { token } = data.login jwt.verify(token, process.env.JWT_SECRET, (err, data) => { expect(data.email).toEqual('test@example.org') @@ -42,7 +41,7 @@ describe('login', () => { describe('with a valid email but incorrect password', () => { it('responds with "Incorrect email address or password."', async () => { try { - await request(getHost(), mutation({ email: 'test@example.org', password: 'wrong' })) + await request(host, mutation({ email: 'test@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } @@ -52,7 +51,7 @@ describe('login', () => { describe('with a non-existing email', () => { it('responds with "Incorrect email address or password."', async () => { try { - await request(getHost(), mutation({ email: 'non-existent@example.org', password: 'wrong' })) + await request(host, mutation({ email: 'non-existent@example.org', password: 'wrong' })) } catch (error) { expect(error.response.errors[0].message).toEqual('Incorrect email address or password.') } diff --git a/src/jest/helpers.js b/src/jest/helpers.js new file mode 100644 index 000000000..f687305ea --- /dev/null +++ b/src/jest/helpers.js @@ -0,0 +1,15 @@ +import { request } from 'graphql-request' + +export const host = 'http://127.0.0.1:3123' + +export async function login ({ email, password }) { + const mutation = ` + mutation { + login(email:"${email}", password:"${password}"){ + token + } + }` + const data = await request(host, mutation) + const { token } = data.login + return token +} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index fb612bb91..9da3a3e9d 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,31 +1,50 @@ -import { request } from 'graphql-request' -import createServer from '../server' -import mocks from '../mocks' +import { GraphQLClient } from 'graphql-request' import { create, cleanDatabase } from '../seed/factories' -import generateJwt from '../jwt/generateToken' +import { host, login } from '../jest/helpers' describe('authorization', () => { - describe('given an existing user', () => { + describe('given two existing users', () => { + beforeEach(async () => { + await create('user', { + email: 'test@example.org', + password: '1234' + }) + await create('user', { + email: 'someone@example.org', + password: 'hello' + }) + }) + + afterEach(async () => { + await cleanDatabase() + }) describe('logged in', () => { - let jwt - beforeEach(() => { - // jwt = generateJwt(user) + let jwt, graphQLClient + + beforeEach(async () => { + jwt = await login({ email: 'test@example.org', password: '1234' }) + graphQLClient = new GraphQLClient(host, { + headers: { + authorization: `Bearer ${jwt}` + } + }) }) - describe('query own user profile', () => { - const mutation = (params) => { - const { email, password } = params + describe('query email', () => { + const query = (params) => { + const { email } = params return `{ User(email: "${email}") { - name + email } }` } - it('returns the owner\'s email address', async () => { - // const data = await request(getHost(), mutation({ email: 'test@example.org' })) - console.log('it runs') + it('exposes the owner\'s email address', async () => { + const data = await graphQLClient.request(query({ email: 'test@example.org' })) + console.log(process.env) + expect(data).toEqual({ User: [ { email: 'test@example.org' } ] }) }) }) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index d665de4a0..69b0b15fd 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -29,12 +29,12 @@ const buildMutation = (model, parameters) => { return builders[model](parameters) } -const create = async (model, parameters) => { - await client.mutate({ mutation: gql(buildMutation(model, parameters)) }) +const create = (model, parameters) => { + return client.mutate({ mutation: gql(buildMutation(model, parameters)) }) } -const cleanDatabase = async () => { - await query('MATCH (n) DETACH DELETE n', session) +const cleanDatabase = () => { + return query('MATCH (n) DETACH DELETE n', session) } export { From 6bbc76911acd340c4ac05f17d7d63db8cdc652b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 16:07:52 +0100 Subject: [PATCH 03/18] Refactor test cases --- src/jest/helpers.js | 18 +++++++++++++++--- src/middleware/permissionsMiddleware.spec.js | 13 +++---------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/jest/helpers.js b/src/jest/helpers.js index f687305ea..28aed9f98 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,15 +1,27 @@ import { request } from 'graphql-request' +import { GraphQLClient } from 'graphql-request' export const host = 'http://127.0.0.1:3123' -export async function login ({ email, password }) { +export async function getJWT({ email, password }) { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ token } }` - const data = await request(host, mutation) - const { token } = data.login + const response = await request(host, mutation) + const { token } = response.login + if(!token) throw `Could not get a JWT token from the backend:\n${response}` return token } + +export async function authenticatedGraphQLClient(params){ + const jwt = await getJWT(params) + const options = { + headers: { + 'Authorization': `Bearer ${jwt}` + } + } + return new GraphQLClient(host, options) +} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 9da3a3e9d..e88362a34 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,6 +1,5 @@ -import { GraphQLClient } from 'graphql-request' import { create, cleanDatabase } from '../seed/factories' -import { host, login } from '../jest/helpers' +import { authenticatedGraphQLClient } from '../jest/helpers' describe('authorization', () => { describe('given two existing users', () => { @@ -20,15 +19,10 @@ describe('authorization', () => { }) describe('logged in', () => { - let jwt, graphQLClient + let graphQLClient beforeEach(async () => { - jwt = await login({ email: 'test@example.org', password: '1234' }) - graphQLClient = new GraphQLClient(host, { - headers: { - authorization: `Bearer ${jwt}` - } - }) + graphQLClient = await authenticatedGraphQLClient({ email: 'test@example.org', password: '1234' }) }) describe('query email', () => { @@ -43,7 +37,6 @@ describe('authorization', () => { it('exposes the owner\'s email address', async () => { const data = await graphQLClient.request(query({ email: 'test@example.org' })) - console.log(process.env) expect(data).toEqual({ User: [ { email: 'test@example.org' } ] }) }) }) From d0b975e78280c8d3732dfafe8d1091589360f9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 20:53:07 +0100 Subject: [PATCH 04/18] Getting strange non-deterministic errors --- package.json | 4 ++- src/jest/helpers.js | 33 +++++++++++++------- src/middleware/permissionsMiddleware.spec.js | 28 +++++++++-------- src/seed/factories/index.js | 13 ++++++-- yarn.lock | 2 +- 5 files changed, 51 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 1fa42cb49..dc1ffd822 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,9 @@ "license": "MIT", "jest": { "verbose": true, - "testMatch": ["**/src/**/?(*.)+(spec|test).js?(x)" ], + "testMatch": [ + "**/src/**/?(*.)+(spec|test).js?(x)" + ], "globalSetup": "/src/jest/globalSetup", "globalTeardown": "/src/jest/globalTeardown" }, diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 28aed9f98..06cfc0e0b 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,9 +1,9 @@ import { request } from 'graphql-request' -import { GraphQLClient } from 'graphql-request' +import fetch from 'node-fetch' export const host = 'http://127.0.0.1:3123' -export async function getJWT({ email, password }) { +export async function authenticatedHeaders ({ email, password }) { const mutation = ` mutation { login(email:"${email}", password:"${password}"){ @@ -12,16 +12,27 @@ export async function getJWT({ email, password }) { }` const response = await request(host, mutation) const { token } = response.login - if(!token) throw `Could not get a JWT token from the backend:\n${response}` - return token + if (!token) throw new Error(`Could not get a JWT token from the backend:\n${response}`) + return { + authorization: `Bearer ${token}` + } } -export async function authenticatedGraphQLClient(params){ - const jwt = await getJWT(params) - const options = { - headers: { - 'Authorization': `Bearer ${jwt}` - } +export async function queryServer ({ headers, query, variables }) { + const defaultHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json' } - return new GraphQLClient(host, options) + const response = await fetch(host, { + method: 'POST', + authenticatedHeaders, + headers: Object.assign({}, defaultHeaders, headers), + body: JSON.stringify({ + operationName: null, + query, + variables + }) + }) + const json = await response.json() + return json.data } diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index e88362a34..88f095d8c 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,5 @@ import { create, cleanDatabase } from '../seed/factories' -import { authenticatedGraphQLClient } from '../jest/helpers' +import { authenticatedHeaders, queryServer } from '../jest/helpers' describe('authorization', () => { describe('given two existing users', () => { @@ -19,25 +19,27 @@ describe('authorization', () => { }) describe('logged in', () => { - let graphQLClient + let headers = {} beforeEach(async () => { - graphQLClient = await authenticatedGraphQLClient({ email: 'test@example.org', password: '1234' }) + // headers = authenticatedHeaders({ + // email: 'test@example.org', + // password: '1234' + // }) }) - describe('query email', () => { - const query = (params) => { - const { email } = params - return `{ - User(email: "${email}") { + describe('query email', async () => { + it('exposes the owner\'s email address', async () => { + const options = { + headers, + query: `{ + User(email: "test@example.org") { email } }` - } - - it('exposes the owner\'s email address', async () => { - const data = await graphQLClient.request(query({ email: 'test@example.org' })) - expect(data).toEqual({ User: [ { email: 'test@example.org' } ] }) + } + const json = await queryServer(options) + expect(json).toEqual({ User: [ { email: 'test@example.org' } ] }) }) }) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 69b0b15fd..93985407f 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -4,7 +4,6 @@ import dotenv from 'dotenv' import { HttpLink } from 'apollo-link-http' import { InMemoryCache } from 'apollo-cache-inmemory' import neo4j from '../../bootstrap/neo4j' -import { query } from '../../graphql-schema' import fetch from 'node-fetch' dotenv.config() @@ -19,7 +18,6 @@ const client = new ApolloClient({ }) const driver = neo4j().getDriver() -const session = driver.session() const builders = { 'user': require('./users.js').default @@ -34,7 +32,16 @@ const create = (model, parameters) => { } const cleanDatabase = () => { - return query('MATCH (n) DETACH DELETE n', session) + const session = driver.session() + const cypher = 'MATCH (n) DETACH DELETE n' + return session + .run(cypher) + .then(function (result) { + session.close() + }) + .catch(function (error) { + console.log(error) + }) } export { diff --git a/yarn.lock b/yarn.lock index caf47bcca..58532f857 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5420,7 +5420,7 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@~2.3.0: +node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== From 70b20302fefabad461415d3fa5ad69d29ea13caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 23:00:21 +0100 Subject: [PATCH 05/18] Probably exposed #106 --- src/middleware/permissionsMiddleware.spec.js | 57 ++++++++++++-------- src/seed/factories/index.js | 17 +++--- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 88f095d8c..3ea3f9e55 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -5,12 +5,12 @@ describe('authorization', () => { describe('given two existing users', () => { beforeEach(async () => { await create('user', { - email: 'test@example.org', - password: '1234' + email: 'owner@example.org', + password: 'iamtheowner' }) await create('user', { email: 'someone@example.org', - password: 'hello' + password: 'else' }) }) @@ -18,28 +18,43 @@ describe('authorization', () => { await cleanDatabase() }) - describe('logged in', () => { + describe('access email address', () => { let headers = {} - - beforeEach(async () => { - // headers = authenticatedHeaders({ - // email: 'test@example.org', - // password: '1234' - // }) - }) - - describe('query email', async () => { - it('exposes the owner\'s email address', async () => { - const options = { - headers, - query: `{ - User(email: "test@example.org") { + const action = async (headers) => { + const options = { + headers, + query: `{ + User(email: "owner@example.org") { email } }` - } - const json = await queryServer(options) - expect(json).toEqual({ User: [ { email: 'test@example.org' } ] }) + } + return await queryServer(options) + } + + describe('not logged in', async () => { + it('does not expose the owner\'s email address', async () => { + expect(await action(headers)).toEqual({ User: [ { email: null } ] }) + }) + }) + + describe('as owner', () => { + it('exposes the owner\'s email address', async () => { + headers = await authenticatedHeaders({ + email: 'owner@example.org', + password: 'iamtheowner' + }) + expect(await action(headers)).toEqual({ User: [ { email: 'owner@example.org' } ] }) + }) + }) + + describe('as someone else', () => { + it('does not expose the owner\'s email address', async () => { + headers = await authenticatedHeaders({ + email: 'someone@example.org', + password: 'else' + }) + expect(await action(headers)).toEqual({ User: [ { email: null } ] }) }) }) }) diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 93985407f..89a462531 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -31,17 +31,16 @@ const create = (model, parameters) => { return client.mutate({ mutation: gql(buildMutation(model, parameters)) }) } -const cleanDatabase = () => { +const cleanDatabase = async () => { const session = driver.session() const cypher = 'MATCH (n) DETACH DELETE n' - return session - .run(cypher) - .then(function (result) { - session.close() - }) - .catch(function (error) { - console.log(error) - }) + try { + const result = await session.run(cypher) + session.close() + return result + } catch (error) { + console.log(error) + } } export { From 6f487e2687a1c17df07c43249bb170eb337d4f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 23:22:12 +0100 Subject: [PATCH 06/18] Fix non-deterministic erros in testing Without the `--runInBand` flag, jest will create a worker pool of child processes and run the tests withing. No surprise, why the tests were running completely non-deterministically! If we clear the database in the middle of the tests we will end up with no records, or if we run the factories in several tests we end up with many duplicate records. FYI: @mattwr18 @appinteractive @tansaku @Kachulio1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc1ffd822..5b024eace 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", - "test:cmd:jest": "jest --forceExit --detectOpenHandles", + "test:cmd:jest": "jest --forceExit --detectOpenHandles --runInBand", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", From 9d541d8f27e1e070b9ca0fa68b1d442836295410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 14 Jan 2019 23:31:00 +0100 Subject: [PATCH 07/18] Clean up helper.js --- src/jest/helpers.js | 23 +------------------- src/middleware/permissionsMiddleware.spec.js | 18 +++++++-------- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 06cfc0e0b..cd66a9d04 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -11,28 +11,7 @@ export async function authenticatedHeaders ({ email, password }) { } }` const response = await request(host, mutation) - const { token } = response.login - if (!token) throw new Error(`Could not get a JWT token from the backend:\n${response}`) return { - authorization: `Bearer ${token}` + authorization: `Bearer ${response.login.token}` } } - -export async function queryServer ({ headers, query, variables }) { - const defaultHeaders = { - Accept: 'application/json', - 'Content-Type': 'application/json' - } - const response = await fetch(host, { - method: 'POST', - authenticatedHeaders, - headers: Object.assign({}, defaultHeaders, headers), - body: JSON.stringify({ - operationName: null, - query, - variables - }) - }) - const json = await response.json() - return json.data -} diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 3ea3f9e55..50f6ebadd 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,6 @@ import { create, cleanDatabase } from '../seed/factories' -import { authenticatedHeaders, queryServer } from '../jest/helpers' +import { host, authenticatedHeaders, queryServer } from '../jest/helpers' +import { GraphQLClient } from 'graphql-request' describe('authorization', () => { describe('given two existing users', () => { @@ -21,15 +22,12 @@ describe('authorization', () => { describe('access email address', () => { let headers = {} const action = async (headers) => { - const options = { - headers, - query: `{ - User(email: "owner@example.org") { - email - } - }` - } - return await queryServer(options) + const graphQLClient = new GraphQLClient(host, { headers }) + return await graphQLClient.request(`{ + User(email: "owner@example.org") { + email + } + }`) } describe('not logged in', async () => { From b2d1685b06c750c23f4435c9166b14b4284f4dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Tue, 15 Jan 2019 00:39:06 +0100 Subject: [PATCH 08/18] WIP: Integrate permissionless app into setup hooks --- package.json | 3 +-- src/jest/helpers.js | 2 +- src/jest/hooks.js | 7 ++++++- src/seed/factories/index.js | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5b024eace..a3a75a60f 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,7 @@ "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", - "test:jest": "$npm_package_config_no_auth run-p --race start test:cmd:jest", - "test:cmd:jest": "jest --forceExit --detectOpenHandles --runInBand", + "test:jest": "cross-env PERMISSIONS=disabled jest --forceExit --detectOpenHandles --runInBand", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", diff --git a/src/jest/helpers.js b/src/jest/helpers.js index cd66a9d04..0e66c7595 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,7 +1,7 @@ import { request } from 'graphql-request' import fetch from 'node-fetch' -export const host = 'http://127.0.0.1:3123' +export const host = 'http://127.0.0.1:4123' export async function authenticatedHeaders ({ email, password }) { const mutation = ` diff --git a/src/jest/hooks.js b/src/jest/hooks.js index d5bcf2f2e..1d285961a 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -1,13 +1,18 @@ const createServer = require('../../dist/server.js').default let app +let permissionlessApp const setup = async function () { const server = createServer() - app = await server.start({ port: 3123 }) + app = await server.start({ port: 4123 }) + + const permissionless = createServer() + permissionlessApp = await server.start({ port: 4001 }) } const teardown = async function () { await app.close() + await permissionlessApp.close() } module.exports = { diff --git a/src/seed/factories/index.js b/src/seed/factories/index.js index 89a462531..e62e98869 100644 --- a/src/seed/factories/index.js +++ b/src/seed/factories/index.js @@ -13,7 +13,7 @@ if (process.env.NODE_ENV === 'production') { } const client = new ApolloClient({ - link: new HttpLink({ uri: process.env.GRAPHQL_URI, fetch }), + link: new HttpLink({ uri: 'http://localhost:4001', fetch }), cache: new InMemoryCache() }) From 9e4edca35b2da0b3a0419e6df9e5c9ec6bc36b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 15:09:31 +0100 Subject: [PATCH 09/18] Use node `spawn` to spin off several servers --- package.json | 3 +- src/jest/helpers.js | 1 - src/jest/hooks.js | 36 +++++++++++++++----- src/middleware/permissionsMiddleware.spec.js | 4 +-- yarn.lock | 2 +- 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index a3a75a60f..2824aab37 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", - "test:jest": "cross-env PERMISSIONS=disabled jest --forceExit --detectOpenHandles --runInBand", + "test:jest": "jest --forceExit --detectOpenHandles --runInBand", + "test:jest:debug": "node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", diff --git a/src/jest/helpers.js b/src/jest/helpers.js index 0e66c7595..01a26e9d3 100644 --- a/src/jest/helpers.js +++ b/src/jest/helpers.js @@ -1,5 +1,4 @@ import { request } from 'graphql-request' -import fetch from 'node-fetch' export const host = 'http://127.0.0.1:4123' diff --git a/src/jest/hooks.js b/src/jest/hooks.js index 1d285961a..80f0de8eb 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -1,18 +1,36 @@ -const createServer = require('../../dist/server.js').default -let app -let permissionlessApp +const { spawn } = require('child_process') +const waitOn = require('wait-on') + +let server +let seeder const setup = async function () { - const server = createServer() - app = await server.start({ port: 4123 }) + server = spawn('node', ['dist/'], { + env: Object.assign({}, process.env, { + GRAPHQL_URI: 'http://localhost:4123', + GRAPHQL_PORT: '4123' + }) + }) - const permissionless = createServer() - permissionlessApp = await server.start({ port: 4001 }) + seeder = spawn('node', ['dist/'], { + env: Object.assign({}, process.env, { + GRAPHQL_URI: 'http://localhost:4001', + GRAPHQL_PORT: '4001', + PERMISSIONS: 'disabled' + }) + }) + + try { + await waitOn({ + resources: ['http://localhost:4123', 'http://localhost:4001'] + }) + } catch (err) { + console.log(err) + } } const teardown = async function () { - await app.close() - await permissionlessApp.close() + [server, seeder].forEach(app => app.kill()) } module.exports = { diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 50f6ebadd..7896f0348 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -1,5 +1,5 @@ import { create, cleanDatabase } from '../seed/factories' -import { host, authenticatedHeaders, queryServer } from '../jest/helpers' +import { host, authenticatedHeaders } from '../jest/helpers' import { GraphQLClient } from 'graphql-request' describe('authorization', () => { @@ -23,7 +23,7 @@ describe('authorization', () => { let headers = {} const action = async (headers) => { const graphQLClient = new GraphQLClient(host, { headers }) - return await graphQLClient.request(`{ + return graphQLClient.request(`{ User(email: "owner@example.org") { email } diff --git a/yarn.lock b/yarn.lock index 58532f857..caf47bcca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5420,7 +5420,7 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@^2.3.0: +node-fetch@^2.1.2, node-fetch@^2.2.0, node-fetch@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== From d50015af3ca032924bf45740acab054f3a9c287c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 15:23:24 +0100 Subject: [PATCH 10/18] Replace node with babel-node This should ensure that you don't have to reubild the server all the time --- README.md | 10 +--------- dist/.gitkeep | 0 src/jest/hooks.js | 4 ++-- 3 files changed, 3 insertions(+), 11 deletions(-) delete mode 100644 dist/.gitkeep diff --git a/README.md b/README.md index eb814d1f0..1b12562d2 100644 --- a/README.md +++ b/README.md @@ -137,15 +137,7 @@ npm run db:reset **Beware**: We have no multiple database setup at the moment. We clean the database after each test, running the tests will wipe out all your data! -First build `server.js`: -```bash -yarn run build -# -or- -npm run build -``` -The additional build step will become obsolete, as soon as [jest transforms global setup teardown modules](https://github.com/facebook/jest/issues/5164). - -Now run the tests: +Run the tests: ```bash yarn run test # -or- diff --git a/dist/.gitkeep b/dist/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/jest/hooks.js b/src/jest/hooks.js index 80f0de8eb..15daccbdf 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -5,14 +5,14 @@ let server let seeder const setup = async function () { - server = spawn('node', ['dist/'], { + server = spawn('babel-node', ['src/index'], { env: Object.assign({}, process.env, { GRAPHQL_URI: 'http://localhost:4123', GRAPHQL_PORT: '4123' }) }) - seeder = spawn('node', ['dist/'], { + seeder = spawn('babel-node', ['src/index'], { env: Object.assign({}, process.env, { GRAPHQL_URI: 'http://localhost:4001', GRAPHQL_PORT: '4001', From cd3f0955f9bf7a1fc89769723bf594e36ba66331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 15:29:47 +0100 Subject: [PATCH 11/18] Properly test 106 I had the wrong test setup for the "expected-to-be-green" side tests (for debugging). --- src/middleware/permissionsMiddleware.spec.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 7896f0348..9e153fe5e 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -32,7 +32,12 @@ describe('authorization', () => { describe('not logged in', async () => { it('does not expose the owner\'s email address', async () => { - expect(await action(headers)).toEqual({ User: [ { email: null } ] }) + try { + await action(headers) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Not Authorised!') + expect(error.response.data).toEqual({ User: [ { email: null } ] }) + } }) }) @@ -52,7 +57,12 @@ describe('authorization', () => { email: 'someone@example.org', password: 'else' }) - expect(await action(headers)).toEqual({ User: [ { email: null } ] }) + try { + await action(headers) + } catch (error) { + expect(error.response.errors[0].message).toEqual('Not Authorised!') + expect(error.response.data).toEqual({ User: [ { email: null } ] }) + } }) }) }) From ad8e64d0604e6b007e451549b7953c94d0fa1728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 16:01:03 +0100 Subject: [PATCH 12/18] Properly exit if seeding fails --- src/seed/data/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/seed/data/index.js b/src/seed/data/index.js index 33bc56f36..1184408d9 100644 --- a/src/seed/data/index.js +++ b/src/seed/data/index.js @@ -33,6 +33,7 @@ export default async function (client) { } catch (err) { /* eslint-disable-next-line no-console */ console.error(err) + process.exit(1) } }) /* eslint-disable-next-line no-console */ From a5c87e0cd5a6688742c62cb2e45ae88b2895aacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:03:05 +0100 Subject: [PATCH 13/18] Add --ci on Travis (it's our ci server :smile:) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eaba8dba3..f4a01b147 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ install: script: - docker-compose exec backend yarn run lint - - docker-compose exec backend yarn run test + - docker-compose exec backend yarn run test --ci - docker-compose exec backend yarn run test:coverage - docker-compose exec backend yarn run db:reset - docker-compose exec backend yarn run db:seed From 6340efbfc585227052455501c118ddf4af474296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:03:28 +0100 Subject: [PATCH 14/18] Fix #106 Thank you @appinteractive ! :gift_heart: FYI: @kachulio1 @mattwr18 --- src/middleware/userMiddleware.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 55b181bc9..161309164 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -1,4 +1,5 @@ import createOrUpdateLocations from './nodes/locations' +import find from 'lodash/find' export default { Mutation: { @@ -12,5 +13,28 @@ export default { await createOrUpdateLocations(args.id, args.locationName, context.driver) return result } + }, + Query: { + User: async (resolve, root, args, context, info) => { + let isIdPresent + let removeIdFromResult + try { + isIdPresent = find(info.fieldNodes[0].selectionSet.selections, item => item.name.value === 'id') + if (!isIdPresent) { + // add id to request as the user did not ask but we need it + info.fieldNodes[0].selectionSet.selections.unshift({ + kind: 'Field', + name: { kind: 'Name', value: 'id' } + }) + removeIdFromResult = true + } + } catch(err) {} + const result = await resolve(root, args, context, info) + if (!isIdPresent && removeIdFromResult) { + // remove id if the user did not ask for it + info.fieldNodes[0].selectionSet.selections.shift() + } + return result + } } } From 918bd863edb36c70868b5b6b62a6f9ba73cd6536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:06:53 +0100 Subject: [PATCH 15/18] Fix typo Replace password with Asterix and Obelix See: http://www.topkool.com/fr/wp-content/uploads/2012/10/asterix-et-obelix-017.jpg @appinteractive :laughing: --- src/middleware/passwordMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/middleware/passwordMiddleware.js b/src/middleware/passwordMiddleware.js index 16480b126..0aff222c8 100644 --- a/src/middleware/passwordMiddleware.js +++ b/src/middleware/passwordMiddleware.js @@ -13,7 +13,7 @@ export default { Query: async (resolve, root, args, context, info) => { const result = await resolve(root, args, context, info) return walkRecursive(result, ['password'], () => { - // replace password with asterix + // replace password with asterisk return '*****' }) } From 47e9e52a840a69dd128c31a324e94a8cd52aa112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 18:31:39 +0100 Subject: [PATCH 16/18] Refactor test to be less confusing --- src/middleware/permissionsMiddleware.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/middleware/permissionsMiddleware.spec.js b/src/middleware/permissionsMiddleware.spec.js index 9e153fe5e..cf86d11c9 100644 --- a/src/middleware/permissionsMiddleware.spec.js +++ b/src/middleware/permissionsMiddleware.spec.js @@ -7,10 +7,12 @@ describe('authorization', () => { beforeEach(async () => { await create('user', { email: 'owner@example.org', + name: 'Owner', password: 'iamtheowner' }) await create('user', { email: 'someone@example.org', + name: 'Someone else', password: 'else' }) }) @@ -24,7 +26,7 @@ describe('authorization', () => { const action = async (headers) => { const graphQLClient = new GraphQLClient(host, { headers }) return graphQLClient.request(`{ - User(email: "owner@example.org") { + User(name: "Owner") { email } }`) From 5dbe5b16a410833f268d886f48e35443cad078bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Thu, 17 Jan 2019 23:38:55 +0100 Subject: [PATCH 17/18] Help @mattwr18 to debug the subprocesses --- src/jest/hooks.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/jest/hooks.js b/src/jest/hooks.js index 15daccbdf..77fa159f2 100644 --- a/src/jest/hooks.js +++ b/src/jest/hooks.js @@ -20,6 +20,11 @@ const setup = async function () { }) }) + server.stdout.on('data', data => console.log(`server stdout:\n${data}`)) + server.stderr.on('data', data => console.log(`server stderr:\n${data}`)) + seeder.stdout.on('data', data => console.log(`seeder stdout:\n${data}`)) + seeder.stderr.on('data', data => console.log(`seeder stderr:\n${data}`)) + try { await waitOn({ resources: ['http://localhost:4123', 'http://localhost:4001'] @@ -30,7 +35,8 @@ const setup = async function () { } const teardown = async function () { - [server, seeder].forEach(app => app.kill()) + server.kill() + seeder.kill() } module.exports = { From c1395f7ec1caed1f2816a72f19a61d8850c0fa08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Fri, 18 Jan 2019 01:58:05 +0100 Subject: [PATCH 18/18] Fix leakage of subprocesses @mattwr18 and I could not find any other way how to prevent leftover processes than using a complex list of npm scripts. Watch: http://youtu.be/byovuFwNXiw and see how we despearately try to fix this stupid problem. --- package.json | 14 +++++----- scripts/test.sh | 1 + src/jest/globalSetup.js | 1 - src/jest/globalTeardown.js | 1 - src/jest/hooks.js | 45 -------------------------------- src/middleware/userMiddleware.js | 2 +- 6 files changed, 10 insertions(+), 54 deletions(-) create mode 100755 scripts/test.sh delete mode 100644 src/jest/globalSetup.js delete mode 100644 src/jest/globalTeardown.js delete mode 100644 src/jest/hooks.js diff --git a/package.json b/package.json index 2824aab37..58d25ebe4 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,16 @@ "scripts": { "build": "babel src/ -d dist/ --copy-files", "start": "node dist/", - "dev": "nodemon --exec babel-node src/index.js", + "dev": "nodemon --exec babel-node src/", "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/index.js", "lint": "eslint src --config .eslintrc.js", "test": "nyc --reporter=text-lcov yarn run test:jest", - "test:jest": "jest --forceExit --detectOpenHandles --runInBand", - "test:jest:debug": "node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", + "test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 babel-node src/ 2> /dev/null", + "test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 PERMISSIONS=disabled babel-node src/ 2> /dev/null", + "test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand", + "test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand", + "test:jest": "run-p --race test:before:* 'test:jest:cmd {@}' --", + "test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --", "test:coverage": "nyc report --reporter=text-lcov > coverage.lcov", "db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js", "db:script:reset": "wait-on tcp:4001 && babel-node src/seed/reset-db.js", @@ -27,9 +31,7 @@ "verbose": true, "testMatch": [ "**/src/**/?(*.)+(spec|test).js?(x)" - ], - "globalSetup": "/src/jest/globalSetup", - "globalTeardown": "/src/jest/globalTeardown" + ] }, "dependencies": { "apollo-cache-inmemory": "~1.3.12", diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 000000000..f1f641af1 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1 @@ +#!/usr/bin/env bash diff --git a/src/jest/globalSetup.js b/src/jest/globalSetup.js deleted file mode 100644 index e2bfa24a5..000000000 --- a/src/jest/globalSetup.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./hooks').setup diff --git a/src/jest/globalTeardown.js b/src/jest/globalTeardown.js deleted file mode 100644 index 944503234..000000000 --- a/src/jest/globalTeardown.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./hooks').teardown diff --git a/src/jest/hooks.js b/src/jest/hooks.js deleted file mode 100644 index 77fa159f2..000000000 --- a/src/jest/hooks.js +++ /dev/null @@ -1,45 +0,0 @@ -const { spawn } = require('child_process') -const waitOn = require('wait-on') - -let server -let seeder - -const setup = async function () { - server = spawn('babel-node', ['src/index'], { - env: Object.assign({}, process.env, { - GRAPHQL_URI: 'http://localhost:4123', - GRAPHQL_PORT: '4123' - }) - }) - - seeder = spawn('babel-node', ['src/index'], { - env: Object.assign({}, process.env, { - GRAPHQL_URI: 'http://localhost:4001', - GRAPHQL_PORT: '4001', - PERMISSIONS: 'disabled' - }) - }) - - server.stdout.on('data', data => console.log(`server stdout:\n${data}`)) - server.stderr.on('data', data => console.log(`server stderr:\n${data}`)) - seeder.stdout.on('data', data => console.log(`seeder stdout:\n${data}`)) - seeder.stderr.on('data', data => console.log(`seeder stderr:\n${data}`)) - - try { - await waitOn({ - resources: ['http://localhost:4123', 'http://localhost:4001'] - }) - } catch (err) { - console.log(err) - } -} - -const teardown = async function () { - server.kill() - seeder.kill() -} - -module.exports = { - setup, - teardown -} diff --git a/src/middleware/userMiddleware.js b/src/middleware/userMiddleware.js index 161309164..d4648413a 100644 --- a/src/middleware/userMiddleware.js +++ b/src/middleware/userMiddleware.js @@ -28,7 +28,7 @@ export default { }) removeIdFromResult = true } - } catch(err) {} + } catch (err) {} const result = await resolve(root, args, context, info) if (!isIdPresent && removeIdFromResult) { // remove id if the user did not ask for it