Skip to content

Commit

Permalink
Merge 0cbdf4b into 0e121ce
Browse files Browse the repository at this point in the history
  • Loading branch information
halimahO committed Jul 3, 2019
2 parents 0e121ce + 0cbdf4b commit 56dd6ca
Show file tree
Hide file tree
Showing 12 changed files with 320 additions and 122 deletions.
17 changes: 9 additions & 8 deletions src/controllers/auth.controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import {
isUserExist
} from '../services/auth.service';
import Helper from '../services/helper';
/**
* format
* @param {object} response
* @param {object} request
* @returns {object}
*/

/**
* @method signUp
Expand Down Expand Up @@ -35,16 +41,11 @@ const signUp = async (request, response) => {
};

/**
* @method login
* - logs in a user
* - validate user input
* - returns user data with a generated token
* Route: POST: /users/login
*
* @param {Object} request request object
* @param {Object} response response object
*
* @returns {Response} response object
* @param {object} request
* @param {object} response
* @returns
*/

const login = async (request, response) => {
Expand Down
16 changes: 16 additions & 0 deletions src/controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { getAllUsersService } from '../services/user.services';
import Helper from '../services/helper';

/**
* @description Get list of all users
* @param {object} request
* @param {object} response
* @returns {object} List of all users
*/
const getUsers = async (request, response) => {
const value = await getAllUsersService();

return Helper.successResponse(response, 200, value);
};

export default { getUsers };
20 changes: 20 additions & 0 deletions src/helpers/tryCatch.helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @description Wraps a controller function in a try-catch block
* @param {object} request
* @param {object} response
* @returns Status code and error message if an error is thrown
*/

/* istanbul ignore next */
const tryCatch = controller => async (request, response) => {
try {
await controller(request, response);
} catch (error) {
return response
.status(500)
.json({ status: 'error', message: error.message });
}
return true;
};

export default tryCatch;
42 changes: 42 additions & 0 deletions src/middlewares/auth.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,47 @@ export default {
error: error.message
});
}
},

/**
* @method isAdmin
* - it checks if user is an admin
* - returns next()
*
* @param {Object} request request object
* @param {Object} response response object
* @param {Function} next function
*
* @returns {Response} response object
*/

async isAdmin(request, response, next) {
if (request.user.role !== 'admin') {
return response.status(403).json({
message: 'You do not have access to this resource, unauthorized'
});
}
next();
},

/**
* @method isSuperAdmin
* - it checks if user is a super_admin
* - returns next()
*
* @param {Object} request request object
* @param {Object} response response object
* @param {Function} next function
*
* @returns {Response} response object
*/

async isSuperAdmin(request, response, next) {
if (request.user.role !== 'super_admin') {
return response.status(403).json({
message: 'You do not have access to this resource, unauthorized'
});
}
next();
}
};
2 changes: 2 additions & 0 deletions src/routes/v1/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import auth from './auth.route';
import users from './user.routes';

export default app => {
app.use('/api/v1/users', auth);
app.use('/api/v1/users/', users);
};
10 changes: 10 additions & 0 deletions src/routes/v1/user.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import express from 'express';
import authentication from '../../middlewares/auth.middleware';
import userController from '../../controllers/user.controller';
import tryCatch from '../../helpers/tryCatch.helper';

const router = express.Router();

router.get('/', authentication.verifyToken, tryCatch(userController.getUsers));

export default router;
13 changes: 13 additions & 0 deletions src/services/user.services.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import model from '../db/models';

const { User } = model;

// eslint-disable-next-line import/prefer-default-export
export const getAllUsersService = () => {
const users = User.findAll({
attributes: {
exclude: ['password', 'confirmEmailCode']
}
});
return users;
};
48 changes: 48 additions & 0 deletions src/tests/controller/user.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import chai from 'chai';
import chaiHttp from 'chai-http';
import sinonChai from 'sinon-chai';
import { getUser } from '../utils/db.utils';
import app from '../../index';

const { expect, request } = chai;

