Skip to content

Commit

Permalink
Add option to plural routes
Browse files Browse the repository at this point in the history
  • Loading branch information
typicode committed Dec 25, 2018
1 parent aef0287 commit bbc2011
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 22 deletions.
81 changes: 81 additions & 0 deletions __tests__/server/plural-fake.js
@@ -0,0 +1,81 @@
const assert = require('assert')
const request = require('supertest')
const jsonServer = require('../../src/server')

describe('Fake server', () => {
let server
let router
let db

beforeEach(() => {
db = {}

db.posts = [{ id: 1, body: 'foo' }, { id: 2, body: 'bar' }]

server = jsonServer.create()
router = jsonServer.router(db, { _isFake: true })
server.use(jsonServer.defaults())
server.use(router)
})

describe('POST /:resource', () => {
test('should respond with json, create a resource and increment id', async () => {
await request(server)
.post('/posts')
.send({ body: 'foo', booleanValue: true, integerValue: 1 })
.expect('Access-Control-Expose-Headers', 'Location')
.expect('Location', /posts\/3$/)
.expect('Content-Type', /json/)
.expect({ id: 3, body: 'foo', booleanValue: true, integerValue: 1 })
.expect(201)
// assert it was not created in database
assert.equal(db.posts.length, 2)
})
})

describe('PUT /:resource/:id', () => {
test('should respond with json and replace resource', async () => {
const post = { id: 1, booleanValue: true, integerValue: 1 }
const res = await request(server)
.put('/posts/1')
.set('Accept', 'application/json')
// body property omitted to test that the resource is replaced
.send(post)
.expect('Content-Type', /json/)
.expect(post)
.expect(200)
// TODO find a "supertest" way to test this
// https://github.com/typicode/json-server/issues/396
assert.deepStrictEqual(res.body, post)
// assert it was not created in database
assert.notDeepStrictEqual(db.posts[0], post)
})
})

describe('PATCH /:resource/:id', () => {
test('should respond with json and update resource', async () => {
const partial = { body: 'bar' }
const post = { id: 1, body: 'bar' }
const res = await request(server)
.patch('/posts/1')
.send(partial)
.expect('Content-Type', /json/)
.expect(post)
.expect(200)
assert.deepStrictEqual(res.body, post)
// assert it was not created in database
assert.notDeepStrictEqual(db.posts[0], post)
})
})

describe('DELETE /:resource/:id', () => {
test('should respond with empty data, destroy resource and dependent resources', async () => {
await request(server)
.del('/posts/1')
.expect({})
.expect(200)
// assert it was not created in database
assert.equal(db.posts.length, 2)
})
})
})
2 changes: 1 addition & 1 deletion src/server/router/index.js
Expand Up @@ -12,7 +12,7 @@ const nested = require('./nested')
const singular = require('./singular')
const mixins = require('../mixins')

module.exports = (db, opts = { foreignKeySuffix: 'Id' }) => {
module.exports = (db, opts = { foreignKeySuffix: 'Id', _isFake: false }) => {
if (typeof db === 'string') {
db = low(new FileSync(db))
} else if (!_.has(db, '__chain__') || !_.has(db, '__wrapped__')) {
Expand Down
72 changes: 51 additions & 21 deletions src/server/router/plural.js
Expand Up @@ -255,10 +255,19 @@ module.exports = (db, name, opts) => {

// POST /name
function create(req, res, next) {
const resource = db
.get(name)
.insert(req.body)
.value()
let resource
if (opts._isFake) {
const id = db
.get(name)
.createId()
.value()
resource = { ...req.body, id }
} else {
resource = db
.get(name)
.insert(req.body)
.value()
}

res.setHeader('Access-Control-Expose-Headers', 'Location')
res.location(`${getFullURL(req)}/${resource.id}`)
Expand All @@ -273,14 +282,29 @@ module.exports = (db, name, opts) => {
// PATCH /name/:id
function update(req, res, next) {
const id = req.params.id
let chain = db.get(name)
let resource

if (opts._isFake) {
resource = db
.get(name)
.getById(id)
.value()

if (req.method === 'PATCH') {
resource = { ...resource, ...req.body }
} else {
resource = { ...req.body, id: resource.id }
}
} else {
let chain = db.get(name)

chain =
req.method === 'PATCH'
? chain.updateById(id, req.body)
: chain.replaceById(id, req.body)
chain =
req.method === 'PATCH'
? chain.updateById(id, req.body)
: chain.replaceById(id, req.body)

const resource = chain.value()
resource = chain.value()
}

if (resource) {
res.locals.data = resource
Expand All @@ -291,18 +315,24 @@ module.exports = (db, name, opts) => {

// DELETE /name/:id
function destroy(req, res, next) {
const resource = db
.get(name)
.removeById(req.params.id)
.value()

// Remove dependents documents
const removable = db._.getRemovable(db.getState(), opts)
removable.forEach(item => {
db.get(item.name)
.removeById(item.id)
let resource

if (opts._isFake) {
resource = db.get(name).value()
} else {
resource = db
.get(name)
.removeById(req.params.id)
.value()
})

// Remove dependents documents
const removable = db._.getRemovable(db.getState(), opts)
removable.forEach(item => {
db.get(item.name)
.removeById(item.id)
.value()
})
}

if (resource) {
res.locals.data = {}
Expand Down

0 comments on commit bbc2011

Please sign in to comment.