added GET /sample/number/{number} route
This commit is contained in:
		@@ -1343,6 +1343,67 @@ describe('/sample', () => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('GET /sample/number/{number}', () => {
 | 
			
		||||
    it('returns the right sample', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/number/33',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200,
 | 
			
		||||
        res: {_id: '400000000000000000000003', number: '33', type: 'part', color: 'black', batch: '1704-005', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material: {_id: '100000000000000000000005', name: 'Amodel A 1133 HS', supplier: 'Solvay', group: 'PPA', properties: {material_template: '130000000000000000000003', mineral: 0, glass_fiber: 33, carbon_fiber: 0}, numbers: ['5514262406']}, notes: {comment: '', sample_references: [{sample_id: '400000000000000000000004', relation: 'granulate to sample'}], custom_fields: {'not allowed for new applications': true}}, measurements: [{_id: '800000000000000000000003', sample_id: '400000000000000000000003', values: {val1: 1}, measurement_template: '300000000000000000000003'}], user: 'admin'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('works with an API key', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/number/33',
 | 
			
		||||
        auth: {key: 'janedoe'},
 | 
			
		||||
        httpStatus: 200,
 | 
			
		||||
        res: {_id: '400000000000000000000003', number: '33', type: 'part', color: 'black', batch: '1704-005', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material: {_id: '100000000000000000000005', name: 'Amodel A 1133 HS', supplier: 'Solvay', group: 'PPA', properties: {material_template: '130000000000000000000003', mineral: 0, glass_fiber: 33, carbon_fiber: 0}, numbers: ['5514262406']}, notes: {comment: '', sample_references: [{sample_id: '400000000000000000000004', relation: 'granulate to sample'}], custom_fields: {'not allowed for new applications': true}}, measurements: [{_id: '800000000000000000000003', sample_id: '400000000000000000000003', values: {val1: 1}, measurement_template: '300000000000000000000003'}], user: 'admin'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('returns a deleted sample for a maintain/admin user', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/number/Rng33',
 | 
			
		||||
        auth: {basic: 'admin'},
 | 
			
		||||
        httpStatus: 200,
 | 
			
		||||
        res: {_id: '400000000000000000000005', number: 'Rng33', type: 'granulate', color: 'black', batch: '1653000308', condition: {condition_template: '200000000000000000000003'}, material: {_id: '100000000000000000000005', name: 'Amodel A 1133 HS', supplier: 'Solvay', group: 'PPA', properties: {material_template: '130000000000000000000003', mineral: 0, glass_fiber: 33, carbon_fiber: 0}, numbers: ['5514262406']}, notes: {}, measurements: [], user: 'admin'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('returns 403 for a write user when requesting a deleted sample', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/number/Rng33',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 403
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('returns 404 for an unknown sample', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/number/Rng883',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 404
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects an invalid id', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/number/xx-xx',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 404
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects unauthorized requests', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/number/33',
 | 
			
		||||
        httpStatus: 401
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('PUT /sample/restore/{id}', () => {
 | 
			
		||||
    it('sets the status', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
 
 | 
			
		||||
@@ -242,6 +242,13 @@ router.get('/samples', async (req, res, next) => {
 | 
			
		||||
    && e !== filters.sort[0]                           // field was not in sort
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  if (fieldsToAdd.find(e => e === 'notes')) {  // add notes
 | 
			
		||||
    queryPtr.push(
 | 
			
		||||
      {$lookup: {from: 'notes', localField: 'note_id', foreignField: '_id', as: 'notes'}},
 | 
			
		||||
      {$addFields: {notes: { $arrayElemAt: ['$notes', 0]}}}
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (fieldsToAdd.find(e => /material\./.test(e)) && !materialAdded) {  // add material, was not added already
 | 
			
		||||
    queryPtr.push(
 | 
			
		||||
      {$lookup: {from: 'materials', localField: 'material_id', foreignField: '_id', as: 'material'}},
 | 
			
		||||
@@ -387,26 +394,7 @@ router.get('/sample/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
 | 
			
		||||
  SampleModel.findById(req.params.id).populate('material_id').populate('user_id', 'name').populate('note_id').exec(async (err, sampleData: any) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
 | 
			
		||||
    if (sampleData) {
 | 
			
		||||
      await sampleData.populate('material_id.group_id').populate('material_id.supplier_id').execPopulate().catch(err => next(err));
 | 
			
		||||
      if (sampleData instanceof Error) return;
 | 
			
		||||
      sampleData = sampleData.toObject();
 | 
			
		||||
 | 
			
		||||
      if (sampleData.status === globals.status.deleted && !req.auth(res, ['maintain', 'admin'], 'all')) return;  // deleted samples only available for maintain/admin
 | 
			
		||||
      sampleData.material = sampleData.material_id;  // map data to right keys
 | 
			
		||||
      sampleData.material.group = sampleData.material.group_id.name;
 | 
			
		||||
      sampleData.material.supplier = sampleData.material.supplier_id.name;
 | 
			
		||||
      sampleData.user = sampleData.user_id.name;
 | 
			
		||||
      sampleData.notes = sampleData.note_id ? sampleData.note_id : {};
 | 
			
		||||
      MeasurementModel.find({sample_id: mongoose.Types.ObjectId(req.params.id), status: {$ne: globals.status.deleted}}).lean().exec((err, data) => {
 | 
			
		||||
        sampleData.measurements = data;
 | 
			
		||||
        res.json(SampleValidate.output(sampleData, 'details'));
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      res.status(404).json({status: 'Not found'});
 | 
			
		||||
    }
 | 
			
		||||
    await sampleReturn(sampleData, req, res, next);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -514,6 +502,15 @@ router.delete('/sample/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.get('/sample/number/:number', (req, res, next) => {
 | 
			
		||||
  if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'all')) return;
 | 
			
		||||
 | 
			
		||||
  SampleModel.findOne({number: req.params.number}).populate('material_id').populate('user_id', 'name').populate('note_id').exec(async (err, sampleData: any) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    await sampleReturn(sampleData, req, res, next);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
router.put('/sample/restore/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
  if (!req.auth(res, ['maintain', 'admin'], 'basic')) return;
 | 
			
		||||
 | 
			
		||||
@@ -769,4 +766,27 @@ function filterQueries (filters) {
 | 
			
		||||
 | 
			
		||||
function dateToOId (date) {  // convert date to ObjectId
 | 
			
		||||
  return mongoose.Types.ObjectId(Math.floor(date / 1000).toString(16) + '0000000000000000');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function sampleReturn (sampleData, req, res, next) {
 | 
			
		||||
  if (sampleData) {
 | 
			
		||||
    console.log(sampleData);
 | 
			
		||||
    await sampleData.populate('material_id.group_id').populate('material_id.supplier_id').execPopulate().catch(err => next(err));
 | 
			
		||||
    if (sampleData instanceof Error) return;
 | 
			
		||||
    sampleData = sampleData.toObject();
 | 
			
		||||
 | 
			
		||||
    if (sampleData.status === globals.status.deleted && !req.auth(res, ['maintain', 'admin'], 'all')) return;  // deleted samples only available for maintain/admin
 | 
			
		||||
    sampleData.material = sampleData.material_id;  // map data to right keys
 | 
			
		||||
    sampleData.material.group = sampleData.material.group_id.name;
 | 
			
		||||
    sampleData.material.supplier = sampleData.material.supplier_id.name;
 | 
			
		||||
    sampleData.user = sampleData.user_id.name;
 | 
			
		||||
    sampleData.notes = sampleData.note_id ? sampleData.note_id : {};
 | 
			
		||||
    MeasurementModel.find({sample_id: sampleData._id, status: {$ne: globals.status.deleted}}).lean().exec((err, data) => {
 | 
			
		||||
      sampleData.measurements = data;
 | 
			
		||||
      res.json(SampleValidate.output(sampleData, 'details'));
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    res.status(404).json({status: 'Not found'});
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -70,13 +70,14 @@ export default class SampleValidate {
 | 
			
		||||
  private static fieldKeys = [
 | 
			
		||||
    ...SampleValidate.sortKeys,
 | 
			
		||||
    'condition',
 | 
			
		||||
    'notes',
 | 
			
		||||
    'material_id',
 | 
			
		||||
    'material',
 | 
			
		||||
    'note_id',
 | 
			
		||||
    'user_id',
 | 
			
		||||
    'material._id',
 | 
			
		||||
    'material.numbers',
 | 
			
		||||
    'measurements.spectrum.dpt'
 | 
			
		||||
    'measurements.spectrum.dpt',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  static input (data, param) {  // validate input, set param to 'new' to make all attributes required
 | 
			
		||||
@@ -134,6 +135,7 @@ export default class SampleValidate {
 | 
			
		||||
        material_id: IdValidate.get(),
 | 
			
		||||
        material: MaterialValidate.outputV().append({number: Joi.string().max(128).allow('')}),
 | 
			
		||||
        note_id: IdValidate.get().allow(null),
 | 
			
		||||
        notes: this.sample.notes,
 | 
			
		||||
        user_id: IdValidate.get(),
 | 
			
		||||
        added: this.sample.added
 | 
			
		||||
      };
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user