Skip to content

Commit

Permalink
ft(feedback):get all feedback
Browse files Browse the repository at this point in the history
Allows a super admin/travel admin to get all feedback for an accommodation

[Finishes #168250889]
  • Loading branch information
parkerthegeniuschild committed Sep 10, 2019
1 parent 1e7e090 commit 4fd3c36
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 7 deletions.
41 changes: 41 additions & 0 deletions src/controllers/feedback.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import models from '../db/models';
import Response from '../utils/response.utils';

const { Feedback, Facility, User } = models;

/**
* This class controls the feedback for facilities
*/
export default class FeedbackController {
/**
* @param {Object} req Contains the param from the URL
* @param {Object} res List of responses returned to the user
* @returns {array} An array of objects containing feedback
*/
static findAll(req, res) {
Facility.findByPk(req.params.id)
.then((data) => {
if (!data) {
return Response.CustomError(res, 404, 'error',
`No facility found with ID: ${req.params.id}`, 'Consult the facility Admin');
}
Feedback.findAll({
where: { facility_id: req.params.id },
attributes: ['id', 'facility_id', 'feedback', 'created_at', 'updated_at'],
include: [{
model: User,
as: 'user',
attributes: ['id', 'first_name', 'last_name']
}],
})
.then((data) => {
if (data.length) {
return Response.Success(res, data, 200);
}
return Response.CustomError(res, 404, 'error', 'No feedback found for this facility',
'Please check again later');
});
})
.catch((err) => Response.InternalServerError(res, err));
}
}
3 changes: 2 additions & 1 deletion src/db/models/feedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ module.exports = (sequelize, DataTypes) => {
allowNull: false
}
}, {
tableName: 'feedback',
tableName: 'feedbacks',
underscored: true
});
Feedback.associate = (models) => {
Feedback.belongsTo(models.User, {
foreignKey: 'user_id',
as: 'user',
onDelete: 'CASCADE'
});
Feedback.belongsTo(models.Facility, {
Expand Down
14 changes: 14 additions & 0 deletions src/middlewares/auth.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,18 @@ export default {
});
}
},

isAdmin: (req, res, next) => {
const { role } = req.body;

if (role !== 'super_admin' && role !== 'travel_admin') {
return res.status(401).json({
status: 'error',
error: {
message: 'Auth Error: Only SuperAdmins/Travel Admins can perform this operation'
},
});
}
return next();
},
};
10 changes: 10 additions & 0 deletions src/routes/api/feedback.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import express from 'express';
import Auth from '../../middlewares/auth.middleware';
import FeedbackController from '../../controllers/feedback.controller';
import Validator from '../../validation/index';

const router = express.Router();

router.get('/feedback/facility/:id', Auth.verifyToken, Auth.isAdmin, Validator.facilityID, FeedbackController.findAll);

export default router;
4 changes: 3 additions & 1 deletion src/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import CommentRoutes from './api/comment.router';
import UserRouter from './api/user.router';
import FacilitiesRouter from './api/facilities.router';
import RatingRouter from './api/rating.router';
import FeedbackRouter from './api/feedback.router';

const router = [RequestsRoutes, AuthRouter, UserRouter, CommentRoutes, FacilitiesRouter, RatingRouter];
const router = [RequestsRoutes, AuthRouter, UserRouter, CommentRoutes,
FacilitiesRouter, RatingRouter, FeedbackRouter];

export default router;
125 changes: 125 additions & 0 deletions src/test/feedback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import chai from 'chai';
import chaiHttp from 'chai-http';
import sinon from 'sinon';
import Sinonchai from 'sinon-chai';
import app from '../index';
import JWTService from '../services/jwt.service';
import FeedbackController from '../controllers/feedback.controller';

chai.use(Sinonchai);
chai.use(chaiHttp);
chai.should();

const feedbackEndpoint = '/api/v1/feedback/facility';

