Update tests to use Promise syntax (#507)

* Use promises in tests

* Fix lint

* Update tests

* Update babelrc

* Update config

* Update engines
This commit is contained in:
typicode
2017-04-01 01:51:07 +02:00
committed by GitHub
parent 77cd4628c7
commit fdf74e0685
6 changed files with 255 additions and 287 deletions

View File

@ -1,5 +1,10 @@
{ {
"presets": [ "presets": [
["es2015", { "loose": true }] ["env", {
"targets": {
"node": 4
},
"exclude": ["transform-regenerator"]
}]
] ]
} }

View File

@ -30,20 +30,20 @@
"yargs": "^6.0.0" "yargs": "^6.0.0"
}, },
"devDependencies": { "devDependencies": {
"babel-cli": "^6.10.1", "babel-cli": "^6.24.0",
"babel-preset-es2015": "^6.16.0", "babel-preset-env": "^1.3.2",
"babel-register": "^6.16.3", "babel-register": "^6.16.3",
"cross-env": "^2.0.1", "cross-env": "^2.0.1",
"husky": "^0.13.0", "husky": "^0.13.0",
"markdown-toc": "^0.13.0", "markdown-toc": "^0.13.0",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"mocha": "^3.1.2", "mocha": "^3.2.0",
"os-tmpdir": "^1.0.1", "os-tmpdir": "^1.0.1",
"pkg-ok": "^1.0.1", "pkg-ok": "^1.0.1",
"rimraf": "^2.5.2", "rimraf": "^2.5.2",
"server-ready": "^0.3.1", "server-ready": "^0.3.1",
"standard": "^8.3.0", "standard": "^8.3.0",
"supertest": "^2.0.0", "supertest": "^3.0.0",
"temp-write": "^2.1.0" "temp-write": "^2.1.0"
}, },
"scripts": { "scripts": {
@ -51,7 +51,7 @@
"test:cli": "npm run build && cross-env NODE_ENV=test mocha test/cli/*.js", "test:cli": "npm run build && cross-env NODE_ENV=test mocha test/cli/*.js",
"test:server": "cross-env NODE_ENV=test mocha test/server/*.js", "test:server": "cross-env NODE_ENV=test mocha test/server/*.js",
"start": "babel-node src/cli/bin", "start": "babel-node src/cli/bin",
"prepush": "npm t", "precommit": "npm test",
"build": "babel src -d lib --copy-files", "build": "babel src -d lib --copy-files",
"toc": "markdown-toc -i README.md", "toc": "markdown-toc -i README.md",
"prepublish": "npm run build && pkg-ok" "prepublish": "npm run build && pkg-ok"
@ -89,6 +89,6 @@
} }
}, },
"engines": { "engines": {
"node": ">= 0.12" "node": ">= 4"
} }
} }

View File

@ -1,3 +1,3 @@
--compilers js:babel-register --require babel-register
--reporter spec --reporter spec
--timeout 5000 --timeout 5000

View File

