Skip to content

Commit

Permalink
idempotent tests + standard
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Tahler committed Aug 13, 2019
1 parent 71c0c18 commit c2d8c1f
Show file tree
Hide file tree
Showing 15 changed files with 913 additions and 767 deletions.
2 changes: 1 addition & 1 deletion __tests__/example.js
Expand Up @@ -15,7 +15,7 @@ describe('actionhero Tests', () => {
})

test('can retrieve server uptime via the status action', async () => {
let { uptime } = await api.specHelper.runAction('status')
const { uptime } = await api.specHelper.runAction('status')
expect(uptime).toBeGreaterThan(0)
})
})
52 changes: 32 additions & 20 deletions __tests__/integration/posts.js
@@ -1,4 +1,4 @@
const r2 = require('r2')
const request = require('request-promise-native')
const ActionHero = require('actionhero')
const actionhero = new ActionHero.Process()
let api
Expand All @@ -9,40 +9,52 @@ describe('integration', () => {
beforeAll(async () => {
api = await actionhero.start()
url = `http://localhost:${api.config.servers.web.port}/api`
})

beforeAll(async () => {
try {
await request.del(`${url}/user/testPoster`, { body: { password: 'password' }, json: true })
} catch (error) {
if (error.statusCode !== 400) { throw error }
}
})

const body = await r2.post(`${url}/user`, { json: { userName: 'testPoster', password: 'password' } }).json
expect(body.error).toBeUndefined()
beforeAll(async () => {
await request.post(`${url}/user`, { body: { userName: 'testPoster', password: 'password' }, json: true })
})

afterAll(async () => { await actionhero.stop() })

test('saves a post', async () => {
const body = await r2.post(`${url}/post/testPoster`, { json: {
password: 'password',
title: 'test post title',
content: 'post content'
} }).json

expect(body.error).toBeUndefined()
const response = await request.post(`${url}/post/testPoster`, {
json: true,
body: {
password: 'password',
title: 'test post title',
content: 'post content'
}
})

expect(response.error).toBeUndefined()
})

test('views a post', async () => {
const body = await r2.get(`${url}/post/testPoster/${encodeURI('test post title')}`).json
expect(body.post.title).toEqual('test post title')
expect(body.post.content).toEqual('post content')
expect(body.error).toBeUndefined()
const response = await request.get(`${url}/post/testPoster/${encodeURI('test post title')}`, { json: true })
expect(response.post.title).toEqual('test post title')
expect(response.post.content).toEqual('post content')
expect(response.error).toBeUndefined()
})

test('lists posts by user', async () => {
const body = await r2.get(`${url}/posts/testPoster`).json
expect(body.posts).toContain('test post title')
expect(body.error).toBeUndefined()
const response = await request.get(`${url}/posts/testPoster`, { json: true })
expect(response.posts).toContain('test post title')
expect(response.error).toBeUndefined()
})

test('does not mix posts for other users', async () => {
const body = await r2.get(`${url}/posts/someoneElse`).json
expect(body.posts).not.toContain('test post title')
expect(body.error).toBeUndefined()
const response = await request.get(`${url}/posts/someoneElse`, { json: true })
expect(response.posts).not.toContain('test post title')
expect(response.error).toBeUndefined()
})
})
})
62 changes: 43 additions & 19 deletions __tests__/integration/users.js
@@ -1,4 +1,4 @@
const r2 = require('r2')
const request = require('request-promise-native')
const ActionHero = require('actionhero')
const actionhero = new ActionHero.Process()
let api
Expand All @@ -10,40 +10,64 @@ describe('integration', () => {
url = `http://localhost:${api.config.servers.web.port}/api`
})

beforeAll(async () => {
try {
await request.del(`${url}/user/evan`, { body: { password: 'password' }, json: true })
} catch (error) {
if (error.statusCode !== 400) { throw error }
}

try {
await request.del(`${url}/user/someoneElse`, { body: { password: 'password' }, json: true })
} catch (error) {
if (error.statusCode !== 400) { throw error }
}
})

afterAll(async () => { await actionhero.stop() })

