import should from 'should/as-function'; import _ from 'lodash'; import TemplateConditionModel from '../models/condition_template'; import TemplateMeasurementModel from '../models/measurement_template'; import TestHelper from "../test/helper"; describe('/template', () => { let server; before(done => TestHelper.before(done)); beforeEach(done => server = TestHelper.beforeEach(server, done)); afterEach(done => TestHelper.afterEach(server, done)); after(done => TestHelper.after(done)); describe('/template/condition', () => { describe('GET /template/conditions', () => { it('returns all condition templates', done => { TestHelper.request(server, done, { method: 'get', url: '/template/conditions', 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.condition_templates.length); should(res.body).matchEach(condition => { should(condition).have.only.keys('_id', 'name', 'version', 'parameters'); should(condition).have.property('_id').be.type('string'); should(condition).have.property('name').be.type('string'); should(condition).have.property('version').be.type('number'); should(condition.parameters).matchEach(number => { should(number).have.only.keys('name', 'range'); should(number).have.property('name').be.type('string'); should(number).have.property('range').be.type('object'); }); }); done(); }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'get', url: '/template/conditions', auth: {key: 'janedoe'}, httpStatus: 401 }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'get', url: '/template/conditions', httpStatus: 401 }); }); }); describe('GET /template/condition/{id}', () => { it('returns the right condition template', done => { TestHelper.request(server, done, { method: 'get', url: '/template/condition/200000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 200, res: {_id: '200000000000000000000001', name: 'heat treatment', version: 1, parameters: [{name: 'material', range: {values: ['copper', 'hot air']}}, {name: 'weeks', range: {min: 1, max: 10}}]} }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'get', url: '/template/condition/200000000000000000000001', auth: {key: 'janedoe'}, httpStatus: 401 }); }); it('rejects an unknown id', done => { TestHelper.request(server, done, { method: 'get', url: '/template/condition/000000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 404 }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'get', url: '/template/condition/200000000000000000000001', httpStatus: 401 }); }); }); describe('PUT /template/condition/{name}', () => { it('returns the right condition template', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {}, res: {_id: '200000000000000000000001', name: 'heat treatment', version: 1, parameters: [{name: 'material', range: {values: ['copper', 'hot air']}}, {name: 'weeks', range: {min: 1, max: 10}}]} }); }); it('keeps unchanged properties', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat treatment', parameters: [{name: 'material', range: {values: ['copper', 'hot air']}}, {name: 'weeks', range: {min: 1, max: 10}}]}, res: {_id: '200000000000000000000001', name: 'heat treatment', version: 1, parameters: [{name: 'material', range: {values: ['copper', 'hot air']}}, {name: 'weeks', range: {min: 1, max: 10}}]} }); }); it('keeps only one unchanged property', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat treatment'}, res: {_id: '200000000000000000000001', name: 'heat treatment', version: 1, parameters: [{name: 'material', range: {values: ['copper', 'hot air']}}, {name: 'weeks', range: {min: 1, max: 10}}]} }); }); it('changes the given properties', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} }).end((err, res) => { if (err) return done(err); TemplateConditionModel.findById(res.body._id).lean().exec((err, data:any) => { if (err) return done(err); should(data).have.only.keys('_id', 'first_id', 'name', 'version', 'parameters', '__v'); should(data.first_id.toString()).be.eql('200000000000000000000001'); should(data).have.property('name', 'heat aging'); should(data).have.property('version', 2); should(data).have.property('parameters').have.lengthOf(1); should(data.parameters[0]).have.property('name', 'time'); should(data.parameters[0]).have.property('range'); should(data.parameters[0].range).have.property('min', 1); done(); }); }); }); it('creates a changelog', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]}, log: { collection: 'condition_templates', dataAdd: { first_id: '200000000000000000000001', version: 2 } } }); }); it('allows changing only one property', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat aging'} }).end((err, res) => { if (err) return done(err); TemplateConditionModel.findById(res.body._id).lean().exec((err, data:any) => { if (err) return done(err); should(data).have.only.keys('_id', 'first_id', 'name', 'version', 'parameters', '__v'); should(data.first_id.toString()).be.eql('200000000000000000000001'); should(data).have.property('name', 'heat aging'); should(data).have.property('version', 2); should(data).have.property('parameters').have.lengthOf(2); should(data.parameters[0]).have.property('name', 'material'); should(data.parameters[1]).have.property('name', 'weeks'); done(); }); }); }); it('supports values ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'time', range: {values: [1, 2, 5]}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'heat treatment', version: 2, parameters: [{name: 'time', range: {values: [1, 2, 5]}}]}); done(); }); }); it('supports min max ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'time', range: {min: 1, max: 11}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'heat treatment', version: 2, parameters: [{name: 'time', range: {min: 1, max: 11}}]}); done(); }); }); it('supports array type ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'time', range: {type: 'array'}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'heat treatment', version: 2, parameters: [{name: 'time', range: {type: 'array'}}]}); done(); }); }); it('supports empty ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'time', range: {}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'heat treatment', version: 2, parameters: [{name: 'time', range: {}}]}); done(); }); }); it('rejects `condition_template` as parameter name', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 400, req: {parameters: [{name: 'condition_template', range: {}}]}, res: {status: 'Invalid body format', details: '"parameters[0].name" contains an invalid value'} }); }); it('rejects not specified parameters', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat treatment', parameters: [{name: 'material', range: {xx: 5}}]}, res: {status: 'Invalid body format', details: '"parameters[0].range.xx" is not allowed'} }); }); it('rejects an invalid id', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/2000000000h0000000000001', auth: {basic: 'admin'}, httpStatus: 404, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} }); }); it('rejects an unknown id', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/000000000000000000000001', auth: {basic: 'admin'}, httpStatus: 404, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {key: 'admin'}, httpStatus: 401, req: {} }); }); it('rejects requests from a write user', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 403, req: {} }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'put', url: '/template/condition/200000000000000000000001', httpStatus: 401, req: {} }); }); }); describe('POST /template/condition/new', () => { it('returns the right condition template', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat treatment3', parameters: [{name: 'material', range: {values: ['copper']}}]} }).end((err, res) => { if (err) return done(err); should(res.body).have.only.keys('_id', 'name', 'version', 'parameters'); should(res.body).have.property('name', 'heat treatment3'); should(res.body).have.property('version', 1); should(res.body).have.property('parameters').have.lengthOf(1); should(res.body.parameters[0]).have.property('name', 'material'); should(res.body.parameters[0]).have.property('range'); should(res.body.parameters[0].range).have.property('values'); should(res.body.parameters[0].range.values[0]).be.eql('copper'); done(); }); }); it('stores the template', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} }).end((err, res) => { if (err) return done(err); TemplateConditionModel.findById(res.body._id).lean().exec((err, data:any) => { if (err) return done(err); should(data).have.only.keys('_id', 'first_id', 'name', 'version', 'parameters', '__v'); should(data.first_id.toString()).be.eql(data._id.toString()); should(data).have.property('name', 'heat aging'); should(data).have.property('version', 1); should(data).have.property('parameters').have.lengthOf(1); should(data.parameters[0]).have.property('name', 'time'); should(data.parameters[0]).have.property('range'); should(data.parameters[0].range).have.property('min', 1); done(); }); }); }); it('creates a changelog', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]}, log: { collection: 'condition_templates', dataAdd: {version: 1}, dataIgn: ['first_id'] } }); }); it('rejects a missing name', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {parameters: [{name: 'time', range: {min: 1}}]}, res: {status: 'Invalid body format', details: '"name" is required'} }); }); it('rejects `condition_template` as parameter name', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat aging', parameters: [{name: 'condition_template', range: {min: 1}}]}, res: {status: 'Invalid body format', details: '"parameters[0].name" contains an invalid value'} }); }); it('rejects a number prefix', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat aging', number_prefix: 'C', parameters: [{name: 'time', range: {min: 1}}]}, res: {status: 'Invalid body format', details: '"number_prefix" is not allowed'} }); }); it('rejects missing parameters', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat aging'}, res: {status: 'Invalid body format', details: '"parameters" is required'} }); }); it('rejects a missing parameter name', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat aging', parameters: [{range: {min: 1}}]}, res: {status: 'Invalid body format', details: '"parameters[0].name" is required'} }); }); it('rejects a missing parameter range', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat aging', parameters: [{name: 'time'}]}, res: {status: 'Invalid body format', details: '"parameters[0].range" is required'} }); }); it('rejects an invalid parameter range property', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat aging', parameters: [{name: 'time', range: {xx: 1}}]}, res: {status: 'Invalid body format', details: '"parameters[0].range.xx" is not allowed'} }); }); it('rejects wrong properties', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'heat aging', parameters: [{name: 'time', range: {}}], xx: 33}, res: {status: 'Invalid body format', details: '"xx" is not allowed'} }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {key: 'admin'}, httpStatus: 401, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} }); }); it('rejects requests from a write user', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', auth: {basic: 'janedoe'}, httpStatus: 403, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'post', url: '/template/condition/new', httpStatus: 401, req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} }); }); }); }); describe('/template/measurement', () => { describe('GET /template/measurements', () => { it('returns all measurement templates', done => { TestHelper.request(server, done, { method: 'get', url: '/template/measurements', 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.measurement_templates.length); should(res.body).matchEach(measurement => { should(measurement).have.only.keys('_id', 'name', 'version', 'parameters'); should(measurement).have.property('_id').be.type('string'); should(measurement).have.property('name').be.type('string'); should(measurement).have.property('version').be.type('number'); should(measurement.parameters).matchEach(number => { should(number).have.only.keys('name', 'range'); should(number).have.property('name').be.type('string'); should(number).have.property('range').be.type('object'); }); }); done(); }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'get', url: '/template/measurements', auth: {key: 'janedoe'}, httpStatus: 401 }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'get', url: '/template/measurements', httpStatus: 401 }); }); }); describe('GET /template/measurement/id', () => { it('returns the right measurement template', done => { TestHelper.request(server, done, { method: 'get', url: '/template/measurement/300000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 200, res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: { type: 'array'}}]} }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'get', url: '/template/measurement/300000000000000000000001', auth: {key: 'janedoe'}, httpStatus: 401 }); }); it('rejects an unknown id', done => { TestHelper.request(server, done, { method: 'get', url: '/template/measurement/000000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 404 }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'get', url: '/template/measurement/300000000000000000000001', httpStatus: 401 }); }); }); describe('PUT /template/measurement/{name}', () => { it('returns the right measurement template', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {}, res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: { type: 'array'}}]} }); }); it('keeps unchanged properties', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'spectrum', parameters: [{name: 'dpt', range: { type: 'array'}}]}, res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: {type: 'array'}}]} }); }); it('keeps only one unchanged property', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'spectrum'}, res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: {type: 'array'}}]} }); }); it('changes the given properties', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'IR spectrum', version: 2, parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]}); TemplateMeasurementModel.findById(res.body._id).lean().exec((err, data:any) => { if (err) return done(err); should(data).have.only.keys('_id', 'first_id', 'name', 'version', 'parameters', '__v'); should(data.first_id.toString()).be.eql('300000000000000000000001'); should(data).have.property('name', 'IR spectrum'); should(data).have.property('version', 2); should(data).have.property('parameters').have.lengthOf(1); should(data.parameters[0]).have.property('name', 'data point table'); should(data.parameters[0]).have.property('range'); should(data.parameters[0].range).have.property('min', 0); should(data.parameters[0].range).have.property('max', 1000); done(); }); }); }); it('creates a changelog', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]}, log: { collection: 'measurement_templates', dataAdd: { first_id: '300000000000000000000001', version: 2 } } }); }); it('allows changing only one property', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'IR spectrum'}, }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'IR spectrum', version: 2, parameters: [{name: 'dpt', range: {type: 'array'}}]}); TemplateMeasurementModel.findById(res.body._id).lean().exec((err, data:any) => { if (err) return done(err); should(data).have.only.keys('_id', 'first_id', 'name', 'version', 'parameters', '__v'); should(data.first_id.toString()).be.eql('300000000000000000000001'); should(data).have.property('name', 'IR spectrum'); should(data).have.property('version', 2); should(data).have.property('parameters').have.lengthOf(1); should(data.parameters[0]).have.property('name', 'dpt'); should(data.parameters[0]).have.property('range'); should(data.parameters[0].range).have.property('type', 'array'); done(); }); }); }); it('supports values ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'dpt', range: {values: [1, 2, 5]}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'spectrum', version: 2, parameters: [{name: 'dpt', range: {values: [1, 2, 5]}}]}); done(); }); }); it('supports min max ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'dpt', range: {min: 0, max: 1000}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'spectrum', version: 2, parameters: [{name: 'dpt', range: {min: 0, max: 1000}}]}); done(); }); }); it('supports array type ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'dpt2', range: {type: 'array'}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'spectrum', version: 2, parameters: [{name: 'dpt2', range: {type: 'array'}}]}); done(); }); }); it('supports empty ranges', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000002', auth: {basic: 'admin'}, httpStatus: 200, req: {parameters: [{name: 'weight %', range: {}}]} }).end((err, res) => { if (err) return done(err); should(_.omit(res.body, '_id')).be.eql({name: 'kf', version: 2, parameters: [{name: 'weight %', range: {}}]}); done(); }); }); it('rejects not specified parameters', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'admin'}, httpStatus: 400, req: {parameters: [{name: 'dpt'}], range: {xx: 33}}, res: {status: 'Invalid body format', details: '"parameters[0].range" is required'} }); }); it('rejects an invalid id', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/3000000000h0000000000001', auth: {basic: 'admin'}, httpStatus: 404, req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]}, }); }); it('rejects an unknown id', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/000000000000000000000001', auth: {basic: 'admin'}, httpStatus: 404, req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]}, }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {key: 'admin'}, httpStatus: 401, req: {} }); }); it('rejects requests from a write user', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', auth: {basic: 'janedoe'}, httpStatus: 403, req: {} }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'put', url: '/template/measurement/300000000000000000000001', httpStatus: 401, req: {} }); }); }); describe('POST /template/measurement/new', () => { it('returns the right measurement template', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'vz', parameters: [{name: 'vz', range: {min: 1}}]} }).end((err, res) => { if (err) return done(err); should(res.body).have.only.keys('_id', 'name', 'version', 'parameters'); should(res.body).have.property('name', 'vz'); should(res.body).have.property('version', 1); should(res.body).have.property('parameters').have.lengthOf(1); should(res.body.parameters[0]).have.property('name', 'vz'); should(res.body.parameters[0]).have.property('range'); should(res.body.parameters[0].range).have.property('min', 1); done(); }); }); it('stores the template', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'vz', parameters: [{name: 'vz', range: {min: 1}}]} }).end(err => { if (err) return done(err); TemplateMeasurementModel.find({name: 'vz'}).lean().exec((err, data:any) => { if (err) return done(err); should(data).have.lengthOf(1); should(data[0]).have.only.keys('_id', 'first_id', 'name', 'version', 'parameters', '__v'); should(data[0].first_id.toString()).be.eql(data[0]._id.toString()); should(data[0]).have.property('name', 'vz'); should(data[0]).have.property('version', 1); should(data[0]).have.property('parameters').have.lengthOf(1); should(data[0].parameters[0]).have.property('name', 'vz'); should(data[0].parameters[0]).have.property('range'); should(data[0].parameters[0].range).have.property('min', 1); done(); }); }); }); it('creates a changelog', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 200, req: {name: 'vz', parameters: [{name: 'vz', range: {min: 1}}]}, log: { collection: 'measurement_templates', dataAdd: {version: 1}, dataIgn: ['first_id'] } }); }); it('rejects a missing name', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 400, req: {parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]}, res: {status: 'Invalid body format', details: '"name" is required'} }); }); it('rejects missing parameters', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'IR spectrum'}, res: {status: 'Invalid body format', details: '"parameters" is required'} }); }); it('rejects a missing parameter name', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'IR spectrum', parameters: [{range: {min: 0, max: 1000}}]}, res: {status: 'Invalid body format', details: '"parameters[0].name" is required'} }); }); it('rejects a missing parameter range', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'IR spectrum', parameters: [{name: 'data point table'}]}, res: {status: 'Invalid body format', details: '"parameters[0].range" is required'} }); }); it('rejects a an invalid parameter range property', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {xx: 0}}]}, res: {status: 'Invalid body format', details: '"parameters[0].range.xx" is not allowed'} }); }); it('rejects wrong properties', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'admin'}, httpStatus: 400, req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {}}], xx: 35}, res: {status: 'Invalid body format', details: '"xx" is not allowed'} }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {key: 'admin'}, httpStatus: 401, req: {name: 'vz', parameters: [{name: 'vz', range: {min: 1}}]} }); }); it('rejects requests from a write user', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', auth: {basic: 'janedoe'}, httpStatus: 403, req: {name: 'vz', parameters: [{name: 'vz', range: {min: 1}}]} }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'post', url: '/template/measurement/new', httpStatus: 401, req: {name: 'vz', parameters: [{name: 'vz', range: {min: 1}}]} }); }); }); }); describe('/template/material', () => { describe('GET /template/materials', () => { it('returns all material templates', done => { TestHelper.request(server, done, { method: 'get', url: '/template/materials', 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.material_templates.length); should(res.body).matchEach(measurement => { should(measurement).have.only.keys('_id', 'name', 'version', 'parameters'); should(measurement).have.property('_id').be.type('string'); should(measurement).have.property('name').be.type('string'); should(measurement).have.property('version').be.type('number'); should(measurement.parameters).matchEach(number => { should(number).have.only.keys('name', 'range'); should(number).have.property('name').be.type('string'); should(number).have.property('range').be.type('object'); }); }); done(); }); }); it('rejects an API key', done => { TestHelper.request(server, done, { method: 'get', url: '/template/materials', auth: {key: 'janedoe'}, httpStatus: 401 }); }); it('rejects unauthorized requests', done => { TestHelper.request(server, done, { method: 'get', url: '/template/materials', httpStatus: 401 }); }); }); // other methods should be covered by measurement and condition tests }); });