Archived
2

PUT finished

This commit is contained in:
VLE2FE 2020-05-14 15:36:47 +02:00
parent 81a7663f6c
commit 8315fc0d3b
11 changed files with 162 additions and 109 deletions

View File

@ -1,7 +1,7 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
const MeasurementTemplateSchema = new mongoose.Schema({ const MeasurementTemplateSchema = new mongoose.Schema({
name: {type: String, index: {unique: true}}, name: String,
version: Number, version: Number,
parameters: [{ parameters: [{
name: String, name: String,

View File

@ -1,7 +1,7 @@
import mongoose from 'mongoose'; import mongoose from 'mongoose';
const TreatmentTemplateSchema = new mongoose.Schema({ const TreatmentTemplateSchema = new mongoose.Schema({
name: {type: String, index: {unique: true}}, name: String,
version: Number, version: Number,
number_prefix: String, number_prefix: String,
parameters: [{ parameters: [{

View File

@ -34,9 +34,7 @@ router.put('/condition/' + IdValidate.parameter(), async (req, res, next) => {
if (error) return res400(error, res); if (error) return res400(error, res);
const data = await ConditionModel.findById(req.params.id).lean().exec().catch(err => {next(err);}) as any; const data = await ConditionModel.findById(req.params.id).lean().exec().catch(err => {next(err);}) as any;
if (data instanceof Error) { if (data instanceof Error) return;
return;
}
if (!data) { if (!data) {
res.status(404).json({status: 'Not found'}); res.status(404).json({status: 'Not found'});
} }

View File

@ -104,9 +104,7 @@ module.exports = router;
async function nameCheck (material, res, next) { // check if name was already taken async function nameCheck (material, res, next) { // check if name was already taken
const materialData = await MaterialModel.findOne({name: material.name}).lean().exec().catch(err => {next(err); return false;}) as any; const materialData = await MaterialModel.findOne({name: material.name}).lean().exec().catch(err => {next(err); return false;}) as any;
if (materialData instanceof Error) { if (materialData instanceof Error) return false;
return false;
}
if (materialData) { // could not find material_id if (materialData) { // could not find material_id
res.status(400).json({status: 'Material name already taken'}); res.status(400).json({status: 'Material name already taken'});
return false; return false;

View File

@ -32,9 +32,7 @@ router.put('/measurement/' + IdValidate.parameter(), async (req, res, next) => {
if (error) return res400(error, res); if (error) return res400(error, res);
const data = await MeasurementModel.findById(req.params.id).lean().exec().catch(err => {next(err);}) as any; const data = await MeasurementModel.findById(req.params.id).lean().exec().catch(err => {next(err);}) as any;
if (data instanceof Error) { if (data instanceof Error) return;
return;
}
if (!data) { if (!data) {
res.status(404).json({status: 'Not found'}); res.status(404).json({status: 'Not found'});
} }

View File

@ -124,6 +124,32 @@ describe('/sample', () => {
}); });
}); });
}); });
it('keeps unchanged notes', done => {
TestHelper.request(server, done, {
method: 'put',
url: '/sample/400000000000000000000002',
auth: {basic: 'janedoe'},
httpStatus: 200,
req: {notes: {comment: 'Stoff gesperrt', sample_references: []}}
}).end((err, res) => {
if (err) return done(err);
should(res.body).be.eql({_id: '400000000000000000000002', number: '21', type: 'granulate', color: 'natural', batch: '1560237365', material_id: '100000000000000000000001', note_id: '500000000000000000000001', user_id: '000000000000000000000002'});
SampleModel.findById('400000000000000000000002').lean().exec((err, data: any) => {
if (err) return done (err);
should(data).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'material_id', 'note_id', 'user_id', 'status', '__v');
should(data).have.property('_id');
should(data).have.property('number', '21');
should(data).have.property('color', 'natural');
should(data).have.property('type', 'granulate');
should(data).have.property('batch', '1560237365');
should(data.material_id.toString()).be.eql('100000000000000000000001');
should(data.user_id.toString()).be.eql('000000000000000000000002');
should(data).have.property('status', 10);
should(data.note_id.toString()).be.eql('500000000000000000000001');
done();
});
});
});
it('changes the given properties', done => { it('changes the given properties', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'put', method: 'put',

View File

@ -46,25 +46,31 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => {
if (!await materialCheck(sample, res, next, sampleData.material_id)) return; if (!await materialCheck(sample, res, next, sampleData.material_id)) return;
} }
if (sample.hasOwnProperty('notes') && sampleData.note_id !== null) { // deal with old notes data if (sample.hasOwnProperty('notes')) {
NoteModel.findById(sampleData.note_id).lean().exec((err, data: any) => { let newNotes = true;
if (err) return console.error(err); if (sampleData.note_id !== null) { // old notes data exists
if (data.hasOwnProperty('custom_fields')) { // update note_fields const data = await NoteModel.findById(sampleData.note_id).lean().exec().catch(err => {next(err);}) as any;
customFieldsChange(Object.keys(data.custom_fields), -1); if (data instanceof Error) return;
newNotes = !_.isEqual(_.pick(IdValidate.stringify(data), _.keys(sample.notes)), sample.notes);
if (newNotes) {
if (data.hasOwnProperty('custom_fields')) { // update note_fields
customFieldsChange(Object.keys(data.custom_fields), -1);
}
NoteModel.findByIdAndDelete(sampleData.note_id).lean().exec(err => { // delete old notes
if (err) return console.error(err);
});
} }
NoteModel.findByIdAndDelete(sampleData.note_id).lean().exec(err => { // delete old notes
if (err) return console.error(err);
})
});
}
if (sample.hasOwnProperty('notes') && Object.keys(sample.notes).length > 0) { // save new notes
if (!await sampleRefCheck(sample, res, next)) return;
if (sample.notes.hasOwnProperty('custom_fields') && Object.keys(sample.notes.custom_fields).length > 0) { // new custom_fields
customFieldsChange(Object.keys(sample.notes.custom_fields), 1);
} }
let data = await new NoteModel(sample.notes).save().catch(err => { return next(err)}); // save new notes
delete sample.notes; if (_.keys(sample.notes).length > 0 && newNotes) { // save new notes
sample.note_id = data._id; if (!await sampleRefCheck(sample, res, next)) return;
if (sample.notes.hasOwnProperty('custom_fields') && Object.keys(sample.notes.custom_fields).length > 0) { // new custom_fields
customFieldsChange(Object.keys(sample.notes.custom_fields), 1);
}
let data = await new NoteModel(sample.notes).save().catch(err => { return next(err)}); // save new notes
delete sample.notes;
sample.note_id = data._id;
}
} }
// check for changes // check for changes
@ -160,9 +166,7 @@ async function numberCheck (sample, res, next) { // validate number, returns fa
async function materialCheck (sample, res, next, id = sample.material_id) { // validate material_id and color, returns false if invalid async function materialCheck (sample, res, next, id = sample.material_id) { // validate material_id and color, returns false if invalid
const materialData = await MaterialModel.findById(id).lean().exec().catch(err => {next(err); return false;}) as any; const materialData = await MaterialModel.findById(id).lean().exec().catch(err => {next(err); return false;}) as any;
if (materialData instanceof Error) { if (materialData instanceof Error) return false;
return false;
}
if (!materialData) { // could not find material_id if (!materialData) { // could not find material_id
res.status(400).json({status: 'Material not available'}); res.status(400).json({status: 'Material not available'});
return false; return false;

View File

@ -1,4 +1,5 @@
import should from 'should/as-function'; import should from 'should/as-function';
import _ from 'lodash';
import TemplateTreatmentModel from '../models/treatment_template'; import TemplateTreatmentModel from '../models/treatment_template';
import TemplateMeasurementModel from '../models/measurement_template'; import TemplateMeasurementModel from '../models/measurement_template';
import TestHelper from "../test/helper"; import TestHelper from "../test/helper";
@ -130,8 +131,7 @@ describe('/template', () => {
req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]} req: {name: 'heat aging', parameters: [{name: 'time', range: {min: 1}}]}
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({_id: '200000000000000000000001', name: 'heat aging', version: 2, number_prefix: 'A', parameters: [{name: 'time', range: {min: 1}}]}); TemplateTreatmentModel.findById(res.body._id).lean().exec((err, data:any) => {
TemplateTreatmentModel.findById('200000000000000000000001').lean().exec((err, data:any) => {
if (err) return done(err); if (err) return done(err);
should(data).have.only.keys('_id', 'name', 'version', 'number_prefix', 'parameters', '__v'); should(data).have.only.keys('_id', 'name', 'version', 'number_prefix', 'parameters', '__v');
should(data).have.property('name', 'heat aging'); should(data).have.property('name', 'heat aging');
@ -154,17 +154,15 @@ describe('/template', () => {
req: {name: 'heat aging'} req: {name: 'heat aging'}
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({_id: '200000000000000000000001', name: 'heat aging', version: 2, number_prefix: 'A', parameters: [{name: 'material', range: {values: ['copper', 'hot air']}}, {name: 'weeks', range: {min: 1, max: 10}}]}); TemplateTreatmentModel.findById(res.body._id).lean().exec((err, data:any) => {
TemplateTreatmentModel.find({name: 'heat aging'}).lean().exec((err, data:any) => {
if (err) return done(err); if (err) return done(err);
should(data).have.lengthOf(1); should(data).have.only.keys('_id', 'name', 'version', 'number_prefix', 'parameters', '__v');
should(data[0]).have.only.keys('_id', 'name', 'version', 'number_prefix', 'parameters', '__v'); should(data).have.property('name', 'heat aging');
should(data[0]).have.property('name', 'heat aging'); should(data).have.property('version', 2);
should(data[0]).have.property('version', 2); should(data).have.property('number_prefix', 'A');
should(data[0]).have.property('number_prefix', 'A'); should(data).have.property('parameters').have.lengthOf(2);
should(data[0]).have.property('parameters').have.lengthOf(1); should(data.parameters[0]).have.property('name', 'material');
should(data[0].parameters[0]).have.property('name', 'material'); should(data.parameters[1]).have.property('name', 'weeks');
should(data[0].parameters[1]).have.property('name', 'weeks');
done(); done();
}); });
}); });
@ -175,8 +173,11 @@ describe('/template', () => {
url: '/template/treatment/200000000000000000000001', url: '/template/treatment/200000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'time', range: {values: [1, 2, 5]}}]}, req: {parameters: [{name: 'time', range: {values: [1, 2, 5]}}]}
res: {_id: '200000000000000000000001', name: 'heat treatment', version: 2, number_prefix: 'A', 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, number_prefix: 'A', parameters: [{name: 'time', range: {values: [1, 2, 5]}}]});
done();
}); });
}); });
it('supports min max ranges', done => { it('supports min max ranges', done => {
@ -185,8 +186,11 @@ describe('/template', () => {
url: '/template/treatment/200000000000000000000001', url: '/template/treatment/200000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'time', range: {min: 1, max: 11}}]}, req: {parameters: [{name: 'time', range: {min: 1, max: 11}}]}
res: {_id: '200000000000000000000001', name: 'heat treatment', version: 2, number_prefix: 'A', 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, number_prefix: 'A', parameters: [{name: 'time', range: {min: 1, max: 11}}]});
done();
}); });
}); });
it('supports array type ranges', done => { it('supports array type ranges', done => {
@ -195,8 +199,12 @@ describe('/template', () => {
url: '/template/treatment/200000000000000000000001', url: '/template/treatment/200000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'time', range: {type: 'array'}}]}, req: {parameters: [{name: 'time', range: {type: 'array'}}]}
res: {_id: '200000000000000000000001', name: 'heat treatment', version: 2, number_prefix: 'A', parameters: [{name: 'time', range: {type: 'array'}}]} }).end((err, res) => {
console.log(res.body);
if (err) return done(err);
should(_.omit(res.body, '_id')).be.eql({name: 'heat treatment', version: 2, number_prefix: 'A', parameters: [{name: 'time', range: {type: 'array'}}]});
done();
}); });
}); });
it('supports empty ranges', done => { it('supports empty ranges', done => {
@ -205,8 +213,11 @@ describe('/template', () => {
url: '/template/treatment/200000000000000000000001', url: '/template/treatment/200000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'time', range: {}}]}, req: {parameters: [{name: 'time', range: {}}]}
res: {_id: '200000000000000000000001', name: 'heat treatment', version: 2, number_prefix: 'A', parameters: [{name: 'time', range: {}}]} }).end((err, res) => {
if (err) return done(err);
should(_.omit(res.body, '_id')).be.eql({name: 'heat treatment', version: 2, number_prefix: 'A', parameters: [{name: 'time', range: {}}]});
done();
}); });
}); });
it('rejects not specified parameters', done => { it('rejects not specified parameters', done => {
@ -216,7 +227,7 @@ describe('/template', () => {
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 400, httpStatus: 400,
req: {name: 'heat treatment', parameters: [{name: 'material', range: {xx: 5}}]}, req: {name: 'heat treatment', parameters: [{name: 'material', range: {xx: 5}}]},
res: {} res: {status: 'Invalid body format', details: '"parameters[0].range.xx" is not allowed'}
}); });
}) })
it('rejects an invalid id', done => { it('rejects an invalid id', done => {
@ -478,7 +489,7 @@ describe('/template', () => {
url: '/template/measurement/300000000000000000000001', url: '/template/measurement/300000000000000000000001',
auth: {basic: 'janedoe'}, auth: {basic: 'janedoe'},
httpStatus: 200, httpStatus: 200,
res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: {}}]} res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: { type: 'array'}}]}
}); });
}); });
it('rejects an API key', done => { it('rejects an API key', done => {
@ -514,7 +525,7 @@ describe('/template', () => {
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {}, req: {},
res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: {}}]} res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: { type: 'array'}}]}
}); });
}); });
it('keeps unchanged properties', done => { it('keeps unchanged properties', done => {
@ -523,7 +534,7 @@ describe('/template', () => {
url: '/template/measurement/300000000000000000000001', url: '/template/measurement/300000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {name: 'spectrum', parameters: [{name: 'dpt', range: {}}]}, req: {name: 'spectrum', parameters: [{name: 'dpt', range: { type: 'array'}}]},
res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: {type: 'array'}}]} res: {_id: '300000000000000000000001', name: 'spectrum', version: 1, parameters: [{name: 'dpt', range: {type: 'array'}}]}
}); });
}); });
@ -546,18 +557,17 @@ describe('/template', () => {
req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]}, req: {name: 'IR spectrum', parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]},
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({_id: '300000000000000000000001', name: 'IR spectrum', parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]}); should(_.omit(res.body, '_id')).be.eql({name: 'IR spectrum', version: 2, parameters: [{name: 'data point table', range: {min: 0, max: 1000}}]});
TemplateMeasurementModel.findById('300000000000000000000001').lean().exec((err, data:any) => { TemplateMeasurementModel.findById(res.body._id).lean().exec((err, data:any) => {
if (err) return done(err); if (err) return done(err);
should(data).have.lengthOf(1); should(data).have.only.keys('_id', 'name', 'version', 'parameters', '__v');
should(data[0]).have.only.keys('_id', 'name', 'version', 'parameters', '__v'); should(data).have.property('name', 'IR spectrum');
should(data[0]).have.property('name', 'IR spectrum'); should(data).have.property('version', 2);
should(data[0]).have.property('version', 2); should(data).have.property('parameters').have.lengthOf(1);
should(data[0]).have.property('parameters').have.lengthOf(1); should(data.parameters[0]).have.property('name', 'data point table');
should(data[0].parameters[0]).have.property('name', 'data point table'); should(data.parameters[0]).have.property('range');
should(data[0].parameters[0]).have.property('range'); should(data.parameters[0].range).have.property('min', 0);
should(data[0].parameters[0].range).have.property('min', 0); should(data.parameters[0].range).have.property('max', 1000);
should(data[0].parameters[0].range).have.property('max', 1000);
done(); done();
}); });
}); });
@ -571,10 +581,9 @@ describe('/template', () => {
req: {name: 'IR spectrum'}, req: {name: 'IR spectrum'},
}).end((err, res) => { }).end((err, res) => {
if (err) return done(err); if (err) return done(err);
should(res.body).be.eql({_id: '300000000000000000000001', name: 'IR spectrum', parameters: [{name: 'dpt', range: {type: 'array'}}]}); should(_.omit(res.body, '_id')).be.eql({name: 'IR spectrum', version: 2, parameters: [{name: 'dpt', range: {type: 'array'}}]});
TemplateMeasurementModel.findById('300000000000000000000001').lean().exec((err, data:any) => { TemplateMeasurementModel.findById(res.body._id).lean().exec((err, data:any) => {
if (err) return done(err); if (err) return done(err);
should(data).have.lengthOf(1);
should(data).have.only.keys('_id', 'name', 'version', 'parameters', '__v'); should(data).have.only.keys('_id', 'name', 'version', 'parameters', '__v');
should(data).have.property('name', 'IR spectrum'); should(data).have.property('name', 'IR spectrum');
should(data).have.property('version', 2); should(data).have.property('version', 2);
@ -592,8 +601,11 @@ describe('/template', () => {
url: '/template/measurement/300000000000000000000001', url: '/template/measurement/300000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'dpt', range: {values: [1, 2, 5]}}]}, req: {parameters: [{name: 'dpt', range: {values: [1, 2, 5]}}]}
res: {_id: '300000000000000000000001', name: 'spectrum', version: 2, 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 => { it('supports min max ranges', done => {
@ -602,18 +614,24 @@ describe('/template', () => {
url: '/template/measurement/300000000000000000000001', url: '/template/measurement/300000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'dpt', range: {min: 0, max: 1000}}]}, req: {parameters: [{name: 'dpt', range: {min: 0, max: 1000}}]}
res: {_id: '300000000000000000000001', name: 'spectrum', version: 2, 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 min max ranges', done => { it('supports array type ranges', done => {
TestHelper.request(server, done, { TestHelper.request(server, done, {
method: 'put', method: 'put',
url: '/template/measurement/300000000000000000000001', url: '/template/measurement/300000000000000000000001',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'dpt', range: {type: 'array'}}]}, req: {parameters: [{name: 'dpt2', range: {type: 'array'}}]}
res: {_id: '300000000000000000000001', name: 'spectrum', version: 2, parameters: [{name: 'dpt', 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 => { it('supports empty ranges', done => {
@ -622,8 +640,11 @@ describe('/template', () => {
url: '/template/measurement/300000000000000000000002', url: '/template/measurement/300000000000000000000002',
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 200, httpStatus: 200,
req: {parameters: [{name: 'weight %', range: {}}]}, req: {parameters: [{name: 'weight %', range: {}}]}
res: {_id: '300000000000000000000002', name: 'kf', version: 2, parameters: [{name: 'weight %', range: {}}]} }).end((err, res) => {
if (err) return done(err);
should(_.omit(res.body, '_id')).be.eql({name: 'kf', version: 3, parameters: [{name: 'weight %', range: {}}]});
done();
}); });
}); });
it('rejects not specified parameters', done => { it('rejects not specified parameters', done => {
@ -633,7 +654,7 @@ describe('/template', () => {
auth: {basic: 'admin'}, auth: {basic: 'admin'},
httpStatus: 400, httpStatus: 400,
req: {parameters: [{name: 'dpt'}], range: {xx: 33}}, req: {parameters: [{name: 'dpt'}], range: {xx: 33}},
res: {} res: {status: 'Invalid body format', details: '"parameters[0].range" is required'}
}); });
}); });
it('rejects an invalid id', done => { it('rejects an invalid id', done => {

View File

@ -35,39 +35,32 @@ router.get('/template/:collection(measurement|treatment)/' + IdValidate.paramete
}); });
}); });
router.put('/template/:collection(measurement|treatment)/' + IdValidate.parameter(), (req, res, next) => { router.put('/template/:collection(measurement|treatment)/' + IdValidate.parameter(), async (req, res, next) => {
if (!req.auth(res, ['maintain', 'admin'], 'basic')) return; if (!req.auth(res, ['maintain', 'admin'], 'basic')) return;
const {error, value: template} = TemplateValidate.input(req.body, 'change', req.params.collection);
if (error) return res400(error, res);
model(req).findOne({name: req.params.name}).lean().exec((err, data) => { const templateData = await model(req).findById(req.params.id).lean().exec().catch(err => {next(err);}) as any;
if (err) next (err); if (templateData instanceof Error) return;
const templateState = data? 'change': 'new'; if (!templateData) {
const {error, value: template} = TemplateValidate.input(req.body, templateState, req.params.collection); res.status(404).json({status: 'Not found'});
if (error) return res400(error, res); }
if (template.hasOwnProperty('name') && template.name !== req.params.name) { if (_.has(template, 'number_prefix') && template.number_prefix !== templateData.number_prefix) { // got new number_prefix
model(req).find({name: template.name}).lean().exec((err, data) => { if (!await numberPrefixCheck(template, req, res, next)) return;
if (err) next (err); }
if (data.length > 0) {
res.status(400).json({status: 'Template name already taken'});
return;
}
else {
f();
}
});
}
else {
f();
}
function f() { // to resolve async if (!_.isEqual(_.pick(templateData, _.keys(template)), template)) { // data was changed
model(req).findOneAndUpdate({name: req.params.name}, template, {new: true, upsert: true}).lean().exec((err, data) => { template.version = templateData.version + 1;
if (err) return next(err); await new (model(req))(_.assign({}, _.omit(templateData, ['_id', '__v']), template)).save((err, data) => {
res.json(TemplateValidate.output(data, req.params.collection)); if (err) next (err);
}); res.json(TemplateValidate.output(data.toObject(), req.params.collection));
} });
}); }
else {
res.json(TemplateValidate.output(templateData, req.params.collection));
}
}); });
// router.delete('/template/:collection(measurement|treatment)/:name', (req, res, next) => { // router.delete('/template/:collection(measurement|treatment)/:name', (req, res, next) => {
@ -89,6 +82,15 @@ router.put('/template/:collection(measurement|treatment)/' + IdValidate.paramete
module.exports = router; module.exports = router;
async function numberPrefixCheck (template, req, res, next) {
const data = await model(req).findOne({number_prefix: template.number_prefix}).lean().exec().catch(err => {next(err); return false;}) as any;
if (data) {
res.status(400).json({status: 'Number prefix already taken'});
return false
}
return true;
}
function model (req) { function model (req) {
return req.params.collection === 'treatment' ? TemplateTreatmentModel : TemplateMeasurementModel; return req.params.collection === 'treatment' ? TemplateTreatmentModel : TemplateMeasurementModel;
} }

View File

@ -27,10 +27,16 @@ export default class TemplateValidate {
min: joi.number(), min: joi.number(),
max: joi.number() max: joi.number(),
type: joi.string()
.valid('array')
}) })
.oxor('values', 'min') .oxor('values', 'min')
.oxor('values', 'max') .oxor('values', 'max')
.oxor('type', 'values')
.oxor('type', 'min')
.oxor('type', 'max')
.required() .required()
}) })
) )

View File

@ -5,7 +5,7 @@ import IdValidate from './id';
export default class UserValidate { // validate input for user export default class UserValidate { // validate input for user
private static user = { private static user = {
name: Joi.string() name: Joi.string() // TODO: check allowed characters
.alphanum() .alphanum()
.lowercase() .lowercase()
.max(128), .max(128),