Skip to content

Commit 6fccc41

Browse files
committed
feat(request comments): request comments
- setup controller for user to comment on requests - setup route for user to comment on requests - setup unit test for user to comment on requests route [Delivers #167750066]
1 parent d580d86 commit 6fccc41

File tree

13 files changed

+614
-4
lines changed

13 files changed

+614
-4
lines changed

src/controllers/accommodationController.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-unused-expressions */
12
import models from '../models';
23
import { successResponse, errorResponse } from '../utils';
34

src/controllers/commentsController.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import models from '../models';
2+
import { successResponse, errorResponse, status } from '../utils';
3+
4+
const { Comments, Requests, Users } = models;
5+
6+
const association = [
7+
{
8+
model: Users,
9+
as: 'theUser',
10+
attributes: ['id', 'firstName', 'lastName', 'email']
11+
}
12+
];
13+
14+
/**
15+
* @class CommentsController
16+
* @description Controllers for handling travel requests comments
17+
* @exports CommentsController
18+
*/
19+
class CommentsController {
20+
/**
21+
* @method addComment
22+
* @description Method to add comment to requests
23+
* @param {object} req - The Request Object
24+
* @param {object} res - The Response Object
25+
* @returns {object} Newly added request comment
26+
*/
27+
static async addComment(req, res) {
28+
const { userId } = req.user;
29+
const { requestId } = req.params;
30+
const { comment } = req.body;
31+
try {
32+
const existingRequest = await Requests.findOne({
33+
where: { id: requestId }
34+
});
35+
if (!existingRequest) {
36+
return errorResponse(res, status.notfound, 'Request does not exist');
37+
}
38+
const commentAdded = await Comments.create({ comment, userId, requestId });
39+
const response = commentAdded.toJSON();
40+
return successResponse(res, status.created, 'Comment added successfully', response);
41+
} catch (error) {
42+
return errorResponse(res, status.error, 'Error adding comment');
43+
}
44+
}
45+
46+
/**
47+
* @method getSingleComment
48+
* @description Method to get a comment
49+
* @param {object} req - The Request Object
50+
* @param {object} res - The Response Object
51+
* @returns {object} retrieved comment details
52+
*/
53+
static async getCommentById(req, res) {
54+
const { commentId } = req.params;
55+
try {
56+
const getComment = await Comments.findOne({ where: { id: commentId }, include: association });
57+
if (!getComment) {
58+
return errorResponse(res, status.notfound, 'Comment not found');
59+
}
60+
const response = getComment.toJSON();
61+
return successResponse(res, status.success, 'Comment retrieved successfully', response);
62+
} catch (error) {
63+
return errorResponse(res, status.error, 'Error retrieving comment');
64+
}
65+
}
66+
67+
/**
68+
* @method updateComment
69+
* @description Method to update comment
70+
* @param {object} req - The Request Object
71+
* @param {object} res - The Response Object
72+
* @returns {object} updated comment details
73+
*/
74+
static async updateCommentById(req, res) {
75+
const { commentId } = req.params;
76+
const { comment } = req.body;
77+
try {
78+
const getComment = await Comments.findOne({ where: { id: commentId } });
79+
if (!getComment) {
80+
return errorResponse(res, status.notfound, 'Comment not found');
81+
}
82+
await Comments.update({ comment }, { where: { id: commentId } });
83+
return successResponse(res, status.success, 'Comment updated successfully');
84+
} catch (error) {
85+
return errorResponse(res, status.error, 'Error updating comment');
86+
}
87+
}
88+
89+
/**
90+
* @method deleteComment
91+
* @description Method to delete comment
92+
* @param {object} req - The Request Object
93+
* @param {object} res - The Response Object
94+
* @returns {object} deleted comment details
95+
*/
96+
static async deleteCommentById(req, res) {
97+
const { commentId } = req.params;
98+
try {
99+
const getComment = await Comments.findByPk(commentId);
100+
if (!getComment) {
101+
return errorResponse(res, status.notfound, 'Comment not found');
102+
}
103+
await Comments.destroy({ where: { id: commentId } });
104+
return successResponse(res, status.success, 'Comment deleted successfully');
105+
} catch (error) {
106+
return errorResponse(res, status.error, 'Error deleting comment');
107+
}
108+
}
109+
110+
/**
111+
* @method getAllCommentsOnRequest
112+
* @description Method to get all comments on requests
113+
* @param {object} req - The Request Object
114+
* @param {object} res - The Response Object
115+
* @returns {object} retrieved comments details
116+
*/
117+
static async getAllCommentsOnRequest(req, res) {
118+
const { requestId } = req.params;
119+
try {
120+
const existingRequest = await Requests.findOne({ where: { id: requestId } });
121+
if (!existingRequest) {
122+
return errorResponse(res, status.notfound, 'Request not found');
123+
}
124+
const response = await Comments.findAll({ where: { requestId }, include: association });
125+
return successResponse(res, status.success, 'Comments retrieved successfully', response);
126+
} catch (error) {
127+
return errorResponse(res, status.error, 'Error retrieving comments');
128+
}
129+
}
130+
}
131+
132+
export default CommentsController;

src/controllers/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import UsersController from './users';
22
import ResetPasswordController from './resetPassword';
33
import AccommodationController from './accommodationController';
44
import RoomController from './roomController';
5+
import CommentsController from './commentsController';
56

67
export {
78
UsersController, ResetPasswordController,
8-
AccommodationController, RoomController
9+
AccommodationController, RoomController, CommentsController
910
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export default {
2+
up: queryInterface => queryInterface.bulkInsert(
3+
'Requests',
4+
[
5+
{
6+
id: '2b770fbc-76e6-4b5a-afab-882759fd1f06',
7+
status: 'pending',
8+
accommodationId: '2b770fbc-76e6-4b5a-afab-882759fd1f06',
9+
userId: 'e71c28fd-73d8-4d92-9125-ab3d022093b9'
10+
},
11+
{
12+
id: 'b356097c-c6d0-4a3d-85f6-33bc2595c974',
13+
status: 'rejected',
14+
accommodationId: '2b770fbc-76e6-4b5a-afab-882759fd1f06',
15+
userId: 'e71c28fd-73d8-4d92-9125-ab3d022093b0'
16+
},
17+
{
18+
id: '777f640e-a2ff-45ee-9ce1-bf37645c42d6',
19+
status: 'approved',
20+
accommodationId: '2b770fbc-76e6-4b5a-afab-882759fd1f06',
21+
userId: '7aa38d4e-7fbf-4067-8821-9c27d2fb6e3a'
22+
},
23+
],
24+
{}
25+
),
26+
27+
down: queryInterface => queryInterface.bulkDelete('Requests', null, {})
28+
};
29+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
export default {
2+
up: queryInterface => queryInterface.bulkInsert(
3+
'Comments',
4+
[
5+
{
6+
id: '2b770fbc-76e6-4b5a-afab-882759fd1f06',
7+
comment: 'my added comment',
8+
userId: 'e71c28fd-73d8-4d92-9125-ab3d022093b9',
9+
requestId: '2b770fbc-76e6-4b5a-afab-882759fd1f06'
10+
},
11+
{
12+
id: 'b356097c-c6d0-4a3d-85f6-33bc2595c974',
13+
comment: 'my added comment',
14+
userId: 'e71c28fd-73d8-4d92-9125-ab3d022093b0',
15+
requestId: '2b770fbc-76e6-4b5a-afab-882759fd1f06'
16+
},
17+
{
18+
id: '777f640e-a2ff-45ee-9ce1-bf37645c42d6',
19+
comment: 'mu added comment',
20+
userId: '7aa38d4e-7fbf-4067-8821-9c27d2fb6e3a',
21+
requestId: '2b770fbc-76e6-4b5a-afab-882759fd1f06',
22+
},
23+
],
24+
{}
25+
),
26+
27+
down: queryInterface => queryInterface.bulkDelete('Comments', null, {})
28+
};
29+

src/models/Comment.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export default (sequelize, DataTypes) => {
66
},
77
}, {});
88
Comment.associate = (models) => {
9-
Comment.belongsTo(models.Users, { as: 'theComment', foreignKey: 'userId' });
9+
Comment.belongsTo(models.Users, { as: 'theUser', foreignKey: 'userId' });
10+
Comment.belongsTo(models.Requests, { as: 'theRequest', foreignKey: 'requestId' });
1011
};
1112
return Comment;
1213
};