let superAdminToken = `Bearer ${JWTService.generateToken({ id: 3, role: 'super_admin'})}`;
let travelAdminToken = `Bearer ${JWTService.generateToken({ id: 9, role: 'travel_admin'})}`;
let userToken = `Bearer ${JWTService.generateToken({ id: 1, role: 'requester'})}`;

describe('/GET FEEDBACK', () => {

it('should allow only logged in users', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/1`)
.set('Authorization', '')
.end((err, res) => {
res.should.have.status(403);
res.body.should.have.property('status').eql('error');
done();
})
});

it('should allow Super Admins', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/1`)
.set('Authorization', superAdminToken)
.end((err, res) => {
res.should.have.status(200);
res.body.should.have.property('status').eql('success');
done();
})
});

it('should allow Travel Admins', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/1`)
.set('Authorization', travelAdminToken)
.end((err, res) => {
res.should.have.status(200);
res.body.should.have.property('status').eql('success');
done();
})
});

it('should deny users who are NOT Super Admins', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/1`)
.set('Authorization', userToken)
.end((err, res) => {
res.should.have.status(401);
res.body.should.have.property('status').eql('error');
done();
})
});

it('should return 404 if facility does not exist', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/1000`)
.set('Authorization', superAdminToken)
.end((err, res) => {
res.should.have.status(404);
res.body.should.have.property('status').eql('error');
done();
})
});

it('should return 404 if no feedback is found for a facility', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/3`)
.set('Authorization', superAdminToken)
.end((err, res) => {
res.should.have.status(404);
res.body.should.have.property('status').eql('error');
done();
})
});

it('should return 200 if feedback is found for a facility', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/1`)
.set('Authorization', superAdminToken)
.end((err, res) => {
res.should.have.status(200);
res.body.should.have.property('status').eql('success');
done();
})
});

it('should return 400 on invalid facility ID', (done) => {
chai.request(app)
.get(`${feedbackEndpoint}/a`)
.set('Authorization', superAdminToken)
.end((err, res) => {
res.should.have.status(400);
res.body.should.have.property('status').eql('error');
done();
})
});

it('should return 500 if something goes wrong', (done) => {
const req = {
params: {}
};

const res = {
status() {},
send() {}
};

sinon.stub(res, 'status').returnsThis();

FeedbackController.findAll(req, res);
(res.status).should.have.callCount(0);
done();
});
});
60 changes: 55 additions & 5 deletions swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
{
"name": "Comment",
"description": "Endpoint for Comments"
}
}
],
"paths": {
"/auth/signup": {
Expand Down Expand Up @@ -240,6 +240,56 @@
}
}
},
"/feedback/facility/{id}": {
"get": {
"description": "Get feedback for a facility by ID",
"summary": "Returns feedback for a single facility",
"tags": [
"Feedback"
],
"produces": [
"application/json"
],
"security": [],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"required": true,
"description": "ID of facility to check for feedback"
},
{
"name": "Authorization",
"in": "header",
"required": true,
"type": "string",
"description": "Supply the 'Bearer <token>'"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Facility-Feedback"
}
},
"400": {
"description": "Invalid ID supplied"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Facility not found"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/requests/:id": {
"patch": {
"description": "A manager can reject a user's request application",
Expand Down Expand Up @@ -349,7 +399,7 @@
}
}
},
"/facilities/rooms": {
"/facilities/rooms": {
"post": {
"description": "Rooms Endpoint",
"summary": "Travel_Admin/Super_Admin Can add rooms to an Acommodation Facilities",
Expand Down Expand Up @@ -913,7 +963,7 @@
}
]
}
},
},
"postComment": {
"title": "Post Comment on Request",
"type": "object",
Expand Down Expand Up @@ -948,9 +998,9 @@
"example": {
"status": "success",
"data": {
"message": "comment deleted successfully"
"message": "comment deleted successfully"
}
}
}
}
}
}

0 comments on commit 4fd3c36

Please sign in to comment.