From d2921d7b14c14781b50a6ba970456eb6e4529ce7 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Tue, 27 Sep 2016 10:17:44 -0300
Subject: [PATCH 01/50] First raw version of a simulation model

---
 src/libs/models/simulation.js | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 src/libs/models/simulation.js

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
new file mode 100644
index 00000000..29de3315
--- /dev/null
+++ b/src/libs/models/simulation.js
@@ -0,0 +1,16 @@
+const mongoose = require('mongoose');
+const libs = `${process.cwd()}/libs`;
+const log = require(`${libs}/log`)(module);
+const Schema = mongoose.Schema;
+
+// set up a mongoose model
+var SimulationSchema = new Schema({
+    location: {
+        type: Number,
+        required: true
+    },
+    time: {
+        type: Number,
+        required: true
+    }
+});
-- 
GitLab


From a3ae2306a2796a5227cbf299b0ad54751000014b Mon Sep 17 00:00:00 2001
From: Vytor Calixto <vytorcalixto@gmail.com>
Date: Wed, 28 Sep 2016 10:34:06 -0300
Subject: [PATCH 02/50] Fix cache problem in route /user

Changes:
* Cache is defined in `api.js`, not in `app.js` anymore
* Enrollment cache lasts for 1 day, states, regions, citys and schools lastas for 15 days

Closes simcaq/SCRUM#58
---
 src/libs/app.js        |  3 ---
 src/libs/routes/api.js | 16 +++++++++++-----
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/libs/app.js b/src/libs/app.js
index f03e2282..73625720 100644
--- a/src/libs/app.js
+++ b/src/libs/app.js
@@ -8,13 +8,11 @@ const compression = require('compression');
 const log = require('./log')(module);
 
 const config = require('./config');
-const cache = require('apicache').options({ debug: config.get('debug') }).middleware;
 
 const app = express();
 
 const api = require('./routes/api');
 
-
 const passport = require('passport');
 
 app.use(passport.initialize());
@@ -26,7 +24,6 @@ app.use(bodyParser.urlencoded({ extended: false }));
 app.use(cookieParser());
 app.use(cors());
 app.use(methodOverride());
-app.use(cache('1 day'));
 app.use(compression(9));
 app.use(api);
 
diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index a1805696..ac005ffb 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -2,6 +2,12 @@ const express = require('express');
 
 const api = express();
 
+const libs = `${process.cwd()}/libs`;
+
+const config = require(`${libs}/config`);
+
+const cache = require('apicache').options({ debug: config.get('debug') }).middleware;
+
 const enrollment = require('./enrollment');
 
 const state = require('./state');
@@ -19,11 +25,11 @@ api.get('/', (req, res) => {
 });
 
 // mount API routes
-api.use('/api/v1/enrollment', enrollment);
-api.use('/api/v1/state', state);
-api.use('/api/v1/region', region);
-api.use('/api/v1/city', city);
-api.use('/api/v1/school', school);
+api.use('/api/v1/enrollment', cache('1 day'), enrollment);
+api.use('/api/v1/state', cache('15 day'), state);
+api.use('/api/v1/region', cache('15 day'), region);
+api.use('/api/v1/city', cache('15 day'), city);
+api.use('/api/v1/school', cache('15 day'), school);
 api.use('/api/v1/user', user);
 
 module.exports = api;
-- 
GitLab


From a6f63136d34c3cce94485c176e5daee8deb57a6a Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Wed, 28 Sep 2016 11:24:48 -0300
Subject: [PATCH 03/50] Changed simulation to object and set locations

---
 src/libs/models/locations.js  | 22 +++++++++++++++++++
 src/libs/models/simulation.js | 41 +++++++++++++++++++++++++----------
 2 files changed, 51 insertions(+), 12 deletions(-)
 create mode 100644 src/libs/models/locations.js

diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js
new file mode 100644
index 00000000..c5b7e6f9
--- /dev/null
+++ b/src/libs/models/locations.js
@@ -0,0 +1,22 @@
+// Location types
+class City {
+    constructor(id) {
+        this.id = id;
+    }
+}
+
+class State {
+    constructor(id) {
+        this.id = id;
+    }
+}
+
+class Region {
+    constructor(id) {
+        this.id = id;
+    }
+}
+
+const locations = { city: City, state: State, region: Region };
+
+module.exports = locations;
diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index 29de3315..bc7c1eb5 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -1,16 +1,33 @@
-const mongoose = require('mongoose');
 const libs = `${process.cwd()}/libs`;
 const log = require(`${libs}/log`)(module);
-const Schema = mongoose.Schema;
 
