Skip to content

Commit

Permalink
Merge c17ae27 into 0be29f4
Browse files Browse the repository at this point in the history
  • Loading branch information
nignanthomas committed Nov 12, 2019
2 parents 0be29f4 + c17ae27 commit d76c2db
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 32 deletions.
30 changes: 30 additions & 0 deletions src/controllers/bookmarksController.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import responseUtil from '../utils/responseUtil';
import strings from '../utils/stringsUtil';
import findBookmarks from '../services/bookmarksServices';
import getAccommodation from '../helpers/getAccommodation';
import models from '../database/models';

const { NOT_FOUND } = strings.accommodation.success;
const { YOUR_BOOKMARKS, NO_BOOKMARKS } = strings.bookmarks;
const { getOneAccommodation } = getAccommodation;

class BoookmarksController {
static async viewBookmarks(req, res) {
Expand All @@ -12,6 +16,32 @@ class BoookmarksController {
return responseUtil(res, 200, (!bookmarks.length)
? NO_BOOKMARKS : YOUR_BOOKMARKS, bookmarks);
}

static async bookmark(req, res) {
const { slug } = req.params;
const { id } = req.user.payload;

const available = await getOneAccommodation({ slug, isActivated: true }, id);

if (!available) {
return responseUtil(res, 404, NOT_FOUND);
}

const bookmark = await models.bookmarks.findOne({
where: {
userId: id,
accommodationId: available.id,
}
});

if (!bookmark) {
await models.bookmarks.create({ userId: id, accommodationId: available.id });
return responseUtil(res, 201, 'Accommodation Bookmarked successfully!');
}

await models.bookmarks.destroy({ where: { accommodationId: available.id } });
return responseUtil(res, 200, 'Accommodation Unbookmarked successfully!');
}
}

export default BoookmarksController;
5 changes: 5 additions & 0 deletions src/database/models/accommodations.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ module.exports = (sequelize, DataTypes) => {
sourceKey: 'id',
as: 'ratings'
});
accommodations.hasMany(models.bookmarks, {
targetKey: 'accommodationId',
sourceKey: 'id',
as: 'bookmarks'
});
};
return accommodations;
};
9 changes: 7 additions & 2 deletions src/database/models/bookmarks.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ module.exports = (sequelize, DataTypes) => {
}, {});
bookmarks.associate = function(models) {
// associations can be defined here
bookmarks.belongsTo(models.users, {
as: 'user',
foreignKey: 'userId',
targetKey: 'id'
});
bookmarks.belongsTo(models.accommodations, {
as: 'accommodation',
sourceKey: 'accommodationId',
targetKey: 'id',
foreignKey: 'accommodationId',
targetKey: 'id'
});
};
return bookmarks;
Expand Down
3 changes: 3 additions & 0 deletions src/helpers/ratingsHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ export const getRatings = async (accommodation, userId) => {

if (accommodation) {
const ratings = await accommodation.getRatings();
const bookmarks = await accommodation.getBookmarks();
const hasRated = ratings.some(rating => rating.userId === userId);
const hasBookmarked = bookmarks.some(bookmark => bookmark.userId === userId);
const summation = await ratings.reduce((averageValue, cuurentValue) => averageValue + cuurentValue.rating, 0);
const averageRating = summation / ratings.length;
accommodation.dataValues.hasRated = hasRated;
accommodation.dataValues.hasBookmarked = hasBookmarked;
accommodation.dataValues.averageRating = averageRating;
accommodation.dataValues.ratings = ratings;
}
Expand Down
30 changes: 30 additions & 0 deletions src/routes/api/accommodations.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import express from 'express';
import multipart from 'connect-multiparty';
import AccommodationController from '../../controllers/accommodationController';
import BookmarkController from '../../controllers/bookmarksController';
import validateToken from '../../middlewares/auth/validateToken';
import InputValidation from '../../middlewares/inputValidation';
import checkRole from '../../middlewares/checkRole';
Expand Down Expand Up @@ -33,6 +34,8 @@ const {
viewOneBooking,
} = AccommodationController;

const { bookmark } = BookmarkController;

const {
validateAddNew,
validateImage,
Expand Down Expand Up @@ -288,6 +291,32 @@ const { checkSupplierRole, checkBookingRole } = checkRole;
* '404':
* description: No Booking Found!
*/
/**
* @swagger
* /accommodations/{slug}/bookmark:
* get:
* security:
* - bearerAuth: []
* tags:
* - Accommodations
* name: Bookmark an accommodation
* summary: Bookmark an accommodation
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: slug
* in: path
* schema:
* type: string
* example: isimbi-hotel
* responses:
* '200':
* description: Accommodation Bookmarked/Unbookmarked Successfully!
* '404':
* description: No Accommodation Found!
*/

router.post('/', validateToken, checkSupplierRole, catchEmptyForm, multipartMiddleware, validateAddNew, validateExistence, validateImage, createAccommodation);
router.get('/', validateToken, getAllAccommodations);
Expand All @@ -297,6 +326,7 @@ router.get('/bookings', validateToken, viewBookings);
router.get('/bookings/search', validateToken, checkSupplierRole, wrongQuery, catchSearchQueries, validateStatusQuery, findStatusId, searchBookings);
router.patch('/book', validateToken, checkBookingRole, validateBooking, bookAccommdation);
router.get('/:slug', validateToken, viewSpecificAccommodation);
router.post('/:slug/bookmark', validateToken, bookmark);
router.patch('/activate/:slug', validateToken, validateReasons, accommodationActivation);
router.get('/admin/deactivated', validateToken, viewDeactivated);
router.patch('/bookings/:action/:id', validateToken, checkSupplierRole, checkId, wrongAction, bookingFound, bookingNotPending, changeStatus);
Expand Down
92 changes: 62 additions & 30 deletions src/tests/bookmarkTests.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,78 @@ console.log(userToken);
const userToken2 = generateToken(mockData.verifiedUser3);
const wrongToken = 'wrongToken'

describe("Bookmarks tests", ()=> {

it('it should retrieve all bookmarks for the logged in user', done => {
chai.request(app)
.get('/api/v1/bookmarks')
.set('Authorization', `Bearer ${userToken}`)
.end((err, res) => {
console.log(userToken);
res.should.have.status(200);
done();
});
});

it('it should reject an invalid token', done => {
describe("~~~~~ Bookmarks Tests ~~~~~", ()=> {
it('it should retrieve all bookmarks for the logged in user', done => {
chai.request(app)
.get('/api/v1/bookmarks')
.set('Authorization', `Bearer ${wrongToken}`)
.set('Authorization', `Bearer ${userToken}`)
.end((err, res) => {
res.should.have.status(400);
console.log(userToken);
res.should.have.status(200);
done();
});
});
it('it should reject a missing token', done => {

it('it should reject an invalid token', done => {
chai.request(app)
.get('/api/v1/bookmarks')
.set('Authorization', `Bearer ${wrongToken}`)
.end((err, res) => {
res.should.have.status(400);
done();
});
});
it('it should reject a missing token', done => {
chai.request(app)
.get('/api/v1/bookmarks')
.end((err, res) => {
res.should.have.status(401);
done();
});
});

it('it should tell the user that no bookmarks were found', done => {
chai.request(app)
.get('/api/v1/bookmarks')
.set('Authorization', `Bearer ${userToken2}`)
.end((err, res) => {
res.should.have.status(401);
console.log(res.body);

res.should.have.status(200);
done();
});
});
});

it('it should tell the user that no bookmarks were found', done => {
chai.request(app)
.get('/api/v1/bookmarks')
.set('Authorization', `Bearer ${userToken2}`)
.end((err, res) => {
console.log(res.body);

res.should.have.status(200);
done();
});
it('Should return a 404 error, accommodation not found', done => {
chai.request(app)
.post('/api/v1/accommodations/no-hotel/bookmark')
.set('Authorization', `Bearer ${userToken}`)
.end((err, res) => {
console.log(res.body);
res.should.have.status(404);
done();
});
});
});

it('Should bookmark an accommodation, 201 status', done => {
chai.request(app)
.post('/api/v1/accommodations/el-gorillaz/bookmark')
.set('Authorization', `Bearer ${userToken}`)
.end((err, res) => {
console.log(res.body);
res.should.have.status(201);
done();
});
});

it('Should unbookmark an accommodation, 200 status', done => {
chai.request(app)
.post('/api/v1/accommodations/el-gorillaz/bookmark')
.set('Authorization', `Bearer ${userToken}`)
.end((err, res) => {
console.log(res.body);
res.should.have.status(200);
done();
});
});
});

0 comments on commit d76c2db

Please sign in to comment.