process.env.NODE_ENV = 'test';

const chai = require('chai');

const dirtyChai = require('dirty-chai');

chai.use(dirtyChai);

const chaiXml = require('chai-xml');

chai.use(chaiXml);

const chaiHttp = require('chai-http');

const assert = chai.assert;

const expect = chai.expect;

const should = chai.should(); // actually call the function

const libs = `${process.cwd()}/libs`;

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);

describe('API is running', () => {
    it('should respond it\'s running', (done) => {
        chai.request(server)
            .get('/api/v1')
            .end((err, res) => {
                res.should.have.status(200);
                res.should.be.json;
                res.body.should.have.property('msg');
                done();
            })
    });
});

describe('request enrollments', () => {
    it('should list the year range', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment/year_range')
            .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('start_year');
                res.body.result[0].should.have.property('end_year');
                done();
            });
    });

    it('should list the education level', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment/education_level')
            .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('id');
                res.body.result[0].should.have.property('name');
                done();
            });
    });

    it('should list the administrative dependencies', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment/adm_dependency ')
            .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('id');
                res.body.result[0].should.have.property('name');
                done();
            });
    });

    it('should list enrollments', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment')
            .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('name');
                res.body.result[0].should.have.property('total');
                done();
            });
    });

    it('should list enrollments with valid filters', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment?filter=min_year:2010,state:41')
            .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('name');
                res.body.result[0].should.have.property('total');
                done();
            });
    });

    it('should list enrollments with invalid filters', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment?filter=foo:2010,bar:41')
            .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('name');
                res.body.result[0].should.have.property('total');
                done();
            });
    });

    it('should list enrollments with valid dimensions', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment?dims=region,state,adm_dependency_id,location_id&filter=min_year:2014,region:4')
            .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('adm_dependency_name');
                res.body.result[0].should.have.property('total');
                done();
            });
    });

    it('should list enrollments with invalid dimensions', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment?dims=foo,bar')
            .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('name');
                res.body.result[0].should.have.property('total');
                done();
            });
    });

    it('should list enrollments with valid dimensions and filters', (done) => {
        chai.request(server)
            .get('/api/v1/enrollment?dims=region,state,education_level_id,school&filter=min_year:2013,max_year:2014,city:3287')
            .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('total');
                res.body.result[0].should.have.property('year');
                done();
            });
    });


});

describe('request regions', () => {
    it('should list all regions', (done) => {
        chai.request(server)
            .get('/api/v1/region')
            .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('pk_regiao_id');
                res.body.result[0].should.have.property('nome');
                done();
            });
    });

    it('should list region by id', (done) => {
        chai.request(server)
            .get('/api/v1/region/1')
            .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.should.have.length(1);
                res.body.result[0].should.have.property('pk_regiao_id');
                res.body.result[0].should.have.property('nome');
                done();
            });
    });
});

describe('request states', () => {
    it('should list all states', (done) => {
        chai.request(server)
            .get('/api/v1/state')
            .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('pk_estado_id');
                res.body.result[0].should.have.property('fk_regiao_id');
                res.body.result[0].should.have.property('nome');
                done();
            });
    });

    it('should list a state by id', (done) => {
        chai.request(server)
            .get('/api/v1/state/11')
            .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.should.have.length(1);
                res.body.result[0].should.have.property('pk_estado_id');
                res.body.result[0].should.have.property('fk_regiao_id');
                res.body.result[0].should.have.property('nome');
                done();
            });
    });

    it('should list states by region id', (done) => {
        chai.request(server)
            .get('/api/v1/state/region/1')
            .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('pk_estado_id');
                res.body.result[0].should.have.property('fk_regiao_id');
                res.body.result[0].should.have.property('nome');
                done();
            });
    });
});

describe('request cities', () => {
    it('should list all cities', (done) => {
        chai.request(server)
            .get('/api/v1/city')
            .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('pk_municipio_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('codigo_ibge');
                done();
            });
    });

    it('should list a city by id', (done) => {
        chai.request(server)
            .get('/api/v1/city/1')
            .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('pk_municipio_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('codigo_ibge');
                done();
            });
    });

    it('should list a city by codigo_ibge', (done) => {
        chai.request(server)
            .get('/api/v1/city/ibge/1200013')
            .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('pk_municipio_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('codigo_ibge');
                done();
            });
    });

    it('should list all cities from a state', (done) => {
        chai.request(server)
            .get('/api/v1/city/state/41')
            .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('pk_municipio_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('codigo_ibge');
                done();
            })
    })
});

describe('request schools', () => {
    it('should list a school by id', (done) => {
        chai.request(server)
            .get('/api/v1/school/185588')
            .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('pk_escola_id');
                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('nome_entidade');
                done();
            });
    });

    it('should list all schools from a state', (done) => {
        chai.request(server)
            .get('/api/v1/school/state/41')
            .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('pk_escola_id');
                res.body.result[0].should.have.property('ano_censo');
                res.body.result[0].should.have.property('nome_entidade');
                done();
            });
    });

    it('should list all schools from a city', (done) => {
        chai.request(server)
            .get('/api/v1/school/city/3287')
            .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('pk_escola_id');
                res.body.result[0].should.have.property('ano_censo');
                res.body.result[0].should.have.property('nome_entidade');
                done();
            })
    })
});

describe('test response', () => {
    it('should list all regions in json', (done) => {
        chai.request(server)
            .get('/api/v1/region')
            .end((err, res) => {
                res.should.have.status(200);
                res.should.be.json;
                done();
            });
    });

    it('should list all regions in xml', (done) => {
        chai.request(server)
            .get('/api/v1/region?format=xml')
            .end((err, res) => {
                res.should.have.status(200);
                res.should.be.xml;
                done();
            });
    });

    it('should list all regions in csv', (done) => {
        chai.request(server)
            .get('/api/v1/region?format=csv')
            .end((err, res) => {
                res.should.have.status(200);
                done();
            });
    });
});

describe('Requires a simulation', () => {
    let newSimulation;

    beforeEach(() => {
        Simulation.remove({}, (err) => {
            console.log('Test collection purged');
        });
    });

    it('should create a new simulation', (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');
                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();
                });
            });
    });
    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';
        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 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';
        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.name.should.equal('test');
                        simulation.should.have.property('location');
                        simulation.location.should.be.a('number');
                        simulation.location.should.equal(5);
                        done();
                    });
                });
        });
    });
    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({
                    name: 'new_name',
                    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('new_name');
                        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';
        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();
                    });
                });
        });
    });
    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();
                });
        });
    });
    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';
        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();
                    });
                });
        });
    });
    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.success.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.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();
                });
        });
    });
    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();
            });
    });
});

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();
                });
            });
    });

});