Fix toJSON responses

This is a non-obvious one. Hapi is happy to convert raw sequelize
instances to proper JSON (likely because Sequelize does nice things),
but we do that, we can't use `config.response.schema`, because it
receives the full sequelize instance instead of JSON.

This is a patch release.
This commit is contained in:
Joey Baker 2016-09-07 21:06:34 -07:00
parent 85111c7dc8
commit 4e078f5ba5
2 changed files with 29 additions and 15 deletions

View File

@ -143,7 +143,7 @@ export const list = ({ server, model, prefix = '/', config }) => {
where, include, where, include,
}); });
reply(list); reply(list.map((item) => item.toJSON()));
}, },
config, config,
@ -168,7 +168,7 @@ export const get = ({ server, model, prefix = '/', config }) => {
if (!instance) return void reply(notFound(`${id} not found.`)); if (!instance) return void reply(notFound(`${id} not found.`));
reply(instance); reply(instance.toJSON());
}, },
config: _.defaultsDeep(config, { config: _.defaultsDeep(config, {
validate: { validate: {
@ -196,7 +196,7 @@ export const scope = ({ server, model, prefix = '/', config }) => {
const list = await model.scope(request.params.scope).findAll({ include, where }); const list = await model.scope(request.params.scope).findAll({ include, where });
reply(list); reply(list.map((item) => item.toJSON()));
}, },
config: _.defaultsDeep(config, { config: _.defaultsDeep(config, {
validate: { validate: {
@ -217,7 +217,7 @@ export const create = ({ server, model, prefix = '/', config }) => {
async handler(request, reply) { async handler(request, reply) {
const instance = await model.create(request.payload); const instance = await model.create(request.payload);
reply(instance); reply(instance.toJSON());
}, },
config, config,
@ -238,7 +238,8 @@ export const destroy = ({ server, model, prefix = '/', config }) => {
await Promise.all(list.map(instance => instance.destroy())); await Promise.all(list.map(instance => instance.destroy()));
reply(list.length === 1 ? list[0] : list); const listAsJSON = list.map((item) => item.toJSON());
reply(listAsJSON.length === 1 ? listAsJSON[0] : listAsJSON);
}, },
config, config,
@ -258,7 +259,8 @@ export const destroyAll = ({ server, model, prefix = '/', config }) => {
await Promise.all(list.map(instance => instance.destroy())); await Promise.all(list.map(instance => instance.destroy()));
reply(list.length === 1 ? list[0] : list); const listAsJSON = list.map((item) => item.toJSON());
reply(listAsJSON.length === 1 ? listAsJSON[0] : listAsJSON);
}, },
config, config,
@ -283,7 +285,8 @@ export const destroyScope = ({ server, model, prefix = '/', config }) => {
await Promise.all(list.map(instance => instance.destroy())); await Promise.all(list.map(instance => instance.destroy()));
reply(list); const listAsJSON = list.map((item) => item.toJSON());
reply(listAsJSON.length === 1 ? listAsJSON[0] : listAsJSON);
}, },
config: _.defaultsDeep(config, { config: _.defaultsDeep(config, {
validate: { validate: {
@ -309,7 +312,7 @@ export const update = ({ server, model, prefix = '/', config }) => {
await instance.update(request.payload); await instance.update(request.payload);
reply(instance); reply(instance.toJSON());
}, },
config: _.defaultsDeep(config, { config: _.defaultsDeep(config, {

View File

@ -1,6 +1,7 @@
import test from 'ava'; import test from 'ava';
import { list } from './crud.js'; import { list } from './crud.js';
import { stub } from 'sinon'; import { stub } from 'sinon';
import uniqueId from 'lodash/uniqueId.js';
import 'sinon-bluebird'; import 'sinon-bluebird';
const METHODS = { const METHODS = {
@ -13,12 +14,23 @@ test.beforeEach('setup server', (t) => {
}; };
}); });
test.beforeEach('setup model', (t) => { const makeModel = () => {
t.context.model = { const id = uniqueId();
return {
findAll: stub(), findAll: stub(),
_plural: 'models', _plural: 'models',
_singular: 'model', _singular: 'model',
toJSON: () => ({ id }),
id,
}; };
};
test.beforeEach('setup model', (t) => {
t.context.model = makeModel();
});
test.beforeEach('setup models', (t) => {
t.context.models = [t.context.model, makeModel()];
}); });
test.beforeEach('setup request stub', (t) => { test.beforeEach('setup request stub', (t) => {
@ -93,12 +105,11 @@ test('crud#list config', (t) => {
}); });
test('crud#list handler', async (t) => { test('crud#list handler', async (t) => {
const { server, model, request, reply } = t.context; const { server, model, request, reply, models } = t.context;
const allModels = [{ id: 1 }, { id: 2 }];
list({ server, model }); list({ server, model });
const { handler } = server.route.args[0][0]; const { handler } = server.route.args[0][0];
model.findAll.resolves(allModels); model.findAll.resolves(models);
try { try {
await handler(request, reply); await handler(request, reply);
@ -115,9 +126,9 @@ test('crud#list handler', async (t) => {
const response = reply.args[0][0]; const response = reply.args[0][0];
t.is( t.deepEqual(
response, response,
allModels, models.map(({ id }) => ({ id })),
'responds with the list of models' 'responds with the list of models'
); );
}); });