Skip to content

Commit

Permalink
feat(Bookmark Articles): Refactor Bookmark Controller- Create a helpe…
Browse files Browse the repository at this point in the history
…r function to handle check for resource existence- Refactor bookmark controller using helper functionfinishes #162414285
  • Loading branch information
Steve Onyeneke authored and Steve Onyeneke committed Jan 30, 2019
1 parent 35b838b commit c4a4018
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 139 deletions.
82 changes: 23 additions & 59 deletions server/controllers/BookmarkController.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import db from '../models';
import response from '../helpers/response';
import Util from '../helpers/Util';

const { Bookmark, Article, User } = db;

Expand All @@ -9,29 +10,29 @@ const { Bookmark, Article, User } = db;
class BookmarkController {
/**
* @static
* @description Method to create bookmark for an article
* @description Method to create or delete bookmarks on an article
* @param {object} req HTTP request object
* @param {object} res HTTP response object
* @returns {object} api route response
*/
static async create(req, res) {
static async createOrRemove(req, res) {
try {
const { slug } = req.params;
const { userId } = req.user;
const articleFound = await Article.findOne({
where: {
slug
}
});
if (!articleFound) return response(res, 404, 'failure', 'Article not found');
const user = await User.findByPk(userId);
if (!user) return response(res, 404, 'failure', 'User not found');

Bookmark.findOrCreate({
where: { userId, articleSlug: slug },
const { slug } = req.params;
const article = await Util.resourceExists(Article, { slug });
if (!article) return response(res, 404, 'failure', 'Article not found');

await Bookmark.findOrCreate({
where: { userId, articleId: article.dataValues.id },
}).spread((bookmark, created) => {
if (created) {
return response(res, 201, 'success', 'You have successfully bookmarked this article', null, bookmark);
}
return response(res, 403, 'failure', 'You have already bookmarked this article');
bookmark.destroy();
return response(res, 200, 'success', 'Bookmark removed successfully');
});
} catch (error) {
return response(res, 500, 'failure', 'Something went wrong on the server', `server error: ${error.message}`);
Expand All @@ -47,22 +48,22 @@ class BookmarkController {
*/
static async getArticleBookmarks(req, res) {
try {
const { slug } = req.params;
const { userId } = req.user;
const user = await User.findByPk(userId);
if (!user) return response(res, 404, 'failure', 'User not found');

const articleFound = await Article.findOne({
where: {
slug
}
});
if (!articleFound) return response(res, 404, 'failure', 'Article not found');
const { slug } = req.params;
const article = await Util.resourceExists(Article, { slug });
if (!article) return response(res, 404, 'failure', 'Article not found');

const bookmarksQuery = await Bookmark.findAll({
attributes: { exclude: ['userId'] },
include: [{
model: User,
attributes: ['userName', 'bio', 'img']
}],
where: {
articleSlug: slug
articleId: article.dataValues.id
},
});
if (bookmarksQuery.length === 0) {
Expand All @@ -86,14 +87,9 @@ class BookmarkController {
static async getUserBookmarks(req, res) {
try {
const { userId } = req.user;
const { userName } = req.params;
const user = await User.findOne({
where: {
userName
}
});
const user = await User.findByPk(userId);
if (!user) return response(res, 404, 'failure', 'User not found');
if (userId !== user.id) return response(res, 401, 'failure', 'Sorry, you are not authorized to view this resource');

const bookmarksQuery = await Bookmark.findAll({
where: {
userId: user.dataValues.id
Expand All @@ -109,37 +105,5 @@ class BookmarkController {
return response(res, 500, 'failure', 'Something went wrong on the server', `server error: ${error.message}`);
}
}

/**
* @static
* @description Method to handle deleting a single user's bookmark
* @param {object} req HTTP request object
* @param {object} res HTTP response object
* @returns {object} api route response
*/
static async delete(req, res) {
try {
const { userId } = req.user;
const { slug } = req.params;
const article = await Article.findOne({
where: {
slug
}
});
if (!article) return response(res, 404, 'failure', 'Article not found');

const bookmark = await Bookmark.findOne({
where: {
articleSlug: slug,
userId,
}
});
if (!bookmark) return response(res, 404, 'failure', 'Bookmark not found');
await bookmark.destroy();
return response(res, 200, 'success', 'Bookmark removed successfully');
} catch (error) {
return response(res, 500, 'failure', 'Something went wrong on the server', `server error: ${error.message}`);
}
}
}
export default BookmarkController;
14 changes: 14 additions & 0 deletions server/helpers/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ class Util {
const date = `${new Date(dateString).toDateString()} ${new Date(dateString).toLocaleTimeString()}`;
return date;
}

/**
* @static
* @description a function to ascertain if a resource exists
* @param {object} model Model to check for resource existence
* @param {object} data
* @returns {object} returns resource if true or null otherwise
*/
static async resourceExists(model, data) {
const resource = await model.findOne({
where: data
});
return resource;
}
}

export default Util;
2 changes: 1 addition & 1 deletion server/middlewares/AuthMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class AuthMiddleware {
* @param {function} next next middleware function
* @returns {object} returns error message if user is not authenticated
*/
static checkIfUserIsAuthenticated(req, res, next) {
static async checkIfUserIsAuthenticated(req, res, next) {
try {
const { authorization } = req.headers;
if (!authorization) {
Expand Down
Empty file removed server/migrations/.gitkeep
Empty file.
34 changes: 34 additions & 0 deletions server/migrations/20190111130817-create-commentLike.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export default {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";')
.then(() => {
return queryInterface.createTable('CommentLikes', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID,
defaultValue: Sequelize.literal('uuid_generate_v4()')
},
userId: {
type: Sequelize.UUID,
allowNull: false
},
commentId: {
type: Sequelize.UUID,
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
}
});
});
},
down: (queryInterface, Sequelize) => queryInterface.dropTable('CommentLikes')
};
8 changes: 3 additions & 5 deletions server/routes/api/bookmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import BookmarkController from '../../controllers/BookmarkController';
import AuthMiddleware from '../../middlewares/AuthMiddleware';

const bookmarkRoutes = Router();
const path = '/articles/:slug/bookmark';

bookmarkRoutes.post(path, AuthMiddleware.checkIfUserIsAuthenticated, BookmarkController.create);
bookmarkRoutes.get(`${path}s`, AuthMiddleware.checkIfUserIsAuthenticated, BookmarkController.getArticleBookmarks);
bookmarkRoutes.get('/users/:userName/bookmarks', AuthMiddleware.checkIfUserIsAuthenticated, BookmarkController.getUserBookmarks);
bookmarkRoutes.delete(path, AuthMiddleware.checkIfUserIsAuthenticated, BookmarkController.delete);
bookmarkRoutes.post('/articles/:slug/bookmark', AuthMiddleware.checkIfUserIsAuthenticated, BookmarkController.createOrRemove);
bookmarkRoutes.get('/articles/:slug/bookmarks', AuthMiddleware.checkIfUserIsAuthenticated, BookmarkController.getArticleBookmarks);
bookmarkRoutes.get('/user/bookmarks', AuthMiddleware.checkIfUserIsAuthenticated, BookmarkController.getUserBookmarks);

export default bookmarkRoutes;
Loading

0 comments on commit c4a4018

Please sign in to comment.