PUT finished
This commit is contained in:
		@@ -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,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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: [{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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'});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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'});
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,18 +46,23 @@ 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
 | 
				
			||||||
 | 
					        const data = await NoteModel.findById(sampleData.note_id).lean().exec().catch(err => {next(err);}) as any;
 | 
				
			||||||
 | 
					        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
 | 
					          if (data.hasOwnProperty('custom_fields')) {  // update note_fields
 | 
				
			||||||
            customFieldsChange(Object.keys(data.custom_fields), -1);
 | 
					            customFieldsChange(Object.keys(data.custom_fields), -1);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          NoteModel.findByIdAndDelete(sampleData.note_id).lean().exec(err => {  // delete old notes
 | 
					          NoteModel.findByIdAndDelete(sampleData.note_id).lean().exec(err => {  // delete old notes
 | 
				
			||||||
            if (err) return console.error(err);
 | 
					            if (err) return console.error(err);
 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    if (sample.hasOwnProperty('notes') && Object.keys(sample.notes).length > 0) {  // save new notes
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (_.keys(sample.notes).length > 0 && newNotes) {  // save new notes
 | 
				
			||||||
        if (!await sampleRefCheck(sample, res, next)) return;
 | 
					        if (!await sampleRefCheck(sample, res, next)) return;
 | 
				
			||||||
        if (sample.notes.hasOwnProperty('custom_fields') && Object.keys(sample.notes.custom_fields).length > 0) {  // new custom_fields
 | 
					        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);
 | 
					          customFieldsChange(Object.keys(sample.notes.custom_fields), 1);
 | 
				
			||||||
@@ -66,6 +71,7 @@ router.put('/sample/' + IdValidate.parameter(), (req, res, next) => {
 | 
				
			|||||||
        delete sample.notes;
 | 
					        delete sample.notes;
 | 
				
			||||||
        sample.note_id = data._id;
 | 
					        sample.note_id = data._id;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // check for changes
 | 
					    // check for changes
 | 
				
			||||||
    if (!_.isEqual(_.pick(IdValidate.stringify(sampleData), _.keys(sample)), _.omit(sample, ['notes']))) {
 | 
					    if (!_.isEqual(_.pick(IdValidate.stringify(sampleData), _.keys(sample)), _.omit(sample, ['notes']))) {
 | 
				
			||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
  model(req).findOne({name: req.params.name}).lean().exec((err, data) => {
 | 
					 | 
				
			||||||
    if (err) next (err);
 | 
					 | 
				
			||||||
    const templateState = data? 'change': 'new';
 | 
					 | 
				
			||||||
    const {error, value: template} = TemplateValidate.input(req.body, templateState, req.params.collection);
 | 
					 | 
				
			||||||
  if (error) return res400(error, res);
 | 
					  if (error) return res400(error, res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (template.hasOwnProperty('name') && template.name !== req.params.name) {
 | 
					  const templateData = await model(req).findById(req.params.id).lean().exec().catch(err => {next(err);}) as any;
 | 
				
			||||||
      model(req).find({name: template.name}).lean().exec((err, data) => {
 | 
					  if (templateData instanceof Error) return;
 | 
				
			||||||
        if (err) next (err);
 | 
					  if (!templateData) {
 | 
				
			||||||
        if (data.length > 0) {
 | 
					    res.status(404).json({status: 'Not found'});
 | 
				
			||||||
          res.status(400).json({status: 'Template name already taken'});
 | 
					 | 
				
			||||||
          return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
          f();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      f();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function f() {  // to resolve async
 | 
					  if (_.has(template, 'number_prefix') && template.number_prefix !== templateData.number_prefix) {  // got new number_prefix
 | 
				
			||||||
      model(req).findOneAndUpdate({name: req.params.name}, template, {new: true, upsert: true}).lean().exec((err, data) => {
 | 
					    if (!await numberPrefixCheck(template, req, res, next)) return;
 | 
				
			||||||
        if (err) return next(err);
 | 
					  }
 | 
				
			||||||
        res.json(TemplateValidate.output(data, req.params.collection));
 | 
					
 | 
				
			||||||
 | 
					  if (!_.isEqual(_.pick(templateData, _.keys(template)), template)) {  // data was changed
 | 
				
			||||||
 | 
					    template.version = templateData.version + 1;
 | 
				
			||||||
 | 
					    await new (model(req))(_.assign({}, _.omit(templateData, ['_id', '__v']), template)).save((err, data) => {
 | 
				
			||||||
 | 
					      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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -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()
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user