describe('users', () => {
test('creates a user', async () => {
const body = await r2.post(`${url}/user`, { json: { userName: 'evan', password: 'password' } }).json
expect(body.error).toBeUndefined()
const response = await request.post(`${url}/user`, { body: { userName: 'evan', password: 'password' }, json: true })
expect(response.error).toBeUndefined()
})

test('prevents duplicate uesers from being created', async () => {
const body = await r2.post(`${url}/user`, { json: { userName: 'evan', password: 'password' } }).json
expect(body.error).toEqual('userName already exists')
try {
await request.post(`${url}/user`, { body: { userName: 'evan', password: 'password' }, json: true })
throw new Error('should not get here')
} catch (error) {
expect(error.statusCode).toEqual(400)
expect(error.error.error).toEqual('userName already exists')
}
})

test('authenticates with the propper password', async () => {
const body = await r2.post(`${url}/authenticate`, { json: { userName: 'evan', password: 'password' } }).json
expect(body.authenticated).toEqual(true)
expect(body.error).toBeUndefined()
const response = await request.post(`${url}/authenticate`, { body: { userName: 'evan', password: 'password' }, json: true })
expect(response.authenticated).toEqual(true)
expect(response.error).toBeUndefined()
})

test('does not authenticate with the propper password', async () => {
const body = await r2.post(`${url}/authenticate`, { json: { userName: 'evan', password: 'xxx' } }).json
expect(body.authenticated).toEqual(false)
expect(body.error).toEqual('unable to log in')
try {
await request.post(`${url}/authenticate`, { body: { userName: 'evan', password: 'xxx' }, json: true })
throw new Error('should not get here')
} catch (error) {
expect(error.statusCode).toEqual(400)
expect(error.error.authenticated).toEqual(false)
expect(error.error.error).toEqual('unable to log in')
}
})

test('returns a list of users', async () => {
const body = await r2.post(`${url}/user`, { json: { userName: 'someoneElse', password: 'password' } }).json
expect(body.error).toBeUndefined()

const usersBody = await r2.get(`${url}/usersList`).json
expect(usersBody.users.length).toBeGreaterThan(1)
expect(usersBody.users).toContain('evan')
expect(usersBody.users).toContain('someoneElse')
expect(usersBody.error).toBeUndefined()
const response = await request.post(`${url}/user`, { body: { userName: 'someoneElse', password: 'password' }, json: true })
expect(response.error).toBeUndefined()

const usersResponse = await request.get(`${url}/usersList`, { json: true })
expect(usersResponse.users.length).toBeGreaterThan(1)
expect(usersResponse.users).toContain('evan')
expect(usersResponse.users).toContain('someoneElse')
expect(usersResponse.error).toBeUndefined()
})
})
})
100 changes: 50 additions & 50 deletions actions/showDocumentation.js
Expand Up @@ -10,77 +10,77 @@ module.exports = class ShowDocumentation extends ActionHero.Action {

outputExample () {
return {
'documentation': {
'cacheTest': {
'1': {
'name': 'cacheTest',
'version': 1,
'description': 'I will test the internal cache functions of the API',
'inputs': {
'key': {
'required': true
documentation: {
cacheTest: {
1: {
name: 'cacheTest',
version: 1,
description: 'I will test the internal cache functions of the API',
inputs: {
key: {
required: true
},
'value': {
'required': true
value: {
required: true
}
},
'outputExample': {
'cacheTestResults': {
'saveResp': true,
'sizeResp': 1,
'loadResp': {
'key': '',
'value': 'value',
'expireTimestamp': 1420953274716,
'createdAt': 1420953269716,
'readAt': null
outputExample: {
cacheTestResults: {
saveResp: true,
sizeResp: 1,
loadResp: {
key: '',
value: 'value',
expireTimestamp: 1420953274716,
createdAt: 1420953269716,
readAt: null
},
'deleteResp': true
deleteResp: true
}
}
}
},
'randomNumber': {
'1': {
'name': 'randomNumber',
'version': 1,
'description': 'I am an API method which will generate a random number',
'inputs': {
randomNumber: {
1: {
name: 'randomNumber',
version: 1,
description: 'I am an API method which will generate a random number',
inputs: {

},
'outputExample': {
'randomNumber': 0.123
outputExample: {
randomNumber: 0.123
}
}
},
'showDocumentation': {
'1': {
'name': 'showDocumentation',
'version': 1,
'description': 'return API documentation',
'inputs': {
showDocumentation: {
1: {
name: 'showDocumentation',
version: 1,
description: 'return API documentation',
inputs: {

}
}
},
'sleepTest': {
'1': {
'name': 'sleepTest',
'version': 1,
'description': 'I will sleep and then return',
'inputs': {
'sleepDuration': {
'required': true
sleepTest: {
1: {
name: 'sleepTest',
version: 1,
description: 'I will sleep and then return',
inputs: {
sleepDuration: {
required: true
}
}
}
},
'status': {
'1': {
'name': 'status',
'version': 1,
'description': 'I will return some basic information about the API',
'inputs': {
status: {
1: {
name: 'status',
version: 1,
description: 'I will return some basic information about the API',
inputs: {

}
}
Expand Down
10 changes: 5 additions & 5 deletions actions/status.js
Expand Up @@ -15,9 +15,9 @@ module.exports = class RandomNumber extends ActionHero.Action {
this.name = 'status'
this.description = 'I will return some basic information about the API'
this.outputExample = {
'id': '192.168.2.11',
'actionheroVersion': '9.4.1',
'uptime': 10469
id: '192.168.2.11',
actionheroVersion: '9.4.1',
uptime: 10469
}
}

Expand All @@ -32,7 +32,7 @@ module.exports = class RandomNumber extends ActionHero.Action {

async checkEventLoop (data) {
const api = ActionHero.api
let eventLoopDelay = await api.utils.eventLoopDelay(10000)
const eventLoopDelay = await api.utils.eventLoopDelay(10000)
data.response.eventLoopDelay = eventLoopDelay
if (eventLoopDelay > maxEventLoopDelay) {
data.response.nodeStatus = data.connection.localize('Node Unhealthy')
Expand All @@ -42,7 +42,7 @@ module.exports = class RandomNumber extends ActionHero.Action {

async checkResqueQueues (data) {
const api = ActionHero.api
let details = await api.tasks.details()
const details = await api.tasks.details()
let length = 0
Object.keys(details.queues).forEach((q) => {
length += details.queues[q].length
Expand Down
2 changes: 1 addition & 1 deletion actions/users.js
Expand Up @@ -47,7 +47,7 @@ exports.usersList = class UsersList extends Action {
}

async run ({ response, params }) {
let users = await api.users.list()
const users = await api.users.list()
response.users = users.map((user) => { return user.userName })
}
}
Expand Down
26 changes: 13 additions & 13 deletions config/api.js
Expand Up @@ -46,16 +46,16 @@ exports['default'] = {
cliIncludeInternal: true,
// configuration for your actionhero project structure
paths: {
'action': [path.join(__dirname, '/../actions')],
'task': [path.join(__dirname, '/../tasks')],
'public': [path.join(__dirname, '/../public')],
'pid': [path.join(__dirname, '/../pids')],
'log': [path.join(__dirname, '/../log')],
'server': [path.join(__dirname, '/../servers')],
'cli': [path.join(__dirname, '/../bin')],
'initializer': [path.join(__dirname, '/../initializers')],
'plugin': [path.join(__dirname, '/../node_modules')],
'locale': [path.join(__dirname, '/../locales')]
action: [path.join(__dirname, '/../actions')],
task: [path.join(__dirname, '/../tasks')],
public: [path.join(__dirname, '/../public')],
pid: [path.join(__dirname, '/../pids')],
log: [path.join(__dirname, '/../log')],
server: [path.join(__dirname, '/../servers')],
cli: [path.join(__dirname, '/../bin')],
initializer: [path.join(__dirname, '/../initializers')],
plugin: [path.join(__dirname, '/../node_modules')],
locale: [path.join(__dirname, '/../locales')]
},
// hash containing chat rooms you wish to be created at server boot
startingChatRooms: {
Expand All @@ -73,11 +73,11 @@ exports.test = {
serverToken: `serverToken-${process.env.JEST_WORKER_ID || 0}`,
developmentMode: true,
startingChatRooms: {
'defaultRoom': {},
'otherRoom': {}
defaultRoom: {},
otherRoom: {}
},
paths: {
'locale': [
locale: [
path.join(__dirname, '..', 'locales')
]
},
Expand Down
2 changes: 1 addition & 1 deletion config/errors.js
Expand Up @@ -4,7 +4,7 @@
exports['default'] = {
errors: (api) => {
return {
'_toExpand': false,
_toExpand: false,

// ///////////////
// SERIALIZERS //
Expand Down

0 comments on commit c2d8c1f

Please sign in to comment.