@ -87,17 +87,17 @@ describe('Server', () => {
}) })
describe('GET /db', () => { describe('GET /db', () => {
it('should respond with json and full database', (done) => { it('should respond with json and full database', () => (
request(server) request(server)
.get('/db') .get('/db')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db) .expect(db)
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource', () => { describe('GET /:resource', () => {
it('should respond with json and corresponding resources', (done) => { it('should respond with json and corresponding resources', () => (
request(server) request(server)
.get('/posts') .get('/posts')
.set('Origin', 'http://example.com') .set('Origin', 'http://example.com')
@ -105,207 +105,207 @@ describe('Server', () => {
.expect('Access-Control-Allow-Credentials', 'true') .expect('Access-Control-Allow-Credentials', 'true')
.expect('Access-Control-Allow-Origin', 'http://example.com') .expect('Access-Control-Allow-Origin', 'http://example.com')
.expect(db.posts) .expect(db.posts)
.expect(200, done) .expect(200)
}) ))
it('should respond with 404 if resource is not found', (done) => { it('should respond with 404 if resource is not found', () => (
request(server) request(server)
.get('/undefined') .get('/undefined')
.expect(404, done) .expect(404)
}) ))
}) })
describe('GET /:resource?attr=&attr=', () => { describe('GET /:resource?attr=&attr=', () => {
it('should respond with json and filter resources', (done) => { it('should respond with json and filter resources', () => (
request(server) request(server)
.get('/comments?postId=1&published=true') .get('/comments?postId=1&published=true')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.comments[0] ]) .expect([ db.comments[0] ])
.expect(200, done) .expect(200)
}) ))
it('should be strict', (done) => { it('should be strict', () => (
request(server) request(server)
.get('/users?tel=123') .get('/users?tel=123')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.users[1] ]) .expect([ db.users[1] ])
.expect(200, done) .expect(200)
}) ))
it('should support multiple filters', (done) => { it('should support multiple filters', () => (
request(server) request(server)
.get('/comments?id=1&id=2') .get('/comments?id=1&id=2')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.comments[0], db.comments[1] ]) .expect([ db.comments[0], db.comments[1] ])
.expect(200, done) .expect(200)
}) ))
it('should support deep filter', (done) => { it('should support deep filter', () => (
request(server) request(server)
.get('/deep?a.b=1') .get('/deep?a.b=1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.deep[0] ]) .expect([ db.deep[0] ])
.expect(200, done) .expect(200)
}) ))
it('should ignore JSONP query parameters callback and _ ', (done) => { it('should ignore JSONP query parameters callback and _ ', () => (
request(server) request(server)
.get('/comments?callback=1&_=1') .get('/comments?callback=1&_=1')
.expect('Content-Type', /text/) .expect('Content-Type', /text/)
.expect(new RegExp(db.comments[0].body)) // JSONP returns text .expect(new RegExp(db.comments[0].body)) // JSONP returns text
.expect(200, done) .expect(200)
}) ))
it('should ignore unknown query parameters', (done) => { it('should ignore unknown query parameters', () => (
request(server) request(server)
.get('/comments?foo=1&bar=2') .get('/comments?foo=1&bar=2')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.comments) .expect(db.comments)
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?q=', () => { describe('GET /:resource?q=', () => {
it('should respond with json and make a full-text search', (done) => { it('should respond with json and make a full-text search', () => (
request(server) request(server)
.get('/tags?q=pho') .get('/tags?q=pho')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.tags[1], db.tags[2] ]) .expect([ db.tags[1], db.tags[2] ])
.expect(200, done) .expect(200)
}) ))
it('should respond with json and make a deep full-text search', (done) => { it('should respond with json and make a deep full-text search', () => (
request(server) request(server)
.get('/deep?q=1') .get('/deep?q=1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.deep) .expect(db.deep)
.expect(200, done) .expect(200)
}) ))
it('should return an empty array when nothing is matched', (done) => { it('should return an empty array when nothing is matched', () => (
request(server) request(server)
.get('/tags?q=nope') .get('/tags?q=nope')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ ]) .expect([ ])
.expect(200, done) .expect(200)
}) ))
it('should support other query parameters', (done) => { it('should support other query parameters', () => (
request(server) request(server)
.get('/comments?q=qu&published=true') .get('/comments?q=qu&published=true')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.comments[3] ]) .expect([ db.comments[3] ])
.expect(200, done) .expect(200)
}) ))
it('should ignore duplicate q query parameters', (done) => { it('should ignore duplicate q query parameters', () => (
request(server) request(server)
.get('/comments?q=foo&q=bar') .get('/comments?q=foo&q=bar')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.comments[0] ]) .expect([ db.comments[0] ])
.expect(200, done) .expect(200)
}) ))
it('should support filtering by boolean value false', (done) => { it('should support filtering by boolean value false', () => (
request(server) request(server)
.get('/comments?published=false') .get('/comments?published=false')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.comments[1], db.comments[2], db.comments[4] ]) .expect([ db.comments[1], db.comments[2], db.comments[4] ])
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?_end=', () => { describe('GET /:resource?_end=', () => {
it('should respond with a sliced array', (done) => { it('should respond with a sliced array', () => (
request(server) request(server)
.get('/comments?_end=2') .get('/comments?_end=2')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect('x-total-count', db.comments.length.toString()) .expect('x-total-count', db.comments.length.toString())
.expect('Access-Control-Expose-Headers', 'X-Total-Count') .expect('Access-Control-Expose-Headers', 'X-Total-Count')
.expect(db.comments.slice(0, 2)) .expect(db.comments.slice(0, 2))
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?_sort=', () => { describe('GET /:resource?_sort=', () => {
it('should respond with json and sort on a field', (done) => { it('should respond with json and sort on a field', () => (
request(server) request(server)
.get('/tags?_sort=body') .get('/tags?_sort=body')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.tags[1], db.tags[0], db.tags[2] ]) .expect([ db.tags[1], db.tags[0], db.tags[2] ])
.expect(200, done) .expect(200)
}) ))
it('should reverse sorting with _order=DESC', (done) => { it('should reverse sorting with _order=DESC', () => (
request(server) request(server)
.get('/tags?_sort=body&_order=DESC') .get('/tags?_sort=body&_order=DESC')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.tags[2], db.tags[0], db.tags[1] ]) .expect([ db.tags[2], db.tags[0], db.tags[1] ])
.expect(200, done) .expect(200)
}) ))
it('should sort on numerical field', (done) => { it('should sort on numerical field', () => (
request(server) request(server)
.get('/posts?_sort=id&_order=DESC') .get('/posts?_sort=id&_order=DESC')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.posts.reverse()) .expect(db.posts.reverse())
.expect(200, done) .expect(200)
}) ))
it('should sort on nested field', (done) => { it('should sort on nested field', () => (
request(server) request(server)
.get('/nested?_sort=resource.name') .get('/nested?_sort=resource.name')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect([ db.nested[1], db.nested[0], db.nested[2] ]) .expect([ db.nested[1], db.nested[0], db.nested[2] ])
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?_start=&_end=', () => { describe('GET /:resource?_start=&_end=', () => {
it('should respond with a sliced array', (done) => { it('should respond with a sliced array', () => (
request(server) request(server)
.get('/comments?_start=1&_end=2') .get('/comments?_start=1&_end=2')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect('X-Total-Count', db.comments.length.toString()) .expect('X-Total-Count', db.comments.length.toString())
.expect('Access-Control-Expose-Headers', 'X-Total-Count') .expect('Access-Control-Expose-Headers', 'X-Total-Count')
.expect(db.comments.slice(1, 2)) .expect(db.comments.slice(1, 2))
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?_start=&_limit=', () => { describe('GET /:resource?_start=&_limit=', () => {
it('should respond with a limited array', (done) => { it('should respond with a limited array', () => (
request(server) request(server)
.get('/comments?_start=1&_limit=1') .get('/comments?_start=1&_limit=1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect('X-Total-Count', db.comments.length.toString()) .expect('X-Total-Count', db.comments.length.toString())
.expect('Access-Control-Expose-Headers', 'X-Total-Count') .expect('Access-Control-Expose-Headers', 'X-Total-Count')
.expect(db.comments.slice(1, 2)) .expect(db.comments.slice(1, 2))
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?_page=', () => { describe('GET /:resource?_page=', () => {
it('should paginate', (done) => { it('should paginate', () => (
request(server) request(server)
.get('/list?_page=2') .get('/list?_page=2')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect('x-total-count', db.list.length.toString()) .expect('x-total-count', db.list.length.toString())
.expect('Access-Control-Expose-Headers', 'X-Total-Count, Link') .expect('Access-Control-Expose-Headers', 'X-Total-Count, Link')
.expect(db.list.slice(10, 20)) .expect(db.list.slice(10, 20))
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?_page=&_limit=', () => { describe('GET /:resource?_page=&_limit=', () => {
it('should paginate with a custom limit', (done) => { it('should paginate with a custom limit', () => {
const link = [ const link = [
'<http://localhost/list?_page=1&_limit=1>; rel="first"', '<http://localhost/list?_page=1&_limit=1>; rel="first"',
'<http://localhost/list?_page=1&_limit=1>; rel="prev"', '<http://localhost/list?_page=1&_limit=1>; rel="prev"',
'<http://localhost/list?_page=3&_limit=1>; rel="next"', '<http://localhost/list?_page=3&_limit=1>; rel="next"',
'<http://localhost/list?_page=15&_limit=1>; rel="last"' '<http://localhost/list?_page=15&_limit=1>; rel="last"'
].join(', ') ].join(', ')
request(server) return request(server)
.get('/list?_page=2&_limit=1') .get('/list?_page=2&_limit=1')
.set('host', 'localhost') .set('host', 'localhost')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
@ -313,32 +313,32 @@ describe('Server', () => {
.expect('link', link) .expect('link', link)
.expect('Access-Control-Expose-Headers', 'X-Total-Count, Link') .expect('Access-Control-Expose-Headers', 'X-Total-Count, Link')
.expect(db.list.slice(1, 2)) .expect(db.list.slice(1, 2))
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource?attr_gte=&attr_lte=', () => { describe('GET /:resource?attr_gte=&attr_lte=', () => {
it('should respond with a limited array', (done) => { it('should respond with a limited array', () => (
request(server) request(server)
.get('/comments?id_gte=2&id_lte=3') .get('/comments?id_gte=2&id_lte=3')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.comments.slice(1, 3)) .expect(db.comments.slice(1, 3))
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?attr_ne=', () => { describe('GET /:resource?attr_ne=', () => {
it('should respond with a limited array', (done) => { it('should respond with a limited array', () => (
request(server) request(server)
.get('/comments?id_ne=1') .get('/comments?id_ne=1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.comments.slice(1)) .expect(db.comments.slice(1))
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource?attr_like=', () => { describe('GET /:resource?attr_like=', () => {
it('should respond with an array that matches the like operator (case insensitive)', (done) => { it('should respond with an array that matches the like operator (case insensitive)', () => (
request(server) request(server)
.get('/tags?body_like=photo') .get('/tags?body_like=photo')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
@ -346,12 +346,12 @@ describe('Server', () => {
db.tags[1], db.tags[1],
db.tags[2] db.tags[2]
]) ])
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:parent/:parentId/:resource', () => { describe('GET /:parent/:parentId/:resource', () => {
it('should respond with json and corresponding nested resources', (done) => { it('should respond with json and corresponding nested resources', () => (
request(server) request(server)
.get('/posts/1/comments') .get('/posts/1/comments')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
@ -359,214 +359,197 @@ describe('Server', () => {
db.comments[0], db.comments[0],
db.comments[1] db.comments[1]
]) ])
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /:resource/:id', () => { describe('GET /:resource/:id', () => {
it('should respond with json and corresponding resource', (done) => { it('should respond with json and corresponding resource', () => (
request(server) request(server)
.get('/posts/1') .get('/posts/1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.posts[0]) .expect(db.posts[0])
.expect(200, done) .expect(200)
}) ))
it('should support string id, respond with json and corresponding resource', (done) => { it('should support string id, respond with json and corresponding resource', () => (
request(server) request(server)
.get('/refs/abcd-1234') .get('/refs/abcd-1234')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.refs[0]) .expect(db.refs[0])
.expect(200, done) .expect(200)
}) ))
it('should support integer id as string', (done) => { it('should support integer id as string', () => (
request(server) request(server)
.get('/stringIds/1234') .get('/stringIds/1234')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(db.stringIds[0]) .expect(db.stringIds[0])
.expect(200, done) .expect(200)
}) ))
it('should respond with 404 if resource is not found', (done) => { it('should respond with 404 if resource is not found', () => (
request(server) request(server)
.get('/posts/9001') .get('/posts/9001')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect({}) .expect({})
.expect(404, done) .expect(404)
}) ))
}) })
describe('GET /:resource?_embed=', () => { describe('GET /:resource?_embed=', () => {
it('should respond with corresponding resources and embedded resources', (done) => { it('should respond with corresponding resources and embedded resources', () => {
const posts = _.cloneDeep(db.posts) const posts = _.cloneDeep(db.posts)
posts[0].comments = [ db.comments[0], db.comments[1] ] posts[0].comments = [ db.comments[0], db.comments[1] ]
posts[1].comments = [ db.comments[2], db.comments[3], db.comments[4] ] posts[1].comments = [ db.comments[2], db.comments[3], db.comments[4] ]
request(server) return request(server)
.get('/posts?_embed=comments') .get('/posts?_embed=comments')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(posts) .expect(posts)
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource?_embed&_embed=', () => { describe('GET /:resource?_embed&_embed=', () => {
it('should respond with corresponding resources and embedded resources', (done) => { it('should respond with corresponding resources and embedded resources', () => {
const posts = _.cloneDeep(db.posts) const posts = _.cloneDeep(db.posts)
posts[0].comments = [ db.comments[0], db.comments[1] ] posts[0].comments = [ db.comments[0], db.comments[1] ]
posts[0].refs = [ db.refs[0] ] posts[0].refs = [ db.refs[0] ]
posts[1].comments = [ db.comments[2], db.comments[3], db.comments[4] ] posts[1].comments = [ db.comments[2], db.comments[3], db.comments[4] ]
posts[1].refs = [] posts[1].refs = []
request(server) return request(server)
.get('/posts?_embed=comments&_embed=refs') .get('/posts?_embed=comments&_embed=refs')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(posts) .expect(posts)
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource/:id?_embed=', () => { describe('GET /:resource/:id?_embed=', () => {
it('should respond with corresponding resources and embedded resources', (done) => { it('should respond with corresponding resources and embedded resources', () => {
const post = _.cloneDeep(db.posts[0]) const post = _.cloneDeep(db.posts[0])
post.comments = [ db.comments[0], db.comments[1] ] post.comments = [ db.comments[0], db.comments[1] ]
request(server) return request(server)
.get('/posts/1?_embed=comments') .get('/posts/1?_embed=comments')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(post) .expect(post)
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource/:id?_embed=&_embed=', () => { describe('GET /:resource/:id?_embed=&_embed=', () => {
it('should respond with corresponding resource and embedded resources', (done) => { it('should respond with corresponding resource and embedded resources', () => {
const post = _.cloneDeep(db.posts[0]) const post = _.cloneDeep(db.posts[0])
post.comments = [ db.comments[0], db.comments[1] ] post.comments = [ db.comments[0], db.comments[1] ]
post.refs = [db.refs[0]] post.refs = [db.refs[0]]
request(server) return request(server)
.get('/posts/1?_embed=comments&_embed=refs') .get('/posts/1?_embed=comments&_embed=refs')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(post) .expect(post)
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource?_expand=', () => { describe('GET /:resource?_expand=', () => {
it('should respond with corresponding resource and expanded inner resources', (done) => { it('should respond with corresponding resource and expanded inner resources', () => {
const refs = _.cloneDeep(db.refs) const refs = _.cloneDeep(db.refs)
refs[0].post = db.posts[0] refs[0].post = db.posts[0]
request(server) return request(server)
.get('/refs?_expand=post') .get('/refs?_expand=post')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(refs) .expect(refs)
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource/:id?_expand=', () => { describe('GET /:resource/:id?_expand=', () => {
it('should respond with corresponding resource and expanded inner resources', (done) => { it('should respond with corresponding resource and expanded inner resources', () => {
const comment = _.cloneDeep(db.comments[0]) const comment = _.cloneDeep(db.comments[0])
comment.post = db.posts[0] comment.post = db.posts[0]
request(server) return request(server)
.get('/comments/1?_expand=post') .get('/comments/1?_expand=post')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(comment) .expect(comment)
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource?_expand=&_expand', () => { describe('GET /:resource?_expand=&_expand', () => {
it('should respond with corresponding resource and expanded inner resources', (done) => { it('should respond with corresponding resource and expanded inner resources', () => {
const refs = _.cloneDeep(db.refs) const refs = _.cloneDeep(db.refs)
refs[0].post = db.posts[0] refs[0].post = db.posts[0]
refs[0].user = db.users[0] refs[0].user = db.users[0]
request(server) return request(server)
.get('/refs?_expand=post&_expand=user') .get('/refs?_expand=post&_expand=user')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(refs) .expect(refs)
.expect(200, done) .expect(200)
}) })
}) })
describe('GET /:resource/:id?_expand=&_expand=', () => { describe('GET /:resource/:id?_expand=&_expand=', () => {
it('should respond with corresponding resource and expanded inner resources', (done) => { it('should respond with corresponding resource and expanded inner resources', () => {
const comments = db.comments[0] const comments = db.comments[0]
comments.post = db.posts[0] comments.post = db.posts[0]
comments.user = db.users[0] comments.user = db.users[0]
request(server) return request(server)
.get('/comments/1?_expand=post&_expand=user') .get('/comments/1?_expand=post&_expand=user')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(comments) .expect(comments)
.expect(200, done) .expect(200)
}) })
}) })
describe('POST /:resource', () => { describe('POST /:resource', () => {
it('should respond with json, create a resource and increment id', it('should respond with json, create a resource and increment id', async () => {
(done) => { await request(server)
request(server) .post('/posts')
.post('/posts') .send({body: 'foo', booleanValue: true, integerValue: 1})
.send({body: 'foo', booleanValue: true, integerValue: 1}) .expect('Access-Control-Expose-Headers', 'Location')
.expect('Access-Control-Expose-Headers', 'Location') .expect('Location', /posts\/3$/)
.expect('Location', /posts\/3$/) .expect('Content-Type', /json/)
.expect('Content-Type', /json/) .expect({id: 3, body: 'foo', booleanValue: true, integerValue: 1})
.expect({id: 3, body: 'foo', booleanValue: true, integerValue: 1}) .expect(201)
.expect(201) assert.equal(db.posts.length, 3)
.end((err, res) => { })
if (err) return done(err)
assert.equal(db.posts.length, 3)
done()
})
}
)
it('should support x-www-form-urlencoded', it('should support x-www-form-urlencoded', async () => {
(done) => { await request(server)
request(server) .post('/posts')
.post('/posts') .type('form')
.type('form') .send({body: 'foo', booleanValue: true, integerValue: 1})
.send({body: 'foo', booleanValue: true, integerValue: 1}) .expect('Content-Type', /json/)
.expect('Content-Type', /json/) // x-www-form-urlencoded will convert to string
// x-www-form-urlencoded will convert to string .expect({id: 3, body: 'foo', booleanValue: 'true', integerValue: '1'})
.expect({id: 3, body: 'foo', booleanValue: 'true', integerValue: '1'}) .expect(201)
.expect(201) assert.equal(db.posts.length, 3)
.end((err, res) => { })
if (err) return done(err)
assert.equal(db.posts.length, 3)
done()
})
}
)
it('should respond with json, create a resource and generate string id', it('should respond with json, create a resource and generate string id', async () => {
(done) => { await request(server)
request(server) .post('/refs')
.post('/refs') .send({url: 'http://foo.com', postId: '1'})
.send({url: 'http://foo.com', postId: '1'}) .expect('Content-Type', /json/)
.expect('Content-Type', /json/) .expect(201)
.expect(201) assert.equal(db.refs.length, 2)
.end((err, res) => { })
if (err) return done(err)
assert.equal(db.refs.length, 2)
done()
})
})
}) })
describe('POST /:parent/:parentId/:resource', () => { describe('POST /:parent/:parentId/:resource', () => {
it('should respond with json and set parentId', (done) => { it('should respond with json and set parentId', () => (
request(server) request(server)
.post('/posts/1/comments') .post('/posts/1/comments')
.send({body: 'foo'}) .send({body: 'foo'})
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect({id: 6, postId: 1, body: 'foo'}) .expect({id: 6, postId: 1, body: 'foo'})
.expect(201, done) .expect(201)
}) ))
}) })
describe('PUT /:resource/:id', () => { describe('PUT /:resource/:id', () => {
it('should respond with json and replace resource', (done) => { it('should respond with json and replace resource', async () => {
var post = {id: 1, booleanValue: true, integerValue: 1} const post = {id: 1, booleanValue: true, integerValue: 1}
request(server) const res = await request(server)
.put('/posts/1') .put('/posts/1')
.set('Accept', 'application/json') .set('Accept', 'application/json')
// body property omitted to test that the resource is replaced // body property omitted to test that the resource is replaced
@ -574,105 +557,93 @@ describe('Server', () => {
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(post) .expect(post)
.expect(200) .expect(200)
.end((err, res) => { // TODO find a "supertest" way to test this
if (err) return done(err) // https://github.com/typicode/json-server/issues/396
// TODO find a "supertest" way to test this assert.deepStrictEqual(res.body, post)
// https://github.com/typicode/json-server/issues/396 // assert it was created in database too
assert.deepStrictEqual(res.body, post) assert.deepStrictEqual(db.posts[0], post)
// assert it was created in database too
assert.deepStrictEqual(db.posts[0], post)
done()
})
}) })
it('should respond with 404 if resource is not found', (done) => { it('should respond with 404 if resource is not found', () => (
request(server) request(server)
.put('/posts/9001') .put('/posts/9001')
.send({id: 1, body: 'bar'}) .send({id: 1, body: 'bar'})
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect({}) .expect({})
.expect(404, done) .expect(404)
}) ))
}) })
describe('PATCH /:resource/:id', () => { describe('PATCH /:resource/:id', () => {
it('should respond with json and update resource', (done) => { it('should respond with json and update resource', async () => {
var partial = {body: 'bar'} const partial = {body: 'bar'}
var post = {id: 1, body: 'bar'} const post = {id: 1, body: 'bar'}
request(server) const res = await request(server)
.patch('/posts/1') .patch('/posts/1')
.send(partial) .send(partial)
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(post) .expect(post)
.expect(200) .expect(200)
.end((err, res) => { assert.deepStrictEqual(res.body, post)
if (err) return done(err) // assert it was created in database too
assert.deepStrictEqual(res.body, post) assert.deepStrictEqual(db.posts[0], post)
// assert it was created in database too
assert.deepStrictEqual(db.posts[0], post)
done()
})
}) })
it('should respond with 404 if resource is not found', (done) => { it('should respond with 404 if resource is not found', () => (
request(server) request(server)
.patch('/posts/9001') .patch('/posts/9001')
.send({body: 'bar'}) .send({body: 'bar'})
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect({}) .expect({})
.expect(404, done) .expect(404)
}) ))
}) })
describe('DELETE /:resource/:id', () => { describe('DELETE /:resource/:id', () => {
it('should respond with empty data, destroy resource and dependent resources', (done) => { it('should respond with empty data, destroy resource and dependent resources', async () => {
request(server) await request(server)
.del('/posts/1') .del('/posts/1')
.expect({}) .expect({})
.expect(200) .expect(200)
.end((err, res) => { assert.equal(db.posts.length, 1)
if (err) return done(err) assert.equal(db.comments.length, 3)
assert.equal(db.posts.length, 1)
assert.equal(db.comments.length, 3)
done()
})
}) })
it('should respond with 404 if resource is not found', (done) => { it('should respond with 404 if resource is not found', () => (
request(server) request(server)
.del('/posts/9001') .del('/posts/9001')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect({}) .expect({})
.expect(404, done) .expect(404)
}) ))
}) })
describe('Static routes', () => { describe('Static routes', () => {
describe('GET /', () => { describe('GET /', () => {
it('should respond with html', (done) => { it('should respond with html', () => (
request(server) request(server)
.get('/') .get('/')
.expect(/You're successfully running JSON Server/) .expect(/You're successfully running JSON Server/)
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /main.js', () => { describe('GET /main.js', () => {
it('should respond with js', (done) => { it('should respond with js', () => (
request(server) request(server)
.get('/main.js') .get('/main.js')
.expect('Content-Type', /javascript/) .expect('Content-Type', /javascript/)
.expect(200, done) .expect(200)
}) ))
}) })
describe('GET /style.css', () => { describe('GET /style.css', () => {
it('should respond with css', (done) => { it('should respond with css', () => (
request(server) request(server)
.get('/style.css') .get('/style.css')
.expect('Content-Type', /css/) .expect('Content-Type', /css/)
.expect(200, done) .expect(200)
}) ))
}) })
}) })
@ -683,82 +654,74 @@ describe('Server', () => {
}) })
describe('Responses', () => { describe('Responses', () => {
it('should have no cache headers (for IE)', (done) => { it('should have no cache headers (for IE)', () => (
request(server) request(server)
.get('/db') .get('/db')
.expect('Cache-Control', 'no-cache') .expect('Cache-Control', 'no-cache')
.expect('Pragma', 'no-cache') .expect('Pragma', 'no-cache')
.expect('Expires', '-1') .expect('Expires', '-1')
.end(done) ))
})
}) })
describe('Rewriter', () => { describe('Rewriter', () => {
it('should rewrite using prefix', (done) => { it('should rewrite using prefix', () => (
request(server) request(server)
.get('/api/posts/1') .get('/api/posts/1')
.expect(db.posts[0]) .expect(db.posts[0])
.end(done) ))
})
it('should rewrite using params', (done) => { it('should rewrite using params', () => (
request(server) request(server)
.get('/blog/posts/1/show') .get('/blog/posts/1/show')
.expect(db.posts[0]) .expect(db.posts[0])
.end(done) ))
})
it('should rewrite using query without params', (done) => { it('should rewrite using query without params', () => {
const expectedPost = _.cloneDeep(db.posts[0]) const expectedPost = _.cloneDeep(db.posts[0])
expectedPost.comments = [ db.comments[0], db.comments[1] ] expectedPost.comments = [ db.comments[0], db.comments[1] ]
request(server) return request(server)
.get('/firstpostwithcomments') .get('/firstpostwithcomments')
.expect(expectedPost) .expect(expectedPost)
.end(done)
}) })
it('should rewrite using params and query', (done) => { it('should rewrite using params and query', () => (
request(server) request(server)
.get('/comments/special/1-quux') .get('/comments/special/1-quux')
.expect([db.comments[4]]) .expect([db.comments[4]])
.end(done) ))
})
// TODO // TODO
// it('should rewrite query params', (done) => { // it('should rewrite query params', () => (
// request(server) // request(server)
// .get('/articles?_id=1') // .get('/articles?_id=1')
// .expect(db.posts[0]) // .expect(db.posts[0])
// .end(done) // .end(done)
// }) // })
it('should expose routes', (done) => { it('should expose routes', () => (
request(server) request(server)
.get('/__rules') .get('/__rules')
.expect(rewriterRules) .expect(rewriterRules)
.end(done) ))
})
}) })
describe('router.render', (done) => { describe('router.render', () => {
beforeEach(() => { beforeEach(() => {
router.render = (req, res) => { router.render = (req, res) => {
res.jsonp({ res.jsonp({ data: res.locals.data })
data: res.locals.data
})
} }
}) })
it('should be possible to wrap response', (done) => { it('should be possible to wrap response', () => (
request(server) request(server)
.get('/posts/1') .get('/posts/1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect({ data: db.posts[0] }) .expect({ data: db.posts[0] })
.expect(200, done) .expect(200)
}) ))
}) })
describe('router.db._.id', (done) => { describe('router.db._.id', () => {
beforeEach(() => { beforeEach(() => {
router.db.setState({ router.db.setState({
posts: [ posts: [
@ -769,21 +732,21 @@ describe('Server', () => {
router.db._.id = '_id' router.db._.id = '_id'
}) })
it('should be possible to GET using a different id property', (done) => { it('should be possible to GET using a different id property', () => (
request(server) request(server)
.get('/posts/1') .get('/posts/1')
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(router.db.getState().posts[0]) .expect(router.db.getState().posts[0])
.expect(200, done) .expect(200)
}) ))
it('should be possible to POST using a different id property', (done) => { it('should be possible to POST using a different id property', () => (
request(server) request(server)
.post('/posts') .post('/posts')
.send({ body: 'hello' }) .send({ body: 'hello' })
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect({ _id: 2, body: 'hello' }) .expect({ _id: 2, body: 'hello' })
.expect(201, done) .expect(201)
}) ))
}) })
}) })

View File

@ -1,12 +1,12 @@
const request = require('supertest') const request = require('supertest')
const jsonServer = require('../../src/server') const jsonServer = require('../../src/server')
describe('Server', function () { describe('Server', () => {
let server let server
let router let router
let db let db
beforeEach(function () { beforeEach(() => {
db = {} db = {}
db.user = { db.user = {
@ -20,44 +20,44 @@ describe('Server', function () {
server.use(router) server.use(router)
}) })
describe('GET /:resource', function () { describe('GET /:resource', () => {
it('should respond with corresponding resource', function (done) { it('should respond with corresponding resource', () => (
request(server) request(server)
.get('/user') .get('/user')
.expect(db.user) .expect(db.user)
.expect(200, done) .expect(200)
}) ))
}) })
describe('POST /:resource', function () { describe('POST /:resource', () => {
it('should create resource', function (done) { it('should create resource', () => {
const user = { name: 'bar' } const user = { name: 'bar' }
request(server) return request(server)
.post('/user') .post('/user')
.send(user) .send(user)
.expect(user) .expect(user)
.expect(201, done) .expect(201)
}) })
}) })
describe('PUT /:resource', function () { describe('PUT /:resource', () => {
it('should update resource', function (done) { it('should update resource', () => {
const user = { name: 'bar' } const user = { name: 'bar' }
request(server) return request(server)
.put('/user') .put('/user')
.send(user) .send(user)
.expect(user) .expect(user)
.expect(200, done) .expect(200)
}) })
}) })
describe('PATCH /:resource', function () { describe('PATCH /:resource', () => {
it('should update resource', function (done) { it('should update resource', () => (
request(server) request(server)
.patch('/user') .patch('/user')
.send({ name: 'bar' }) .send({ name: 'bar' })
.expect({ name: 'bar', email: 'foo@example.com' }) .expect({ name: 'bar', email: 'foo@example.com' })
.expect(200, done) .expect(200)
}) ))
}) })
}) })

View File

@ -1,12 +1,12 @@
const assert = require('assert') const assert = require('assert')
const utils = require('../../src/server/utils') const utils = require('../../src/server/utils')
describe('utils', function () { describe('utils', () => {
describe('getPage', function () { describe('getPage', () => {
const array = [1, 2, 3, 4, 5] const array = [1, 2, 3, 4, 5]
const perPage = 2 const perPage = 2
it('should return first page', function () { it('should return first page', () => {
assert.deepEqual( assert.deepEqual(
utils.getPage(array, 1, perPage), utils.getPage(array, 1, perPage),
{ {
@ -19,7 +19,7 @@ describe('utils', function () {
) )
}) })
it('should return second page', function () { it('should return second page', () => {
assert.deepEqual( assert.deepEqual(
utils.getPage(array, 2, perPage), utils.getPage(array, 2, perPage),
{ {
@ -33,7 +33,7 @@ describe('utils', function () {
) )
}) })
it('should return third page (last)', function () { it('should return third page (last)', () => {
assert.deepEqual( assert.deepEqual(
utils.getPage(array, 3, perPage), utils.getPage(array, 3, perPage),
{ {
@ -46,7 +46,7 @@ describe('utils', function () {
) )
}) })
it('should return an empty array if page is greater than the last page', function () { it('should return an empty array if page is greater than the last page', () => {
assert.deepEqual( assert.deepEqual(
utils.getPage(array, 99, perPage), utils.getPage(array, 99, perPage),
{ {
@ -55,7 +55,7 @@ describe('utils', function () {
) )
}) })
it('should return the array if perPage is greater than the array size', function () { it('should return the array if perPage is greater than the array size', () => {
assert.deepEqual( assert.deepEqual(
utils.getPage(array, 1, 99), utils.getPage(array, 1, 99),
{ {
@ -64,7 +64,7 @@ describe('utils', function () {
) )
}) })
it('should return an empty array if the array is empty', function () { it('should return an empty array if the array is empty', () => {
assert.deepEqual( assert.deepEqual(
utils.getPage([], 1, 1), utils.getPage([], 1, 1),
{ {