Skip to content

Commit

Permalink
Merge 4af8d90 into fe16abe
Browse files Browse the repository at this point in the history
  • Loading branch information
minlinx committed Sep 8, 2019
2 parents fe16abe + 4af8d90 commit 32e7583
Show file tree
Hide file tree
Showing 16 changed files with 238 additions and 15 deletions.
1 change: 0 additions & 1 deletion src/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ const config = {
DATABASE_URL: process.env.DATABASE_URL
}
};

module.exports = config;
38 changes: 38 additions & 0 deletions src/controllers/AccommodationController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import models from '../models';
import { HelperMethods } from '../utils';

const { Room } = models;

/**
* Class representing the Accomodation controller
* @class AccommodationController
* @description accommodation controller
*/
class AccommodationController {
/**
* Book An Accommodation.
* Route: POST: /accommodation
* @param {object} req - HTTP Request object
* @param {object} res - HTTP Response object
* @return {res} res - HTTP Response object
* @memberof AccommodationController
*/
static async bookAnAccommodation(req, res) {
try {
const { body } = req;
const { dataValues } = await Room.create({ ...body });
if (dataValues.id) {
HelperMethods.requestSuccessful(res, {
success: true,
message: 'Accommodation booked successfully',
accommodationCreated: dataValues,
}, 201);
}
} catch (error) {
if (error.errors) return HelperMethods.sequelizeValidationError(res, error);
return HelperMethods.serverError(res);
}
}
}

