implemented code coverage
This commit is contained in:
		
							
								
								
									
										25
									
								
								src/db.ts
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								src/db.ts
									
									
									
									
									
								
							@@ -42,15 +42,18 @@ export default class db {
 | 
			
		||||
    });
 | 
			
		||||
    mongoose.connection.on('error', console.error.bind(console, 'connection error:'));
 | 
			
		||||
    mongoose.connection.on('disconnected', () => {  // reset state on disconnect
 | 
			
		||||
      console.info('Database disconnected');
 | 
			
		||||
      this.state.db = 0;
 | 
			
		||||
      done();
 | 
			
		||||
      if (process.env.NODE_ENV !== 'test') {  // Do not interfere with testing
 | 
			
		||||
        console.info('Database disconnected');
 | 
			
		||||
        this.state.db = 0;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    process.on('SIGINT', () => {  // close connection when app is terminated
 | 
			
		||||
      mongoose.connection.close(() => {
 | 
			
		||||
        console.info('Mongoose default connection disconnected through app termination');
 | 
			
		||||
        process.exit(0);
 | 
			
		||||
      });
 | 
			
		||||
      if (!this.state.db) {  // database still connected
 | 
			
		||||
        mongoose.connection.close(() => {
 | 
			
		||||
          console.info('Mongoose default connection disconnected through app termination');
 | 
			
		||||
          process.exit(0);
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    mongoose.connection.once('open', () => {
 | 
			
		||||
      mongoose.set('useFindAndModify', false);
 | 
			
		||||
@@ -60,6 +63,14 @@ export default class db {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static disconnect (done) {
 | 
			
		||||
    mongoose.connection.close(() => {
 | 
			
		||||
      console.info(process.env.NODE_ENV === 'test' ? '' : `Disconnected from database`);
 | 
			
		||||
      this.state.db = 0;
 | 
			
		||||
      done();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static getState () {
 | 
			
		||||
    return this.state;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ import db from './db';
 | 
			
		||||
// TODO: add multiple samples at once
 | 
			
		||||
// TODO: coverage
 | 
			
		||||
// TODO: think about the display of deleted/new samples and validation in data and UI
 | 
			
		||||
// TODO: improve error coverage
 | 
			
		||||
 | 
			
		||||
// tell if server is running in debug or production environment
 | 
			
		||||
console.info(process.env.NODE_ENV === 'production' ? '===== PRODUCTION =====' : process.env.NODE_ENV === 'test' ? '' :'===== DEVELOPMENT =====');
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ describe('/material', () => {
 | 
			
		||||
  before(done => TestHelper.before(done));
 | 
			
		||||
  beforeEach(done => server = TestHelper.beforeEach(server, done));
 | 
			
		||||
  afterEach(done => TestHelper.afterEach(server, done));
 | 
			
		||||
  after(done => TestHelper.after(done));
 | 
			
		||||
 | 
			
		||||
  describe('GET /materials', () => {
 | 
			
		||||
    it('returns all materials', done => {
 | 
			
		||||
@@ -146,7 +147,6 @@ describe('/material', () => {
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
        done();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('rejects requests from a write user', done => {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,14 +5,17 @@ import globals from '../globals';
 | 
			
		||||
 | 
			
		||||
// TODO: restore measurements for m/a
 | 
			
		||||
 | 
			
		||||
// TODO: coverage!!!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
describe('/measurement', () => {
 | 
			
		||||
  let server;
 | 
			
		||||
  before(done => TestHelper.before(done));
 | 
			
		||||
  beforeEach(done => server = TestHelper.beforeEach(server, done));
 | 
			
		||||
  afterEach(done => TestHelper.afterEach(server, done));
 | 
			
		||||
  after(done => TestHelper.after(done));
 | 
			
		||||
 | 
			
		||||
  describe('GET /mesurement/{id}', () => {
 | 
			
		||||
  describe('GET /measurement/{id}', () => {
 | 
			
		||||
    it('returns the right measurement', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ router.put('/measurement/' + IdValidate.parameter(), async (req, res, next) => {
 | 
			
		||||
  const data = await MeasurementModel.findById(req.params.id).lean().exec().catch(err => {next(err);}) as any;
 | 
			
		||||
  if (data instanceof Error) return;
 | 
			
		||||
  if (!data) {
 | 
			
		||||
    res.status(404).json({status: 'Not found'});
 | 
			
		||||
    return res.status(404).json({status: 'Not found'});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // add properties needed for sampleIdCheck
 | 
			
		||||
@@ -55,7 +55,6 @@ router.put('/measurement/' + IdValidate.parameter(), async (req, res, next) => {
 | 
			
		||||
  if (!await templateCheck(measurement, 'change', res, next)) return;
 | 
			
		||||
  await MeasurementModel.findByIdAndUpdate(req.params.id, measurement, {new: true}).lean().exec((err, data) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    console.log(data);
 | 
			
		||||
    res.json(MeasurementValidate.output(data));
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -66,12 +65,12 @@ router.delete('/measurement/' + IdValidate.parameter(), (req, res, next) => {
 | 
			
		||||
  MeasurementModel.findById(req.params.id).lean().exec(async (err, data) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    if (!data) {
 | 
			
		||||
      res.status(404).json({status: 'Not found'});
 | 
			
		||||
      return res.status(404).json({status: 'Not found'});
 | 
			
		||||
    }
 | 
			
		||||
    if (!await sampleIdCheck(data, req, res, next)) return;
 | 
			
		||||
    await MeasurementModel.findByIdAndUpdate(req.params.id, {status:globals.status.deleted}).lean().exec(err => {
 | 
			
		||||
      if (err) return next(err);
 | 
			
		||||
      res.json({status: 'OK'});
 | 
			
		||||
      return res.json({status: 'OK'});
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -89,7 +88,6 @@ router.post('/measurement/new', async (req, res, next) => {
 | 
			
		||||
  measurement.status = 0;
 | 
			
		||||
  await new MeasurementModel(measurement).save((err, data) => {
 | 
			
		||||
    if (err) return next(err);
 | 
			
		||||
    console.log(data);
 | 
			
		||||
    res.json(MeasurementValidate.output(data.toObject()));
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import TestHelper from "../test/helper";
 | 
			
		||||
import db from '../db';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
describe('/', () => {
 | 
			
		||||
@@ -6,6 +7,7 @@ describe('/', () => {
 | 
			
		||||
  before(done => TestHelper.before(done));
 | 
			
		||||
  beforeEach(done => server = TestHelper.beforeEach(server, done));
 | 
			
		||||
  afterEach(done => TestHelper.afterEach(server, done));
 | 
			
		||||
  after(done => TestHelper.after(done));
 | 
			
		||||
 | 
			
		||||
  describe('GET /', () => {
 | 
			
		||||
    it('returns the root message', done => {
 | 
			
		||||
@@ -40,7 +42,15 @@ describe('/', () => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/authorized',
 | 
			
		||||
        auth: {name: 'admin', pass: 'Abc123!!'},
 | 
			
		||||
        auth: {basic: {name: 'admin', pass: 'Abc123!!'}},
 | 
			
		||||
        httpStatus: 401
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    it('does not work with incorrect username', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/authorized',
 | 
			
		||||
        auth: {basic: {name: 'adminxx', pass: 'Abc123!!'}},
 | 
			
		||||
        httpStatus: 401
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -66,4 +76,32 @@ describe('/', () => {
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('An invalid JSON body', () => {
 | 
			
		||||
    it('is rejected', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'post',
 | 
			
		||||
        url: '/',
 | 
			
		||||
        httpStatus: 400,
 | 
			
		||||
        reqType: 'json',
 | 
			
		||||
        req: '{"xxx"}',
 | 
			
		||||
        res: {status: 'Invalid JSON body'}
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('A not connected database', () => {
 | 
			
		||||
    it('resolves to an 500 error', done => {
 | 
			
		||||
      db.disconnect(() => {
 | 
			
		||||
        TestHelper.request(server, done, {
 | 
			
		||||
          method: 'get',
 | 
			
		||||
          url: '/',
 | 
			
		||||
          httpStatus: 500
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // describe('API')  // TODO not in production
 | 
			
		||||
});
 | 
			
		||||
@@ -19,6 +19,7 @@ describe('/sample', () => {
 | 
			
		||||
  before(done => TestHelper.before(done));
 | 
			
		||||
  beforeEach(done => server = TestHelper.beforeEach(server, done));
 | 
			
		||||
  afterEach(done => TestHelper.afterEach(server, done));
 | 
			
		||||
  after(done => TestHelper.after(done));
 | 
			
		||||
 | 
			
		||||
  describe('GET /samples', () => {
 | 
			
		||||
    it('returns all samples', done => {
 | 
			
		||||
@@ -197,7 +198,7 @@ describe('/sample', () => {
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('returns a deleted sample for a maintain/admin user', done => {  // TODO: make tests work
 | 
			
		||||
    it('returns a deleted sample for a maintain/admin user', done => {
 | 
			
		||||
      TestHelper.request(server, done, {
 | 
			
		||||
        method: 'get',
 | 
			
		||||
        url: '/sample/400000000000000000000005',
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ describe('/template', () => {
 | 
			
		||||
  before(done => TestHelper.before(done));
 | 
			
		||||
  beforeEach(done => server = TestHelper.beforeEach(server, done));
 | 
			
		||||
  afterEach(done => TestHelper.afterEach(server, done));
 | 
			
		||||
  after(done => TestHelper.after(done));
 | 
			
		||||
 | 
			
		||||
  describe('/template/condition', () => {
 | 
			
		||||
    describe('GET /template/conditions', () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ router.put('/template/:collection(measurement|condition)/' + IdValidate.paramete
 | 
			
		||||
  const templateData = await model(req).findById(req.params.id).lean().exec().catch(err => {next(err);}) as any;
 | 
			
		||||
  if (templateData instanceof Error) return;
 | 
			
		||||
  if (!templateData) {
 | 
			
		||||
    res.status(404).json({status: 'Not found'});
 | 
			
		||||
    return res.status(404).json({status: 'Not found'});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!_.isEqual(_.pick(templateData, _.keys(template)), template)) {  // data was changed
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ describe('/user', () => {
 | 
			
		||||
  before(done => TestHelper.before(done));
 | 
			
		||||
  beforeEach(done => server = TestHelper.beforeEach(server, done));
 | 
			
		||||
  afterEach(done => TestHelper.afterEach(server, done));
 | 
			
		||||
  after(done => TestHelper.after(done));
 | 
			
		||||
 | 
			
		||||
  describe('GET /users', () => {
 | 
			
		||||
    it('returns all users', done => {
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,10 @@ export default class TestHelper {
 | 
			
		||||
    server.close(done);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static after(done) {
 | 
			
		||||
    db.disconnect(done);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static request (server, done, options) {  // options in form: {method, url, auth: {key/basic: 'name' or 'key'/{name, pass}}, httpStatus, req, res}
 | 
			
		||||
    let st = supertest(server);
 | 
			
		||||
    if (options.hasOwnProperty('auth') && options.auth.hasOwnProperty('key')) {  // resolve API key
 | 
			
		||||
@@ -58,6 +62,9 @@ export default class TestHelper {
 | 
			
		||||
        st = st.delete(options.url)
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    if (options.hasOwnProperty('reqType')) {  // request body
 | 
			
		||||
      st = st.type(options.reqType);
 | 
			
		||||
    }
 | 
			
		||||
    if (options.hasOwnProperty('req')) {  // request body
 | 
			
		||||
      st = st.send(options.req);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user