chai.use(chaiHttp);
chai.use(sinonChai);
let userToken;
describe('User API endpoints', () => {
let responseHook;
before('sign up a random user', async () => {
const randomUser = getUser();
responseHook = await request(app)
.post('/api/v1/users/signup')
.send(randomUser);
});
describe('GET /users', async () => {
it('should get all users', done => {
userToken = responseHook.body.data.token;
request(app)
.get('/api/v1/users')
.set({ Authorization: `Bearer ${userToken}` })
.end((error, response) => {
expect(response.status).to.be.equal(200);
expect(response.body.data).to.be.an('array');
expect(response.body.data[0]).to.have.property('id');
expect(response.body.data[0]).to.have.property('firstName');
done();
});
});
it('should not get all users if token is invalid', done => {
request(app)
.get('/api/v1/users')
.end((error, response) => {
expect(response.status).to.be.equal(400);
expect(response.body).to.have.property('error');
expect(response.body.error).to.eq(
'No token provided, you do not have access to this page'
);
done();
console.log(response.body);
});
});
});
});
1 change: 1 addition & 0 deletions src/tests/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ import './misc/index.spec';
import './middleware/auth.spec';
import './models/user.spec';
import './controller/auth.spec';
import './controller/user.spec';
46 changes: 40 additions & 6 deletions src/tests/middleware/auth.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ chai.use(sinonChai);

describe('Authentication middleware', () => {
it('Should return an error if token is not provided', async () => {
const req = {
const request = {
headers: {
authorization: ''
}
Expand All @@ -25,7 +25,7 @@ describe('Authentication middleware', () => {
sinon.stub(response, 'status').returnsThis();
sinon.stub(response, 'json').returnsThis();
const next = () => {};
await middleware.verifyToken(req, response, next);
await middleware.verifyToken(request, response, next);
expect(response.status).to.have.been.calledWith(400);
expect(response.json).to.have.been.calledWith({
status: 400,
Expand All @@ -39,7 +39,7 @@ describe('Authentication middleware', () => {
role: 'sample'
});

const req = {
const request = {
headers: {
authorization: `Bearer ${token}`
}
Expand All @@ -48,7 +48,7 @@ describe('Authentication middleware', () => {
sinon.stub(response, 'status').returnsThis();
sinon.stub(response, 'json').returnsThis();
const next = () => {};
await middleware.verifyToken(req, response, next);
await middleware.verifyToken(request, response, next);
expect(response.status).to.have.been.calledWith(400);
expect(response.json).to.have.been.calledWith({
status: 400,
Expand All @@ -57,7 +57,7 @@ describe('Authentication middleware', () => {
});

it('Should return an error if there is an invalid token', async () => {
const req = {
const request = {
headers: {
authorization: `Bearer uieruierueior.ererer.ererer.erre`
}
Expand All @@ -66,11 +66,45 @@ describe('Authentication middleware', () => {
sinon.stub(response, 'status').returnsThis();
sinon.stub(response, 'json').returnsThis();
const next = () => {};
await middleware.verifyToken(req, response, next);
await middleware.verifyToken(request, response, next);
expect(response.status).to.have.been.calledWith(400);
expect(response.json).to.have.been.calledWith({
status: 400,
error: 'jwt malformed'
});
});

it('Should return an error if user is not an admin ', () => {
const request = {
user: {
role: null
}
};
const response = new Response();
sinon.stub(response, 'status').returnsThis();
sinon.stub(response, 'json').returnsThis();
const next = () => {};
middleware.isAdmin(request, response, next);
expect(response.status).to.have.been.calledWith(403);
expect(response.json).to.have.been.calledWith({
message: 'You do not have access to this resource, unauthorized'
});
});

it('Should return an error if user is not super admin ', () => {
const request = {
user: {
role: null
}
};
const response = new Response();
sinon.stub(response, 'status').returnsThis();
sinon.stub(response, 'json').returnsThis();
const next = () => {};
middleware.isSuperAdmin(request, response, next);
expect(response.status).to.have.been.calledWith(403);
expect(response.json).to.have.been.calledWith({
message: 'You do not have access to this resource, unauthorized'
});
});
});
1 change: 0 additions & 1 deletion src/validators/user.validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ const UserValidator = {
];

default:
return [];
}
},

Expand Down
Loading

0 comments on commit 56dd6ca

Please sign in to comment.