From 1eb46b55d7eb45baba6787d43a215365e8cc2986 Mon Sep 17 00:00:00 2001 From: dmahajan980 Date: Wed, 12 Feb 2020 01:28:18 +0530 Subject: [PATCH] Wrote Travis configuration file and tests using Jest Added some in-line comments --- .travis.yml | 19 ++++++++ package.json | 11 ++++- tests/fixtures/db.js | 81 +++++++++++++++++++++++++++++++ tests/instances.test.js | 105 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 .travis.yml create mode 100644 tests/fixtures/db.js create mode 100644 tests/instances.test.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e7424a6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: node_js + +node_js: + - 'lts/*' + +services: mongodb + +before_install: + # Set up environment variables + # Tests are ran on a separate database named 'regsitry-test' + - export MONGODB_URL=mongodb://127.0.0.1:27017/registry-test + +install: + # Install all the project dependencies + - npm install + +script: + # Run test script + - npm run test \ No newline at end of file diff --git a/package.json b/package.json index b0c0e9d..908edc9 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,11 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "node ./bin/www" + "start": "node ./bin/www", + "test": "jest --forceExit --maxWorkers=10" + }, + "jest": { + "testEnvironment": "node" }, "dependencies": { "async": "^2.6.2", @@ -32,5 +36,10 @@ "serve-favicon": "^2.5.0", "swagger-express": "~1.0.5", "swagger-ui-express": "^2.0.15" + }, + "devDependencies": { + "env-cmd": "^10.0.1", + "jest": "^25.1.0", + "supertest": "^4.0.2" } } diff --git a/tests/fixtures/db.js b/tests/fixtures/db.js new file mode 100644 index 0000000..f8b620a --- /dev/null +++ b/tests/fixtures/db.js @@ -0,0 +1,81 @@ +const User = require('../../models/user'); +const Instance = require('../../models/instance'); + +// User credentials required for testing +const userOne = { + user: 'testuser', + password: 'asdfghj' +}; + +// Mine data to be stored in the database +const flyMine = { + "name": "FlyMine", + "namespace": "flymine", + "neighbours": [ + "MODs" + ], + "organisms": [ + "Drosophila" + ], + "url": "http://www.flymine.org/query", + "description": "FlyMine is an integrated database of genomic, expression and protein data for Drosophila, Anopheles and C. elegans", + "location": { + "latitude": "52.2003399", + "longitude": "0.120109" + }, + "twitter": "@intermineorg" +}; + +// Mine data to be stored in the database +const chickpeaMine = { + "name": "ChickpeaMine", + "namespace": "chickpeamine", + "neighbours": [ + "Plants" + ], + "url": "http://mines.legumeinfo.org/chickpeamine", + "organisms": [ + "A. ipaensis", "A. duranensis", "A. thaliana", "C. arietinum desi", "C. arietinum kabuli", "G. max", "M. truncatula", "P. vulgaris" + ], + "description": "A mine with chickpea data (both desi and kabuli varieties) from the Legume Information Systems (LIS) tripal.chado database", + "location": { + "latitude": "72.2003399", + "longitude": "10.120109" + }, + "twitter": "@LegumeFed" +}; + +// Updates to be apllied on FlyMine during testing +const flymineUpdate = { + "neighbours": [ + "Plants" + ], + "namespace": "flymine" +}; + +// Update involving change of namespace +const changeNamespace = { + "neighbours": [ + "Plants" + ], + "namespace": "flymine alpha" +}; + +// Run before tests +const setupDatabase = async () => { + // Clear the test-database + await Instance.deleteMany(); + await User.deleteMany(); + + // Create a new user for testing + await new User(userOne).save(); +}; + +module.exports = { + setupDatabase, + userOne, + flyMine, + chickpeaMine, + flymineUpdate, + changeNamespace +}; \ No newline at end of file diff --git a/tests/instances.test.js b/tests/instances.test.js new file mode 100644 index 0000000..14d60fe --- /dev/null +++ b/tests/instances.test.js @@ -0,0 +1,105 @@ +const request = require('supertest'); +const app = require('../app'); +const { + setupDatabase, + userOne, + flyMine, + chickpeaMine, + flymineUpdate, + changeNamespace +} = require('./fixtures/db'); + +jest.setTimeout(15000); + +beforeAll(async () => { + await setupDatabase(); + + // Save an instance to the database before testing + await request(app).post('/service/instances/') + .auth(userOne.user, userOne.password) + .send(chickpeaMine); +}); + +test('POST /instances : Should add an instance to the InterMine Registry', async () => { + await request(app).post('/service/instances/') + .auth(userOne.user, userOne.password) + .send(flyMine) + .expect(201); +}); + +test('POST /instances : Shoud not add an existing namespace to the InterMine Registry', async () => { + await request(app).post('/service/instances/') + .auth(userOne.user, userOne.password) + .send(flyMine) + .expect(409); +}); + +test('GET /instances : Should get all InterMine Registry instances information when there are no params', async () => { + const response = await request(app).get('/service/instances/') + .send() + .expect(200); + + // No of returned instances should be correct + expect(response.body.instances).toHaveLength(2); +}); + +test('GET /instances : Should get the correct InterMine Registry instance information when parameter q is passed', async () => { + const response = await request(app).get('/service/instances?q=flymine') + .send() + .expect(200); + + // Response namespace should be correct + expect(response.body.instances[0].namespace).toMatch('flymine'); +}); + +test('GET /instances : Should not return any InterMine Registry instances with "isProduction": true when parameter "mines=dev" is passed', async () => { + const response = await request(app).get('/service/instances?mines=dev') + .send() + .expect(200); + + // Check value of 'isProduction' for each instance + // Value of 'isProduction' should not be true + const instances = response.body.instances; + instances.forEach(instance => expect(instance.isProduction).not.toBe(true)); +}); + +test('GET /instances : Should not return any InterMine Registry instances with "isProduction": false when parameter "mines=prod" is passed', async () => { + const response = await request(app).get('/service/instances?mines=prod') + .send() + .expect(200); + + // Check value of "isProduction" for each instance + // Value of 'isProduction' should not be false + const instances = response.body.instances; + instances.forEach(instance => expect(instance.isProduction).not.toBe(false)); +}); + +test('GET /instances : Should return a count of InterMine Registry instances when parameter "mines=all" is passed', async () => { + const response = await request(app).get('/service/instances?mines=all') + .send() + .expect(200); + + // No of returned instances should be correct + expect(response.body.instances).toHaveLength(2); +}); + +test('PUT /instances : Should update the given InterMine Registry instance only', async () => { + await request(app).put('/service/instances/2') + .auth(userOne.user, userOne.password) + .send(flymineUpdate) + .expect(201); +}); + +test('PUT /instances : Should not allow a namespace to be changed', async () => { + await request(app).put('/service/instances/2') + .auth(userOne.user, userOne.password) + .send(changeNamespace) + .expect(409); +}); + +test('DELETE /instances : Should delete the given InterMine Registry instance only', async () => { + await request(app).delete('/service/instances/2') + .auth(userOne.user, userOne.password) + .send() + .expect(200); +}); \ No newline at end of file