diff --git a/api/schemas.yaml b/api/schemas.yaml index 7141cbb..3be9b11 100644 --- a/api/schemas.yaml +++ b/api/schemas.yaml @@ -111,7 +111,7 @@ Material: - $ref: 'api.yaml#/components/schemas/Color' properties: number: - type: number + type: string example: 5514263423 Condition: diff --git a/src/models/material.ts b/src/models/material.ts index a5378e0..71d6b34 100644 --- a/src/models/material.ts +++ b/src/models/material.ts @@ -9,9 +9,9 @@ const MaterialSchema = new mongoose.Schema({ carbon_fiber: String, numbers: [{ color: String, - number: Number + number: String }], status: Number -}); +}, {minimize: false}); export default mongoose.model('material', MaterialSchema); \ No newline at end of file diff --git a/src/routes/condition.spec.ts b/src/routes/condition.spec.ts index 5881e4b..8b4a73c 100644 --- a/src/routes/condition.spec.ts +++ b/src/routes/condition.spec.ts @@ -333,7 +333,7 @@ describe('/condition', () => { }); }); - describe('POST /condition/new', () => { // TODO: sample number generation + describe('POST /condition/new', () => { it('returns the right condition', done => { TestHelper.request(server, done, { method: 'post', diff --git a/src/routes/material.spec.ts b/src/routes/material.spec.ts index 0faf04e..746a620 100644 --- a/src/routes/material.spec.ts +++ b/src/routes/material.spec.ts @@ -1,8 +1,8 @@ import should from 'should/as-function'; +import _ from 'lodash'; import MaterialModel from '../models/material'; import TestHelper from "../test/helper"; -// TODO: numbers with color only (no number) // TODO: deal with numbers with leading zeros describe('/material', () => { @@ -21,7 +21,6 @@ describe('/material', () => { }).end((err, res) => { if (err) return done(err); const json = require('../test/db.json'); - console.log(res.body); should(res.body).have.lengthOf(json.collections.materials.filter(e => e.status === 10).length); should(res.body).matchEach(material => { should(material).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers'); @@ -35,7 +34,7 @@ describe('/material', () => { 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('number'); + should(number).have.property('number').be.type('string'); }); }); done(); @@ -63,7 +62,7 @@ describe('/material', () => { 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('number'); + should(number).have.property('number').be.type('string'); }); }); done(); @@ -85,7 +84,7 @@ describe('/material', () => { url: '/material/100000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 200, - res: {_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]} + res: {_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: '5514263423'}, {color: 'natural', number: '5514263422'}]} }); }); it('returns the right material for an API key', done => { @@ -97,6 +96,15 @@ describe('/material', () => { res: {_id: '100000000000000000000003', name: 'PA GF 50 black (2706)', supplier: 'Akro-Plastic', group: 'PA66+PA6I/6T', mineral: 0, glass_fiber: 0, carbon_fiber: 0, numbers: []} }); }); + it('returns a material with a color without number', done => { + TestHelper.request(server, done, { + method: 'get', + url: '/material/100000000000000000000007', + auth: {basic: 'janedoe'}, + httpStatus: 200, + res: {_id: '100000000000000000000007', name: 'Ultramid A4H', supplier: 'BASF', group: 'PA66', mineral: 0, glass_fiber: 0, carbon_fiber: 0, numbers: [{color: 'black', number: ''}]} + }); + }); it('rejects an invalid id', done => { TestHelper.request(server, done, { method: 'get', @@ -130,7 +138,7 @@ describe('/material', () => { auth: {basic: 'janedoe'}, httpStatus: 200, req: {}, - res: {_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]} + res: {_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: '5514263423'}, {color: 'natural', number: '5514263422'}]} }); }); it('keeps unchanged properties', done => { @@ -139,10 +147,10 @@ describe('/material', () => { url: '/material/100000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 200, - req: {name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]} + req: {name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: '5514263423'}, {color: 'natural', number: '5514263422'}]} }).end((err, res) => { if (err) return done(err); - should(res.body).be.eql({_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]}); + should(res.body).be.eql({_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: '5514263423'}, {color: 'natural', number: '5514263422'}]}); MaterialModel.findById('100000000000000000000001').lean().exec((err, data) => { if (err) return done(err); should(data).have.property('status', 10); @@ -159,7 +167,7 @@ describe('/material', () => { req: {name: 'Stanyl TW 200 F8'} }).end((err, res) => { if (err) return done(err); - should(res.body).be.eql({_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}, {color: 'natural', number: 5514263422}]}); + should(res.body).be.eql({_id: '100000000000000000000001', name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: '5514263423'}, {color: 'natural', number: '5514263422'}]}); MaterialModel.findById('100000000000000000000001').lean().exec((err, data) => { if (err) return done(err); should(data).have.property('status', 10); @@ -173,20 +181,30 @@ describe('/material', () => { url: '/material/100000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 200, - req: {name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: 5514212901}, {color: 'signalviolet', number: 5514612901}]} + req: {name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: '5514212901'}, {color: 'signalviolet', number: '5514612901'}]} , }).end((err, res) => { if (err) return done(err); - should(res.body).be.eql({_id: '100000000000000000000001', name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: 5514212901}, {color: 'signalviolet', number: 5514612901}]}); + should(res.body).be.eql({_id: '100000000000000000000001', name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: '5514212901'}, {color: 'signalviolet', number: '5514612901'}]}); MaterialModel.findById('100000000000000000000001').lean().exec((err, data:any) => { if (err) return done(err); data._id = data._id.toString(); data.numbers = data.numbers.map(e => {return {color: e.color, number: e.number}}); - should(data).be.eql({_id: '100000000000000000000001', name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: '0', glass_fiber: '35', carbon_fiber: '0', numbers: [{color: 'black', number: 5514212901}, {color: 'signalviolet', number: 5514612901}], status: 0, __v: 0}); + should(data).be.eql({_id: '100000000000000000000001', name: 'UltramidTKR4355G7_2', supplier: 'BASF', group: 'PA6/6T', mineral: '0', glass_fiber: '35', carbon_fiber: '0', numbers: [{color: 'black', number: '5514212901'}, {color: 'signalviolet', number: '5514612901'}], status: 0, __v: 0}); done(); }); }); }); + it('accepts a color without number', done => { + TestHelper.request(server, done, { + method: 'put', + url: '/material/100000000000000000000007', + auth: {basic: 'janedoe'}, + httpStatus: 200, + req: {numbers: [{color: 'black', number: ''}, {color: 'natural', number: ''}]}, + res: {_id: '100000000000000000000007', name: 'Ultramid A4H', supplier: 'BASF', group: 'PA66', mineral: 0, glass_fiber: 0, carbon_fiber: 0, numbers: [{color: 'black', number: ''}, {color: 'natural', number: ''}]} + }); + }) it('rejects already existing material names', done => { TestHelper.request(server, done, { method: 'put', @@ -233,20 +251,10 @@ describe('/material', () => { url: '/material/100000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {numbers: [{colorxx: 'black', number: 55}]}, + req: {numbers: [{colorxx: 'black', number: '55'}]}, res: {status: 'Invalid body format', details: '"numbers[0].color" is required'} }); }); - it('rejects a wrong color number property', done => { - TestHelper.request(server, done, { - method: 'put', - url: '/material/100000000000000000000001', - auth: {basic: 'janedoe'}, - httpStatus: 400, - req: {numbers: [{color: 'black', number: 'xxx'}]}, - res: {status: 'Invalid body format', details: '"numbers[0].number" must be a number'} - }); - }); it('rejects an invalid id', done => { TestHelper.request(server, done, { method: 'put', @@ -307,7 +315,7 @@ describe('/material', () => { if (err) return done(err); data._id = data._id.toString(); data.numbers = data.numbers.map(e => {return {color: e.color, number: e.number}}); - should(data).be.eql({_id: '100000000000000000000002', name: 'Ultramid T KR 4355 G7', supplier: 'BASF', group: 'PA6/6T', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: 5514212901}, {color: 'signalviolet', number: 5514612901}], status: -1, __v: 0} + should(data).be.eql({_id: '100000000000000000000002', name: 'Ultramid T KR 4355 G7', supplier: 'BASF', group: 'PA6/6T', mineral: 0, glass_fiber: 35, carbon_fiber: 0, numbers: [{color: 'black', number: '5514212901'}, {color: 'signalviolet', number: '5514612901'}], status: -1, __v: 0} ); done(); }); @@ -370,7 +378,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 200, - req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: 5515798402}]} + req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: '5515798402'}]} }).end((err, res) => { if (err) return done (err); should(res.body).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers'); @@ -384,7 +392,7 @@ describe('/material', () => { should(res.body.numbers).matchEach(number => { should(number).have.only.keys('color', 'number'); should(number).have.property('color', 'black'); - should(number).have.property('number', 5515798402); + should(number).have.property('number', '5515798402'); }); done(); }); @@ -415,13 +423,52 @@ describe('/material', () => { }); }); }); + it('accepts a color without number', done => { + TestHelper.request(server, done, { + method: 'post', + url: '/material/new', + auth: {basic: 'janedoe'}, + httpStatus: 200, + req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: ''}]} + }).end((err, res) => { + if (err) return done (err); + should(res.body).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers'); + should(res.body).have.property('_id').be.type('string'); + should(res.body).have.property('name', 'Crastin CE 2510'); + should(res.body).have.property('supplier', 'Du Pont'); + should(res.body).have.property('group', 'PBT'); + should(res.body).have.property('mineral', 0); + should(res.body).have.property('glass_fiber', 30); + should(res.body).have.property('carbon_fiber', 0); + should(res.body.numbers).matchEach(number => { + should(number).have.only.keys('color', 'number'); + should(number).have.property('color', 'black'); + should(number).have.property('number', ''); + }); + MaterialModel.find({name: 'Crastin CE 2510'}).lean().exec((err, data: any) => { + if (err) return done (err); + should(data).have.lengthOf(1); + should(data[0]).have.only.keys('_id', 'name', 'supplier', 'group', 'mineral', 'glass_fiber', 'carbon_fiber', 'numbers', 'status', '__v'); + should(data[0]).have.property('_id'); + should(data[0]).have.property('name', 'Crastin CE 2510'); + should(data[0]).have.property('supplier', 'Du Pont'); + should(data[0]).have.property('group', 'PBT'); + should(data[0]).have.property('mineral', '0'); + should(data[0]).have.property('glass_fiber', '30'); + should(data[0]).have.property('carbon_fiber', '0'); + should(data[0]).have.property('status', 0); + should(_.omit(data[0].numbers[0], '_id')).be.eql({color: 'black', number: ''}); + done(); + }); + }); + }); it('rejects already existing material names', done => { TestHelper.request(server, done, { method: 'post', url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: 5514263423}]}, + req: {name: 'Stanyl TW 200 F8', supplier: 'DSM', group: 'PA46', mineral: 0, glass_fiber: 40, carbon_fiber: 0, numbers: [{color: 'black', number: '5514263423'}]}, res: {status: 'Material name already taken'} }); }); @@ -431,7 +478,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: 5515798402}]}, + req: {supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: '5515798402'}]}, res: {status: 'Invalid body format', details: '"name" is required'} }); }); @@ -441,7 +488,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {name: 'Crastin CE 2510', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: 5515798402}]}, + req: {name: 'Crastin CE 2510', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: '5515798402'}]}, res: {status: 'Invalid body format', details: '"supplier" is required'} }); }); @@ -451,7 +498,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {name: 'Crastin CE 2510', supplier: 'Du Pont', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: 5515798402}]}, + req: {name: 'Crastin CE 2510', supplier: 'Du Pont', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: '5515798402'}]}, res: {status: 'Invalid body format', details: '"group" is required'} }); }); @@ -461,7 +508,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: 5515798402}]}, + req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', glass_fiber: 30, carbon_fiber: 0, numbers: [{color: 'black', number: '5515798402'}]}, res: {status: 'Invalid body format', details: '"mineral" is required'} }); }); @@ -471,7 +518,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, carbon_fiber: 0, numbers: [{color: 'black', number: 5515798402}]}, + req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, carbon_fiber: 0, numbers: [{color: 'black', number: '5515798402'}]}, res: {status: 'Invalid body format', details: '"glass_fiber" is required'} }); }); @@ -481,7 +528,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, numbers: [{color: 'black', number: 5515798402}]}, + req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, numbers: [{color: 'black', number: '5515798402'}]}, res: {status: 'Invalid body format', details: '"carbon_fiber" is required'} }); }); @@ -501,7 +548,7 @@ describe('/material', () => { url: '/material/new', auth: {basic: 'janedoe'}, httpStatus: 400, - req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{number: 5515798402}]}, + req: {name: 'Crastin CE 2510', supplier: 'Du Pont', group: 'PBT', mineral: 0, glass_fiber: 30, carbon_fiber: 0, numbers: [{number: '5515798402'}]}, res: {status: 'Invalid body format', details: '"numbers[0].color" is required'} }); }); diff --git a/src/routes/validate/material.ts b/src/routes/validate/material.ts index c8b6e91..b09c494 100644 --- a/src/routes/validate/material.ts +++ b/src/routes/validate/material.ts @@ -33,8 +33,9 @@ export default class MaterialValidate { // validate input for material color: joi.string() .max(128) .required(), - number: joi.number() - .min(0) + number: joi.string() + .max(128) + .allow('') .required() })) }; diff --git a/src/test/db.json b/src/test/db.json index 62d18ea..fcd1631 100644 --- a/src/test/db.json +++ b/src/test/db.json @@ -121,11 +121,11 @@ "numbers": [ { "color": "black", - "number": 5514263423 + "number": "5514263423" }, { "color": "natural", - "number": 5514263422 + "number": "5514263422" } ], "status": 10, @@ -142,11 +142,11 @@ "numbers": [ { "color": "black", - "number": 5514212901 + "number": "5514212901" }, { "color": "signalviolet", - "number": 5514612901 + "number": "5514612901" } ], "status": 10, @@ -176,7 +176,7 @@ "numbers": [ { "color": "black", - "number": 5513933405 + "number": "5513933405" } ], "status": 10, @@ -193,7 +193,7 @@ "numbers": [ { "color": "black", - "number": 5514262406 + "number": "5514262406" } ], "status": 10, @@ -210,11 +210,28 @@ "numbers": [ { "color": "natural", - "number": 10000000 + "number": "10000000" } ], "status": -1, "__v": 0 + }, + { + "_id": {"$oid":"100000000000000000000007"}, + "name": "Ultramid A4H", + "supplier": "BASF", + "group": "PA66", + "mineral": 0, + "glass_fiber": 0, + "carbon_fiber": 0, + "numbers": [ + { + "color": "black", + "number": "" + } + ], + "status": 10, + "__v": 0 } ], "conditions": [