Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrote tests and Travis CI configuration file and separated mongoose related code into db/mongoose.js #147

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var index = require('./routes/index');
var instances = require('./routes/instances');
var synchronize = require('./routes/synchronize');
const swaggerUi = require('swagger-ui-express');
require('./db/mongoose');
// Swagger.json file is used to generate the API-DOCS
const swaggerDocument = require('./swagger.json');
const scheduledAutomaticUpdate = require('./scheduled/automaticUpdate');
Expand Down
8 changes: 1 addition & 7 deletions createUser.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
const User = require('./models/user');
const mongoose = require('mongoose');

mongoose.connect(process.env.MONGODB_URL);

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

require('./db/mongoose');
const readline = require('readline');

const rl = readline.createInterface({
Expand Down
11 changes: 11 additions & 0 deletions db/mongoose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Registry Connection
var mongoose = require('mongoose');

mongoose.connect(process.env.MONGODB_URL, {
useNewUrlParser: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these additional properties?

Copy link
Contributor Author

@dmahajan980 dmahajan980 Feb 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arunans23 we are using them because the current properties such as the Current URL parser are deprecated and the console will generate the following warnings:
warn

useUnifiedTopology: true,
useCreateIndex: true
});

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
6 changes: 1 addition & 5 deletions models/instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
*/
// Registry Connection
var mongoose = require('mongoose');

mongoose.connect(process.env.MONGODB_URL);

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
require('../db/mongoose');

// Schema Modeling
var Schema = mongoose.Schema;
Expand Down
2 changes: 1 addition & 1 deletion models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ module.exports.comparePassword = function(candidatePassowrd, hash, callback){

module.exports.getUserByUsername = function(username, callback){
User.findOne({user:username}, callback);
}
}
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"
}
}
81 changes: 81 additions & 0 deletions tests/fixtures/db.js
Original file line number Diff line number Diff line change
@@ -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
};
105 changes: 105 additions & 0 deletions tests/instances.test.js
Original file line number Diff line number Diff line change
@@ -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);
});