export default AccommodationController;
7 changes: 4 additions & 3 deletions src/controllers/RequestController.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ class RequestController {
* @return {res} res - HTTP Response object
* @memberof RequestController
*/
static async confirmRequestApproval(req, res) {
static async confirmRequestApproval(req, res, next) {
try {
const approvedRequest = await Request.findOne({
where: { id: req.body.id },
Expand All @@ -361,8 +361,9 @@ class RequestController {
return HelperMethods.clientError(res,
'The request you are trying to confirm cannot be found', 404);
} catch (error) {
if (error.errors) return HelperMethods.sequelizeValidationError(res, error);
return HelperMethods.serverError(res);
// if (error.errors) return HelperMethods.sequelizeValidationError(res, error);
// return HelperMethods.serverError(res);
return next(error)
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/controllers/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import UserController from './UserController';
import RequestController from './RequestController';
import AccommodationController from './AccommodationController';

export { UserController, RequestController };
export { UserController, RequestController, AccommodationController };
4 changes: 2 additions & 2 deletions src/migrations/02-create-accommodations.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('Accommodations', {
up: (queryInterface, Sequelize) => queryInterface.createTable('Rooms', {
id: {
primaryKey: true,
type: Sequelize.UUID,
Expand Down Expand Up @@ -37,5 +37,5 @@ module.exports = {
}
}),

down: queryInterface => queryInterface.dropTable('Accommodations')
down: queryInterface => queryInterface.dropTable('Rooms')
};
2 changes: 1 addition & 1 deletion src/migrations/03-create-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ module.exports = {
accommodationId: {
type: Sequelize.UUID,
references: {
model: 'Accommodations',
model: 'Rooms',
key: 'id'
}
},
Expand Down
8 changes: 4 additions & 4 deletions src/models/Accommodation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default (sequelize, DataTypes) => {
const Accommodation = sequelize.define('Accommodation', {
const Room = sequelize.define('Room', {
id: {
type: DataTypes.UUID,
primaryKey: true,
Expand Down Expand Up @@ -36,12 +36,12 @@ export default (sequelize, DataTypes) => {
},
});

Accommodation.associate = models => {
Accommodation.hasMany(models.Request, {
Room.associate = models => {
Room.hasMany(models.Request, {
foreignKey: 'accommodationId',
as: 'accommodation',
});
};

return Accommodation;
return Room;
};
2 changes: 1 addition & 1 deletion src/models/Request.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default (sequelize, DataTypes) => {
foreignKey: 'userId',
onDelete: 'CASCADE',
});
Request.belongsTo(models.Accommodation, {
Request.belongsTo(models.Room, {
foreignKey: 'accommodationId',
onDelete: 'CASCADE',
});
Expand Down
14 changes: 14 additions & 0 deletions src/routes/accommodationRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AccommodationController } from '../controllers';
import { Authorization } from '../middlewares';
import Validate from '../validation';

const accommodationRoute = app => {
app.post(
'/api/v1/accommodation',
Validate.validateUserInput,
Authorization.checkToken,
AccommodationController.bookAnAccommodation
);
};

export default accommodationRoute;
2 changes: 2 additions & 0 deletions src/routes/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import authRoute from './authRoute';
import requestRoute from './requestRoute';
import accommodationRoute from './accommodationRoute';
import userRoute from './userRoute';
import socialAuthRoute from './socialAuthRoute';
/**
Expand All @@ -19,6 +20,7 @@ const routes = app => {
requestRoute(app);
userRoute(app);
socialAuthRoute(app);
accommodationRoute(app);
};

export default routes;
4 changes: 2 additions & 2 deletions src/seeders/02-demo-accommodation.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
up: queryInterface => queryInterface.bulkInsert('Accommodations', [
up: queryInterface => queryInterface.bulkInsert('Rooms', [
{
id: '2125be7b-f1f1-4f0a-af86-49c657870b5c',
name: 'Southern Sun Ikoyi Hotel',
Expand Down Expand Up @@ -32,5 +32,5 @@ module.exports = {
}
], {}),

down: queryInterface => queryInterface.bulkDelete('Accommodations', null, {})
down: queryInterface => queryInterface.bulkDelete('Rooms', null, {})
};
57 changes: 57 additions & 0 deletions src/test/integrationTests/accommodationController.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import chai from 'chai';
import chaiHttp from 'chai-http';
import app from '../../index';

chai.use(chaiHttp);
const { expect } = chai;

describe('Integration Tests For Accommodation Controller', () => {
describe('Test book accommodation controller', () => {
const accommodationDetails = {
name: 'Southern Sun Ikoyi Hotel',
address: '174, Owolabi street, Yaba',
roomName: 'C3',
roomType: '2 bedroom',
vacantNumber: '1',
};
let token;
before('Get Token', async () => {
const loginResponse = await chai.request(app).post('/api/v1/auth/login')
.send({
email: 'demo2@demo.com',
password: 'password',
});
token = loginResponse.body.data.userDetails.token;
});
it('should book an accommodation for a user', async () => {
const response = await chai.request(app).post('/api/v1/accommodation')
.send(accommodationDetails).set('x-access-token', token);
expect(response.status).to.deep.equal(201);
expect(response.body.data).to.have.property('success');
expect(response.body.data.success).to.equal(true);
expect(response.body.data).to.have.property('message');
expect(response.body.data.message)
.to.equal('Accommodation booked successfully');
});
it('should return client error when some details are missing', async () => {
const response = await chai.request(app).post('/api/v1/accommodation')
.send().set({ 'x-access-token': token });
expect(response.status).to.deep.equal(400);
expect(response.body).to.have.property('success');
expect(response.body.success).to.equal(false);
expect(response.body).to.have.property('message');
expect(response.body.message)
.to.equal('The "name" field is required');
});
it('should return error for missing token', async () => {
const response = await chai.request(app).post('/api/v1/accommodation')
.send(accommodationDetails);
expect(response.status).to.deep.equal(401);
expect(response.body).to.have.property('success');
expect(response.body.success).to.equal(false);
expect(response.body).to.have.property('message');
expect(response.body.message)
.to.equal('User not authorized');
});
});
});
1 change: 1 addition & 0 deletions src/test/integrationTests/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './requestController.test';
import './userController.test';
import './socialController.test';
import './accommodationController.test';
35 changes: 35 additions & 0 deletions src/test/unitTests/accomodationController.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import sinon from 'sinon';
import chai from 'chai';
import { AccommodationController } from '../../controllers';
import models from '../../models';

const { expect } = chai;
const { Room } = models;

const req = { decoded: { id: 'some id' } };

const res = {
status() {
return this;
},
json(obj) {
return obj;
}
};

describe('unit test for the Accomodation Controller', () => {
let stubbedMethod;
afterEach(() => {
if (stubbedMethod.restore) stubbedMethod.restore();
});
it('should return a server error when an unexpected error happens', async () => {
stubbedMethod = sinon.stub(Room, 'create').throws({
dataValues: 'some thing'
});
const response = await AccommodationController.bookAnAccommodation(req, res);
expect(response).to.have.property('message');
expect(response.message).to.equal('Internal server error');
expect(response).to.have.property('success');
expect(response.success).to.equal(false);
});
});
2 changes: 2 additions & 0 deletions src/test/unitTests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ import './authentication.test';
import './sendEmail.test';
import './helperMethods.test';
import './requestController.test';
import './accomodationController.test';
import './userController.test';
import './middleware.test';
import './searchRequestsMiddleware.test';
73 changes: 73 additions & 0 deletions src/test/unitTests/userController.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import sinon from 'sinon';
import chai from 'chai';
import { UserController } from '../../controllers';
import models from '../../models';

const { expect } = chai;
const { User } = models;

const req = { decoded: { id: 'some id' } };

const res = {
status() {
return this;
},
json(obj) {
return obj;
}
};

describe('unit test for the User Controller', () => {
let stubbedMethod;
afterEach(() => {
if (stubbedMethod.restore) stubbedMethod.restore();
});
it('should return a server error when an unexpected error happens', async () => {
stubbedMethod = sinon.stub(User, 'findByPk').throws({
dataValues: 'some thing'
});
const response = await UserController.updateProfile(req, res);
expect(response).to.have.property('message');
expect(response.message).to.equal('Internal server error');
expect(response).to.have.property('success');
expect(response.success).to.equal(false);
});
it('should return a server error when an unexpected error happens', async () => {
stubbedMethod = sinon.stub(User, 'findByPk').throws({
dataValues: 'some thing'
});
const response = await UserController.getProfile(req, res);
expect(response).to.have.property('message');
expect(response.message).to.equal('Internal server error');
expect(response).to.have.property('success');
expect(response.success).to.equal(false);
});
it('should return a server error when an unexpected error happens', async () => {
stubbedMethod = sinon.stub(User, 'findByPk').throws({
dataValues: 'some thing'
});
const response = await UserController.verifyEmail(req, res);
expect(response).to.have.property('message');
expect(response.message).to.equal('Internal server error');
expect(response).to.have.property('success');
expect(response.success).to.equal(false);
});
it('should return a server error when an unexpected error happens', async () => {
stubbedMethod = sinon.stub(User, 'findOne').throws({
dataValues: 'some thing'
});
const response = await UserController.resetPassword(req, res);
expect(response).to.have.property('message');
expect(response.message).to.equal('Internal server error');
expect(response).to.have.property('success');
expect(response.success).to.equal(false);
});
it('should only allow managers reject a User', async () => {
stubbedMethod = sinon.stub(User, 'update').throws({ dataValues: 'some thing' });
const response = await UserController.rememberUserDetails(req, res);
expect(response).to.have.property('message');
expect(response.message).to.equal('Internal server error');
expect(response).to.have.property('success');
expect(response.success).to.equal(false);
});
});

0 comments on commit 32e7583

Please sign in to comment.