implemented paging
This commit is contained in:
		@@ -10,6 +10,7 @@ import mongoose from 'mongoose';
 | 
			
		||||
// TODO: generate output for ML in format DPT -> data, implement filtering, field selection
 | 
			
		||||
// TODO: generate csv
 | 
			
		||||
// TODO: write script for data import
 | 
			
		||||
// TODO: allowed types: tension rod, part, granulate, other
 | 
			
		||||
 | 
			
		||||
describe('/sample', () => {
 | 
			
		||||
  let server;
 | 
			
		||||
@@ -18,6 +19,7 @@ describe('/sample', () => {
 | 
			
		||||
  afterEach(done => TestHelper.afterEach(server, done));
 | 
			
		||||
  after(done => TestHelper.after(done));
 | 
			
		||||
 | 
			
		||||
  // TODO: sort, added date filter, has measurements/condition filter
 | 
			
		||||
  describe('GET /samples', () => {
 | 
			
		||||
    it('returns all samples', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
@@ -30,7 +32,7 @@ describe('/sample', () => {
 | 
			
		||||
        const json = require('../test/db.json');
 | 
			
		||||
        should(res.body).have.lengthOf(json.collections.samples.filter(e => e.status ===globals.status.validated).length);
 | 
			
		||||
        should(res.body).matchEach(sample => {
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
          should(sample).have.property('_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('number').be.type('string');
 | 
			
		||||
          should(sample).have.property('type').be.type('string');
 | 
			
		||||
@@ -41,6 +43,7 @@ describe('/sample', () => {
 | 
			
		||||
          should(sample).have.property('material_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('note_id');
 | 
			
		||||
          should(sample).have.property('user_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('added').be.type('string');
 | 
			
		||||
        });
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
@@ -56,7 +59,7 @@ describe('/sample', () => {
 | 
			
		||||
        const json = require('../test/db.json');
 | 
			
		||||
        should(res.body).have.lengthOf(json.collections.samples.filter(e => e.status ===globals.status.validated).length);
 | 
			
		||||
        should(res.body).matchEach(sample => {
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
          should(sample).have.property('_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('number').be.type('string');
 | 
			
		||||
          should(sample).have.property('type').be.type('string');
 | 
			
		||||
@@ -67,6 +70,7 @@ describe('/sample', () => {
 | 
			
		||||
          should(sample).have.property('material_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('note_id');
 | 
			
		||||
          should(sample).have.property('user_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('added').be.type('string');
 | 
			
		||||
        });
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
@@ -82,7 +86,7 @@ describe('/sample', () => {
 | 
			
		||||
        const json = require('../test/db.json');
 | 
			
		||||
        should(res.body).have.lengthOf(json.collections.samples.filter(e => e.status ===globals.status.new).length);
 | 
			
		||||
        should(res.body).matchEach(sample => {
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
          should(sample).have.property('_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('number').be.type('string');
 | 
			
		||||
          should(sample).have.property('type').be.type('string');
 | 
			
		||||
@@ -92,10 +96,114 @@ describe('/sample', () => {
 | 
			
		||||
          should(sample).have.property('material_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('note_id');
 | 
			
		||||
          should(sample).have.property('user_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('added').be.type('string');
 | 
			
		||||
        });
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('uses the given page size', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?status=all&page-size=3',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body).have.lengthOf(3);
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('returns results starting after last-id', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?status=all&last-id=400000000000000000000002',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body[0]).have.property('_id', '400000000000000000000003');
 | 
			
		||||
        should(res.body[1]).have.property('_id', '400000000000000000000004');
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('returns the right page number', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?status=all&to-page=2&page-size=2',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body[0]).have.property('_id', '400000000000000000000006');
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('works with negative page numbers', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?status=all&to-page=-1&page-size=2&last-id=400000000000000000000004',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body[0]).have.property('_id', '400000000000000000000001');
 | 
			
		||||
        should(res.body[1]).have.property('_id', '400000000000000000000002');
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('returns an empty array for a page number out of range', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?status=all&to-page=100&page-size=2',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body).have.lengthOf(0);
 | 
			
		||||
        should(res.body).be.eql([]);
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('returns an empty array for a page number out of negative range', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?status=all&to-page=-100&page-size=3&last-id=400000000000000000000004',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body).have.lengthOf(0);
 | 
			
		||||
        should(res.body).be.eql([]);
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects a negative page size', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?page-size=-3',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 400,
 | 
			
		||||
        res: {status: 'Invalid body format', details: '"page-size" must be larger than or equal to 1'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects an invalid last-id', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?last-id=40000000000h000000000002',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 400,
 | 
			
		||||
        res: {status: 'Invalid body format', details: '"last-id" with value "40000000000h000000000002" fails to match the required pattern: /[0-9a-f]{24}/'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects a to-page without page-size', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/samples?to-page=3',
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 400,
 | 
			
		||||
        res: {status: 'Invalid body format', details: '"to-page" missing required peer "page-size"'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects an invalid state name', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
@@ -127,7 +235,7 @@ describe('/sample', () => {
 | 
			
		||||
        let asyncCounter = res.body.length;
 | 
			
		||||
        should(res.body).have.lengthOf(json.collections.samples.filter(e => e.status ===globals.status.new).length);
 | 
			
		||||
        should(res.body).matchEach(sample => {
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
          should(sample).have.property('_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('number').be.type('string');
 | 
			
		||||
          should(sample).have.property('type').be.type('string');
 | 
			
		||||
@@ -140,6 +248,7 @@ describe('/sample', () => {
 | 
			
		||||
          should(sample).have.property('material_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('note_id');
 | 
			
		||||
          should(sample).have.property('user_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('added').be.type('string');
 | 
			
		||||
          SampleModel.findById(sample._id).lean().exec((err, data) => {
 | 
			
		||||
            should(data).have.property('status',globals.status.new);
 | 
			
		||||
            if (--asyncCounter === 0) {
 | 
			
		||||
@@ -161,7 +270,7 @@ describe('/sample', () => {
 | 
			
		||||
        let asyncCounter = res.body.length;
 | 
			
		||||
        should(res.body).have.lengthOf(json.collections.samples.filter(e => e.status === -1).length);
 | 
			
		||||
        should(res.body).matchEach(sample => {
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
          should(sample).have.only.keys('_id', 'number', 'type', 'color', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
          should(sample).have.property('_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('number').be.type('string');
 | 
			
		||||
          should(sample).have.property('type').be.type('string');
 | 
			
		||||
@@ -174,6 +283,7 @@ describe('/sample', () => {
 | 
			
		||||
          should(sample).have.property('material_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('note_id');
 | 
			
		||||
          should(sample).have.property('user_id').be.type('string');
 | 
			
		||||
          should(sample).have.property('added').be.type('string');
 | 
			
		||||
          SampleModel.findById(sample._id).lean().exec((err, data) => {
 | 
			
		||||
            should(data).have.property('status',globals.status.deleted);
 | 
			
		||||
            if (--asyncCounter === 0) {
 | 
			
		||||
@@ -269,7 +379,7 @@ describe('/sample', () => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('PUT /sample/{id}', () => {
 | 
			
		||||
  describe('PUT /sample/{id}', () => {  // TODO: fix tests, work on /samples
 | 
			
		||||
    it('returns the right sample', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'put',
 | 
			
		||||
@@ -277,7 +387,7 @@ describe('/sample', () => {
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200,
 | 
			
		||||
        req: {},
 | 
			
		||||
        res: {_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'}
 | 
			
		||||
        res: {_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002', added: '2004-01-10T13:37:04.000Z'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('keeps unchanged properties', done => {
 | 
			
		||||
@@ -289,7 +399,7 @@ describe('/sample', () => {
 | 
			
		||||
        req: {type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', notes: {}}
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'});
 | 
			
		||||
        should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002', added: '2004-01-10T13:37:04.000Z'});
 | 
			
		||||
        SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => {
 | 
			
		||||
          if (err) return done (err);
 | 
			
		||||
          should(data).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'status', '__v');
 | 
			
		||||
@@ -316,7 +426,7 @@ describe('/sample', () => {
 | 
			
		||||
        req: {type: 'granulate'}
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'});
 | 
			
		||||
        should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002', added: '2004-01-10T13:37:04.000Z'});
 | 
			
		||||
        SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => {
 | 
			
		||||
          if (err) return done (err);
 | 
			
		||||
          should(data).have.property('status',globals.status.validated);
 | 
			
		||||
@@ -333,7 +443,7 @@ describe('/sample', () => {
 | 
			
		||||
        req: {condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}}
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done(err);
 | 
			
		||||
        should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'});
 | 
			
		||||
        should(res.body).be.eql({_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002', added: '2004-01-10T13:37:04.000Z'});
 | 
			
		||||
        SampleModel.findById('400000000000000000000001').lean().exec((err, data: any) => {
 | 
			
		||||
          if (err) return done (err);
 | 
			
		||||
          should(data).have.property('status',globals.status.validated);
 | 
			
		||||
@@ -350,7 +460,7 @@ describe('/sample', () => {
 | 
			
		||||
        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', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000001', note_id: '500000000000000000000001', user_id: '000000000000000000000002'});
 | 
			
		||||
        should(res.body).be.eql({_id: '400000000000000000000002', number: '21', type: 'granulate', color: 'natural', batch: '1560237365', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000001', note_id: '500000000000000000000001', user_id: '000000000000000000000002', added: '2004-01-10T13:37:04.000Z'});
 | 
			
		||||
        SampleModel.findById('400000000000000000000002').lean().exec((err, data: any) => {
 | 
			
		||||
          if (err) return done (err);
 | 
			
		||||
          should(data).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'status', '__v');
 | 
			
		||||
@@ -627,7 +737,7 @@ describe('/sample', () => {
 | 
			
		||||
        auth: {basic: 'janedoe'},
 | 
			
		||||
        httpStatus: 200,
 | 
			
		||||
        req: {condition: {}},
 | 
			
		||||
        res: {_id: '400000000000000000000006', number: 'Rng36', type: 'granulate', color: 'black', batch: '', condition: {}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'}
 | 
			
		||||
        res: {_id: '400000000000000000000006', number: 'Rng36', type: 'granulate', color: 'black', batch: '', condition: {}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002', added: '2004-01-10T13:37:04.000Z'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects an old version of a condition template', done => {
 | 
			
		||||
@@ -647,7 +757,7 @@ describe('/sample', () => {
 | 
			
		||||
        auth: {basic: 'admin'},
 | 
			
		||||
        httpStatus: 200,
 | 
			
		||||
        req: {condition: {p1: 36, condition_template: '200000000000000000000004'}},
 | 
			
		||||
        res: {_id: '400000000000000000000004', number: '32', type: 'granulate', color: 'black', batch: '1653000308', condition: {p1: 36, condition_template: '200000000000000000000004'}, material_id: '100000000000000000000005', note_id: '500000000000000000000003', user_id: '000000000000000000000003'}
 | 
			
		||||
        res: {_id: '400000000000000000000004', number: '32', type: 'granulate', color: 'black', batch: '1653000308', condition: {p1: 36, condition_template: '200000000000000000000004'}, material_id: '100000000000000000000005', note_id: '500000000000000000000003', user_id: '000000000000000000000003', added: '2004-01-10T13:37:04.000Z'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects an changing back to an empty condition', done => {
 | 
			
		||||
@@ -694,7 +804,7 @@ describe('/sample', () => {
 | 
			
		||||
        auth: {basic: 'admin'},
 | 
			
		||||
        httpStatus: 200,
 | 
			
		||||
        req: {},
 | 
			
		||||
        res: {_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {condition_template: '200000000000000000000001', material: 'copper', weeks: 3}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002'}
 | 
			
		||||
        res: {_id: '400000000000000000000001', number: '1', type: 'granulate', color: 'black', batch: '', condition: {condition_template: '200000000000000000000001', material: 'copper', weeks: 3}, material_id: '100000000000000000000004', note_id: null, user_id: '000000000000000000000002', added: '2004-01-10T13:37:04.000Z'}
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects requests from a read user', done => {
 | 
			
		||||
@@ -1085,7 +1195,7 @@ describe('/sample', () => {
 | 
			
		||||
        req: {color: 'black', type: 'granulate', batch: '1560237365', condition: {material: 'copper', weeks: 3, condition_template: '200000000000000000000001'}, material_id: '100000000000000000000001', notes: {comment: 'Testcomment', sample_references: [{sample_id: '400000000000000000000003', relation: 'part to this sample'}]}}
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done (err);
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
        should(res.body).have.property('_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('number', 'Rng37');
 | 
			
		||||
        should(res.body).have.property('color', 'black');
 | 
			
		||||
@@ -1095,6 +1205,8 @@ describe('/sample', () => {
 | 
			
		||||
        should(res.body).have.property('material_id', '100000000000000000000001');
 | 
			
		||||
        should(res.body).have.property('note_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('user_id', '000000000000000000000002');
 | 
			
		||||
        should(res.body).have.property('added').be.type('string');
 | 
			
		||||
        should(new Date().getTime() - new Date(res.body.added).getTime()).be.below(1000);
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -1198,7 +1310,7 @@ describe('/sample', () => {
 | 
			
		||||
        req: {color: 'black', type: 'granulate', batch: '1560237365', material_id: '100000000000000000000001', notes: {comment: 'Testcomment', sample_references: [{sample_id: '400000000000000000000003', relation: 'part to this sample'}]}}
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done (err);
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
        should(res.body).have.property('_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('number', 'Fe1');
 | 
			
		||||
        should(res.body).have.property('color', 'black');
 | 
			
		||||
@@ -1207,6 +1319,8 @@ describe('/sample', () => {
 | 
			
		||||
        should(res.body).have.property('material_id', '100000000000000000000001');
 | 
			
		||||
        should(res.body).have.property('note_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('user_id', '000000000000000000000004');
 | 
			
		||||
        should(res.body).have.property('added').be.type('string');
 | 
			
		||||
        should(new Date().getTime() - new Date(res.body.added).getTime()).be.below(1500);
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -1219,7 +1333,7 @@ describe('/sample', () => {
 | 
			
		||||
        req: {color: 'black', type: 'granulate', batch: '1560237365', material_id: '100000000000000000000001', notes: {comment: 'Testcomment', sample_references: [{sample_id: '400000000000000000000003', relation: 'part to this sample'}]}}
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done (err);
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
        should(res.body).have.property('_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('number', 'Rng37');
 | 
			
		||||
        should(res.body).have.property('color', 'black');
 | 
			
		||||
@@ -1229,6 +1343,8 @@ describe('/sample', () => {
 | 
			
		||||
        should(res.body).have.property('material_id', '100000000000000000000001');
 | 
			
		||||
        should(res.body).have.property('note_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('user_id', '000000000000000000000002');
 | 
			
		||||
        should(res.body).have.property('added').be.type('string');
 | 
			
		||||
        should(new Date().getTime() - new Date(res.body.added).getTime()).be.below(1000);
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -1271,7 +1387,7 @@ describe('/sample', () => {
 | 
			
		||||
        req: {number: 'Rng34', color: 'black', type: 'granulate', batch: '1560237365', material_id: '100000000000000000000001', notes: {comment: 'Testcomment', sample_references: [{sample_id: '400000000000000000000003', relation: 'part to this sample'}]}},
 | 
			
		||||
      }).end((err, res) => {
 | 
			
		||||
        if (err) return done (err);
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id');
 | 
			
		||||
        should(res.body).have.only.keys('_id', 'number', 'color', 'type', 'batch', 'condition', 'material_id', 'note_id', 'user_id', 'added');
 | 
			
		||||
        should(res.body).have.property('_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('number', 'Rng34');
 | 
			
		||||
        should(res.body).have.property('color', 'black');
 | 
			
		||||
@@ -1281,6 +1397,8 @@ describe('/sample', () => {
 | 
			
		||||
        should(res.body).have.property('material_id', '100000000000000000000001');
 | 
			
		||||
        should(res.body).have.property('note_id').be.type('string');
 | 
			
		||||
        should(res.body).have.property('user_id', '000000000000000000000003');
 | 
			
		||||
        should(res.body).have.property('added').be.type('string');
 | 
			
		||||
        should(new Date().getTime() - new Date(res.body.added).getTime()).be.below(1000);
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -25,22 +25,43 @@ router.get('/samples', (req, res, next) => {
 | 
			
		||||
  const {error, value: filters} = SampleValidate.query(req.query);
 | 
			
		||||
  if (error) return res400(error, res);
 | 
			
		||||
 | 
			
		||||
  let conditions;
 | 
			
		||||
 | 
			
		||||
  let status;
 | 
			
		||||
  if (filters.hasOwnProperty('status')) {
 | 
			
		||||
    if(filters.status === 'all') {
 | 
			
		||||
      conditions = {$or: [{status: globals.status.validated}, {status: globals.status.new}]}
 | 
			
		||||
      status = {$or: [{status: globals.status.validated}, {status: globals.status.new}]}
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      conditions = {status: globals.status[filters.status]};
 | 
			
		||||
      status = {status: globals.status[filters.status]};
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else {  // default
 | 
			
		||||
    conditions = {status: globals.status.validated};
 | 
			
		||||
    status = {status: globals.status.validated};
 | 
			
		||||
  }
 | 
			
		||||
  const query = SampleModel.find(status);
 | 
			
		||||
 | 
			
		||||
  if (filters['page-size']) {
 | 
			
		||||
    query.limit(filters['page-size']);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  SampleModel.find(conditions).lean().exec((err, data) => {
 | 
			
		||||
  if (filters['last-id']) {
 | 
			
		||||
    if (filters['to-page'] && filters['to-page'] < 0) {
 | 
			
		||||
      query.lte('_id', mongoose.Types.ObjectId(filters['last-id']));  // TODO: consider sorting
 | 
			
		||||
      query.sort({_id: -1});
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      query.gt('_id', mongoose.Types.ObjectId(filters['last-id']));  // TODO: consider sorting
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (filters['to-page']) {
 | 
			
		||||
    query.skip(Math.abs(filters['to-page']) * filters['page-size']);  // TODO: check order for negative numbers
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  query.lean().exec((err, data) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    if (filters['to-page'] && filters['to-page'] < 0) {
 | 
			
		||||
      data.reverse();
 | 
			
		||||
    }
 | 
			
		||||
    res.json(_.compact(data.map(e => SampleValidate.output(e))));  // validate all and filter null values from validation errors
 | 
			
		||||
  })
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,11 @@ export default class SampleValidate {
 | 
			
		||||
            Joi.date()
 | 
			
		||||
          )
 | 
			
		||||
        )
 | 
			
		||||
    })
 | 
			
		||||
    }),
 | 
			
		||||
 | 
			
		||||
    added: Joi.date()
 | 
			
		||||
      .iso()
 | 
			
		||||
      .min('1970-01-01T00:00:00.000Z')
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static input (data, param) {  // validate input, set param to 'new' to make all attributes required
 | 
			
		||||
@@ -85,6 +89,7 @@ export default class SampleValidate {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static output (data, param = 'refs') {  // validate output and strip unwanted properties, returns null if not valid
 | 
			
		||||
    data.added = data._id.getTimestamp();
 | 
			
		||||
    data = IdValidate.stringify(data);
 | 
			
		||||
    let joiObject;
 | 
			
		||||
    if (param === 'refs') {
 | 
			
		||||
@@ -97,7 +102,8 @@ export default class SampleValidate {
 | 
			
		||||
        condition: this.sample.condition,
 | 
			
		||||
        material_id: IdValidate.get(),
 | 
			
		||||
        note_id: IdValidate.get().allow(null),
 | 
			
		||||
        user_id: IdValidate.get()
 | 
			
		||||
        user_id: IdValidate.get(),
 | 
			
		||||
        added: this.sample.added
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
    else if(param === 'details') {
 | 
			
		||||
@@ -123,7 +129,10 @@ export default class SampleValidate {
 | 
			
		||||
 | 
			
		||||
  static query (data) {
 | 
			
		||||
    return Joi.object({
 | 
			
		||||
      status: Joi.string().valid('validated', 'new', 'all')
 | 
			
		||||
    }).validate(data);
 | 
			
		||||
      status: Joi.string().valid('validated', 'new', 'all'),
 | 
			
		||||
      'last-id': IdValidate.get(),
 | 
			
		||||
      'to-page': Joi.number().integer(),
 | 
			
		||||
      'page-size': Joi.number().integer().min(1)
 | 
			
		||||
    }).with('to-page', 'page-size').validate(data);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user