-// set up a mongoose model
-var SimulationSchema = new Schema({
-    location: {
-        type: Number,
-        required: true
-    },
-    time: {
-        type: Number,
-        required: true
+const locations = require(`${libs}/models/locations`);
+
+class Simulation {
+    /* Simulation object to manage parameters and storing */
+    constructor(in_object = null) {
+        this.name = null;
+        this.location = null;
+        this.sim_time = null;
+        this.goals = {
+            care: null,
+            inclusion: null,
+        };
+
+        if (in_object) {
+            for (let prop in in_object) {
+                this[prop] = in_object[prop];
+            }
+        }
     }
-});
+    run() {
+        /* Runs the Simulation with given parameters */
+        // if (!this.name || !this.location || !this.time) {
+        //     console.log('This is supposed to be an error.');
+        // }
+        // identify of location type can be tested with instanceof operator.
+        // Example: if (this.location instanceof locations.city) *Do some stuff*
+    }
+}
+
+module.exports = Simulation;
-- 
GitLab


From 9d567436527fdce3e886d9e39f9a151a12b7321d Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Wed, 28 Sep 2016 11:39:03 -0300
Subject: [PATCH 04/50] Extending locations and simulations...

---
 src/libs/models/locations.js  | 11 ++++++++---
 src/libs/models/simulation.js | 26 +++++++++++++++++++++++++-
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js
index c5b7e6f9..ccfab379 100644
--- a/src/libs/models/locations.js
+++ b/src/libs/models/locations.js
@@ -1,17 +1,22 @@
+/* These classes are defined to allow checking of location type with the
+instanceof operator. */
+
+class Location
+
 // Location types
-class City {
+class City extends Location{
     constructor(id) {
         this.id = id;
     }
 }
 
-class State {
+class State extends Location{
     constructor(id) {
         this.id = id;
     }
 }
 
-class Region {
+class Region extends Location{
     constructor(id) {
         this.id = id;
     }
diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index bc7c1eb5..a3134e92 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -3,12 +3,16 @@ const log = require(`${libs}/log`)(module);
 
 const locations = require(`${libs}/models/locations`);
 
+// Should define this somewhere else
+const MAX_SIMULATION_TIME = 10;
+
+
 class Simulation {
     /* Simulation object to manage parameters and storing */
     constructor(in_object = null) {
         this.name = null;
         this.location = null;
-        this.sim_time = null;
+        this.time = null;
         this.goals = {
             care: null,
             inclusion: null,
@@ -20,6 +24,26 @@ class Simulation {
             }
         }
     }
+    setTime(t) {
+        t = parseInt(t, 10);
+        if(t>MAX_SIMULATION_TIME){
+            // Throw an error?
+            return;
+        }
+        this.time = t;
+    }
+    setLocation(l) {
+        // Should sanitize
+        this.location = l;
+    }
+    setCareGoals(g) {
+        // Should sanitize
+        this.goals.care = g;
+    }
+    setInclusionGoals(g) {
+        // Should sanitize
+        this.goals.inclusion = g;
+    }
     run() {
         /* Runs the Simulation with given parameters */
         // if (!this.name || !this.location || !this.time) {
-- 
GitLab


From d1e63a57409471544a6cbb7e793ca2c7d7bf9dca Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Thu, 29 Sep 2016 09:39:10 -0300
Subject: [PATCH 05/50] Revert "small fix"

This reverts commit c8b441a72ec649289c1ed1217b7b5ed7871364af.
---
 src/libs/routes/user.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 4cb42c04..274e68bb 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -55,7 +55,7 @@ userApp.post('/authenticate', (req, res) => {
         if (err) throw err;
 
         if(!user){
-            res.json({success: false, msg: 'Authentication failed. User not found.'});
+            res.send({success: false, msg: 'Authentication failed. User not found.'});
         }
         else {
             user.comparePassword(req.body.password, (err, isMatch) => {
-- 
GitLab


From 4512efc1ab3170462dfed478e292bd661498f30f Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Thu, 29 Sep 2016 11:40:22 -0300
Subject: [PATCH 06/50] Changed simulation object back to mongoose schema

---
 src/libs/models/locations.js  | 17 +++++--
 src/libs/models/simulation.js | 92 ++++++++++++++++++-----------------
 2 files changed, 59 insertions(+), 50 deletions(-)

diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js
index ccfab379..e169e53b 100644
--- a/src/libs/models/locations.js
+++ b/src/libs/models/locations.js
@@ -1,27 +1,34 @@
 /* These classes are defined to allow checking of location type with the
 instanceof operator. */
 
-class Location
+class Location {}
 
 // Location types
-class City extends Location{
+class City extends Location {
     constructor(id) {
+        super();
         this.id = id;
     }
 }
 
-class State extends Location{
+class State extends Location {
     constructor(id) {
+        super();
         this.id = id;
     }
 }
 
-class Region extends Location{
+class Region extends Location {
     constructor(id) {
+        super();
         this.id = id;
     }
 }
 
-const locations = { city: City, state: State, region: Region };
+const locations = {
+    location: Location,
+    city: City,
+    state: State,
+    region: Region };
 
 module.exports = locations;
diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index a3134e92..dfefc8bc 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -1,57 +1,59 @@
+const mongoose = require('mongoose')
+
 const libs = `${process.cwd()}/libs`;
 const log = require(`${libs}/log`)(module);
 
 const locations = require(`${libs}/models/locations`);
 
+const Schema = mongoose.Schema;
+
 // Should define this somewhere else
 const MAX_SIMULATION_TIME = 10;
 
 
-class Simulation {
-    /* Simulation object to manage parameters and storing */
-    constructor(in_object = null) {
-        this.name = null;
-        this.location = null;
-        this.time = null;
-        this.goals = {
-            care: null,
-            inclusion: null,
-        };
-
-        if (in_object) {
-            for (let prop in in_object) {
-                this[prop] = in_object[prop];
-            }
-        }
-    }
-    setTime(t) {
-        t = parseInt(t, 10);
-        if(t>MAX_SIMULATION_TIME){
-            // Throw an error?
-            return;
-        }
-        this.time = t;
-    }
-    setLocation(l) {
-        // Should sanitize
-        this.location = l;
-    }
-    setCareGoals(g) {
-        // Should sanitize
-        this.goals.care = g;
-    }
-    setInclusionGoals(g) {
-        // Should sanitize
-        this.goals.inclusion = g;
+let SimulationSchema = new Schema({
+    name: {
+        type: String,
+        required: true,
+    },
+    location: Object,
+    time: Number,
+    failure_rate: Array,
+    goals_care: Array,
+    goals_inclusion: Array,
+});
+
+SimulationSchema.methods.setTime = (t) => {
+    t = parseInt(t, 10);
+    if(!t || t>MAX_SIMULATION_TIME){
+        // Throw an error?
+        return;
     }
-    run() {
-        /* Runs the Simulation with given parameters */
-        // if (!this.name || !this.location || !this.time) {
-        //     console.log('This is supposed to be an error.');
-        // }
-        // identify of location type can be tested with instanceof operator.
-        // Example: if (this.location instanceof locations.city) *Do some stuff*
+    this.time = t;
+};
+SimulationSchema.methods.setLocation = (l) => {
+    // Should sanitize
+    if(!(l instanceof locations.location)){
+        // Throw an error?
+        return;
     }
-}
+    this.location = l;
+};
+SimulationSchema.methods.setCareGoals = (g) => {
+    // Should sanitize
+    this.goals.care = g;
+};
+SimulationSchema.methods.setInclusionGoals = (g) => {
+    // Should sanitize
+    this.goals.inclusion = g;
+};
+SimulationSchema.methods.run = () => {
+    /* Runs the Simulation with given parameters */
+    // if (!this.name || !this.location || !this.time) {
+    //     console.log('This is supposed to be an error.');
+    // }
+    // identify of location type can be tested with instanceof operator.
+    // Example: if (this.location instanceof locations.city) *Do some stuff*
+};
 
-module.exports = Simulation;
+module.exports = mongoose.model('Simulation', SimulationSchema);
-- 
GitLab


From dbc67855d0f61f6a421e1ec1c072a30eb639d0c3 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Fri, 30 Sep 2016 09:39:42 -0300
Subject: [PATCH 07/50] reference file using libs variable

---
 src/libs/middlewares/passport.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js
index 4b915419..76cdf598 100644
--- a/src/libs/middlewares/passport.js
+++ b/src/libs/middlewares/passport.js
@@ -2,7 +2,7 @@ const JwtStrategy = require('passport-jwt').Strategy;
 const ExtractJwt = require('passport-jwt').ExtractJwt;
 const libs = `${process.cwd()}/libs`;
 const config = require(`${libs}/config`);
-const User = ('../models/user');
+const User = require(`${libs}/models/user`)
 
 module.exports = function(passport){
     var opts = {};
-- 
GitLab


From d4f0295a65d4bc2e800ce481ccda2fb5a4d40043 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Mon, 3 Oct 2016 09:48:28 -0300
Subject: [PATCH 08/50] set relative route to user model

---
 src/libs/routes/user.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 274e68bb..1323c5ef 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -8,7 +8,7 @@ const config = require(`${libs}/config`);
 
 const log = require(`${libs}/log`)(module);
 
-const User = require('../models/user');
+const User = require(`${libs}/models/user`);
 
 const jwt = require('jwt-simple');
 
@@ -55,7 +55,7 @@ userApp.post('/authenticate', (req, res) => {
         if (err) throw err;
 
         if(!user){
-            res.send({success: false, msg: 'Authentication failed. User not found.'});
+            res.json({success: false, msg: 'Authentication failed. User not found.'});
         }
         else {
             user.comparePassword(req.body.password, (err, isMatch) => {
-- 
GitLab


From 2bfdf1fb0339dbe8649f8ffa3d55e0756a963d26 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 3 Oct 2016 10:52:38 -0300
Subject: [PATCH 09/50] First persistent simulation model

---
 src/libs/models/simulation.js |   1 +
 src/libs/routes/api.js        |   3 +
 src/libs/routes/simulation.js | 105 ++++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+)
 create mode 100644 src/libs/routes/simulation.js

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index dfefc8bc..7d9afbb0 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -1,6 +1,7 @@
 const mongoose = require('mongoose')
 
 const libs = `${process.cwd()}/libs`;
+const config = require(`${libs}/config`);
 const log = require(`${libs}/log`)(module);
 
 const locations = require(`${libs}/models/locations`);
diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 06953296..61c7121d 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -12,6 +12,8 @@ const city = require('./city');
 
 const school = require('./school');
 
+const simulation = require('./simulation');
+
 api.get('/api/v1', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
@@ -22,5 +24,6 @@ api.use('/api/v1/state', state);
 api.use('/api/v1/region', region);
 api.use('/api/v1/city', city);
 api.use('/api/v1/school', school);
+api.use('/api/v1/simulation', simulation);
 
 module.exports = api;
diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
new file mode 100644
index 00000000..a776795f
--- /dev/null
+++ b/src/libs/routes/simulation.js
@@ -0,0 +1,105 @@
+const express = require('express');
+
+const simulationApp = express();
+
+const libs = `${process.cwd()}/libs`;
+
+
+const log = require(`${libs}/log`)(module);
+const config = require(`${libs}/config`);
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`);
+
+const response = require(`${libs}/middlewares/response`);
+
+const Simulation = require(`${libs}/models/simulation`);
+
+simulationApp.get('/', (req, res) => {
+    res.send({ success: true, msg: 'controller working' });
+});
+
+
+
+simulationApp.post('/', (req, res, next) => {
+    // This method must associate new entry with user.
+    /* Creates a new simulation. Requires a name. */
+    if (!req.body.name) {
+        res.send({ success: false, msg: 'Must send a name for new entry' });
+    } else {
+        next();
+    }
+}, (req, res) => {
+    let newSimulation = new Simulation({
+        name: req.body.name,
+    });
+    newSimulation.save((err) => {
+        if (err) {
+            res.send({ success: false, msg: err });
+        } else {
+            res.send({
+                success: true,
+                msg: 'new sim created',
+                id: newSimulation._id,
+            });
+        }
+    });
+});
+
+simulationApp.get('/:id', (req, res) => {
+    /* Can be used to check simulation construction status */
+    Simulation.findById(req.params.id, (err, simulation) => {
+        log.debug(req.params.id);
+        if (err) {
+            res.send({ success: false, msg: err });
+            return;
+        }
+
+        if (!simulation) {
+            res.send({ success: false, msg: 'Entry not found' });
+        } else {
+            res.send(JSON.stringify(simulation));
+        }
+    });
+});
+
+simulationApp.post('/:id', (req, res, next) => {
+    if (!req.body) {
+        res.send({ success: false, msg: 'No field informed to update' });
+    } else {
+        next();
+    }
+}, (req, res, next) => {
+    let simulation = Simulation.findById(req.params.id, (err, simulation) => {
+        if (err) {
+            res.send({ success: false, msg: err });
+        } else {
+            if (!simulation) {
+                res.send({ success: false, msg: 'Entry not found' });
+            } else {
+                req.simulation = simulation;
+                next();
+            }
+        }
+    });
+}, (req, res) => {
+    for (let property in req.body) {
+        if(Simulation.schema.tree.hasOwnProperty(property)) {
+            req.simulation[property] = req.body[property];
+        }
+    }
+    req.simulation.save((err) => {
+        if (err) {
+            res.send({ success: false, msg: err });
+        } else {
+            res.send({
+                success: true,
+                msg: 'sim updated',
+                id: req.simulation._id,
+            });
+        }
+    });
+});
+
+module.exports = simulationApp;
-- 
GitLab


From 56cee352ce59a500c14ff39b9cdb055e34f45143 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 3 Oct 2016 11:31:50 -0300
Subject: [PATCH 10/50] Changed update to methods

---
 src/libs/models/simulation.js | 30 +++++++++++++++++++-----------
 src/libs/routes/simulation.js |  4 ++--
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index 7d9afbb0..b2c7daef 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -24,30 +24,38 @@ let SimulationSchema = new Schema({
     goals_inclusion: Array,
 });
 
-SimulationSchema.methods.setTime = (t) => {
+SimulationSchema.methods.setTime = function (t) {
     t = parseInt(t, 10);
-    if(!t || t>MAX_SIMULATION_TIME){
+    if (!t || t > MAX_SIMULATION_TIME) {
         // Throw an error?
         return;
     }
     this.time = t;
 };
-SimulationSchema.methods.setLocation = (l) => {
+SimulationSchema.methods.setLocation = function (l) {
     // Should sanitize
-    if(!(l instanceof locations.location)){
-        // Throw an error?
-        return;
-    }
     this.location = l;
 };
-SimulationSchema.methods.setCareGoals = (g) => {
+SimulationSchema.methods.setFailureRate = function (fr) {
     // Should sanitize
-    this.goals.care = g;
+    this.failure_rate = fr;
 };
-SimulationSchema.methods.setInclusionGoals = (g) => {
+SimulationSchema.methods.setCareGoals = function (g) {
     // Should sanitize
-    this.goals.inclusion = g;
+    this.goals_care = g;
 };
+SimulationSchema.methods.setInclusionGoals = function (g) {
+    // Should sanitize
+    this.goals_inclusion = g;
+};
+SimulationSchema.methods.update = function (property, value) {
+    if (property === "time") this.setTime(value);
+    if (property === "location") this.setLocation(value);
+    if (property === "failure_rate") this.setFailureRate(value);
+    if (property === "goals_care") this.setCareGoals(value);
+    if (property === "goals_inclusion") this.setInclusionGoals(value);
+};
+
 SimulationSchema.methods.run = () => {
     /* Runs the Simulation with given parameters */
     // if (!this.name || !this.location || !this.time) {
diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
index a776795f..d3fcc2b5 100644
--- a/src/libs/routes/simulation.js
+++ b/src/libs/routes/simulation.js
@@ -85,8 +85,8 @@ simulationApp.post('/:id', (req, res, next) => {
     });
 }, (req, res) => {
     for (let property in req.body) {
-        if(Simulation.schema.tree.hasOwnProperty(property)) {
-            req.simulation[property] = req.body[property];
+        if (Simulation.schema.tree.hasOwnProperty(property)) {
+            req.simulation.update(property, req.body[property]);
         }
     }
     req.simulation.save((err) => {
-- 
GitLab


From 68018f8ff76f291d8ceae1ec0684e32fa273b1ba Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 3 Oct 2016 11:42:08 -0300
Subject: [PATCH 11/50] Minor syntax changes

---
 src/libs/models/simulation.js | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index b2c7daef..fcfc26d3 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -49,20 +49,18 @@ SimulationSchema.methods.setInclusionGoals = function (g) {
     this.goals_inclusion = g;
 };
 SimulationSchema.methods.update = function (property, value) {
-    if (property === "time") this.setTime(value);
-    if (property === "location") this.setLocation(value);
-    if (property === "failure_rate") this.setFailureRate(value);
-    if (property === "goals_care") this.setCareGoals(value);
-    if (property === "goals_inclusion") this.setInclusionGoals(value);
+    if (property === 'time') this.setTime(value);
+    if (property === 'location') this.setLocation(value);
+    if (property === 'failure_rate') this.setFailureRate(value);
+    if (property === 'goals_care') this.setCareGoals(value);
+    if (property === 'goals_inclusion') this.setInclusionGoals(value);
 };
 
-SimulationSchema.methods.run = () => {
+SimulationSchema.methods.run = function () {
     /* Runs the Simulation with given parameters */
     // if (!this.name || !this.location || !this.time) {
     //     console.log('This is supposed to be an error.');
     // }
-    // identify of location type can be tested with instanceof operator.
-    // Example: if (this.location instanceof locations.city) *Do some stuff*
 };
 
 module.exports = mongoose.model('Simulation', SimulationSchema);
-- 
GitLab


From 95a9486758509104cf9fb2b70ce2c4ac0d5978db Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 3 Oct 2016 12:05:51 -0300
Subject: [PATCH 12/50] First test for simulation creation - raw

---
 src/test/test.js | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/test/test.js b/src/test/test.js
index e6bdd1fd..7501e567 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -160,3 +160,20 @@ describe('request cities', () => {
             });
     });
 });
+
+describe('Create new sim', () => {
+    it('should return a new simulation id', (done) => {
+        chai.request(server)
+            .post('/api/v1/simulation')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({ name: 'test_entry' })
+            .end((err, res) => {
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('id');
+                res.body.id.should.be.a('string');
+                done();
+            });
+    });
+});
-- 
GitLab


From 68b8c84c989f507d1850ba81c3b4219e908598d6 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Tue, 4 Oct 2016 10:52:55 -0300
Subject: [PATCH 13/50] Added test_config.json

---
 .gitignore         |  1 +
 gulpfile.babel.js  |  2 ++
 src/libs/app.js    |  2 +-
 src/libs/config.js | 18 +++++++++++++++++-
 src/test/test.js   |  2 ++
 5 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 979717eb..136ccb71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ build/*
 
 config.json
 docs/
+test_config.json
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index 1f23dd9e..3a61dace 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -48,6 +48,8 @@ gulp.task('compile', () => {
     // copy configuration file to build directory
     gulp.src('config.json')
         .pipe(gulp.dest('build'));
+    gulp.src('test_config.json')
+        .pipe(gulp.dest('build'));
 });
 
 gulp.task('build', ['compile']);
diff --git a/src/libs/app.js b/src/libs/app.js
index 4e3e51c6..bed5deb7 100644
--- a/src/libs/app.js
+++ b/src/libs/app.js
@@ -10,6 +10,7 @@ const libs = `${process.cwd()}/libs`;
 
 const log = require(`${libs}/log`)(module);
 
+process.env.NODE_ENV = process.env.NODE_ENV || 'development';
 const config = require(`${libs}/config`);
 const cache = require('apicache').options({ debug: config.get('debug') }).middleware;
 
@@ -22,7 +23,6 @@ const mongoose = require(`${libs}/db/mongoose`);
 const db = mongoose();
 
 // Set default node environment
-process.env.NODE_ENV = process.env.NODE_ENV || 'development';
 
 // Parse json received in requests
 app.use(bodyParser.json());
diff --git a/src/libs/config.js b/src/libs/config.js
index 5aea5a9c..dd2d88c4 100644
--- a/src/libs/config.js
+++ b/src/libs/config.js
@@ -1,8 +1,24 @@
 const nconf = require('nconf');
 
+let config_file;
+
+switch(process.env.NODE_ENV) {
+    case 'development':
+        config_file = 'config.json';
+        break;
+    case 'test':
+        config_file = 'test_config.json';
+        break;
+    case 'production':
+        config_file = 'config.json';
+        break;
+}
+
 // Exports the config.json as an object with get functions
 nconf.argv()
     .env()
-    .file({ file: `${process.cwd()}/config.json` });
+    .file({ file: `${process.cwd()}/${config_file}` });
+
+console.log(nconf.get('mongodb'));
 
 module.exports = nconf;
diff --git a/src/test/test.js b/src/test/test.js
index 7501e567..90103f0a 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -1,3 +1,5 @@
+process.env.NODE_ENV = 'test';
+
 const chai = require('chai');
 
 const dirtyChai = require('dirty-chai');
-- 
GitLab


From 6e1112e77528b379fb0bb24d960bd37dd97ad837 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Tue, 4 Oct 2016 12:01:09 -0300
Subject: [PATCH 14/50] More simulation testing

---
 src/libs/routes/simulation.js |  2 +-
 src/test/test.js              | 50 +++++++++++++++++++++++++++++++++++
 test_config.json.example      | 21 +++++++++++++++
 3 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 test_config.json.example

diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
index d3fcc2b5..9b97e7bb 100644
--- a/src/libs/routes/simulation.js
+++ b/src/libs/routes/simulation.js
@@ -59,7 +59,7 @@ simulationApp.get('/:id', (req, res) => {
         if (!simulation) {
             res.send({ success: false, msg: 'Entry not found' });
         } else {
-            res.send(JSON.stringify(simulation));
+            res.send(simulation);
         }
     });
 });
diff --git a/src/test/test.js b/src/test/test.js
index 90103f0a..092780a1 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -16,6 +16,9 @@ const should = chai.should(); // actually call the function
 
 const server = require('../libs/app');
 
+const mongoose = require('../libs/db/mongoose');
+const Simulation = require('../libs/models/simulation');
+
 chai.use(chaiHttp);
 
 describe('request enrollments', () => {
@@ -164,6 +167,12 @@ describe('request cities', () => {
 });
 
 describe('Create new sim', () => {
+    let newSimulation;
+
+    beforeEach(() => {
+        Simulation.remove();
+    });
+
     it('should return a new simulation id', (done) => {
         chai.request(server)
             .post('/api/v1/simulation')
@@ -178,4 +187,45 @@ describe('Create new sim', () => {
                 done();
             });
     });
+    it('should find an existing simulation', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .get(`/api/v1/simulation/${id}`)
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('_id');
+                    res.body._id.should.be.a('string');
+                    res.body.should.have.property('name');
+                    res.body._id.should.be.a('string');
+                    done();
+                });
+        });
+    });
+    it('should update an existing simulation', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({location: 5})
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('id');
+                    res.body.id.should.be.a('string');
+                    Simulation.findById(res.body.id, (err, simulation) => {
+                        simulation.should.have.property('name');
+                        simulation.name.should.be.a('string');
+                        simulation.should.have.property('location');
+                        simulation.location.should.be.a('number');
+                    });
+                    done();
+                });
+        });
+    });
 });
diff --git a/test_config.json.example b/test_config.json.example
new file mode 100644
index 00000000..0a8d9146
--- /dev/null
+++ b/test_config.json.example
@@ -0,0 +1,21 @@
+{
+    "port": 3000,
+    "ip": "127.0.0.1",
+    "debug" : true,
+    "monetdb": {
+        "host": "simcaqdb1",
+        "port": 50000,
+        "dbname": "simcaq_dev",
+        "user": "monetdb",
+        "password":"monetdb",
+        "nrConnections": "16"
+    },
+    "mongodb" : {
+        "uri": "mongodb://localhost/test_users"
+    },
+    "default": {
+        "api": {
+            "version" : "v1"
+        }
+    }
+}
-- 
GitLab


From 90a2f1e87242e52a51c2878ee37c9d9c6325c52e Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Wed, 5 Oct 2016 09:29:42 -0300
Subject: [PATCH 15/50] Better simulation testing

---
 src/test/test.js | 42 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/src/test/test.js b/src/test/test.js
index 092780a1..55d96515 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -166,14 +166,16 @@ describe('request cities', () => {
     });
 });
 
-describe('Create new sim', () => {
+describe('Requires a simulation', () => {
     let newSimulation;
 
     beforeEach(() => {
-        Simulation.remove();
+        Simulation.remove({}, (err) => {
+            console.log('Test collection purged');
+        });
     });
 
-    it('should return a new simulation id', (done) => {
+    it('should create a new simulation', (done) => {
         chai.request(server)
             .post('/api/v1/simulation')
             .set('content-type', 'application/x-www-form-urlencoded')
@@ -184,6 +186,11 @@ describe('Create new sim', () => {
                 res.should.be.json;
                 res.body.should.have.property('id');
                 res.body.id.should.be.a('string');
+                Simulation.findById(res.body.id, (err, simulation) => {
+                    simulation.should.have.property('name');
+                    simulation.name.should.be.a('string');
+                    simulation.name.should.equal('test_entry');
+                });
                 done();
             });
     });
@@ -205,14 +212,14 @@ describe('Create new sim', () => {
                 });
         });
     });
-    it('should update an existing simulation', (done) => {
+    it('should update an existing simulation\'s location', (done) => {
         newSimulation = new Simulation();
         newSimulation.name = 'test';
         newSimulation.save((err, sim) => {
             let id = sim._id;
             chai.request(server)
                 .post(`/api/v1/simulation/${id}`)
-                .send({location: 5})
+                .send({ location: 5 })
                 .end((err, res) => {
                     res.should.have.status(200);
                     res.should.be.json;
@@ -223,6 +230,31 @@ describe('Create new sim', () => {
                         simulation.name.should.be.a('string');
                         simulation.should.have.property('location');
                         simulation.location.should.be.a('number');
+                        simulation.location.should.equal(5);
+                    });
+                    done();
+                });
+        });
+    });
+    it('should update an existing simulation\'s time', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({ time: 5 })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('id');
+                    res.body.id.should.be.a('string');
+                    Simulation.findById(res.body.id, (err, simulation) => {
+                        simulation.should.have.property('name');
+                        simulation.name.should.be.a('string');
+                        simulation.should.have.property('time');
+                        simulation.time.should.be.a('number');
+                        simulation.time.should.equal(5);
                     });
                     done();
                 });
-- 
GitLab


From cd664360afa27bca4336673e9baf9b4417bf35da Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Wed, 5 Oct 2016 09:30:53 -0300
Subject: [PATCH 16/50] Removed location models

---
 src/libs/models/locations.js  | 34 ----------------------------------
 src/libs/models/simulation.js |  2 --
 2 files changed, 36 deletions(-)
 delete mode 100644 src/libs/models/locations.js

diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js
deleted file mode 100644
index e169e53b..00000000
--- a/src/libs/models/locations.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* These classes are defined to allow checking of location type with the
-instanceof operator. */
-
-class Location {}
-
-// Location types
-class City extends Location {
-    constructor(id) {
-        super();
-        this.id = id;
-    }
-}
-
-class State extends Location {
-    constructor(id) {
-        super();
-        this.id = id;
-    }
-}
-
-class Region extends Location {
-    constructor(id) {
-        super();
-        this.id = id;
-    }
-}
-
-const locations = {
-    location: Location,
-    city: City,
-    state: State,
-    region: Region };
-
-module.exports = locations;
diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index fcfc26d3..b2bfe828 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -4,8 +4,6 @@ const libs = `${process.cwd()}/libs`;
 const config = require(`${libs}/config`);
 const log = require(`${libs}/log`)(module);
 
-const locations = require(`${libs}/models/locations`);
-
 const Schema = mongoose.Schema;
 
 // Should define this somewhere else
-- 
GitLab


From fac5408225fc1bd73a10119c70e93aa355beae80 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Wed, 5 Oct 2016 09:56:39 -0300
Subject: [PATCH 17/50] Even more simulation tests

---
 src/test/test.js | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/src/test/test.js b/src/test/test.js
index 55d96515..e3f03fc2 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -194,6 +194,23 @@ describe('Requires a simulation', () => {
                 done();
             });
     });
+    it('should not create a nameless simulation', (done) => {
+        chai.request(server)
+            .post('/api/v1/simulation')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .end((err, res) => {
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.not.have.property('id');
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                Simulation.findById(res.body.id, (err, simulation) => {
+                    expect(simulation).to.not.exist;
+                });
+                done();
+            });
+    });
     it('should find an existing simulation', (done) => {
         newSimulation = new Simulation();
         newSimulation.name = 'test';
@@ -212,6 +229,19 @@ describe('Requires a simulation', () => {
                 });
         });
     });
+    it('should not find an unexisting simulation', (done) => {
+        newSimulation = new Simulation();
+        let id = newSimulation._id;
+        chai.request(server)
+            .get(`/api/v1/simulation/${id}`)
+            .end((err, res) => {
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                done();
+            });
+    });
     it('should update an existing simulation\'s location', (done) => {
         newSimulation = new Simulation();
         newSimulation.name = 'test';
-- 
GitLab


From bb7f77a56e0dc6a9403858b24ae967d5cc67e818 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Wed, 5 Oct 2016 10:40:50 -0300
Subject: [PATCH 18/50] Moved config files to config folder

---
 config.json.example => config/config.json.example        | 0
 .../test_config.json.example                             | 0
 gulpfile.babel.js                                        | 8 ++++----
 src/libs/config.js                                       | 9 ++++-----
 4 files changed, 8 insertions(+), 9 deletions(-)
 rename config.json.example => config/config.json.example (100%)
 rename test_config.json.example => config/test_config.json.example (100%)

diff --git a/config.json.example b/config/config.json.example
similarity index 100%
rename from config.json.example
rename to config/config.json.example
diff --git a/test_config.json.example b/config/test_config.json.example
similarity index 100%
rename from test_config.json.example
rename to config/test_config.json.example
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index 3a61dace..66bc5000 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -46,10 +46,10 @@ gulp.task('compile', () => {
         .pipe(gulp.dest('build'));  // move compiled files to build directory
 
     // copy configuration file to build directory
-    gulp.src('config.json')
-        .pipe(gulp.dest('build'));
-    gulp.src('test_config.json')
-        .pipe(gulp.dest('build'));
+    gulp.src('config/config.json')
+        .pipe(gulp.dest('build/config'));
+    gulp.src('config/test_config.json')
+        .pipe(gulp.dest('build/config'));
 });
 
 gulp.task('build', ['compile']);
diff --git a/src/libs/config.js b/src/libs/config.js
index dd2d88c4..d61eff99 100644
--- a/src/libs/config.js
+++ b/src/libs/config.js
@@ -1,16 +1,17 @@
 const nconf = require('nconf');
 
+const CONFIG_DIR = `config`
 let config_file;
 
 switch(process.env.NODE_ENV) {
     case 'development':
-        config_file = 'config.json';
+        config_file = `${CONFIG_DIR}/config.json`;
         break;
     case 'test':
-        config_file = 'test_config.json';
+        config_file = `${CONFIG_DIR}/test_config.json`;
         break;
     case 'production':
-        config_file = 'config.json';
+        config_file = `${CONFIG_DIR}/config.json`;
         break;
 }
 
@@ -19,6 +20,4 @@ nconf.argv()
     .env()
     .file({ file: `${process.cwd()}/${config_file}` });
 
-console.log(nconf.get('mongodb'));
-
 module.exports = nconf;
-- 
GitLab


From 873a1406958b7b6c2e74ce168c7ad9be0756c73c Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Thu, 6 Oct 2016 16:18:49 -0300
Subject: [PATCH 19/50] Config file style changed

---
 .gitignore                      |  1 -
 config.json.example             | 68 +++++++++++++++++++++++++++++++++
 config/config.json.example      | 21 ----------
 config/test_config.json.example | 21 ----------
 gulpfile.babel.js               |  6 +--
 src/libs/app.js                 |  2 +-
 src/libs/config.js              | 24 ++----------
 src/libs/db/monet.js            | 12 +++---
 src/libs/db/mongoose.js         |  2 +-
 src/libs/log.js                 |  2 +-
 src/libs/models/simulation.js   |  1 -
 src/libs/routes/simulation.js   |  1 -
 src/server.js                   |  4 +-
 13 files changed, 84 insertions(+), 81 deletions(-)
 create mode 100644 config.json.example
 delete mode 100644 config/config.json.example
 delete mode 100644 config/test_config.json.example

diff --git a/.gitignore b/.gitignore
index 136ccb71..979717eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,4 +20,3 @@ build/*
 
 config.json
 docs/
-test_config.json
diff --git a/config.json.example b/config.json.example
new file mode 100644
index 00000000..67f5a4f1
--- /dev/null
+++ b/config.json.example
@@ -0,0 +1,68 @@
+{
+    "development":
+    {
+        "port": 3000,
+        "ip": "127.0.0.1",
+        "debug" : true,
+        "monetdb": {
+            "host": "simcaqdb1",
+            "port": 50000,
+            "dbname": "simcaq_dev",
+            "user": "monetdb",
+            "password":"monetdb",
+            "nrConnections": "16"
+        },
+        "mongodb" : {
+            "uri": "mongodb://localhost/users"
+        },
+        "default": {
+            "api": {
+                "version" : "v1"
+            }
+        }
+    },
+    "test":
+    {
+        "port": 3000,
+        "ip": "127.0.0.1",
+        "debug" : true,
+        "monetdb": {
+            "host": "simcaqdb1",
+            "port": 50000,
+            "dbname": "simcaq_dev",
+            "user": "monetdb",
+            "password":"monetdb",
+            "nrConnections": "16"
+        },
+        "mongodb" : {
+            "uri": "mongodb://localhost/test_users"
+        },
+        "default": {
+            "api": {
+                "version" : "v1"
+            }
+        }
+    },
+    "production":
+    {
+        "port": 3000,
+        "ip": "127.0.0.1",
+        "debug" : true,
+        "monetdb": {
+            "host": "simcaqdb1",
+            "port": 50000,
+            "dbname": "simcaq_dev",
+            "user": "monetdb",
+            "password":"monetdb",
+            "nrConnections": "16"
+        },
+        "mongodb" : {
+            "uri": "mongodb://localhost/users"
+        },
+        "default": {
+            "api": {
+                "version" : "v1"
+            }
+        }
+    }
+}
diff --git a/config/config.json.example b/config/config.json.example
deleted file mode 100644
index 136ee928..00000000
--- a/config/config.json.example
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    "port": 3000,
-    "ip": "127.0.0.1",
-    "debug" : false,
-    "monetdb": {
-        "host": "simcaqdb1",
-        "port": 50000,
-        "dbname": "simcaq_dev",
-        "user": "monetdb",
-        "password":"monetdb",
-        "nrConnections": "16"
-    },
-    "mongodb" : {
-        "uri": "mongodb://localhost/users"
-    },
-    "default": {
-        "api": {
-            "version" : "v1"
-        }
-    }
-}
diff --git a/config/test_config.json.example b/config/test_config.json.example
deleted file mode 100644
index 0a8d9146..00000000
--- a/config/test_config.json.example
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-    "port": 3000,
-    "ip": "127.0.0.1",
-    "debug" : true,
-    "monetdb": {
-        "host": "simcaqdb1",
-        "port": 50000,
-        "dbname": "simcaq_dev",
-        "user": "monetdb",
-        "password":"monetdb",
-        "nrConnections": "16"
-    },
-    "mongodb" : {
-        "uri": "mongodb://localhost/test_users"
-    },
-    "default": {
-        "api": {
-            "version" : "v1"
-        }
-    }
-}
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index 66bc5000..1f23dd9e 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -46,10 +46,8 @@ gulp.task('compile', () => {
         .pipe(gulp.dest('build'));  // move compiled files to build directory
 
     // copy configuration file to build directory
-    gulp.src('config/config.json')
-        .pipe(gulp.dest('build/config'));
-    gulp.src('config/test_config.json')
-        .pipe(gulp.dest('build/config'));
+    gulp.src('config.json')
+        .pipe(gulp.dest('build'));
 });
 
 gulp.task('build', ['compile']);
diff --git a/src/libs/app.js b/src/libs/app.js
index bed5deb7..a1b3ff01 100644
--- a/src/libs/app.js
+++ b/src/libs/app.js
@@ -12,7 +12,7 @@ const log = require(`${libs}/log`)(module);
 
 process.env.NODE_ENV = process.env.NODE_ENV || 'development';
 const config = require(`${libs}/config`);
-const cache = require('apicache').options({ debug: config.get('debug') }).middleware;
+const cache = require('apicache').options({ debug: config.debug }).middleware;
 
 const app = express();
 
diff --git a/src/libs/config.js b/src/libs/config.js
index d61eff99..2c07d19e 100644
--- a/src/libs/config.js
+++ b/src/libs/config.js
@@ -1,23 +1,5 @@
-const nconf = require('nconf');
+let conf = require(`${process.cwd()}/config.json`);
 
-const CONFIG_DIR = `config`
-let config_file;
+conf = conf[process.env.NODE_ENV];
 
-switch(process.env.NODE_ENV) {
-    case 'development':
-        config_file = `${CONFIG_DIR}/config.json`;
-        break;
-    case 'test':
-        config_file = `${CONFIG_DIR}/test_config.json`;
-        break;
-    case 'production':
-        config_file = `${CONFIG_DIR}/config.json`;
-        break;
-}
-
-// Exports the config.json as an object with get functions
-nconf.argv()
-    .env()
-    .file({ file: `${process.cwd()}/${config_file}` });
-
-module.exports = nconf;
+module.exports = conf;
diff --git a/src/libs/db/monet.js b/src/libs/db/monet.js
index dd7e620a..d19fb37d 100644
--- a/src/libs/db/monet.js
+++ b/src/libs/db/monet.js
@@ -6,16 +6,16 @@ const config = require(`${libs}/config`);
 
 // Connection options
 const poolOptions = {
-    nrConnections: config.get('monetdb:nrConnections'),
+    nrConnections: config.monetdb.nrConnections,
 };
 
 // Configuration options
 const options = {
-    host: config.get('monetdb:host'),
-    port: config.get('monetdb:port'),
-    dbname: config.get('monetdb:dbname'),
-    user: config.get('monetdb:user'),
-    password: config.get('monetdb:password'),
+    host: config.monetdb.host,
+    port: config.monetdb.port,
+    dbname: config.monetdb.dbname,
+    user: config.monetdb.user,
+    password: config.monetdb.password,
 };
 
 // Connection singleton
diff --git a/src/libs/db/mongoose.js b/src/libs/db/mongoose.js
index b1a078fd..8571b993 100644
--- a/src/libs/db/mongoose.js
+++ b/src/libs/db/mongoose.js
@@ -8,7 +8,7 @@ const mongoose = require('mongoose');
 
 module.exports = () => {
     // Get mongodb URI (ip and port) in config file
-    const mongoUri = config.get('mongodb:uri');
+    const mongoUri = config.mongodb.uri;
     log.debug(`Connecting to MongDB on URI ${mongoUri}`);
     // Connection singleton
     const db = mongoose.connect(mongoUri);
diff --git a/src/libs/log.js b/src/libs/log.js
index ee975b8d..1cf59931 100644
--- a/src/libs/log.js
+++ b/src/libs/log.js
@@ -47,7 +47,7 @@ function logger(module) {
         ],
         exitOnError: false,
     });
-    if (!config.get('debug')) {
+    if (!config.debug) {
         log.remove('debug-log');
     }
     return log;
diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index b2bfe828..a445c280 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -1,7 +1,6 @@
 const mongoose = require('mongoose')
 
 const libs = `${process.cwd()}/libs`;
-const config = require(`${libs}/config`);
 const log = require(`${libs}/log`)(module);
 
 const Schema = mongoose.Schema;
diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
index 9b97e7bb..30aa6b5a 100644
--- a/src/libs/routes/simulation.js
+++ b/src/libs/routes/simulation.js
@@ -6,7 +6,6 @@ const libs = `${process.cwd()}/libs`;
 
 
 const log = require(`${libs}/log`)(module);
-const config = require(`${libs}/config`);
 
 const squel = require('squel');
 
diff --git a/src/server.js b/src/server.js
index d9e37cac..ea8de70e 100644
--- a/src/server.js
+++ b/src/server.js
@@ -9,10 +9,10 @@ const log = require(`${libs}/log`)(module);
 const app = require(`${libs}/app`);
 
 // Set default port: first environment variable PORT, then configuration and last 3000
-app.set('port', process.env.PORT || config.get('port') || 3000);
+app.set('port', process.env.PORT || config.port || 3000);
 
 // Set default ip: first environment variable IOP, then configuration and last '127.0.0.1'
-app.set('ip', process.env.IP || config.get('ip') || '127.0.0.1');
+app.set('ip', process.env.IP || config.ip || '127.0.0.1');
 
 const server = app.listen(app.get('port'), () => {
     log.info(`Express server listening on port ${server.address().port}`);
-- 
GitLab


From 35e17fd7c108453b54cf9c8aca03f79f03dc4e6b Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Fri, 7 Oct 2016 10:39:25 -0300
Subject: [PATCH 20/50] Simulation test coverage increase

---
 src/libs/routes/simulation.js |  2 +-
 src/test/test.js              | 76 +++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
index 30aa6b5a..961f6173 100644
--- a/src/libs/routes/simulation.js
+++ b/src/libs/routes/simulation.js
@@ -64,7 +64,7 @@ simulationApp.get('/:id', (req, res) => {
 });
 
 simulationApp.post('/:id', (req, res, next) => {
-    if (!req.body) {
+    if (!Object.keys(req.body).length) {
         res.send({ success: false, msg: 'No field informed to update' });
     } else {
         next();
diff --git a/src/test/test.js b/src/test/test.js
index c25c218b..a5fc30a6 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -492,6 +492,7 @@ describe('Requires a simulation', () => {
                     Simulation.findById(res.body.id, (err, simulation) => {
                         simulation.should.have.property('name');
                         simulation.name.should.be.a('string');
+                        simulation.name.should.equal('test');
                         simulation.should.have.property('location');
                         simulation.location.should.be.a('number');
                         simulation.location.should.equal(5);
@@ -500,6 +501,63 @@ describe('Requires a simulation', () => {
                 });
         });
     });
+    it('should update multiple fields on a single request', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    location: 5,
+                    time: 3,
+                    failure_rate: [0.1, 0.2, 0.3],
+                    goals_care: [0.3, 0.2, 0.1],
+                    goals_inclusion: [0.8, 0.9, 1]
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('id');
+                    res.body.id.should.be.a('string');
+                    Simulation.findById(res.body.id, (err, simulation) => {
+                        simulation.should.have.property('name');
+                        simulation.name.should.be.a('string');
+                        simulation.name.should.equal('test');
+                        simulation.should.have.property('location');
+                        simulation.location.should.be.a('number');
+                        simulation.location.should.equal(5);
+                        simulation.should.have.property('time');
+                        simulation.time.should.be.a('number');
+                        simulation.time.should.equal(3);
+                        simulation.should.have.property('failure_rate');
+                        simulation.failure_rate.should.be.a('array');
+                        simulation.failure_rate.length.should.equal(3);
+                        simulation.should.have.property('goals_care');
+                        simulation.goals_care.should.be.a('array');
+                        simulation.goals_care.length.should.equal(3);
+                        simulation.should.have.property('goals_inclusion');
+                        simulation.goals_inclusion.should.be.a('array');
+                        simulation.goals_inclusion.length.should.equal(3);
+                    });
+                    done();
+                });
+        });
+    });
+    it('should not update an unexisting simulation', (done) => {
+        newSimulation = new Simulation();
+        let id = newSimulation._id;
+        chai.request(server)
+            .post(`/api/v1/simulation/${id}`)
+            .send({ location: 5 })
+            .end((err, res) => {
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                done();
+            });
+    });
     it('should update an existing simulation\'s time', (done) => {
         newSimulation = new Simulation();
         newSimulation.name = 'test';
@@ -524,4 +582,22 @@ describe('Requires a simulation', () => {
                 });
         });
     });
+    it('should not change results for empty post requests', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    done();
+                });
+        });
+
+    });
+
 });
-- 
GitLab


From b118549485b359610792e52246a5ba2c88f41389 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 10 Oct 2016 10:41:39 -0300
Subject: [PATCH 21/50] Sanitization of enrollments for simulation model

---
 src/libs/models/simulation.js | 47 ++++++++++++++++++++++++++++++-----
 src/libs/routes/simulation.js | 14 ++++++++++-
 src/test/test.js              | 29 +++++++++++++++++++--
 3 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index a445c280..cf6ad41c 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -19,38 +19,73 @@ let SimulationSchema = new Schema({
     failure_rate: Array,
     goals_care: Array,
     goals_inclusion: Array,
+    enrollments: Array,
 });
 
 SimulationSchema.methods.setTime = function (t) {
     t = parseInt(t, 10);
     if (!t || t > MAX_SIMULATION_TIME) {
         // Throw an error?
-        return;
+        return false;
     }
     this.time = t;
+    return true;
 };
 SimulationSchema.methods.setLocation = function (l) {
     // Should sanitize
     this.location = l;
+    return true;
 };
 SimulationSchema.methods.setFailureRate = function (fr) {
     // Should sanitize
     this.failure_rate = fr;
+    return true;
 };
 SimulationSchema.methods.setCareGoals = function (g) {
     // Should sanitize
     this.goals_care = g;
+    return true;
 };
 SimulationSchema.methods.setInclusionGoals = function (g) {
     // Should sanitize
     this.goals_inclusion = g;
+    return true;
 };
+SimulationSchema.methods.setEnrollments = function (e) {
+    e = JSON.parse(e);
+    for(let i=0; i<e.length; i++){
+        if(!(e[i] instanceof Array)){
+            return false;
+        }
+        if(e[i].length !== this.time){
+            return false;
+        }
+        for(let n of e[i])
+            if(!(n instanceof Number) && (n !== parseInt(n, 10))){
+                return false;
+            }
+    }
+    log.debug("rolou");
+    this.enrollments = e;
+
+    return true;
+}
 SimulationSchema.methods.update = function (property, value) {
-    if (property === 'time') this.setTime(value);
-    if (property === 'location') this.setLocation(value);
-    if (property === 'failure_rate') this.setFailureRate(value);
-    if (property === 'goals_care') this.setCareGoals(value);
-    if (property === 'goals_inclusion') this.setInclusionGoals(value);
+    let success = true;
+    if (property === 'time') {
+        if (!this.setTime(value)) success = false;
+    } else if (property === 'location') {
+        if (!this.setLocation(value)) success = false;
+    } else if (property === 'failure_rate') {
+        if (!this.setFailureRate(value)) success = false;
+    } else if (property === 'goals_care') {
+        if (!this.setCareGoals(value)) success = false;
+    } else if (property === 'goals_inclusion') {
+        if (!this.setInclusionGoals(value)) success = false;
+    } else if (property === 'enrollments') {
+        if (!this.setEnrollments(value)) success = false;
+    } else success = false;
+    return success;
 };
 
 SimulationSchema.methods.run = function () {
diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
index 961f6173..ce1a2ff0 100644
--- a/src/libs/routes/simulation.js
+++ b/src/libs/routes/simulation.js
@@ -85,7 +85,19 @@ simulationApp.post('/:id', (req, res, next) => {
 }, (req, res) => {
     for (let property in req.body) {
         if (Simulation.schema.tree.hasOwnProperty(property)) {
-            req.simulation.update(property, req.body[property]);
+            if(!req.simulation.update(property, req.body[property])){
+                res.send({
+                    success: false,
+                    msg: 'Invalid format for ' + property,
+                });
+                return ;
+            }
+        } else {
+            res.send({
+                success: false,
+                msg: 'Unknown property ' + property,
+            });
+            return ;
         }
     }
     req.simulation.save((err) => {
diff --git a/src/test/test.js b/src/test/test.js
index a5fc30a6..d0763cbe 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -597,7 +597,32 @@ describe('Requires a simulation', () => {
                     done();
                 });
         });
-
     });
-
+    it('should include consistent enrollment tables', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    time: 5,
+                    enrollments: "[[100, 150, 200, 250, 300]]",
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('id');
+                    res.body.id.should.be.a('string');
+                    Simulation.findById(res.body.id, (err, simulation) => {
+                        simulation.should.have.property('name');
+                        simulation.name.should.be.a('string');
+                        simulation.should.have.property('time');
+                        simulation.time.should.be.a('number');
+                        simulation.time.should.equal(5);
+                    });
+                    done();
+                });
+        });
+    });
 });
-- 
GitLab


From a25508e03c9910a59fdbe895c8c88d6c5d7877c8 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 10 Oct 2016 10:45:44 -0300
Subject: [PATCH 22/50] Changed uggly if chain for switch statement

---
 src/libs/models/simulation.js | 38 +++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index cf6ad41c..7d5df97e 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -72,19 +72,31 @@ SimulationSchema.methods.setEnrollments = function (e) {
 }
 SimulationSchema.methods.update = function (property, value) {
     let success = true;
-    if (property === 'time') {
-        if (!this.setTime(value)) success = false;
-    } else if (property === 'location') {
-        if (!this.setLocation(value)) success = false;
-    } else if (property === 'failure_rate') {
-        if (!this.setFailureRate(value)) success = false;
-    } else if (property === 'goals_care') {
-        if (!this.setCareGoals(value)) success = false;
-    } else if (property === 'goals_inclusion') {
-        if (!this.setInclusionGoals(value)) success = false;
-    } else if (property === 'enrollments') {
-        if (!this.setEnrollments(value)) success = false;
-    } else success = false;
+    switch(property){
+        case 'time':
+            if (!this.setTime(value)) success = false;
+            break;
+        case 'location':
+            if (!this.setLocation(value)) success = false;
+            break;
+        case 'failure_rate':
+            if (!this.setFailureRate(value)) success = false;
+            break;
+        case 'goals_care':
+            if (!this.setCareGoals(value)) success = false;
+            break;
+        case 'goals_inclusion':
+            if (!this.setInclusionGoals(value)) success = false;
+            break;
+        case 'enrollments':
+            if (!this.setEnrollments(value)) success = false;
+            break;
+        case 'name':
+            this.name = value;
+            break;
+        default:
+            success = false;
+    }
     return success;
 };
 
-- 
GitLab


From 17bb36270d92522105cb50ccae03d55625170dc3 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 10 Oct 2016 11:12:49 -0300
Subject: [PATCH 23/50] More simulation testing

---
 src/test/test.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/src/test/test.js b/src/test/test.js
index d0763cbe..bcda16e0 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -509,6 +509,7 @@ describe('Requires a simulation', () => {
             chai.request(server)
                 .post(`/api/v1/simulation/${id}`)
                 .send({
+                    name: 'new_name',
                     location: 5,
                     time: 3,
                     failure_rate: [0.1, 0.2, 0.3],
@@ -523,7 +524,7 @@ describe('Requires a simulation', () => {
                     Simulation.findById(res.body.id, (err, simulation) => {
                         simulation.should.have.property('name');
                         simulation.name.should.be.a('string');
-                        simulation.name.should.equal('test');
+                        simulation.name.should.equal('new_name');
                         simulation.should.have.property('location');
                         simulation.location.should.be.a('number');
                         simulation.location.should.equal(5);
@@ -598,6 +599,29 @@ describe('Requires a simulation', () => {
                 });
         });
     });
+    it('should not update in case of invalid field', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    name: 'other_name',
+                    totally_not_valid_value_for_an_entry: 'not hacking this api',
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    Simulation.findById(id, (err, simulation) => {
+                        simulation.name.should.equal('test');
+                        done();
+                    });
+                });
+        });
+    });
     it('should include consistent enrollment tables', (done) => {
         newSimulation = new Simulation();
         newSimulation.name = 'test';
@@ -625,4 +649,43 @@ describe('Requires a simulation', () => {
                 });
         });
     });
+    it('should not accept an invalid time', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    time: "I'm an inocent time entry, don't mind me",
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.id.should.equal(false);
+                    });
+                    done();
+                });
+    });
+    it('should not accept enrollments table different than provided time', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    time: 5,
+                    enrollments: "[[1,2,3]]",
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.id.should.equal(false);
+                    });
+                    done();
+        });
+    });
 });
-- 
GitLab


From ff3da334bfd4a811d33cc63a3bdc1be343a2b0fb Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 10 Oct 2016 11:49:51 -0300
Subject: [PATCH 24/50] More simulation tests and code cleaning

---
 src/libs/models/simulation.js | 22 ++++++----
 src/test/test.js              | 78 +++++++++++++++++++++++++++++++----
 2 files changed, 82 insertions(+), 18 deletions(-)

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index 7d5df97e..aa6589d1 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -52,7 +52,12 @@ SimulationSchema.methods.setInclusionGoals = function (g) {
     return true;
 };
 SimulationSchema.methods.setEnrollments = function (e) {
-    e = JSON.parse(e);
+    try{
+        e = JSON.parse(e);
+    } catch (err) {
+        return false;
+    }
+    let success = true;
     for(let i=0; i<e.length; i++){
         if(!(e[i] instanceof Array)){
             return false;
@@ -60,15 +65,16 @@ SimulationSchema.methods.setEnrollments = function (e) {
         if(e[i].length !== this.time){
             return false;
         }
-        for(let n of e[i])
-            if(!(n instanceof Number) && (n !== parseInt(n, 10))){
-                return false;
+        e[i].forEach((n, i, array) => {
+            if(n !== parseInt(n, 10)){
+                success = false;
             }
+        });
+
     }
-    log.debug("rolou");
-    this.enrollments = e;
+    if (success) this.enrollments = e;
 
-    return true;
+    return success;
 }
 SimulationSchema.methods.update = function (property, value) {
     let success = true;
@@ -94,8 +100,6 @@ SimulationSchema.methods.update = function (property, value) {
         case 'name':
             this.name = value;
             break;
-        default:
-            success = false;
     }
     return success;
 };
diff --git a/src/test/test.js b/src/test/test.js
index bcda16e0..ba617e12 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -424,8 +424,8 @@ describe('Requires a simulation', () => {
                     simulation.should.have.property('name');
                     simulation.name.should.be.a('string');
                     simulation.name.should.equal('test_entry');
+                    done();
                 });
-                done();
             });
     });
     it('should not create a nameless simulation', (done) => {
@@ -441,8 +441,8 @@ describe('Requires a simulation', () => {
                 res.body.success.should.equal(false);
                 Simulation.findById(res.body.id, (err, simulation) => {
                     expect(simulation).to.not.exist;
+                    done();
                 });
-                done();
             });
     });
     it('should find an existing simulation', (done) => {
@@ -496,8 +496,8 @@ describe('Requires a simulation', () => {
                         simulation.should.have.property('location');
                         simulation.location.should.be.a('number');
                         simulation.location.should.equal(5);
+                        done();
                     });
-                    done();
                 });
         });
     });
@@ -540,8 +540,8 @@ describe('Requires a simulation', () => {
                         simulation.should.have.property('goals_inclusion');
                         simulation.goals_inclusion.should.be.a('array');
                         simulation.goals_inclusion.length.should.equal(3);
+                        done();
                     });
-                    done();
                 });
         });
     });
@@ -578,8 +578,8 @@ describe('Requires a simulation', () => {
                         simulation.should.have.property('time');
                         simulation.time.should.be.a('number');
                         simulation.time.should.equal(5);
+                        done();
                     });
-                    done();
                 });
         });
     });
@@ -644,8 +644,8 @@ describe('Requires a simulation', () => {
                         simulation.should.have.property('time');
                         simulation.time.should.be.a('number');
                         simulation.time.should.equal(5);
+                        done();
                     });
-                    done();
                 });
         });
     });
@@ -663,7 +663,7 @@ describe('Requires a simulation', () => {
                     res.should.have.status(200);
                     res.should.be.json;
                     res.body.should.have.property('success');
-                    res.body.id.should.equal(false);
+                    res.body.success.should.equal(false);
                     });
                     done();
                 });
@@ -683,9 +683,69 @@ describe('Requires a simulation', () => {
                     res.should.have.status(200);
                     res.should.be.json;
                     res.body.should.have.property('success');
-                    res.body.id.should.equal(false);
-                    });
+                    res.body.success.should.equal(false);
+                    done();
+                });
+        });
+    });
+    it('should not include arrays of non arrays as enrollments', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    time: 5,
+                    enrollments: "[\"Tomato\"]",
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    done();
+                });
+        });
+    });
+    it('should not accept non array enrollments', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    time: 5,
+                    enrollments: "Am I still wanted here?",
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
                     done();
+                });
+        });
+    });
+    it('should not accept an enrollment with anything other than a number', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .post(`/api/v1/simulation/${id}`)
+                .send({
+                    time: 5,
+                    enrollments: "[[1,2,\"malicious payload\",4,5]]",
+                })
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    done();
+                });
         });
     });
 });
-- 
GitLab


From 2ff94c669e7811ddbfe6ae580b2393176a6aea40 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 11 Oct 2016 10:10:10 -0300
Subject: [PATCH 25/50] small fix on /authenticate

---
 src/libs/routes/user.js | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 1323c5ef..1cf6e04e 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -48,7 +48,14 @@ userApp.post('/', (req, res, next) => {
     });
 });
 
-userApp.post('/authenticate', (req, res) => {
+userApp.post('/authenticate', (req, res, next) => {
+    if (!req.body.email || !req.body.password) {
+        res.json({success: false, msg: 'Please pass email and password.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
     User.findOne({
         email: req.body.email
     }, (err, user) => {
@@ -71,9 +78,9 @@ userApp.post('/authenticate', (req, res) => {
                 else {
                     res.json({success: false, msg: 'Authentication failed. Wrong password'});
                 }
-            })
+            });
         }
-    })
-})
+    });
+});
 
 module.exports = userApp;
-- 
GitLab


From 079e682a5b2036c4ba41dcb5ee180c1d5e1c2863 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 11 Oct 2016 10:33:23 -0300
Subject: [PATCH 26/50] update user model to contain all required fields

---
 src/libs/models/user.js | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/src/libs/models/user.js b/src/libs/models/user.js
index 01124ec2..5e90e114 100644
--- a/src/libs/models/user.js
+++ b/src/libs/models/user.js
@@ -14,7 +14,48 @@ var UserSchema = new Schema({
     password: {
         type: String,
         required: true
+    },
+    name: {
+        type: String,
+        required: true
+    },
+    cpf:{
+        type: String,
+        unique: true,
+        required: true
+    },
+    schooling: {
+        type: String,
+        required: true
+    },
+    course: {
+        type: String,
+        required: true
+    },
+    segment: {
+        type: String,
+        required: true
+    },
+    role: {
+        type: String,
+        required: true
+    },
+    institution_name: {
+        type: String,
+        required: true
+    },
+    state: {
+        type: String,
+        required: true
+    },
+    city: {
+        type: String,
+        required: true
+    },
+    receive_emails{
+        type: Boolean
     }
+
 });
 
 UserSchema.pre('save', function (next) {
-- 
GitLab


From 92308927edbc10bae542cbd41b01733f44ac5569 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 11 Oct 2016 11:06:56 -0300
Subject: [PATCH 27/50] small syntax fix on model

---
 src/libs/models/user.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/models/user.js b/src/libs/models/user.js
index 5e90e114..8adac2cd 100644
--- a/src/libs/models/user.js
+++ b/src/libs/models/user.js
@@ -52,7 +52,7 @@ var UserSchema = new Schema({
         type: String,
         required: true
     },
-    receive_emails{
+    receive_emails: {
         type: Boolean
     }
 
-- 
GitLab


From 58d3fdbd0e5cdce03db8eed09df1707630805752 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 11 Oct 2016 11:29:12 -0300
Subject: [PATCH 28/50] save new fields on post /user

---
 src/libs/routes/user.js | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 1cf6e04e..fc2a9b8b 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -35,7 +35,17 @@ userApp.post('/', (req, res, next) => {
 }, (req, res, next) => {
     var newUser = new User({
         email: req.body.email,
-        password: req.body.password
+        password: req.body.password,
+        name: req.body.name,
+        cpf: req.body.cpf,
+        schooling: req.body.schooling,
+        course: req.body.course,
+        segment: req.body.segment,
+        role: req.body.role,
+        institution_name: req.body.institution_name,
+        state: req.body.state,
+        city: req.body.city,
+        receive_emails: req.body.receive_emails
     });
 
     // save the user
-- 
GitLab


From 8e4b722981d101d763f95e8d279f2045ba45b3b7 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Thu, 13 Oct 2016 09:55:08 -0300
Subject: [PATCH 29/50] add checkage for all required fields before saving user

---
 src/libs/routes/user.js | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index fc2a9b8b..ccd8ddc6 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -12,6 +12,8 @@ const User = require(`${libs}/models/user`);
 
 const jwt = require('jwt-simple');
 
+const required_fields = ["email", "password", "name", "cpf", "schooling", "course", "segment", "role", "institution_name", "state", "city"];
+
 
 function emailSyntax(email) {
     const regex = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
@@ -19,8 +21,15 @@ function emailSyntax(email) {
 }
 
 userApp.post('/', (req, res, next) => {
-    if (!req.body.email || !req.body.password) {
-        res.json({success: false, msg: 'Please pass email and password.'});
+    if (!req.body.email) {
+        res.json({success: false, msg: 'Please pass email.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.password) {
+        res.json({success: false, msg: 'Please pass password.'});
     } else {
         next();
     }
@@ -32,6 +41,14 @@ userApp.post('/', (req, res, next) => {
         next();
     }
 
+}, (req, res, next) => {
+    for (let property of required_fields){
+        if(!Object.prototype.hasOwnProperty.call(req.body, property)){
+            res.json({success: false, msg: 'Please fill out all mandatory fields.'});
+            return;
+        }
+    }
+    next();
 }, (req, res, next) => {
     var newUser = new User({
         email: req.body.email,
-- 
GitLab


From 20fa0d399ce658e1841508c8193440d214a19bef Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Fri, 14 Oct 2016 11:29:21 -0300
Subject: [PATCH 30/50] made course field not required

---
 src/libs/models/user.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/libs/models/user.js b/src/libs/models/user.js
index 8adac2cd..8c4f92a2 100644
--- a/src/libs/models/user.js
+++ b/src/libs/models/user.js
@@ -30,7 +30,6 @@ var UserSchema = new Schema({
     },
     course: {
         type: String,
-        required: true
     },
     segment: {
         type: String,
-- 
GitLab


From 3c7962d5ed12568345b1798b0f8a1bccee02cee1 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Fri, 14 Oct 2016 11:29:55 -0300
Subject: [PATCH 31/50] add user route to app (was lost during merge)

---
 src/libs/routes/api.js | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 3faaa926..d0a7aca3 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -12,6 +12,8 @@ const city = require('./city');
 
 const school = require('./school');
 
+const user = require('./user');
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
@@ -22,5 +24,6 @@ api.use('/state', state);
 api.use('/region', region);
 api.use('/city', city);
 api.use('/school', school);
+api.use('/user', user);
 
 module.exports = api;
-- 
GitLab


From aa59e1c2bedc6512116dd310bfd536541f8e7ddf Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Fri, 14 Oct 2016 11:51:43 -0300
Subject: [PATCH 32/50] add mongoose promise (was lost during merge)

---
 src/libs/db/mongoose.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/libs/db/mongoose.js b/src/libs/db/mongoose.js
index 30b4d493..4188f5c4 100644
--- a/src/libs/db/mongoose.js
+++ b/src/libs/db/mongoose.js
@@ -6,6 +6,8 @@ const log = require(`${libs}/log`)(module);
 
 const mongoose = require('mongoose');
 
+mongoose.Promise = global.Promise;
+
 module.exports = () => {
     const mongoUri = process.env.MONGO_URI || config.get('mongodb:uri');
     log.debug(`Connecting to MongDB on URI ${mongoUri}`);
-- 
GitLab


From cd6da73bc1458bda7286edc9ce08ba82b538ebc0 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Fri, 14 Oct 2016 11:52:45 -0300
Subject: [PATCH 33/50] remove course from required fields

---
 src/libs/routes/user.js | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index ccd8ddc6..c043a66b 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -12,7 +12,7 @@ const User = require(`${libs}/models/user`);
 
 const jwt = require('jwt-simple');
 
-const required_fields = ["email", "password", "name", "cpf", "schooling", "course", "segment", "role", "institution_name", "state", "city"];
+const required_fields = ["email", "password", "name", "cpf", "schooling", "segment", "role", "institution_name", "state", "city"];
 
 
 function emailSyntax(email) {
@@ -43,10 +43,10 @@ userApp.post('/', (req, res, next) => {
 
 }, (req, res, next) => {
     for (let property of required_fields){
-        if(!Object.prototype.hasOwnProperty.call(req.body, property)){
-            res.json({success: false, msg: 'Please fill out all mandatory fields.'});
-            return;
-        }
+        // if(!Object.prototype.hasOwnProperty.call(req.body, property)){
+        //     res.json({success: false, msg: 'Please fill out all mandatory fields.'});
+        //     return;
+        // }
     }
     next();
 }, (req, res, next) => {
-- 
GitLab


From 7e65334fb842173641f6451e5d0f23d545afb864 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Fri, 14 Oct 2016 18:08:25 -0300
Subject: [PATCH 34/50] add missing dependencies to package.json

---
 package.json | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/package.json b/package.json
index acc29cd2..a7056dc9 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "apicache": "0.0.14",
+    "bcrypt": "^0.8.7",
     "body-parser": "^1.13.1",
     "chai": "^3.5.0",
     "chai-http": "^3.0.0",
@@ -23,11 +24,13 @@
     "faker": "^2.1.5",
     "forever": "^0.15.2",
     "js2xmlparser": "^1.0.0",
+    "jwt-simple": "^0.5.0",
     "method-override": "^2.3.3",
     "mocha": "^2.5.3",
     "monetdb-pool": "0.0.8",
     "mongoose": "^4.6.0",
     "nconf": "^0.6.x",
+    "passport": "^0.3.2",
     "squel": "^5.4.2",
     "winston": "^2.2.0"
   },
-- 
GitLab


From e1a94382af511564e81060901d65e137512868b0 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Mon, 17 Oct 2016 09:18:09 -0200
Subject: [PATCH 35/50] fix routes

---
 src/libs/routes/api.js | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index ac005ffb..7ae5b3e8 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -25,11 +25,11 @@ api.get('/', (req, res) => {
 });
 
 // mount API routes
-api.use('/api/v1/enrollment', cache('1 day'), enrollment);
-api.use('/api/v1/state', cache('15 day'), state);
-api.use('/api/v1/region', cache('15 day'), region);
-api.use('/api/v1/city', cache('15 day'), city);
-api.use('/api/v1/school', cache('15 day'), school);
-api.use('/api/v1/user', user);
+api.use('/user', user);
+api.use('/enrollment', cache('1 day'), enrollment);
+api.use('/state', cache('15 day'), state);
+api.use('/region', cache('15 day'), region);
+api.use('/city', cache('15 day'), city);
+api.use('/school', cache('15 day'), school);
 
 module.exports = api;
-- 
GitLab


From d6f3af11c95bff5df134786b2e78bae76778fd2d Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Mon, 17 Oct 2016 10:48:51 -0200
Subject: [PATCH 36/50] update API response for missing fields

---
 src/libs/routes/user.js | 71 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 60 insertions(+), 11 deletions(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index c043a66b..9ba9be45 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -22,33 +22,81 @@ function emailSyntax(email) {
 
 userApp.post('/', (req, res, next) => {
     if (!req.body.email) {
-        res.json({success: false, msg: 'Please pass email.'});
+        res.json({success: false, msg: 'O campo Email é obrigatório.'});
     } else {
         next();
     }
 
 }, (req, res, next) => {
     if (!req.body.password) {
-        res.json({success: false, msg: 'Please pass password.'});
+        res.json({success: false, msg: 'O campo Senha é obrigatório.'});
     } else {
         next();
     }
 
 }, (req, res, next) => {
     if(!emailSyntax(req.body.email)){
-        res.json({success: false, msg: 'Invalid email syntax.'});
+        res.json({success: false, msg: 'O email Informado é inválido.'});
     } else {
         next();
     }
 
 }, (req, res, next) => {
-    for (let property of required_fields){
-        // if(!Object.prototype.hasOwnProperty.call(req.body, property)){
-        //     res.json({success: false, msg: 'Please fill out all mandatory fields.'});
-        //     return;
-        // }
+    if (!req.body.name) {
+        res.json({success: false, msg: 'O campo Nome é obrigatório.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.cpf) {
+        res.json({success: false, msg: 'O campo CPF é obrigatório.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.schooling) {
+        res.json({success: false, msg: 'O campo Escolaridade é obrigatório.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.segment) {
+        res.json({success: false, msg: 'O campo Segmento é obrigatório.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.role) {
+        res.json({success: false, msg: 'O campo Função é obrigatório.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.institution_name) {
+        res.json({success: false, msg: 'O campo Intituição em que trabalha é obrigatório.'});
+    } else {
+        next();
     }
-    next();
+
+}, (req, res, next) => {
+    if (!req.body.city) {
+        res.json({success: false, msg: 'O campo Cidade é obrigatório.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.state) {
+        res.json({success: false, msg: 'O campo Estado é obrigatório.'});
+    } else {
+        next();
+    }
+
 }, (req, res, next) => {
     var newUser = new User({
         email: req.body.email,
@@ -68,9 +116,10 @@ userApp.post('/', (req, res, next) => {
     // save the user
     newUser.save((err) => {
         if (err) {
-            res.json({success: false, msg: 'Email already in use.'});
+            //no momento retorna essa mensagem se o email OU CPF já estiver cadastrado
+            res.json({success: false, msg: 'O email informado já está cadastrado.'});
         } else {
-            res.json({success: true, msg: 'Successful created new user.'});
+            res.json({success: true, msg: 'Usuário cadastrado com sucesso!'});
         }
     });
 });
-- 
GitLab


From d4647a7f90cea454cec9991b07c775fffaf88c5e Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Mon, 17 Oct 2016 15:48:56 -0200
Subject: [PATCH 37/50] Some extra methods previously ignored for simulations

---
 src/libs/models/simulation.js |  2 +-
 src/libs/routes/api.js        |  2 +-
 src/libs/routes/simulation.js | 36 ++++++++++++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index aa6589d1..6ba85b49 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -15,7 +15,7 @@ let SimulationSchema = new Schema({
         required: true,
     },
     location: Object,
-    time: Number,
+    time: Date,
     failure_rate: Array,
     goals_care: Array,
     goals_inclusion: Array,
diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 4fc68cf2..2c259bab 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -6,7 +6,7 @@ const libs = `${process.cwd()}/libs`;
 
 const config = require(`${libs}/config`);
 
-const cache = require('apicache').options({ debug: config.get('debug') }).middleware;
+const cache = require('apicache').options({ debug: config.debug }).middleware;
 
 const enrollment = require('./enrollment');
 
diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
index ce1a2ff0..b1599750 100644
--- a/src/libs/routes/simulation.js
+++ b/src/libs/routes/simulation.js
@@ -16,7 +16,14 @@ const response = require(`${libs}/middlewares/response`);
 const Simulation = require(`${libs}/models/simulation`);
 
 simulationApp.get('/', (req, res) => {
-    res.send({ success: true, msg: 'controller working' });
+    let out = { success: true, msg: 'controller working' };
+    out.result = new Array()
+    Simulation.find({}, function(err, sims) {
+        sims.forEach((sim) => {
+            out.result.push(sim);
+        });
+        res.send(out);
+    });
 });
 
 
@@ -30,8 +37,10 @@ simulationApp.post('/', (req, res, next) => {
         next();
     }
 }, (req, res) => {
+    let currentdate = new Date();
     let newSimulation = new Simulation({
         name: req.body.name,
+        time: currentdate.getDate(),
     });
     newSimulation.save((err) => {
         if (err) {
@@ -113,4 +122,29 @@ simulationApp.post('/:id', (req, res, next) => {
     });
 });
 
+simulationApp.delete('/:id', (req, res, next) => {
+    let simulation = Simulation.findById(req.params.id, (err, simulation) => {
+        if (err) {
+            res.send({ success: false, msg: err });
+        } else {
+            if (!simulation) {
+                res.send({ success: false, msg: 'Entry not found' });
+            } else {
+                next();
+            }
+        }
+    });
+}, (req, res) => {
+    Simulation.remove({"_id": req.params.id}, (err) => {
+        if (err) {
+            res.send({ success: false, msg: err });
+        } else {
+            res.send({
+                success: true,
+                msg: 'sim removed',
+            });
+        }
+    });
+});
+
 module.exports = simulationApp;
-- 
GitLab


From aa701c4aa03da5cb2fac7e673be6945e9dbf0b29 Mon Sep 17 00:00:00 2001
From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br>
Date: Tue, 18 Oct 2016 09:56:42 -0200
Subject: [PATCH 38/50] Test fixes

---
 src/libs/models/simulation.js |  3 ++-
 src/libs/routes/simulation.js |  4 +---
 src/test/test.js              | 29 +++++++++++++++++++++++++++++
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js
index 6ba85b49..e70c93a9 100644
--- a/src/libs/models/simulation.js
+++ b/src/libs/models/simulation.js
@@ -15,11 +15,12 @@ let SimulationSchema = new Schema({
         required: true,
     },
     location: Object,
-    time: Date,
+    time: Number,
     failure_rate: Array,
     goals_care: Array,
     goals_inclusion: Array,
     enrollments: Array,
+    timestamp: Date,
 });
 
 SimulationSchema.methods.setTime = function (t) {
diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js
index b1599750..16c7dcf8 100644
--- a/src/libs/routes/simulation.js
+++ b/src/libs/routes/simulation.js
@@ -26,8 +26,6 @@ simulationApp.get('/', (req, res) => {
     });
 });
 
-
-
 simulationApp.post('/', (req, res, next) => {
     // This method must associate new entry with user.
     /* Creates a new simulation. Requires a name. */
@@ -40,7 +38,7 @@ simulationApp.post('/', (req, res, next) => {
     let currentdate = new Date();
     let newSimulation = new Simulation({
         name: req.body.name,
-        time: currentdate.getDate(),
+        timestamp: currentdate.getDate(),
     });
     newSimulation.save((err) => {
         if (err) {
diff --git a/src/test/test.js b/src/test/test.js
index ba617e12..5529e056 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -748,4 +748,33 @@ describe('Requires a simulation', () => {
                 });
         });
     });
+    it('should delete an entry', (done) => {
+        newSimulation = new Simulation();
+        newSimulation.name = 'test';
+        newSimulation.save((err, sim) => {
+            let id = sim._id;
+            chai.request(server)
+                .delete(`/api/v1/simulation/${id}`)
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(true);
+                    done();
+                });
+        });
+    });
+    it('should not delete an unexisting entry', (done) => {
+        let sim = new Simulation();
+        let id = sim._id;
+        chai.request(server)
+            .delete(`/api/v1/simulation/${id}`)
+            .end((err, res) => {
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                done();
+            });
+    });
 });
-- 
GitLab


From 2f184b19943f68c4e57e038e5bfb584415a8c32a Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 18 Oct 2016 10:38:29 -0200
Subject: [PATCH 39/50] checks for informed email and CPF on db before saving
 new user

---
 src/libs/routes/user.js | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 9ba9be45..9b24fbdc 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -97,6 +97,32 @@ userApp.post('/', (req, res, next) => {
         next();
     }
 
+}, (req, res, next) => {
+    User.count({'email': req.body.email}, function(err, count){
+        if (err){
+            console.log('MongoDB error: ' + err);
+            res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'});
+        }
+        if(count){
+            res.json({success: false, msg: 'O email informado já está cadastrado.'});
+        } else {
+            next();
+        }
+    });
+
+}, (req, res, next) => {
+    User.count({'cpf': req.body.cpf}, function(err, count){
+        if (err){
+            console.log('MongoDB error: ' + err);
+            res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'});
+        }
+        if(count){
+            res.json({success: false, msg: 'O CPF informado já está cadastrado.'});
+        } else {
+            next();
+        }
+    });
+
 }, (req, res, next) => {
     var newUser = new User({
         email: req.body.email,
@@ -116,8 +142,7 @@ userApp.post('/', (req, res, next) => {
     // save the user
     newUser.save((err) => {
         if (err) {
-            //no momento retorna essa mensagem se o email OU CPF já estiver cadastrado
-            res.json({success: false, msg: 'O email informado já está cadastrado.'});
+            res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'});
         } else {
             res.json({success: true, msg: 'Usuário cadastrado com sucesso!'});
         }
-- 
GitLab


From daab538b3bd5b08fc0e158c56874fbe746176d01 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Thu, 20 Oct 2016 09:35:03 -0200
Subject: [PATCH 40/50] small fix on passport config

---
 src/libs/middlewares/passport.js | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js
index 76cdf598..4092f146 100644
--- a/src/libs/middlewares/passport.js
+++ b/src/libs/middlewares/passport.js
@@ -18,10 +18,6 @@ module.exports = function(passport){
                 return done(null, false, {message: 'Unknown user'});
             }
 
-            if (!user.comparePassword(password)) {
-                return done(null, false, {message: 'Invalid password'});
-            }
-
             return done(null, user);
         });
     }));
-- 
GitLab


From aee72b358acd228e8fd364dadbb9157a1dc66f1d Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Thu, 20 Oct 2016 11:09:45 -0200
Subject: [PATCH 41/50] update API responses to match use cases's

---
 src/libs/routes/user.js | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 9b24fbdc..2f410fbc 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -150,8 +150,15 @@ userApp.post('/', (req, res, next) => {
 });
 
 userApp.post('/authenticate', (req, res, next) => {
-    if (!req.body.email || !req.body.password) {
-        res.json({success: false, msg: 'Please pass email and password.'});
+    if (!req.body.email) {
+        res.json({success: false, msg: 'O campo Email é obrigatório.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.password) {
+        res.json({success: false, msg: 'O campo Senha é obrigatório.'});
     } else {
         next();
     }
@@ -163,7 +170,7 @@ userApp.post('/authenticate', (req, res, next) => {
         if (err) throw err;
 
         if(!user){
-            res.json({success: false, msg: 'Authentication failed. User not found.'});
+            res.json({success: false, msg: 'O Email informado não está cadastrado.'});
         }
         else {
             user.comparePassword(req.body.password, (err, isMatch) => {
@@ -174,10 +181,10 @@ userApp.post('/authenticate', (req, res, next) => {
                     var token = jwt.encode(user, secret);
 
                     //returns user info including token as json
-                    res.json({success: true, token: 'JWT ' + token});
+                    res.json({success: true, token: 'JWT ' + token, msg: 'Usuário autenticado com sucesso'});
                 }
                 else {
-                    res.json({success: false, msg: 'Authentication failed. Wrong password'});
+                    res.json({success: false, msg: 'A Senha informada é inválida.'});
                 }
             });
         }
-- 
GitLab


From 4e7f70a68d2791258c6e7e95aa18b66593ce5dce Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Thu, 20 Oct 2016 11:27:35 -0200
Subject: [PATCH 42/50] update config.json.example

---
 config.json.example | 1 +
 1 file changed, 1 insertion(+)

diff --git a/config.json.example b/config.json.example
index 136ee928..0a0603ce 100644
--- a/config.json.example
+++ b/config.json.example
@@ -12,6 +12,7 @@
     },
     "mongodb" : {
         "uri": "mongodb://localhost/users"
+        "secret": "SimCAQC3SL"
     },
     "default": {
         "api": {
-- 
GitLab


From 4753e07efb0d5b8ad68a068bc512d40733bab932 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Mon, 24 Oct 2016 12:03:00 -0200
Subject: [PATCH 43/50] add some tests for user (wip)

---
 src/libs/routes/user.js |   2 +-
 src/test/test.js        | 268 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 269 insertions(+), 1 deletion(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 2f410fbc..223552a5 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -36,7 +36,7 @@ userApp.post('/', (req, res, next) => {
 
 }, (req, res, next) => {
     if(!emailSyntax(req.body.email)){
-        res.json({success: false, msg: 'O email Informado é inválido.'});
+        res.json({success: false, msg: 'O email informado é inválido.'});
     } else {
         next();
     }
diff --git a/src/test/test.js b/src/test/test.js
index 5529e056..65187f1c 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -24,6 +24,7 @@ const server = require(`${libs}/app`);
 
 const mongoose = require('../libs/db/mongoose');
 const Simulation = require('../libs/models/simulation');
+const User = require('../libs/models/user');
 
 chai.use(chaiHttp);
 
@@ -778,3 +779,270 @@ describe('Requires a simulation', () => {
             });
     });
 });
+
+describe('Saves a user', () => {
+
+    beforeEach(() => {
+        User.remove({}, (err) => {
+            console.log('Test collection purged');
+        });
+    });
+
+    it('should create a new user', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila Baby',
+                   cpf: '48303270737',
+                   schooling: 'Doutorado',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(true);
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                    if (err){
+                        console.log('MongoDB error: ' + err);
+                    }
+
+                    user.should.have.property('email');
+                    done();
+                });
+            });
+    });
+
+    it('should not create a user with an email that is already in use', (done) => {
+        let newUser = new User();
+
+        newUser.email = 'lorem@ipsum.com';
+        newUser.password = '123mudar';
+        newUser.name = 'Gute';
+        newUser.cpf = '08236017907';
+        newUser.schooling = 'Doutorado';
+        newUser.course = 'Ciência da Computação';
+        newUser.segment = 'Comunidade acadêmica';
+        newUser.role = 'Pesquisador';
+        newUser.institution_name = 'UFPR';
+        newUser.state = 'PR';
+        newUser.city = 'Curitiba';
+
+        newUser.save((err) => {
+            if (err) {
+                console.log('MongoDB error:' + err);
+            }
+        }).then(function(newuser){
+            chai.request(server)
+                .post('/api/v1/user')
+                .set('content-type', 'application/x-www-form-urlencoded')
+                .set('x-apicache-bypass', 'true')
+                .send({email: 'lorem@ipsum.com',
+                       password: '123mudar',
+                       name: 'Tequila Baby',
+                       cpf: '48303270737',
+                       schooling: 'Doutorado',
+                       course: 'Ciência da Computação',
+                       segment: 'Comunidade acadêmica',
+                       role: 'Pesquisador',
+                       institution_name: 'UFPR',
+                       state: 'PR',
+                       city: 'Cutiriba'})
+                .end((err, res) =>{
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    res.body.should.have.property('msg');
+                    res.body.msg.should.equal('O email informado já está cadastrado.');
+                    User.findOne({'cpf': '48303270737'}, (err, user) => {
+                            expect(user).to.not.exist;
+                            done();
+                    });
+                });
+        });
+    });
+
+    it('should not save an user without email', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({password: '123mudar',
+                   name: 'Tequila Baby',
+                   cpf: '48303270737',
+                   schooling: 'Doutorado',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Email é obrigatório.');
+                User.findOne({'cpf': '48303270737'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without password', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   name: 'Tequila Baby',
+                   cpf: '48303270737',
+                   schooling: 'Doutorado',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Senha é obrigatório.');
+                User.findOne({'cpf': '48303270737'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user with invalid email', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'notavalidemail',
+                   password: '123mudar',
+                   name: 'Tequila Baby',
+                   cpf: '48303270737',
+                   schooling: 'Doutorado',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O email informado é inválido.');
+                User.findOne({'cpf': '48303270737'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without name', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   cpf: '48303270737',
+                   schooling: 'Doutorado',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Nome é obrigatório.');
+                User.findOne({'cpf': '48303270737'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without CPF', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila baby',
+                   schooling: 'Doutorado',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo CPF é obrigatório.');
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without CPF', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila baby',
+                   cpf: '48303270737',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Escolaridade é obrigatório.');
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+});
-- 
GitLab


From 533557c9b65a45b7aaefe39802990b392131776d Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 25 Oct 2016 10:02:12 -0200
Subject: [PATCH 44/50] finish tests for /user route

---
 src/test/test.js | 197 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 196 insertions(+), 1 deletion(-)

diff --git a/src/test/test.js b/src/test/test.js
index 65187f1c..854e26ff 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -870,6 +870,56 @@ describe('Saves a user', () => {
         });
     });
 
+    it('should not create a user with a CPF that is already in use', (done) => {
+        let newUser = new User();
+
+        newUser.email = 'lorem@ipsum.com';
+        newUser.password = '123mudar';
+        newUser.name = 'Gute';
+        newUser.cpf = '08236017907';
+        newUser.schooling = 'Doutorado';
+        newUser.course = 'Ciência da Computação';
+        newUser.segment = 'Comunidade acadêmica';
+        newUser.role = 'Pesquisador';
+        newUser.institution_name = 'UFPR';
+        newUser.state = 'PR';
+        newUser.city = 'Curitiba';
+
+        newUser.save((err) => {
+            if (err) {
+                console.log('MongoDB error:' + err);
+            }
+        }).then(function(newuser){
+            chai.request(server)
+                .post('/api/v1/user')
+                .set('content-type', 'application/x-www-form-urlencoded')
+                .set('x-apicache-bypass', 'true')
+                .send({email: 'dolor@ipsum.com',
+                       password: '123mudar',
+                       name: 'Tequila Baby',
+                       cpf: '08236017907',
+                       schooling: 'Doutorado',
+                       course: 'Ciência da Computação',
+                       segment: 'Comunidade acadêmica',
+                       role: 'Pesquisador',
+                       institution_name: 'UFPR',
+                       state: 'PR',
+                       city: 'Cutiriba'})
+                .end((err, res) =>{
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    res.body.should.have.property('msg');
+                    res.body.msg.should.equal('O CPF informado já está cadastrado.');
+                    User.findOne({'email': 'dolor@ipsum.com'}, (err, user) => {
+                            expect(user).to.not.exist;
+                            done();
+                    });
+                });
+        });
+    });
+
     it('should not save an user without email', (done) => {
         chai.request(server)
             .post('/api/v1/user')
@@ -1016,7 +1066,36 @@ describe('Saves a user', () => {
             });
     });
 
-    it('should not save an user without CPF', (done) => {
+    it('should not save an user without segment', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila baby',
+                   schooling: 'Doutorado',
+                   cpf: '48303270737',
+                   course: 'Ciência da Computação',
+                   role: 'Pesquisador',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Segmento é obrigatório.');
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without schooling', (done) => {
         chai.request(server)
             .post('/api/v1/user')
             .set('content-type', 'application/x-www-form-urlencoded')
@@ -1045,4 +1124,120 @@ describe('Saves a user', () => {
             });
     });
 
+    it('should not save an user without role', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila baby',
+                   schooling: 'Doutorado',
+                   cpf: '48303270737',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   institution_name: 'UFPR',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Função é obrigatório.');
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without institution', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila baby',
+                   schooling: 'Doutorado',
+                   cpf: '48303270737',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   role: 'Pesquisador',
+                   state: 'PR',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Instituição em que trabalha é obrigatório.');
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without city', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila baby',
+                   schooling: 'Doutorado',
+                   cpf: '48303270737',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   institution_name: 'UFPR',
+                   role: 'Pesquisador',
+                   state: 'PR'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Cidade é obrigatório.');
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
+    it('should not save an user without state', (done) => {
+        chai.request(server)
+            .post('/api/v1/user')
+            .set('content-type', 'application/x-www-form-urlencoded')
+            .set('x-apicache-bypass', 'true')
+            .send({email: 'lorem@ipsum.com',
+                   password: '123mudar',
+                   name: 'Tequila baby',
+                   schooling: 'Doutorado',
+                   cpf: '48303270737',
+                   course: 'Ciência da Computação',
+                   segment: 'Comunidade acadêmica',
+                   institution_name: 'UFPR',
+                   role: 'Pesquisador',
+                   city: 'Cutiriba'})
+            .end((err, res) =>{
+                res.should.have.status(200);
+                res.should.be.json;
+                res.body.should.have.property('success');
+                res.body.success.should.equal(false);
+                res.body.should.have.property('msg');
+                res.body.msg.should.equal('O campo Estado é obrigatório.');
+                User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => {
+                        expect(user).to.not.exist;
+                        done();
+                });
+            });
+    });
+
 });
-- 
GitLab


From bbf84d45c236c9615e156bfd14726fe3bff4efaa Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 25 Oct 2016 10:02:40 -0200
Subject: [PATCH 45/50] small fixes on some msgs

---
 src/libs/routes/user.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 223552a5..4239c62b 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -78,7 +78,7 @@ userApp.post('/', (req, res, next) => {
 
 }, (req, res, next) => {
     if (!req.body.institution_name) {
-        res.json({success: false, msg: 'O campo Intituição em que trabalha é obrigatório.'});
+        res.json({success: false, msg: 'O campo Instituição em que trabalha é obrigatório.'});
     } else {
         next();
     }
-- 
GitLab


From 459a5c280c7ff512d91010dc7902de54e9e5ba4f Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 25 Oct 2016 10:51:55 -0200
Subject: [PATCH 46/50] change info fecthed from config.json

---
 src/libs/routes/user.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 4239c62b..05724ab8 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -175,7 +175,7 @@ userApp.post('/authenticate', (req, res, next) => {
         else {
             user.comparePassword(req.body.password, (err, isMatch) => {
                 if (isMatch && !err) {
-                    var secret = config.get('mongodb:secret');
+                    var secret = config.mongodb.secret;
 
                     // if user is found and password is right create a token
                     var token = jwt.encode(user, secret);
-- 
GitLab


From ff65ca4575468ec7fcf453dc931ad8e410f62a8a Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 25 Oct 2016 11:09:24 -0200
Subject: [PATCH 47/50] add tests for /user/authenticate

---
 src/test/test.js | 200 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 200 insertions(+)

diff --git a/src/test/test.js b/src/test/test.js
index 854e26ff..71f9227c 100644
--- a/src/test/test.js
+++ b/src/test/test.js
@@ -1241,3 +1241,203 @@ describe('Saves a user', () => {
     });
 
 });
+
+describe('Authenticates a user', () => {
+
+    beforeEach(() => {
+        User.remove({}, (err) => {
+            console.log('Test collection purged');
+        });
+    });
+
+    it('should authenticate a user', (done) => {
+        let newUser = new User();
+
+        newUser.email = 'lorem@ipsum.com';
+        newUser.password = '123mudar';
+        newUser.name = 'Gute';
+        newUser.cpf = '08236017907';
+        newUser.schooling = 'Doutorado';
+        newUser.course = 'Ciência da Computação';
+        newUser.segment = 'Comunidade acadêmica';
+        newUser.role = 'Pesquisador';
+        newUser.institution_name = 'UFPR';
+        newUser.state = 'PR';
+        newUser.city = 'Curitiba';
+
+        newUser.save((err) => {
+            if (err) {
+                console.log('MongoDB error:' + err);
+            }
+        }).then(function(newuser){
+            chai.request(server)
+                .post('/api/v1/user/authenticate')
+                .set('content-type', 'application/x-www-form-urlencoded')
+                .set('x-apicache-bypass', 'true')
+                .send({email: 'lorem@ipsum.com',
+                       password: '123mudar'})
+                .end((err, res) => {
+                    let token;
+
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(true);
+                    res.body.should.have.property('token');
+                    token = res.body.token;
+                    token.substr(0, 3).should.equal('JWT');
+                    done();
+                });
+            });
+    });
+
+    it('should not authenticate a user with wrong password', (done) => {
+        let newUser = new User();
+
+        newUser.email = 'lorem@ipsum.com';
+        newUser.password = '123mudar';
+        newUser.name = 'Gute';
+        newUser.cpf = '08236017907';
+        newUser.schooling = 'Doutorado';
+        newUser.course = 'Ciência da Computação';
+        newUser.segment = 'Comunidade acadêmica';
+        newUser.role = 'Pesquisador';
+        newUser.institution_name = 'UFPR';
+        newUser.state = 'PR';
+        newUser.city = 'Curitiba';
+
+        newUser.save((err) => {
+            if (err) {
+                console.log('MongoDB error:' + err);
+            }
+        }).then(function(newuser){
+            chai.request(server)
+                .post('/api/v1/user/authenticate')
+                .set('content-type', 'application/x-www-form-urlencoded')
+                .set('x-apicache-bypass', 'true')
+                .send({email: 'lorem@ipsum.com',
+                       password: 'umasenhaerrada'})
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    res.body.should.have.property('msg');
+                    res.body.msg.should.equal('A Senha informada é inválida.')
+                    done();
+                });
+            });
+    });
+
+    it('should not authenticate a user with wrong email', (done) => {
+        let newUser = new User();
+
+        newUser.email = 'lorem@ipsum.com';
+        newUser.password = '123mudar';
+        newUser.name = 'Gute';
+        newUser.cpf = '08236017907';
+        newUser.schooling = 'Doutorado';
+        newUser.course = 'Ciência da Computação';
+        newUser.segment = 'Comunidade acadêmica';
+        newUser.role = 'Pesquisador';
+        newUser.institution_name = 'UFPR';
+        newUser.state = 'PR';
+        newUser.city = 'Curitiba';
+
+        newUser.save((err) => {
+            if (err) {
+                console.log('MongoDB error:' + err);
+            }
+        }).then(function(newuser){
+            chai.request(server)
+                .post('/api/v1/user/authenticate')
+                .set('content-type', 'application/x-www-form-urlencoded')
+                .set('x-apicache-bypass', 'true')
+                .send({email: 'dolor@ipsum.com',
+                       password: '123mudar'})
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    res.body.should.have.property('msg');
+                    res.body.msg.should.equal('O Email informado não está cadastrado.')
+                    done();
+                });
+            });
+    });
+
+    it('should not authenticate a user with missing email', (done) => {
+        let newUser = new User();
+
+        newUser.email = 'lorem@ipsum.com';
+        newUser.password = '123mudar';
+        newUser.name = 'Gute';
+        newUser.cpf = '08236017907';
+        newUser.schooling = 'Doutorado';
+        newUser.course = 'Ciência da Computação';
+        newUser.segment = 'Comunidade acadêmica';
+        newUser.role = 'Pesquisador';
+        newUser.institution_name = 'UFPR';
+        newUser.state = 'PR';
+        newUser.city = 'Curitiba';
+
+        newUser.save((err) => {
+            if (err) {
+                console.log('MongoDB error:' + err);
+            }
+        }).then(function(newuser){
+            chai.request(server)
+                .post('/api/v1/user/authenticate')
+                .set('content-type', 'application/x-www-form-urlencoded')
+                .set('x-apicache-bypass', 'true')
+                .send({password: '123mudar'})
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    res.body.should.have.property('msg');
+                    res.body.msg.should.equal('O campo Email é obrigatório.')
+                    done();
+                });
+            });
+    });
+
+    it('should not authenticate a user with missing password', (done) => {
+        let newUser = new User();
+
+        newUser.email = 'lorem@ipsum.com';
+        newUser.password = '123mudar';
+        newUser.name = 'Gute';
+        newUser.cpf = '08236017907';
+        newUser.schooling = 'Doutorado';
+        newUser.course = 'Ciência da Computação';
+        newUser.segment = 'Comunidade acadêmica';
+        newUser.role = 'Pesquisador';
+        newUser.institution_name = 'UFPR';
+        newUser.state = 'PR';
+        newUser.city = 'Curitiba';
+
+        newUser.save((err) => {
+            if (err) {
+                console.log('MongoDB error:' + err);
+            }
+        }).then(function(newuser){
+            chai.request(server)
+                .post('/api/v1/user/authenticate')
+                .set('content-type', 'application/x-www-form-urlencoded')
+                .set('x-apicache-bypass', 'true')
+                .send({email:'lorem@ipsum.com'})
+                .end((err, res) => {
+                    res.should.have.status(200);
+                    res.should.be.json;
+                    res.body.should.have.property('success');
+                    res.body.success.should.equal(false);
+                    res.body.should.have.property('msg');
+                    res.body.msg.should.equal('O campo Senha é obrigatório.')
+                    done();
+                });
+            });
+    });
+});
-- 
GitLab


From 73edd413523181609a2c7ac1385489cf9d7a3408 Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Tue, 1 Nov 2016 12:42:57 -0200
Subject: [PATCH 48/50] replace the console.log with the application logger to
 log errors/warnings/info

---
 src/libs/db/mongoose.js | 2 +-
 src/libs/routes/user.js | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libs/db/mongoose.js b/src/libs/db/mongoose.js
index 400898c6..d8594158 100644
--- a/src/libs/db/mongoose.js
+++ b/src/libs/db/mongoose.js
@@ -11,7 +11,7 @@ mongoose.Promise = global.Promise;
 module.exports = () => {
     // Get mongodb URI (ip and port) in config file
     const mongoUri = process.env.MONGO_URI || config.mongodb.uri;
-    log.debug(`Connecting to MongDB on URI ${mongoUri}`);
+    log.debug(`Connecting to MongoDB on URI ${mongoUri}`);
     // Connection singleton
     const db = mongoose.connect(mongoUri);
 
diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
index 05724ab8..eb1732b1 100644
--- a/src/libs/routes/user.js
+++ b/src/libs/routes/user.js
@@ -100,7 +100,7 @@ userApp.post('/', (req, res, next) => {
 }, (req, res, next) => {
     User.count({'email': req.body.email}, function(err, count){
         if (err){
-            console.log('MongoDB error: ' + err);
+            log.error('MongoDB error: ' + err);
             res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'});
         }
         if(count){
@@ -113,7 +113,7 @@ userApp.post('/', (req, res, next) => {
 }, (req, res, next) => {
     User.count({'cpf': req.body.cpf}, function(err, count){
         if (err){
-            console.log('MongoDB error: ' + err);
+            log.error('MongoDB error: ' + err);
             res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'});
         }
         if(count){
-- 
GitLab


From 434a5106c3f281b054359506bc8dbb98aa56e78e Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Thu, 3 Nov 2016 11:20:04 -0200
Subject: [PATCH 49/50] add documentation on how to check if a user is
 authenticated

---
 src/libs/middlewares/passport.js | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js
index 4092f146..431eada8 100644
--- a/src/libs/middlewares/passport.js
+++ b/src/libs/middlewares/passport.js
@@ -9,7 +9,7 @@ module.exports = function(passport){
     opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
     opts.secretOrKey = config.get('mongodb:secret');
     passport.use(new JwtStrategy(opts, function(jwt_payload, done){
-        User.find({id: jwt_payload.id}, function(err, user){
+        User.find({email: jwt_payload.email}, function(err, user){
             if (err) {
                 return done(err);
             }
@@ -22,3 +22,29 @@ module.exports = function(passport){
         });
     }));
 };
+
+/* To check if a user has access to a route, one must use passport.authenticate() specifying 'JWT' as the strategy in the route declaration, like so:
+app.post('/route', passport.authenticate('jwt', { session: false}), function(req, res) { });
+
+the user object is then accessible via req.user
+----
+
+Another way to check if a user is authenticated, is to check the request header for the json web token, like so:
+
+getToken = function (headers) {
+  if (headers && headers.authorization) {
+    var parted = headers.authorization.split(' ');
+    if (parted.length === 2) {
+      return parted[1];
+    } else {
+      return null;
+    }
+  } else {
+    return null;
+  }
+};
+
+var token = getToken(req.headers);
+  if (token) {
+    var decoded = jwt.decode(token, config.get(mongodb.secret));
+  }
-- 
GitLab


From b71b2fce8e738676a85e543fee17302444c5fccd Mon Sep 17 00:00:00 2001
From: Lucas Gabriel Lima <lgl15@inf.ufpr.br>
Date: Thu, 3 Nov 2016 11:23:18 -0200
Subject: [PATCH 50/50] small fix on commentary

---
 src/libs/middlewares/passport.js | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js
index 431eada8..c9399260 100644
--- a/src/libs/middlewares/passport.js
+++ b/src/libs/middlewares/passport.js
@@ -24,6 +24,9 @@ module.exports = function(passport){
 };
 
 /* To check if a user has access to a route, one must use passport.authenticate() specifying 'JWT' as the strategy in the route declaration, like so:
+//pass passportfor configuration
+require('./config/passport')(passport);
+
 app.post('/route', passport.authenticate('jwt', { session: false}), function(req, res) { });
 
 the user object is then accessible via req.user
@@ -48,3 +51,4 @@ var token = getToken(req.headers);
   if (token) {
     var decoded = jwt.decode(token, config.get(mongodb.secret));
   }
+ */
-- 
GitLab