diff --git a/pages/api/__tests__/score.unit.test.js b/pages/api/__tests__/score.unit.test.js index 91a5733..3f08538 100644 --- a/pages/api/__tests__/score.unit.test.js +++ b/pages/api/__tests__/score.unit.test.js @@ -16,4 +16,72 @@ describe('score endpoint', () => { expect(res.end).toHaveBeenCalledWith('Method not allowed'); }); }); + describe('when called with a POST method', () => { + const emptyBody = { + jsonA: '{}', + jsonB: '{}', + }; + + const res = { end: jest.fn(), json: jest.fn() }; + const req = { + method: 'POST', + body: emptyBody, + }; + beforeEach(() => { + req.body = emptyBody; + }); + + it('should answer 200 ok', async () => { + // act + score(req, res); + + // assert + expect(res.statusCode).toEqual(200); + }); + it('should return a json object with the basic keys', async () => { + // act + score(req, res); + + // assert + expect(res.json).toHaveBeenCalledWith({ + children: [], + count: 0, + matched: 0, + metaData: { + key: '/', + }, + scoreNumber: 1, + }); + }); + describe.each([ + 'jsonA', + 'jsonB', + ])('when param %s is not present', (json) => { + it('should return a 422 explaining the missing param', async () => { + // arrange + req.body[json] = undefined; + // act + score(req, res); + + // assert + expect(res.statusCode).toEqual(422); + expect(res.end).toHaveBeenCalledWith(`Missing Param: Body must contain ${json}`); + }); + }); + describe.each([ + 'jsonA', + 'jsonB', + ])('when param %s is not JSON-formatted', (json) => { + it('should return a 422 explaining the missing param', async () => { + // arrange + req.body[json] = 'some non-json string'; + // act + score(req, res); + + // assert + expect(res.statusCode).toEqual(422); + expect(res.end).toHaveBeenCalledWith(`Could not parse ${json} param as a JSON object`); + }); + }); + }); }); diff --git a/pages/api/score.js b/pages/api/score.js index 8f385fc..2d74bbe 100644 --- a/pages/api/score.js +++ b/pages/api/score.js @@ -1,10 +1,42 @@ import { calculateScore } from '~/utils/score'; +function isJson(str) { + try { + JSON.parse(str); + } catch (e) { + return false; + } + return true; +} + +/** + * Endpoint that triggers the calculateScore function, checks that params are correct (jsonA and jsonB are JSON objects) + * @param req + * @param res + * @return {*|void|Promise} + */ export default (req, res) => { if (req.method === 'POST') { - res.statusCode = 200; - res.json(calculateScore(JSON.parse(req.body.jsonA), JSON.parse(req.body.jsonB))); + const validParams = ['jsonA', 'jsonB'].map((json) => { + res.statusCode = 422; + if (!req.body[json]) { + res.end(`Missing Param: Body must contain ${json}`); + return false; + } + if (!isJson(req.body[json])) { + res.end(`Could not parse ${json} param as a JSON object`); + return false; + } + return true; + }); + + if (validParams.every((isValid) => isValid === true)) { + res.statusCode = 200; + return res.json(calculateScore(JSON.parse(req.body.jsonA), JSON.parse(req.body.jsonB))); + } + } else { + res.statusCode = 405; + return res.end('Method not allowed'); } - res.statusCode = 405; - res.end('Method not allowed'); + return null; };