Skip to content

Commit

Permalink
Merge pull request #4439 from NMDSdevopsServiceAdm/test
Browse files Browse the repository at this point in the history
Live: Admin parent requests and removing parent status button
  • Loading branch information
Richard-Pentecost authored Jan 4, 2022
2 parents 482e92e + 7b3a44d commit 6a73e70
Show file tree
Hide file tree
Showing 55 changed files with 1,992 additions and 1,062 deletions.
2 changes: 1 addition & 1 deletion server.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ app.use(compression());
app.use(function (req, res, next) {
if (toobusy()) {
res.setHeader('Retry-After', '1');
res.send(503, 'Server busy, try again later');
res.status(503).send('Server busy, try again later');
} else {
next();
}
Expand Down
13 changes: 12 additions & 1 deletion server/models/establishment.js
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,11 @@ module.exports = function (sequelize, DataTypes) {
as: 'notes',
onDelete: 'CASCADE',
});
Establishment.hasMany(models.establishment, {
foreignKey: 'parentId',
sourceKey: 'id',
as: 'Subsidiaries',
});
};

Establishment.turnoverData = function (establishmentId) {
Expand Down Expand Up @@ -980,6 +985,12 @@ module.exports = function (sequelize, DataTypes) {
as: 'Parent',
required: false,
},
{
model: sequelize.models.establishment,
attributes: ['NameValue'],
as: 'Subsidiaries',
required: false,
},
{
model: sequelize.models.user,
attributes: ['id', 'uid', 'FullNameValue', 'SecurityQuestionValue', 'SecurityQuestionAnswerValue'],
Expand All @@ -992,7 +1003,7 @@ module.exports = function (sequelize, DataTypes) {
include: [
{
model: sequelize.models.login,
attributes: ['username', 'status'],
attributes: ['username', 'isActive'],
},
],
},
Expand Down
1 change: 1 addition & 0 deletions server/routes/admin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ router.use('/unlock-account', require('./unlock-account'));
router.use('/email-campaigns', require('./email-campaigns'));
router.use('/move-workplace', require('./move-workplace'));
router.use('/local-authority-return', require('./local-authority-return'));
router.use('/remove-parent-status', require('./remove-parent-status'));

router.route('/').post(async function (req, res) {
return res.status(200).send({ success: 'from admin' });
Expand Down
25 changes: 25 additions & 0 deletions server/routes/admin/parent-approval/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const express = require('express');
const router = express.Router();
const models = require('../../../models');
const notifications = require('../../../data/notifications');
const { convertIndividualParentRequest } = require('../../../utils/parentIndividualRequestUtils');
const uuid = require('uuid');

const parentApprovalConfirmation = 'Parent request approved';
Expand All @@ -18,6 +19,27 @@ const getParentRequests = async (req, res) => {
}
};

const getIndividualParentRequest = async (req, res) => {
try {
const { establishmentUid } = req.params;
const establishment = await models.establishment.findByUid(establishmentUid);

if (!establishment) {
return res.status(400).json({
message: 'Establishment could not be found',
});
}

const individualParentRequest = await models.Approvals.findbyEstablishmentId(establishment.id, 'BecomeAParent');

const convertedIndividualParentRequest = convertIndividualParentRequest(individualParentRequest);
res.status(200).send(convertedIndividualParentRequest);
} catch (error) {
console.error(error);
res.status(500).json({ message: 'There was an error retrieving the parent request' });
}
};

const parentApproval = async (req, res) => {
try {
if (req.body.approve) {
Expand Down Expand Up @@ -106,10 +128,13 @@ const _notify = async (approvalId, userUid, establishmentId) => {

router.route('/').post(parentApproval);
router.route('/').get(getParentRequests);
router.route('/:establishmentUid').get(getIndividualParentRequest);
router.use('/updateStatus', require('./updateStatus.js'));

module.exports = router;
module.exports.parentApproval = parentApproval;
module.exports.getParentRequests = getParentRequests;

module.exports.getIndividualParentRequest = getIndividualParentRequest;
module.exports.parentApprovalConfirmation = parentApprovalConfirmation;
module.exports.parentRejectionConfirmation = parentRejectionConfirmation;
39 changes: 39 additions & 0 deletions server/routes/admin/parent-approval/updateStatus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const models = require('../../../models');

const updateStatus = async (req, res) => {
try {
const { uid, status, reviewer, inReview } = req.body;
const establishment = await models.establishment.findByUid(uid);

if (!establishment) {
return res.status(400).send({ error: 'Workplace could not be found' });
}

const approval = await models.Approvals.findbyEstablishmentId(establishment.id, 'BecomeAParent');

if (!approval) {
return res.status(400).send({ error: 'Parent request could not be found' });
}

if (approval.InReview && reviewer && approval.Reviewer !== reviewer) {
return res.status(400).send({ error: 'This parent request is already being reviewed' });
}

approval.Status = status;
approval.Reviewer = reviewer;
approval.InReview = inReview;
await approval.save();

res.status(200).send();
} catch (error) {
console.log(error);
res.status(500).send();
}
};

const router = require('express').Router();

router.route('/').post(updateStatus);

module.exports = router;
module.exports.updateStatus = updateStatus;
25 changes: 25 additions & 0 deletions server/routes/admin/remove-parent-status/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const express = require('express');
const models = require('../../../models');
const router = express.Router({ mergeParams: true });

const removeParentStatus = async (req, res) => {
try {
const { establishmentId } = req.body;
const workplace = await models.establishment.findByUid(establishmentId);
if (!workplace) {
return res.status(400).json({ message: 'Establishment could not be found' });
}
await models.establishment.updateEstablishment(workplace.id, {
isParent: false,
});
res.status(200).send();
} catch (error) {
console.error(error);
res.status(500).json({ message: 'There was an error removing parent status' });
}
};

router.route('/').post(removeParentStatus);

module.exports = router;
module.exports.removeParentStatus = removeParentStatus;
138 changes: 138 additions & 0 deletions server/test/unit/routes/admin/parent-approval/updateStatus.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
chai.should();
chai.use(sinonChai);
const httpMocks = require('node-mocks-http');

const models = require('../../../../../models');

const { updateStatus } = require('../../../../../routes/admin/parent-approval/updateStatus');

describe('updateStatus', () => {
let req;
let res;

const dummyDetails = {
Status: 'Pending',
UUID: 'bbd54f18-f0bd-4fc2-893d-e492faa9b278',
ID: 1,
InReview: false,
Reviewer: null,
User: { FullNameValue: 'Joe Bloggs', RegistrationID: 1 },
Establishment: {
id: 1,
uid: 'f61696f7-30fe-441c-9c59-e25dfcb51f59',
nmdsId: 'J111111',
NameValue: 'Workplace 1',
address1: 'Care Home 1',
address2: '31 King Street',
address3: 'Sale',
town: 'Manchester',
county: 'Cheshire',
postcode: 'CA1 2BD',
},
save() {
return true;
},
};

beforeEach(() => {
const request = {
method: 'POST',
body: {
status: 'In progress',
uid: 'someuid',
reviewer: 'admin',
inReview: true,
},
};

req = httpMocks.createRequest(request);
res = httpMocks.createResponse();

sinon.stub(models.Approvals, 'findbyEstablishmentId').returns(dummyDetails);
sinon.stub(models.establishment, 'findByUid').returns({ id: 123 });
});

afterEach(() => {
sinon.restore();
});

it('should return 200 when the pending flag gets updated', async () => {
await updateStatus(req, res);

expect(res.statusCode).to.deep.equal(200);
});

it('should return 200 when the approval is In progress but being reviewed by the person making the request', async () => {
const newDummyDetails = { ...dummyDetails, Status: 'In progress', Reviewer: 'admin', InReview: true };

sinon.restore();
sinon.stub(models.Approvals, 'findbyEstablishmentId').returns(newDummyDetails);
sinon.stub(models.establishment, 'findByUid').returns({ id: 123 });

await updateStatus(req, res);

expect(res.statusCode).to.deep.equal(200);
});

it('should return 400 when the establishment cannot be found', async () => {
sinon.restore();
sinon.stub(models.establishment, 'findByUid').returns(null);

await updateStatus(req, res);
const expectedResponse = { error: 'Workplace could not be found' };

expect(res.statusCode).to.deep.equal(400);
expect(res._getData()).to.deep.equal(expectedResponse);
});

it('should return 400 when the approval cannot be found', async () => {
sinon.restore();
sinon.stub(models.establishment, 'findByUid').returns({ id: 123 });
sinon.stub(models.Approvals, 'findbyEstablishmentId').returns(null);

await updateStatus(req, res);
const expectedResponse = { error: 'Parent request could not be found' };

expect(res.statusCode).to.deep.equal(400);
expect(res._getData()).to.deep.equal(expectedResponse);
});

it('should return 400 if the approval is already being reviewed by someone else', async () => {
sinon.restore();
sinon.stub(models.establishment, 'findByUid').returns({ id: 123 });
sinon.stub(models.Approvals, 'findbyEstablishmentId').returns({
InReview: true,
Reviewer: 'someoneElse',
status: 'In progress',
});

await updateStatus(req, res);
const expectedResponse = { error: 'This parent request is already being reviewed' };

expect(res.statusCode).to.deep.equal(400);
expect(res._getData()).to.deep.equal(expectedResponse);
});

it('should return 500 when an error is thrown getting the establishment', async () => {
sinon.restore();
sinon.stub(models.establishment, 'findByUid').throws();

await updateStatus(req, res);

expect(res.statusCode).to.deep.equal(500);
});

it('should return 500 when an error is thrown getting the approval', async () => {
sinon.restore();
sinon.stub(models.establishment, 'findByUid').returns({ id: 123 });
sinon.stub(models.Approvals, 'findbyEstablishmentId').throws();

await updateStatus(req, res);

expect(res.statusCode).to.deep.equal(500);
});
});
69 changes: 69 additions & 0 deletions server/test/unit/routes/admin/remove-parent-status/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const expect = require('chai').expect;
const sinon = require('sinon');
const httpMocks = require('node-mocks-http');
const models = require('../../../../../models');

const { removeParentStatus } = require('../../../../../routes/admin/remove-parent-status');

describe('removeParentStatus', () => {
const establishmentId = 'a131313dasd123325453bac';
let req;
let res;

beforeEach(() => {
const request = {
method: 'POST',
url: `/api/establishment/${establishmentId}/remove-parent-status`,
body: {
establishmentId,
},
};

req = httpMocks.createRequest(request);
res = httpMocks.createResponse();
});

afterEach(() => {
sinon.restore();
});

it('should reply with a status of 200', async () => {
sinon.stub(models.establishment, 'findByUid').returns({ id: 1 });
sinon.stub(models.establishment, 'updateEstablishment');

await removeParentStatus(req, res);
expect(res.statusCode).to.deep.equal(200);
});

it('should return 400 error code when given an incorrect establishment ID', async () => {
sinon.stub(models.establishment, 'findByUid').returns(null);

await removeParentStatus(req, res);
const { message } = res._getJSONData();

expect(res.statusCode).to.deep.equal(400);
expect(message).to.equal('Establishment could not be found');
});

it('should return 500 when an error is thrown by updateEstablishment', async () => {
sinon.stub(models.establishment, 'findByUid').throws();

await removeParentStatus(req, res);
const { message } = res._getJSONData();

expect(res.statusCode).to.deep.equal(500);
expect(message).to.equal('There was an error removing parent status');
});

it('should return 500 when an error is thrown by updateEstablishment', async () => {
sinon.stub(models.establishment, 'findByUid').returns({ id: 1 });
sinon.stub(models.establishment, 'updateEstablishment').throws();

await removeParentStatus(req, res);

const { message } = res._getJSONData();

expect(res.statusCode).to.deep.equal(500);
expect(message).to.equal('There was an error removing parent status');
});
});
Loading

0 comments on commit 6a73e70

Please sign in to comment.