Skip to content
Snippets Groups Projects
Commit 32a80d4e authored by Vytor Calixto's avatar Vytor Calixto :space_invader:
Browse files

Merge branch 'development' into 'auth'

Conflicts:
  gulpfile.babel.js
parents 5fcee9e5 42fea162
No related branches found
No related tags found
2 merge requests!116Release v1.0.0,!30Auth
Pipeline #
Showing
with 222 additions and 171 deletions
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
"import" "import"
], ],
"rules": { "rules": {
"jsx-a11y/heading-has-content": [ "off" ],
"jsx-a11y/anchor-has-content": [ "off" ],
"indent": [ "error", 4 ], "indent": [ "error", 4 ],
"no-unused-vars": [ "error", { "args": "none" }], "no-unused-vars": [ "error", { "args": "none" }],
"no-param-reassign": [ "off" ] "no-param-reassign": [ "off" ]
......
...@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) ...@@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased ## Unreleased
- Change parseParams default value from `null` to `true`
- Query middleware throws a 404 when the result is empty
- Change filters and dimensions names! No more `_id`. **Breaks compability**
- Add a basic sanitize function
## 0.1.0 - 2016-10-10 ## 0.1.0 - 2016-10-10
### Added ### Added
......
...@@ -17,6 +17,7 @@ Bugs are reported and tracked at [simcaq/SCRUM](https://gitlab.c3sl.ufpr.br/simc ...@@ -17,6 +17,7 @@ Bugs are reported and tracked at [simcaq/SCRUM](https://gitlab.c3sl.ufpr.br/simc
* **development**: default branch * **development**: default branch
* **issue/??**: issue branch - a branch created to solve a issue * **issue/??**: issue branch - a branch created to solve a issue
* **feature_????**: feature branch - a branch created to add a feature * **feature_????**: feature branch - a branch created to add a feature
* **hotfix_????**: hotfix branch - a branch created to fix a problem or error
* **release_vM.m.f**: release branch - a branch created to merge with master and set a release. The verion follows the [semantic versioning](http://semver.org) * **release_vM.m.f**: release branch - a branch created to merge with master and set a release. The verion follows the [semantic versioning](http://semver.org)
## Styleguide ## Styleguide
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
"dbname": "simcaq_dev", "dbname": "simcaq_dev",
"user": "monetdb", "user": "monetdb",
"password":"monetdb", "password":"monetdb",
"nrConnections": "16" "nrConnections": "4"
}, },
"mongodb" : { "mongodb" : {
"uri": "mongodb://localhost/users", "uri": "mongodb://localhost/users",
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
"dbname": "simcaq_dev", "dbname": "simcaq_dev",
"user": "monetdb", "user": "monetdb",
"password":"monetdb", "password":"monetdb",
"nrConnections": "16" "nrConnections": "4"
}, },
"mongodb" : { "mongodb" : {
"uri": "mongodb://localhost/test_users", "uri": "mongodb://localhost/test_users",
...@@ -49,14 +49,14 @@ ...@@ -49,14 +49,14 @@
{ {
"port": 3000, "port": 3000,
"ip": "127.0.0.1", "ip": "127.0.0.1",
"debug" : true, "debug" : false,
"monetdb": { "monetdb": {
"host": "simcaqdb1", "host": "simcaqdb1",
"port": 50000, "port": 50000,
"dbname": "simcaq_dev", "dbname": "simcaq_dev",
"user": "monetdb", "user": "monetdb",
"password":"monetdb", "password":"monetdb",
"nrConnections": "16" "nrConnections": "4"
}, },
"mongodb" : { "mongodb" : {
"uri": "mongodb://localhost/users", "uri": "mongodb://localhost/users",
......
...@@ -47,16 +47,17 @@ gulp.task('compile', ['lint'], () => { ...@@ -47,16 +47,17 @@ gulp.task('compile', ['lint'], () => {
.pipe(babel()) // compile only modified files .pipe(babel()) // compile only modified files
// .pipe(cache.cache()) // cache compiled files // .pipe(cache.cache()) // cache compiled files
.pipe(gulp.dest('build')); // move compiled files to build directory .pipe(gulp.dest('build')); // move compiled files to build directory
});
gulp.task('build', ['compile'], () => {
var filesToCopy = [ 'config.json', 'package.json' ];
// copy configuration file to build directory // copy configuration file to build directory
gulp.src('config.json') gulp.src(filesToCopy)
.pipe(gulp.dest('build')); .pipe(gulp.dest('build'));
createLogDir(); createLogDir();
}); });
gulp.task('build', ['compile']);
gulp.task('docco', () => { gulp.task('docco', () => {
gulp.src('./src/**/*.js') gulp.src('./src/**/*.js')
.pipe(docco()) .pipe(docco())
...@@ -74,7 +75,7 @@ gulp.task('pre-test', () => { ...@@ -74,7 +75,7 @@ gulp.task('pre-test', () => {
gulp.task('test', ['pre-test'], () => { gulp.task('test', ['pre-test'], () => {
process.chdir('build'); process.chdir('build');
gulp.src('test/test.js', {read: false}) gulp.src('test/test.js', {read: false})
.pipe(mocha()) .pipe(mocha({timeout: 15000}))
.pipe(istanbul.writeReports()) .pipe(istanbul.writeReports())
.pipe(istanbul.enforceThresholds({ .pipe(istanbul.enforceThresholds({
thresholds: { thresholds: {
...@@ -114,4 +115,4 @@ gulp.task('run', () => { ...@@ -114,4 +115,4 @@ gulp.task('run', () => {
}); });
}); });
gulp.task('default', ['run']); gulp.task('default', ['run']);
\ No newline at end of file
...@@ -4,32 +4,37 @@ ...@@ -4,32 +4,37 @@
"author": "C3SL", "author": "C3SL",
"description": "Simulador custo aluno-qualidade", "description": "Simulador custo aluno-qualidade",
"private": true, "private": true,
"engines": {
"node": ">= 6.8.1"
},
"engineStrict": true,
"scripts": { "scripts": {
"start": "cd build && forever start server.js || node server.js", "start": "cd build && forever start server.js || node server.js",
"test": "cd build && mocha" "test": "cd build && mocha"
}, },
"dependencies": { "dependencies": {
"apicache": "0.0.14", "apicache": "0.7.0",
"bcrypt": "^0.8.7", "bcrypt-nodejs": "0.0.3",
"body-parser": "^1.13.1", "body-parser": "^1.13.1",
"chai": "^3.5.0", "chai": "^3.5.0",
"chai-http": "^3.0.0", "chai-http": "^3.0.0",
"chalk": "^1.1.3",
"compression": "^1.6.2", "compression": "^1.6.2",
"cookie-parser": "^1.3.5", "cookie-parser": "^1.3.5",
"cors": "^2.7.1", "cors": "^2.7.1",
"csv-express": "^1.1.0", "csv-express": "^1.1.0",
"debug": "~2.0.x", "debug": "~2.3.x",
"dirty-chai": "^1.2.2", "dirty-chai": "^1.2.2",
"express": "^4.13.0", "express": "^4.13.0",
"faker": "^2.1.5", "faker": "^3.1.0",
"forever": "^0.15.2", "forever": "^0.15.2",
"js2xmlparser": "^1.0.0", "js2xmlparser": "^2.0.2",
"jwt-simple": "^0.5.0", "jwt-simple": "^0.5.0",
"method-override": "^2.3.3", "method-override": "^2.3.3",
"mocha": "^2.5.3", "mocha": "^3.1.2",
"monetdb-pool": "0.0.8", "monetdb-pool": "0.0.8",
"mongoose": "^4.6.0", "mongoose": "^4.6.0",
"nconf": "^0.6.x", "nconf": "^0.8.x",
"passport": "^0.3.2", "passport": "^0.3.2",
"squel": "^5.4.2", "squel": "^5.4.2",
"winston": "^2.2.0" "winston": "^2.2.0"
...@@ -45,9 +50,9 @@ ...@@ -45,9 +50,9 @@
"chai-xml": "^0.3.1", "chai-xml": "^0.3.1",
"docdash": "^0.4.0", "docdash": "^0.4.0",
"eslint": "^3.3.1", "eslint": "^3.3.1",
"eslint-config-airbnb": "^10.0.1", "eslint-config-airbnb": "^13.0.0",
"eslint-plugin-import": "^1.13.0", "eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^2.1.0", "eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.1.1", "eslint-plugin-react": "^6.1.1",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-babel": "^6.1.2", "gulp-babel": "^6.1.2",
...@@ -55,9 +60,9 @@ ...@@ -55,9 +60,9 @@
"gulp-docco": "0.0.4", "gulp-docco": "0.0.4",
"gulp-eslint": "^3.0.1", "gulp-eslint": "^3.0.1",
"gulp-file-cache": "0.0.1", "gulp-file-cache": "0.0.1",
"gulp-function": "^1.3.6", "gulp-function": "^2.2.0",
"gulp-istanbul": "^1.1.1", "gulp-istanbul": "^1.1.1",
"gulp-jsdoc3": "^0.3.0", "gulp-jsdoc3": "^1.0.1",
"gulp-mocha": "^3.0.1", "gulp-mocha": "^3.0.1",
"gulp-nodemon": "^2.1.0", "gulp-nodemon": "^2.1.0",
"gulp-plumber": "^1.1.0", "gulp-plumber": "^1.1.0",
......
...@@ -37,16 +37,17 @@ app.use((req, res, next) => { ...@@ -37,16 +37,17 @@ app.use((req, res, next) => {
req.sql = squel.select(); req.sql = squel.select();
next(); next();
}); });
// Mounts all API routes under /api/v1
app.use('/api/v1', api); app.use('/api/v1', api);
// Catch 404 and forward to error handler // Catch 404 and forward to error handler
app.use((req, res, next) => { app.use((req, res, next) => {
res.status(404); res.status(404);
log.debug('%s %d %s', req.method, res.statusCode, req.url); log.error('%s %d %s', req.method, res.statusCode, req.url);
res.json({ error: 'Not found' }).end(); res.json({ error: 'Error 404: Page not found' }).end();
}); });
// Error handlers // Express' default error handler
app.use((err, req, res, next) => { app.use((err, req, res, next) => {
res.status(err.status || 500); res.status(err.status || 500);
log.error('%s %d %s', req.method, res.statusCode, err.message); log.error('%s %d %s', req.method, res.statusCode, err.message);
......
...@@ -19,26 +19,25 @@ function execSqlQuery(sqlQuery, sqlQueryParams = []) { ...@@ -19,26 +19,25 @@ function execSqlQuery(sqlQuery, sqlQueryParams = []) {
log.debug(`Executing SQL query '${sqlQuery}' with params '${sqlQueryParams}'`); log.debug(`Executing SQL query '${sqlQuery}' with params '${sqlQueryParams}'`);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Prepare statement // Prepare statement
conn.prepare(sqlQuery, true).then( conn.prepare(sqlQuery, true).then((dbQuery) => {
(dbQuery) => { // Execute query
// Execute query dbQuery.exec(sqlQueryParams).then((dbResult) => {
dbQuery.exec(sqlQueryParams).then( log.debug(`Query result: ${dbResult.data}`);
// Success // release resources allocated for the prepared statement
(dbResult) => { dbQuery.release();
log.debug(`Query result: ${dbResult.data}`); resolve(dbResult.data);
log.debug(dbResult.data); }).catch((queryError) => {
resolve(dbResult.data); log.error(`SQL query execution error: ${queryError.message}`);
}, log.error(`SQL query: ${sqlQuery} with params: ${sqlQueryParams}`);
// Error // release resources allocated for the prepared statement
(dbError) => { dbQuery.release();
log.error(`SQL query execution error: ${dbError.message}`); reject(new Error(queryError.message));
reject(new Error(dbError.message)); });
} }).catch((prepError) => {
); log.error(`SQL prepared statement error: ${prepError.message}`);
// Release resources allocated for prepared statement log.error(`SQL query: ${sqlQuery} with params: ${sqlQueryParams}`);
conn.release(); reject(new Error(prepError.message));
} });
);
}); });
} }
......
const curPath = process.cwd();
const libs = `${process.cwd()}/libs`;
const log = require(`${libs}/log`)(module);
const chalk = require('chalk');
const packageConf = require(`${curPath}/package.json`);
module.exports = () => {
// Parse version number from strings such as 'v4.2.0' or `>=4.0.0'
function parseVersionNumber(versionString) {
return parseFloat(versionString.replace(/[^\d\.]/g, ''));
}
// Ensure minimum supported node version is used
const minNodeVersion = parseVersionNumber(packageConf.engines.node);
const currentNodeVersion = parseVersionNumber(process.version);
if (minNodeVersion > currentNodeVersion) {
log.error(chalk.red(`You must upgrade node to >=${minNodeVersion}.x to use simcaq-node!`));
return false;
} else {
log.info('Node version should work!');
return true;
}
};
...@@ -36,7 +36,7 @@ function parseParams(queryParam, arr) { ...@@ -36,7 +36,7 @@ function parseParams(queryParam, arr) {
// Get the key and the value - state:41 is key 'state' whith value 41 // Get the key and the value - state:41 is key 'state' whith value 41
const kv = param.split(':'); const kv = param.split(':');
// Check if there is a value. If there isn't, assign null // Check if there is a value. If there isn't, assign null
obj[kv[0]] = (typeof kv[1] === 'undefined') ? null : kv[1]; obj[kv[0]] = (typeof kv[1] === 'undefined') ? true : kv[1];
} }
// If the array exists and is not empty we intersect // If the array exists and is not empty we intersect
......
...@@ -9,9 +9,13 @@ function query(req, res, next) { ...@@ -9,9 +9,13 @@ function query(req, res, next) {
execQuery(sql.text, sql.values).then((result) => { execQuery(sql.text, sql.values).then((result) => {
log.debug(result); log.debug(result);
req.result = result; req.result = result;
if (result.length === 0) {
next({status: 404, message: 'Not Found'});
}
next(); next();
}, (error) => { }, (error) => {
next(error); log.error(error.stack);
next(new Error('Request could not be satisfied due to a database error.'));
}); });
} }
......
...@@ -12,7 +12,7 @@ function response(value) { ...@@ -12,7 +12,7 @@ function response(value) {
res.attachment(`${value}.csv`); res.attachment(`${value}.csv`);
res.csv(req.result); res.csv(req.result);
} else if (req.query.format === 'xml') { } else if (req.query.format === 'xml') {
res.send(xml('result', JSON.stringify({ [value]: req.result }))); res.send(xml.parse('result', { [value]: req.result }));
} else { } else {
res.json({ result: req.result }); res.json({ result: req.result });
} }
......
const mongoose = require('mongoose'); const mongoose = require('mongoose');
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt-nodejs');
const libs = `${process.cwd()}/libs`; const libs = `${process.cwd()}/libs`;
const log = require(`${libs}/log`)(module); const log = require(`${libs}/log`)(module);
const Schema = mongoose.Schema; const Schema = mongoose.Schema;
......
...@@ -12,27 +12,27 @@ const response = require(`${libs}/middlewares/response`); ...@@ -12,27 +12,27 @@ const response = require(`${libs}/middlewares/response`);
// Return all cities // Return all cities
cityApp.get('/', (req, res, next) => { cityApp.get('/', (req, res, next) => {
req.sql.from('municipios'); req.sql.from('municipio');
next(); next();
}, query, response('city')); }, query, response('city'));
// Return a specific city by it's id // Return a specific city by it's id
cityApp.get('/:id', (req, res, next) => { cityApp.get('/:id', (req, res, next) => {
req.sql.from('municipios') req.sql.from('municipio')
.where('pk_municipio_id = ?', parseInt(req.params.id, 10)); .where('pk_cod_ibge = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('city')); }, query, response('city'));
// Return a specific city by it's IBGE code // Return a specific city by it's IBGE code
cityApp.get('/ibge/:id', (req, res, next) => { cityApp.get('/ibge/:id', (req, res, next) => {
req.sql.from('municipios') req.sql.from('municipio')
.where('codigo_ibge = ?', req.params.id); .where('pk_cod_ibge = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('city')); }, query, response('city'));
// Return all the cities from a specific state // Return all the cities from a specific state
cityApp.get('/state/:id', (req, res, next) => { cityApp.get('/state/:id', (req, res, next) => {
req.sql.from('municipios') req.sql.from('municipio')
.where('fk_estado_id = ?', parseInt(req.params.id, 10)); .where('fk_estado_id = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('city')); }, query, response('city'));
......
...@@ -20,18 +20,16 @@ const parseParams = require(`${libs}/middlewares/parseParams`); ...@@ -20,18 +20,16 @@ const parseParams = require(`${libs}/middlewares/parseParams`);
// Complete range of the enrollments dataset. // Complete range of the enrollments dataset.
// Returns a tuple of start and ending years of the complete enrollments dataset. // Returns a tuple of start and ending years of the complete enrollments dataset.
enrollmentApp.get('/year_range', (req, res, next) => { enrollmentApp.get('/year_range', (req, res, next) => {
req.sql = squel.select() req.sql.from('turma')
.from('turmas') .field('MIN(turma.ano_censo)', 'start_year')
.field('MIN(turmas.ano_censo)', 'start_year') .field('MAX(turma.ano_censo)', 'end_year');
.field('MAX(turmas.ano_censo)', 'end_year');
next(); next();
}, query, response('range')); }, query, response('range'));
// Returns all educational levels avaible // Returns all educational levels avaible
enrollmentApp.get('/education_level', (req, res, next) => { enrollmentApp.get('/education_level', (req, res, next) => {
req.sql = squel.select() req.sql.from('etapa_ensino')
.from('etapa_ensino')
.field('pk_etapa_ensino_id', 'id') .field('pk_etapa_ensino_id', 'id')
.field('desc_etapa', 'name'); .field('desc_etapa', 'name');
...@@ -40,8 +38,7 @@ enrollmentApp.get('/education_level', (req, res, next) => { ...@@ -40,8 +38,7 @@ enrollmentApp.get('/education_level', (req, res, next) => {
// Returns all adm dependencies // Returns all adm dependencies
enrollmentApp.get('/adm_dependency', (req, res, next) => { enrollmentApp.get('/adm_dependency', (req, res, next) => {
req.sql = squel.select() req.sql.from('dependencia_adm')
.from('dependencia_adms')
.field('pk_dependencia_adm_id', 'id') .field('pk_dependencia_adm_id', 'id')
.field('nome', 'name'); .field('nome', 'name');
...@@ -52,17 +49,17 @@ enrollmentApp.get('/adm_dependency', (req, res, next) => { ...@@ -52,17 +49,17 @@ enrollmentApp.get('/adm_dependency', (req, res, next) => {
enrollmentApp.use('/', parseParams('filter', [ enrollmentApp.use('/', parseParams('filter', [
'min_year', 'min_year',
'max_year', 'max_year',
'adm_dependency_id', 'adm_dependency',
'location_id', 'location',
'education_level_id', 'education_level',
'region', 'region',
'state', 'state',
'city', 'city',
'school' 'school'
]), parseParams('dims', [ ]), parseParams('dims', [
'adm_dependency_id', 'adm_dependency',
'location_id', 'location',
'education_level_id', 'education_level',
'region', 'region',
'state', 'state',
'city', 'city',
...@@ -72,86 +69,81 @@ enrollmentApp.use('/', parseParams('filter', [ ...@@ -72,86 +69,81 @@ enrollmentApp.use('/', parseParams('filter', [
log.debug(req.dims); log.debug(req.dims);
// Do the joins // Do the joins
if(typeof req.filter.adm_dependency_id !== 'undefined' if(typeof req.filter.adm_dependency !== 'undefined'
|| typeof req.dims.adm_dependency_id !== 'undefined') { || typeof req.dims.adm_dependency !== 'undefined') {
req.sql.join('dependencia_adms', null, 'fk_dependencia_adm_id=dependencia_adms.pk_dependencia_adm_id'); req.sql.join('dependencia_adm', null, 'fk_dependencia_adm_id=dependencia_adm.pk_dependencia_adm_id');
} }
if(typeof req.filter.education_level_id !== 'undefined' if(typeof req.filter.education_level !== 'undefined'
|| typeof req.dims.education_level_id !== 'undefined') { || typeof req.dims.education_level !== 'undefined') {
req.sql.join('etapa_ensino', null, 'fk_etapa_ensino_id=etapa_ensino.pk_etapa_ensino_id'); req.sql.join('etapa_ensino', null, 'fk_etapa_ensino_id=etapa_ensino.pk_etapa_ensino_id');
} }
if(typeof req.filter.region !== 'undefined' if(typeof req.filter.region !== 'undefined'
|| typeof req.dims.region !== 'undefined') { || typeof req.dims.region !== 'undefined') {
req.sql.join('municipios', null, 'fk_municipio_id=municipios.pk_municipio_id') req.sql.join('regiao', null, 'fk_regiao_id=regiao.pk_regiao_id');
.join('estados', null, 'municipios.fk_estado_id=estados.pk_estado_id')
.join('regioes', null, 'estados.fk_regiao_id=regioes.pk_regiao_id');
} }
if((typeof req.filter.state !== 'undefined' if(typeof req.filter.state !== 'undefined'
|| typeof req.dims.state !== 'undefined') || typeof req.dims.state !== 'undefined') {
&& (typeof req.filter.region === 'undefined' req.sql.join('estado', null, 'fk_estado_id=estado.pk_estado_id');
&& typeof req.dims.region === 'undefined')) {
req.sql.join('municipios', null, 'fk_municipio_id=municipios.pk_municipio_id')
.join('estados', null, 'municipios.fk_estado_id=estados.pk_estado_id');
} }
if((typeof req.filter.city !== 'undefined' if(typeof req.filter.city !== 'undefined'
|| typeof req.dims.city !== 'undefined') || typeof req.dims.city !== 'undefined') {
&& (typeof req.filter.state === 'undefined' req.sql.join('municipio', null, 'fk_municipio_id=municipio.pk_cod_ibge');
&& typeof req.dims.state === 'undefined')
&& (typeof req.filter.region === 'undefined'
&& typeof req.dims.region === 'undefined')) {
req.sql.join('municipios', null, 'fk_municipio_id=municipios.pk_municipio_id');
} }
if(typeof req.dims.school !== 'undefined') { if(typeof req.dims.school !== 'undefined') {
req.sql.join('escolas', null, 'fk_escola_id=escolas.pk_escola_id'); req.sql.join('escola', null, 'turma.cod_entidade=escola.cod_entidade');
}
if(typeof req.dims.location !== 'undefined') {
req.sql.join('localizacao', null, 'turma.id_localizacao=localizacao.pk_localizacao_id')
} }
// Dimensions (add fields) // Dimensions (add fields)
if(typeof req.dims.education_level_id !== 'undefined') { if(typeof req.dims.education_level !== 'undefined') {
req.sql.field('desc_etapa', 'education_level') req.sql.field('desc_etapa', 'education_level')
.group('desc_etapa') .group('desc_etapa')
.order('desc_etapa'); .order('desc_etapa');
} }
if(typeof req.dims.region !== 'undefined') { if(typeof req.dims.region !== 'undefined') {
req.sql.field('regioes.nome', 'region_name') req.sql.field('regiao.nome', 'region_name')
.group('regioes.nome') .group('regiao.nome')
.order('regioes.nome'); .order('regiao.nome');
} }
if(typeof req.dims.state !== 'undefined') { if(typeof req.dims.state !== 'undefined') {
req.sql.field('estados.nome', 'state_name') req.sql.field('estado.nome', 'state_name')
.group('estados.nome') .group('estado.nome')
.order('estados.nome'); .order('estado.nome');
} }
if(typeof req.dims.city !== 'undefined') { if(typeof req.dims.city !== 'undefined') {
req.sql.field('municipios.nome', 'city_name') req.sql.field('municipio.nome', 'city_name')
.group('municipios.nome') .group('municipio.nome')
.order('municipios.nome'); .order('municipio.nome');
} }
if(typeof req.dims.school !== 'undefined') { if(typeof req.dims.school !== 'undefined') {
req.sql.field('escolas.nome_entidade', 'school_name') req.sql.field('escola.cod_entidade', 'school_name')
.group('escolas.nome_entidade') .group('escola.cod_entidade')
.order('escolas.nome_entidade'); .order('escola.cod_entidade');
} }
if(typeof req.dims.adm_dependency_id !== 'undefined') { if(typeof req.dims.adm_dependency !== 'undefined') {
req.sql.field('dependencia_adms.nome', 'adm_dependency_name') req.sql.field('dependencia_adm.nome', 'adm_dependency_name')
.group('dependencia_adms.nome') .group('dependencia_adm.nome')
.order('dependencia_adms.nome'); .order('dependencia_adm.nome');
} }
if(typeof req.dims.location_id !== 'undefined') { if(typeof req.dims.location !== 'undefined') {
req.sql.field('turmas.id_localizacao', 'location') req.sql.field('localizacao.descricao', 'location_name')
.group('turmas.id_localizacao') .group('localizacao.descricao')
.order('turmas.id_localizacao'); .order('localizacao.descricao');
} }
if(typeof req.dims.region === 'undefined' if(typeof req.dims.region === 'undefined'
...@@ -164,23 +156,23 @@ enrollmentApp.use('/', parseParams('filter', [ ...@@ -164,23 +156,23 @@ enrollmentApp.use('/', parseParams('filter', [
// Filter (add where) // Filter (add where)
if (typeof req.filter.min_year !== 'undefined') { if (typeof req.filter.min_year !== 'undefined') {
req.sql.where('turmas.ano_censo>=?', parseInt(req.filter.min_year, 10)); req.sql.where('turma.ano_censo>=?', parseInt(req.filter.min_year, 10));
} }
if (typeof req.filter.max_year !== 'undefined') { if (typeof req.filter.max_year !== 'undefined') {
req.sql.where('turmas.ano_censo<=?', parseInt(req.filter.max_year, 10)); req.sql.where('turma.ano_censo<=?', parseInt(req.filter.max_year, 10));
} }
if (typeof req.filter.adm_dependency_id !== 'undefined') { if (typeof req.filter.adm_dependency !== 'undefined') {
req.sql.where('pk_dependencia_adm_id=?', parseInt(req.filter.adm_dependency_id, 10)); req.sql.where('pk_dependencia_adm_id=?', parseInt(req.filter.adm_dependency, 10));
} }
if (typeof req.filter.location_id !== 'undefined') { if (typeof req.filter.location !== 'undefined') {
req.sql.where('turmas.id_localizacao=?', parseInt(req.filter.location_id, 10)); req.sql.where('turma.id_localizacao=?', parseInt(req.filter.location, 10));
} }
if (typeof req.filter.education_level_id !== 'undefined') { if (typeof req.filter.education_level !== 'undefined') {
req.sql.where('pk_etapa_ensino_id=?', parseInt(req.filter.education_level_id, 10)); req.sql.where('pk_etapa_ensino_id=?', parseInt(req.filter.education_level, 10));
} }
if (typeof req.filter.region !== 'undefined') { if (typeof req.filter.region !== 'undefined') {
...@@ -192,11 +184,11 @@ enrollmentApp.use('/', parseParams('filter', [ ...@@ -192,11 +184,11 @@ enrollmentApp.use('/', parseParams('filter', [
} }
if (typeof req.filter.city !== 'undefined') { if (typeof req.filter.city !== 'undefined') {
req.sql.where('turmas.fk_municipio_id=?', parseInt(req.filter.city, 10)); req.sql.where('turma.fk_municipio_id=?', parseInt(req.filter.city, 10));
} }
if (typeof req.filter.school !== 'undefined') { if (typeof req.filter.school !== 'undefined') {
req.sql.where('turmas.fk_escola_id=?', parseInt(req.filter.school, 10)); req.sql.where('turma.fk_escola_id=?', parseInt(req.filter.school, 10));
} }
log.debug(req.sql.toParam()); log.debug(req.sql.toParam());
next(); next();
...@@ -204,11 +196,11 @@ enrollmentApp.use('/', parseParams('filter', [ ...@@ -204,11 +196,11 @@ enrollmentApp.use('/', parseParams('filter', [
enrollmentApp.get('/', (req, res, next) => { enrollmentApp.get('/', (req, res, next) => {
req.sql.field('COALESCE(SUM(num_matriculas), 0)', 'total') req.sql.field('COALESCE(SUM(num_matriculas), 0)', 'total')
.field('turmas.ano_censo', 'year') .field('turma.ano_censo', 'year')
.from('turmas') .from('turma')
.group('turmas.ano_censo') .group('turma.ano_censo')
.order('turmas.ano_censo'); .order('turma.ano_censo');
next(); next();
}, query, response('test')); }, query, response('enrollment'));
module.exports = enrollmentApp; module.exports = enrollmentApp;
...@@ -12,13 +12,13 @@ const response = require(`${libs}/middlewares/response`); ...@@ -12,13 +12,13 @@ const response = require(`${libs}/middlewares/response`);
// Get all regions // Get all regions
regionApp.get('/', (req, res, next) => { regionApp.get('/', (req, res, next) => {
req.sql.from('regioes'); req.sql.from('regiao');
next(); next();
}, query, response('region')); }, query, response('region'));
// Get a region by it's id // Get a region by it's id
regionApp.get('/:id', (req, res, next) => { regionApp.get('/:id', (req, res, next) => {
req.sql.from('regioes') req.sql.from('regiao')
.where('pk_regiao_id = ?', parseInt(req.params.id, 10)); .where('pk_regiao_id = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('region')); }, query, response('region'));
......
...@@ -17,43 +17,40 @@ const response = require(`${libs}/middlewares/response`); ...@@ -17,43 +17,40 @@ const response = require(`${libs}/middlewares/response`);
* Pense na cena do elevador de driver mas o elevador é uma bomba de fusão e demora mais que uma luta do DBz * Pense na cena do elevador de driver mas o elevador é uma bomba de fusão e demora mais que uma luta do DBz
*/ */
// schoolApp.get('/', (req, res, next) => { // schoolApp.get('/', (req, res, next) => {
// req.sql = squel.select().from('escolas') // req.sql = squel.select().from('escola')
// .field('pk_escola_id') // .field('cod_entidade')
// .field('nome_entidade', 'name')
// .field('ano_censo', 'year') // .field('ano_censo', 'year')
// .field('fk_cod_estado') // .field('fk_estado_id')
// .field('fk_cod_municipio'); // .field('fk_municipio_id');
// next(); // next();
// }, query, response('school')); // }, query, response('school'));
// Get a school by it's id // Get a school by it's id
schoolApp.get('/:id', (req, res, next) => { schoolApp.get('/:id', (req, res, next) => {
req.sql.from('escolas') req.sql.from('escola')
.where('pk_escola_id = ?', parseInt(req.params.id, 10)); .where('escola.cod_entidade = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('school')); }, query, response('school'));
// Get all schools from a state // Get all schools from a state
schoolApp.get('/state/:id', (req, res, next) => { schoolApp.get('/state/:id', (req, res, next) => {
req.sql.from('escolas') req.sql.from('escola')
.field('pk_escola_id') .field('escola.cod_entidade')
.field('nome_entidade')
.field('ano_censo') .field('ano_censo')
.field('fk_cod_estado') .field('fk_estado_id')
.field('fk_cod_municipio') .field('fk_municipio_id')
.where('fk_cod_estado = ?', parseInt(req.params.id, 10)); .where('fk_estado_id = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('school')); }, query, response('school'));
// Get all schools from a city // Get all schools from a city
schoolApp.get('/city/:id', (req, res, next) => { schoolApp.get('/city/:id', (req, res, next) => {
req.sql.from('escolas') req.sql.from('escola')
.field('pk_escola_id') .field('escola.cod_entidade')
.field('nome_entidade')
.field('ano_censo') .field('ano_censo')
.field('fk_cod_estado') .field('fk_estado_id')
.field('fk_cod_municipio') .field('fk_municipio_id')
.where('fk_cod_municipio = ?', parseInt(req.params.id, 10)); .where('fk_municipio_id = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('school')); }, query, response('school'));
......
...@@ -12,20 +12,20 @@ const response = require(`${libs}/middlewares/response`); ...@@ -12,20 +12,20 @@ const response = require(`${libs}/middlewares/response`);
// Get all states // Get all states
stateApp.get('/', (req, res, next) => { stateApp.get('/', (req, res, next) => {
req.sql.from('estados'); req.sql.from('estado');
next(); next();
}, query, response('state')); }, query, response('state'));
// Get a state // Get a state
stateApp.get('/:id', (req, res, next) => { stateApp.get('/:id', (req, res, next) => {
req.sql.from('estados') req.sql.from('estado')
.where('pk_estado_id = ?', parseInt(req.params.id, 10)); .where('pk_estado_id = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('state')); }, query, response('state'));
// Get all states from a region // Get all states from a region
stateApp.get('/region/:id', (req, res, next) => { stateApp.get('/region/:id', (req, res, next) => {
req.sql.from('estados') req.sql.from('estado')
.where('fk_regiao_id = ?', parseInt(req.params.id, 10)); .where('fk_regiao_id = ?', parseInt(req.params.id, 10));
next(); next();
}, query, response('state')); }, query, response('state'));
......
...@@ -8,6 +8,13 @@ const log = require(`${libs}/log`)(module); ...@@ -8,6 +8,13 @@ const log = require(`${libs}/log`)(module);
const app = require(`${libs}/app`); const app = require(`${libs}/app`);
const compatVersion = require(`${libs}/middlewares/checkVersion`);
// Check if Node version is compatible
if (!compatVersion()) {
process.exit(1);
}
// Set default port: first environment variable PORT, then configuration and last 3000 // Set default port: first environment variable PORT, then configuration and last 3000
app.set('port', process.env.PORT || config.port || 3000); app.set('port', process.env.PORT || config.port || 3000);
process.env.NODE_ENV = process.env.NODE_ENV || 'development'; process.env.NODE_ENV = process.env.NODE_ENV || 'development';
......
...@@ -128,7 +128,7 @@ describe('request enrollments', () => { ...@@ -128,7 +128,7 @@ describe('request enrollments', () => {
it('should list enrollments with valid dimensions', (done) => { it('should list enrollments with valid dimensions', (done) => {
chai.request(server) chai.request(server)
.get('/api/v1/enrollment?dims=region,state,adm_dependency_id,location_id&filter=min_year:2014,region:4') .get('/api/v1/enrollment?dims=region,state,adm_dependency,location&filter=min_year:2014,region:4')
.end((err, res) => { .end((err, res) => {
res.should.have.status(200); res.should.have.status(200);
res.should.be.json; res.should.be.json;
...@@ -137,6 +137,7 @@ describe('request enrollments', () => { ...@@ -137,6 +137,7 @@ describe('request enrollments', () => {
res.body.result[0].should.have.property('region_name'); res.body.result[0].should.have.property('region_name');
res.body.result[0].should.have.property('state_name'); res.body.result[0].should.have.property('state_name');
res.body.result[0].should.have.property('adm_dependency_name'); res.body.result[0].should.have.property('adm_dependency_name');
res.body.result[0].should.have.property('location_name');
res.body.result[0].should.have.property('total'); res.body.result[0].should.have.property('total');
done(); done();
}); });
...@@ -158,7 +159,7 @@ describe('request enrollments', () => { ...@@ -158,7 +159,7 @@ describe('request enrollments', () => {
it('should list enrollments with valid dimensions and filters', (done) => { it('should list enrollments with valid dimensions and filters', (done) => {
chai.request(server) chai.request(server)
.get('/api/v1/enrollment?dims=region,state,education_level_id,school&filter=min_year:2013,max_year:2014,city:3287') .get('/api/v1/enrollment?dims=region,state,education_level,school&filter=min_year:2013,max_year:2014,city:4106902')
.end((err, res) => { .end((err, res) => {
res.should.have.status(200); res.should.have.status(200);
res.should.be.json; res.should.be.json;
...@@ -174,6 +175,26 @@ describe('request enrollments', () => { ...@@ -174,6 +175,26 @@ describe('request enrollments', () => {
}); });
}); });
it('should list enrollments using all dimensions and filters', (done) => {
chai.request(server)
.get('/api/v1/enrollment?dims=region,state,city,education_level,school,adm_dependency,location&filter=min_year:2013,max_year:2014,city:4106902,adm_dependency:3,location:1,education_level:99')
.end((err, res) => {
res.should.have.status(200);
res.should.be.json;
res.body.should.have.property('result');
res.body.result.should.be.a('array');
res.body.result[0].should.have.property('region_name');
res.body.result[0].should.have.property('state_name');
res.body.result[0].should.have.property('school_name');
res.body.result[0].should.have.property('education_level');
res.body.result[0].should.have.property('location_name');
res.body.result[0].should.have.property('adm_dependency_name');
res.body.result[0].should.have.property('total');
res.body.result[0].should.have.property('year');
done();
});
});
}); });
...@@ -265,42 +286,39 @@ describe('request cities', () => { ...@@ -265,42 +286,39 @@ describe('request cities', () => {
res.should.be.json; res.should.be.json;
res.body.should.have.property('result'); res.body.should.have.property('result');
res.body.result.should.be.a('array'); res.body.result.should.be.a('array');
res.body.result[0].should.have.property('pk_municipio_id'); res.body.result[0].should.have.property('pk_cod_ibge');
res.body.result[0].should.have.property('fk_estado_id');
res.body.result[0].should.have.property('nome'); res.body.result[0].should.have.property('nome');
res.body.result[0].should.have.property('codigo_ibge'); res.body.result[0].should.have.property('fk_estado_id');
done(); done();
}); });
}); });
it('should list a city by id', (done) => { it('should list a city by id', (done) => {
chai.request(server) chai.request(server)
.get('/api/v1/city/1') .get('/api/v1/city/4106902')
.end((err, res) => { .end((err, res) => {
res.should.have.status(200); res.should.have.status(200);
res.should.be.json; res.should.be.json;
res.body.should.have.property('result'); res.body.should.have.property('result');
res.body.result.should.be.a('array'); res.body.result.should.be.a('array');
res.body.result[0].should.have.property('pk_municipio_id'); res.body.result[0].should.have.property('pk_cod_ibge');
res.body.result[0].should.have.property('fk_estado_id'); res.body.result[0].should.have.property('fk_estado_id');
res.body.result[0].should.have.property('nome'); res.body.result[0].should.have.property('nome');
res.body.result[0].should.have.property('codigo_ibge');
done(); done();
}); });
}); });
it('should list a city by codigo_ibge', (done) => { it('should list a city by codigo_ibge', (done) => {
chai.request(server) chai.request(server)
.get('/api/v1/city/ibge/1200013') .get('/api/v1/city/ibge/4106902')
.end((err, res) => { .end((err, res) => {
res.should.have.status(200); res.should.have.status(200);
res.should.be.json; res.should.be.json;
res.body.should.have.property('result'); res.body.should.have.property('result');
res.body.result.should.be.a('array'); res.body.result.should.be.a('array');
res.body.result[0].should.have.property('pk_municipio_id'); res.body.result[0].should.have.property('pk_cod_ibge');
res.body.result[0].should.have.property('fk_estado_id'); res.body.result[0].should.have.property('fk_estado_id');
res.body.result[0].should.have.property('nome'); res.body.result[0].should.have.property('nome');
res.body.result[0].should.have.property('codigo_ibge');
done(); done();
}); });
}); });
...@@ -313,10 +331,9 @@ describe('request cities', () => { ...@@ -313,10 +331,9 @@ describe('request cities', () => {
res.should.be.json; res.should.be.json;
res.body.should.have.property('result'); res.body.should.have.property('result');
res.body.result.should.be.a('array'); res.body.result.should.be.a('array');
res.body.result[0].should.have.property('pk_municipio_id'); res.body.result[0].should.have.property('pk_cod_ibge');
res.body.result[0].should.have.property('fk_estado_id'); res.body.result[0].should.have.property('fk_estado_id');
res.body.result[0].should.have.property('nome'); res.body.result[0].should.have.property('nome');
res.body.result[0].should.have.property('codigo_ibge');
done(); done();
}) })
}) })
...@@ -325,16 +342,14 @@ describe('request cities', () => { ...@@ -325,16 +342,14 @@ describe('request cities', () => {
describe('request schools', () => { describe('request schools', () => {
it('should list a school by id', (done) => { it('should list a school by id', (done) => {
chai.request(server) chai.request(server)
.get('/api/v1/school/185588') .get('/api/v1/school/41000021')
.end((err, res) => { .end((err, res) => {
res.should.have.status(200); res.should.have.status(200);
res.should.be.json; res.should.be.json;
res.body.should.have.property('result'); res.body.should.have.property('result');
res.body.result.should.be.a('array'); res.body.result.should.be.a('array');
res.body.result[0].should.have.property('pk_escola_id');
res.body.result[0].should.have.property('ano_censo'); res.body.result[0].should.have.property('ano_censo');
res.body.result[0].should.have.property('cod_entidade'); res.body.result[0].should.have.property('cod_entidade');
res.body.result[0].should.have.property('nome_entidade');
done(); done();
}); });
}); });
...@@ -347,24 +362,22 @@ describe('request schools', () => { ...@@ -347,24 +362,22 @@ describe('request schools', () => {
res.should.be.json; res.should.be.json;
res.body.should.have.property('result'); res.body.should.have.property('result');
res.body.result.should.be.a('array'); res.body.result.should.be.a('array');
res.body.result[0].should.have.property('pk_escola_id'); res.body.result[0].should.have.property('cod_entidade');
res.body.result[0].should.have.property('ano_censo'); res.body.result[0].should.have.property('ano_censo');
res.body.result[0].should.have.property('nome_entidade');
done(); done();
}); });
}); });
it('should list all schools from a city', (done) => { it('should list all schools from a city', (done) => {
chai.request(server) chai.request(server)
.get('/api/v1/school/city/3287') .get('/api/v1/school/city/4106902')
.end((err, res) => { .end((err, res) => {
res.should.have.status(200); res.should.have.status(200);
res.should.be.json; res.should.be.json;
res.body.should.have.property('result'); res.body.should.have.property('result');
res.body.result.should.be.a('array'); res.body.result.should.be.a('array');
res.body.result[0].should.have.property('pk_escola_id'); res.body.result[0].should.have.property('cod_entidade');
res.body.result[0].should.have.property('ano_censo'); res.body.result[0].should.have.property('ano_censo');
res.body.result[0].should.have.property('nome_entidade');
done(); done();
}) })
}) })
...@@ -784,6 +797,9 @@ describe('Saves a user', () => { ...@@ -784,6 +797,9 @@ describe('Saves a user', () => {
beforeEach(() => { beforeEach(() => {
User.remove({}, (err) => { User.remove({}, (err) => {
if(err) {
console.log('Error while purging: ' + err);
}
console.log('Test collection purged'); console.log('Test collection purged');
}); });
}); });
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment