Skip to content

Commit

Permalink
Merge 721150b into fe16abe
Browse files Browse the repository at this point in the history
  • Loading branch information
minlinx committed Sep 10, 2019
2 parents fe16abe + 721150b commit 54e9e07
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 4 deletions.
41 changes: 41 additions & 0 deletions src/controllers/AccommodationController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import models from '../models';
import { HelperMethods } from '../utils';

const { Accommodation } = 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 { id } = req.decoded;
const { dataValues } = await Accommodation.create({ ...body, userId: id });
if (dataValues.id) {
HelperMethods.requestSuccessful(res, {
success: true,
message: 'Accommodation booked successfully',
accommodationCreated: dataValues,
}, 201);
}
return HelperMethods.serverError(res,
'Could not create an accommodation. Please try again');
} catch (error) {
if (error.errors) return HelperMethods.sequelizeValidationError(res, error);
return HelperMethods.serverError(res);
}
}
}

export default AccommodationController;
2 changes: 1 addition & 1 deletion src/controllers/RequestController.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class RequestController {
try {
const { id } = req.decoded;
const { body } = req;
const { dataValues } = await Request.create({ ...body, userId: id, });
const { dataValues } = await Request.create({ ...body, userId: id });
if (dataValues.id) {
HelperMethods.requestSuccessful(res, {
success: true,
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 };
7 changes: 7 additions & 0 deletions src/migrations/02-create-accommodations.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ module.exports = {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4
},
userId: {
type: Sequelize.UUID,
references: {
model: 'Users',
key: 'id',
}
},
name: {
type: Sequelize.STRING,
allowNull: false,
Expand Down
7 changes: 5 additions & 2 deletions src/models/Accommodation.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ export default (sequelize, DataTypes) => {
}
}
},
});
}, { tableName: 'Accommodations' });

Accommodation.associate = models => {
Accommodation.belongsTo(models.User, {
foreignKey: 'userId',
onDelete: 'CASCADE',
});
Accommodation.hasMany(models.Request, {
foreignKey: 'accommodationId',
as: 'accommodation',
});
};

Expand Down
8 changes: 8 additions & 0 deletions src/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ export default (sequelize, DataTypes) => {
foreignKey: 'userId',
as: 'users_request',
});
User.hasMany(models.Accommodation, {
foreignKey: 'userId',
as: 'users_accommodation',
});
}
}
});
Expand All @@ -207,6 +211,10 @@ export default (sequelize, DataTypes) => {
foreignKey: 'userId',
onDelete: 'CASCADE'
});
User.hasMany(models.Accommodation, {
foreignKey: 'userId',
onDelete: 'CASCADE'
});
};

// eslint-disable-next-line func-names
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;
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 { Accommodation } = 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(Accommodation, '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 54e9e07

Please sign in to comment.