Refactor tests with the new factory API

This commit is contained in:
Robert Schäfer 2019-02-21 15:40:31 +01:00
parent aa07a2a616
commit 132dba04dd
6 changed files with 84 additions and 63 deletions

View File

@ -1,17 +1,19 @@
import { create, cleanDatabase } from './seed/factories'
import Factory from './seed/factories'
import jwt from 'jsonwebtoken'
import { testServerHost as host, authenticatedHeaders } from './jest/helpers'
import { host, login } from './jest/helpers'
import { GraphQLClient, request } from 'graphql-request'
const factory = Factory()
beforeEach(async () => {
await create('user', {
await factory.create('user', {
email: 'test@example.org',
password: '1234'
})
})
afterEach(async () => {
await cleanDatabase()
await factory.cleanDatabase()
})
describe('login', () => {
@ -28,7 +30,10 @@ describe('login', () => {
describe('ask for a `token`', () => {
describe('with valid email/password combination', () => {
it('responds with a JWT token', async () => {
const data = await request(host, 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')
@ -39,21 +44,23 @@ describe('login', () => {
describe('with a valid email but incorrect password', () => {
it('responds with "Incorrect email address or password."', async () => {
try {
await request(host, mutation({ email: 'test@example.org', password: 'wrong' }))
} catch (error) {
expect(error.response.errors[0].message).toEqual('Incorrect email address or password.')
}
await expect(
request(host, mutation({
email: 'test@example.org',
password: 'wrong'
}))
).rejects.toThrow('Incorrect email address or password.')
})
})
describe('with a non-existing email', () => {
it('responds with "Incorrect email address or password."', async () => {
try {
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.')
}
await expect(
request(host, mutation({
email: 'non-existent@example.org',
password: 'wrong'
}))
).rejects.toThrow('Incorrect email address or password.')
})
})
})
@ -76,7 +83,7 @@ describe('CreatePost', () => {
let headers
let response
beforeEach(async () => {
headers = await authenticatedHeaders({ email: 'test@example.org', password: '1234' })
headers = await login({ email: 'test@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
response = await client.request(`mutation {
CreatePost(

View File

@ -1,8 +1,10 @@
import { request } from 'graphql-request'
export const testServerHost = 'http://127.0.0.1:4123'
// this is the to-be-tested server host
// not to be confused with the seeder host
export const host = 'http://127.0.0.1:4123'
export async function authenticatedHeaders ({ email, password }, host = testServerHost) {
export async function login ({ email, password }) {
const mutation = `
mutation {
login(email:"${email}", password:"${password}"){

View File

@ -1,16 +1,18 @@
import { create, cleanDatabase } from '../seed/factories'
import { testServerHost as host, authenticatedHeaders } from '../jest/helpers'
import Factory from '../seed/factories'
import { host, login } from '../jest/helpers'
import { GraphQLClient } from 'graphql-request'
const factory = Factory()
describe('authorization', () => {
describe('given two existing users', () => {
beforeEach(async () => {
await create('user', {
await factory.create('user', {
email: 'owner@example.org',
name: 'Owner',
password: 'iamtheowner'
})
await create('user', {
await factory.create('user', {
email: 'someone@example.org',
name: 'Someone else',
password: 'else'
@ -18,28 +20,28 @@ describe('authorization', () => {
})
afterEach(async () => {
await cleanDatabase()
await factory.cleanDatabase()
})
describe('access email address', () => {
let headers = {}
const action = async (headers) => {
let loginCredentials = null
const action = async () => {
if (loginCredentials) {
headers = await login(loginCredentials)
}
const graphQLClient = new GraphQLClient(host, { headers })
return graphQLClient.request(`{
User(name: "Owner") {
email
}
}`)
return graphQLClient.request('{User(name: "Owner") { email } }')
}
describe('not logged in', async () => {
it('rejects', async () => {
await expect(action(headers)).rejects.toThrow('Not Authorised!')
await expect(action()).rejects.toThrow('Not Authorised!')
})
it('does not expose the owner\'s email address', async () => {
try {
await action(headers)
await action()
} catch (error) {
expect(error.response.data).toEqual({ User: [ { email: null } ] })
}
@ -47,30 +49,33 @@ describe('authorization', () => {
})
describe('as owner', () => {
it('exposes the owner\'s email address', async () => {
headers = await authenticatedHeaders({
beforeEach(() => {
loginCredentials = {
email: 'owner@example.org',
password: 'iamtheowner'
})
expect(await action(headers)).toEqual({ User: [ { email: 'owner@example.org' } ] })
}
})
it('exposes the owner\'s email address', async () => {
await expect(action()).resolves.toEqual({ User: [ { email: 'owner@example.org' } ] })
})
})
describe('as someone else', () => {
describe('authenticated as another user', () => {
beforeEach(async () => {
headers = await authenticatedHeaders({
loginCredentials = {
email: 'someone@example.org',
password: 'else'
})
}
})
it('rejects', async () => {
await expect(action(headers)).rejects.toThrow('Not Authorised!')
await expect(action()).rejects.toThrow('Not Authorised!')
})
it('does not expose the owner\'s email address', async () => {
try {
await action(headers)
await action()
} catch (error) {
expect(error.response.data).toEqual({ User: [ { email: null } ] })
}

View File

@ -1,41 +1,48 @@
import { create, cleanDatabase } from '../seed/factories'
import { testServerHost as host, authenticatedHeaders } from '../jest/helpers'
import Factory from '../seed/factories'
import { host, login } from '../jest/helpers'
import { GraphQLClient } from 'graphql-request'
let client
let authenticatedClient
let headers
const factory = Factory()
beforeEach(async () => {
await create('user', { email: 'user@example.org', password: '1234' })
headers = await authenticatedHeaders({ email: 'user@example.org', password: '1234' })
client = new GraphQLClient(host, { headers })
await factory.create('user', { email: 'user@example.org', password: '1234' })
await factory.create('user', { email: 'someone@example.org', password: '1234' })
headers = await login({ email: 'user@example.org', password: '1234' })
authenticatedClient = new GraphQLClient(host, { headers })
})
afterEach(async () => {
await cleanDatabase()
await factory.cleanDatabase()
})
describe('slugify', () => {
describe('CreatePost', () => {
it('generates a slug based on title', async () => {
const response = await client.request(`mutation {
const response = await authenticatedClient.request(`mutation {
CreatePost(
title: "I am a brand new post",
content: "Some content"
) { slug }
}`, { headers })
}`)
expect(response).toEqual({ CreatePost: { slug: 'i-am-a-brand-new-post' } })
})
describe('if slug exists', () => {
beforeEach(async () => {
await create('post', {
const asSomeoneElse = await Factory().authenticateAs({
email: 'someone@example.org',
password: '1234'
})
await asSomeoneElse.create('post', {
title: 'Pre-existing post',
slug: 'pre-existing-post'
}, { headers })
})
})
it('chooses another slug', async () => {
const response = await client.request(`mutation {
const response = await authenticatedClient.request(`mutation {
CreatePost(
title: "Pre-existing post",
content: "Some content"
@ -46,7 +53,7 @@ describe('slugify', () => {
describe('but if the client specifies a slug', () => {
it('rejects CreatePost', async () => {
await expect(client.request(`mutation {
await expect(authenticatedClient.request(`mutation {
CreatePost(
title: "Pre-existing post",
content: "Some content",
@ -61,9 +68,9 @@ describe('slugify', () => {
describe('CreateUser', () => {
const action = async (mutation, params) => {
return client.request(`mutation {
return authenticatedClient.request(`mutation {
${mutation}(password: "yo", ${params}) { slug }
}`, { headers })
}`)
}
it('generates a slug based on name', async () => {
await expect(action('CreateUser', 'name: "I am a user"'))

View File

@ -61,7 +61,7 @@ export const cleanDatabase = async (options = {}) => {
}
}
export default function factoryFun (options = {}) {
export default function Factory (options = {}) {
const {
neo4jDriver = getDriver(),
seedServerHost = 'http://127.0.0.1:4001'

View File

@ -1,4 +1,4 @@
import factoryFun, { create, relate } from './factories'
import Factory, { create, relate } from './factories'
/* eslint-disable no-multi-spaces */
(async function () {
@ -70,12 +70,12 @@ import factoryFun, { create, relate } from './factories'
])
const [ asAdmin, asModerator, asUser, asTick, asTrick, asTrack ] = await Promise.all([
factoryFun().authenticateAs({ email: 'admin@example.org', password: '1234' }),
factoryFun().authenticateAs({ email: 'moderator@example.org', password: '1234' }),
factoryFun().authenticateAs({ email: 'user@example.org', password: '1234' }),
factoryFun().authenticateAs({ email: 'tick@example.org', password: '1234' }),
factoryFun().authenticateAs({ email: 'trick@example.org', password: '1234' }),
factoryFun().authenticateAs({ email: 'track@example.org', password: '1234' })
Factory().authenticateAs({ email: 'admin@example.org', password: '1234' }),
Factory().authenticateAs({ email: 'moderator@example.org', password: '1234' }),
Factory().authenticateAs({ email: 'user@example.org', password: '1234' }),
Factory().authenticateAs({ email: 'tick@example.org', password: '1234' }),
Factory().authenticateAs({ email: 'trick@example.org', password: '1234' }),
Factory().authenticateAs({ email: 'track@example.org', password: '1234' })
])
await Promise.all([