src/routes/api/comments.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Router } from 'express';
2+
import { CommentsController } from '../../controllers';
3+
import middlewares from '../../middlewares';
4+
5+
const router = new Router();
6+
7+
const { validate, Authenticate } = middlewares;
8+
const { verifyToken } = Authenticate;
9+
10+
const {
11+
addComment, getCommentById, deleteCommentById, updateCommentById, getAllCommentsOnRequest
12+
} = CommentsController;
13+
14+
router.post('/requests/:requestId/comments', verifyToken, validate('addComment'), addComment);
15+
router.get('/comments/:commentId', verifyToken, getCommentById);
16+
router.patch('/comments/:commentId', verifyToken, validate('addComment'), updateCommentById);
17+
router.delete('/comments/:commentId', verifyToken, deleteCommentById);
18+
router.get('/requests/:requestId/comments', verifyToken, getAllCommentsOnRequest);
19+
20+
21+
export default router;

src/routes/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import profileRoutes from './api/profile';
55
import resetPasswordRoute from './api/resetPassword';
66
import accommodationRoute from './api/accommodation';
77
import roomRoute from './api/room';
8+
import commentsRoute from './api/comments';
9+
810

911
const router = new Router();
1012

@@ -14,5 +16,7 @@ router.use('/', roomRoute);
1416
router.use('/auth', authRoutes);
1517
router.use('/users', userRoute);
1618
router.use('/profiles', profileRoutes);
19+
router.use('/', commentsRoute);
20+
1721

1822
export default router;

src/services/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable import/prefer-default-export */
12
import sendEmail from './autoMailer';
23

34
export { sendEmail };

0 commit comments

Comments
 (0)