UNPKG

node-express-mongodb-jwt-rest-api-skeleton

Version:

Node.js express.js MongoDB JWT REST API - This is a basic API REST skeleton written on JavaScript using async/await. Great for building a starter web API for your front-end (Android, iOS, Vue, react, angular, or anything that can consume an API)

310 lines (303 loc) 9.1 kB
/* eslint handle-callback-err: "off"*/ process.env.NODE_ENV = 'test' const User = require('../app/models/user') const faker = require('faker') const chai = require('chai') const chaiHttp = require('chai-http') const server = require('../server') // eslint-disable-next-line no-unused-vars const should = chai.should() const loginDetails = { admin: { id: '5aa1c2c35ef7a4e97b5e995a', email: 'admin@admin.com', password: '12345' }, user: { id: '5aa1c2c35ef7a4e97b5e995b', email: 'user@user.com', password: '12345' } } const tokens = { admin: '', user: '' } const email = faker.internet.email() const createdID = [] chai.use(chaiHttp) describe('*********** USERS ***********', () => { describe('/POST login', () => { it('it should GET token as admin', (done) => { chai .request(server) .post('/login') .send(loginDetails.admin) .end((err, res) => { res.should.have.status(200) res.body.should.be.an('object') res.body.should.have.property('token') tokens.admin = res.body.token done() }) }) it('it should GET token as user', (done) => { chai .request(server) .post('/login') .send(loginDetails.user) .end((err, res) => { res.should.have.status(200) res.body.should.be.an('object') res.body.should.have.property('token') tokens.user = res.body.token done() }) }) }) describe('/GET users', () => { it('it should NOT be able to consume the route since no token was sent', (done) => { chai .request(server) .get('/users') .end((err, res) => { res.should.have.status(401) done() }) }) it('it should GET all the users', (done) => { chai .request(server) .get('/users') .set('Authorization', `Bearer ${tokens.admin}`) .end((err, res) => { res.should.have.status(200) res.body.should.be.an('object') res.body.docs.should.be.a('array') done() }) }) it('it should GET the users with filters', (done) => { chai .request(server) .get('/users?filter=admin&fields=name,email,city,country,phone') .set('Authorization', `Bearer ${tokens.admin}`) .end((err, res) => { res.should.have.status(200) res.body.should.be.an('object') res.body.docs.should.be.a('array') res.body.docs.should.have.lengthOf(1) res.body.docs[0].should.have.property('email').eql('admin@admin.com') done() }) }) }) describe('/POST user', () => { it('it should NOT POST a user without name', (done) => { const user = {} chai .request(server) .post('/users') .set('Authorization', `Bearer ${tokens.admin}`) .send(user) .end((err, res) => { res.should.have.status(422) res.body.should.be.a('object') res.body.should.have.property('errors') done() }) }) it('it should POST a user ', (done) => { const user = { name: faker.random.words(), email, password: faker.random.words(), role: 'admin', urlTwitter: faker.internet.url(), urlGitHub: faker.internet.url(), phone: faker.phone.phoneNumber(), city: faker.random.words(), country: faker.random.words() } chai .request(server) .post('/users') .set('Authorization', `Bearer ${tokens.admin}`) .send(user) .end((err, res) => { res.should.have.status(201) res.body.should.be.a('object') res.body.should.include.keys('_id', 'name', 'email', 'verification') createdID.push(res.body._id) done() }) }) it('it should NOT POST a user with email that already exists', (done) => { const user = { name: faker.random.words(), email, password: faker.random.words(), role: 'admin' } chai .request(server) .post('/users') .set('Authorization', `Bearer ${tokens.admin}`) .send(user) .end((err, res) => { res.should.have.status(422) res.body.should.be.a('object') res.body.should.have.property('errors') done() }) }) it('it should NOT POST a user with not known role', (done) => { const user = { name: faker.random.words(), email, password: faker.random.words(), role: faker.random.words() } chai .request(server) .post('/users') .set('Authorization', `Bearer ${tokens.admin}`) .send(user) .end((err, res) => { res.should.have.status(422) res.body.should.be.a('object') res.body.should.have.property('errors') done() }) }) }) describe('/GET/:id user', () => { it('it should GET a user by the given id', (done) => { const id = createdID.slice(-1).pop() chai .request(server) .get(`/users/${id}`) .set('Authorization', `Bearer ${tokens.admin}`) .end((error, res) => { res.should.have.status(200) res.body.should.be.a('object') res.body.should.have.property('name') res.body.should.have.property('_id').eql(id) done() }) }) }) describe('/PATCH/:id user', () => { it('it should UPDATE a user given the id', (done) => { const id = createdID.slice(-1).pop() const user = { name: 'JS123456', email: 'emailthatalreadyexists@email.com', role: 'admin', urlTwitter: faker.internet.url(), urlGitHub: faker.internet.url(), phone: faker.phone.phoneNumber(), city: faker.random.words(), country: faker.random.words() } chai .request(server) .patch(`/users/${id}`) .set('Authorization', `Bearer ${tokens.admin}`) .send(user) .end((error, res) => { res.should.have.status(200) res.body.should.be.a('object') res.body.should.have.property('_id').eql(id) res.body.should.have.property('name').eql('JS123456') res.body.should.have .property('email') .eql('emailthatalreadyexists@email.com') createdID.push(res.body._id) done() }) }) it('it should NOT UPDATE a user with email that already exists', (done) => { const id = createdID.slice(-1).pop() const user = { name: faker.random.words(), email: 'admin@admin.com', role: 'admin' } chai .request(server) .patch(`/users/${id}`) .set('Authorization', `Bearer ${tokens.admin}`) .send(user) .end((err, res) => { res.should.have.status(422) res.body.should.be.a('object') res.body.should.have.property('errors') done() }) }) it('it should NOT UPDATE another user if not an admin', (done) => { const id = createdID.slice(-1).pop() const user = { name: faker.random.words(), email: 'toto@toto.com', role: 'user' } chai .request(server) .patch(`/users/${id}`) .set('Authorization', `Bearer ${tokens.user}`) .send(user) .end((err, res) => { res.should.have.status(401) res.body.should.be.a('object') res.body.should.have.property('errors') done() }) }) }) describe('/DELETE/:id user', () => { it('it should DELETE a user given the id', (done) => { const user = { name: faker.random.words(), email: faker.internet.email(), password: faker.random.words(), role: 'admin', urlTwitter: faker.internet.url(), urlGitHub: faker.internet.url(), phone: faker.phone.phoneNumber(), city: faker.random.words(), country: faker.random.words() } chai .request(server) .post('/users') .set('Authorization', `Bearer ${tokens.admin}`) .send(user) .end((err, res) => { res.should.have.status(201) res.body.should.be.a('object') res.body.should.include.keys('_id', 'name', 'email', 'verification') chai .request(server) .delete(`/users/${res.body._id}`) .set('Authorization', `Bearer ${tokens.admin}`) .end((error, result) => { result.should.have.status(200) result.body.should.be.a('object') result.body.should.have.property('msg').eql('DELETED') done() }) }) }) }) after(() => { createdID.forEach((id) => { User.findByIdAndRemove(id, (err) => { if (err) { console.log(err) } }) }) }) })