From 869a675840fe54f0c1e169111c645b4e9db453ea Mon Sep 17 00:00:00 2001 From: VLE2FE Date: Wed, 17 Jun 2020 13:42:14 +0200 Subject: [PATCH] added status filter for materials --- api/material.yaml | 7 +++++++ src/routes/material.spec.ts | 37 +++++++++++++++++++++++++++++++++ src/routes/material.ts | 19 ++++++++++++++++- src/routes/validate/material.ts | 6 ++++++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/api/material.yaml b/api/material.yaml index 378628d..593afb1 100644 --- a/api/material.yaml +++ b/api/material.yaml @@ -5,6 +5,13 @@ x-doc: returns only materials with status 10 tags: - /material + parameters: + - name: status + description: 'values: validated|new|all, defaults to validated' + in: query + schema: + type: string + example: all responses: 200: description: all material details diff --git a/src/routes/material.spec.ts b/src/routes/material.spec.ts index e91e87e..e412615 100644 --- a/src/routes/material.spec.ts +++ b/src/routes/material.spec.ts @@ -72,6 +72,43 @@ describe('/material', () => { done(); }); }); + it('allows filtering by state', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/materials?status=new', + auth: {basic: 'janedoe'}, + httpStatus: 200 + }).end((err, res) => { + if (err) return done(err); + const json = require('../test/db.json'); + should(res.body).have.lengthOf(json.collections.materials.filter(e => e.status === globals.status.new).length); + should(res.body).matchEach(material => { + should(material).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers'); + should(material).have.property('_id').be.type('string'); + should(material).have.property('name').be.type('string'); + should(material).have.property('supplier').be.type('string'); + should(material).have.property('group').be.type('string'); + should(material).have.property('mineral').be.type('number'); + should(material).have.property('glass_fiber').be.type('number'); + should(material).have.property('carbon_fiber').be.type('number'); + should(material.numbers).matchEach(number => { + should(number).have.only.keys('color', 'number'); + should(number).have.property('color').be.type('string'); + should(number).have.property('number').be.type('string'); + }); + }); + done(); + }); + }); + it('rejects an invalid state name', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/materials?status=xxx', + auth: {basic: 'janedoe'}, + httpStatus: 400, + res: {status: 'Invalid body format', details: '"status" must be one of [validated, new, all]'} + }); + }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'get', diff --git a/src/routes/material.ts b/src/routes/material.ts index 8373c9d..3f34e3a 100644 --- a/src/routes/material.ts +++ b/src/routes/material.ts @@ -19,7 +19,24 @@ const router = express.Router(); router.get('/materials', (req, res, next) => { if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return; - MaterialModel.find({status:globals.status.validated}).populate('group_id').populate('supplier_id').lean().exec((err, data) => { + const {error, value: filters} = MaterialValidate.query(req.query); + if (error) return res400(error, res); + + let conditions; + + if (filters.hasOwnProperty('status')) { + if(filters.status === 'all') { + conditions = {$or: [{status: globals.status.validated}, {status: globals.status.new}]} + } + else { + conditions = {status: globals.status[filters.status]}; + } + } + else { // default + conditions = {status: globals.status.validated}; + } + + MaterialModel.find(conditions).populate('group_id').populate('supplier_id').lean().exec((err, data) => { if (err) return next(err); res.json(_.compact(data.map(e => MaterialValidate.output(e)))); // validate all and filter null values from validation errors diff --git a/src/routes/validate/material.ts b/src/routes/validate/material.ts index 7a2c3fb..969ac43 100644 --- a/src/routes/validate/material.ts +++ b/src/routes/validate/material.ts @@ -107,4 +107,10 @@ export default class MaterialValidate { // validate input for material numbers: this.material.numbers }); } + + static query (data) { + return Joi.object({ + status: Joi.string().valid('validated', 'new', 'all') + }).validate(data); + } } \ No newline at end of file