diff --git a/src/config/index.ts b/src/config/index.ts index 1b359081b..074b7f22c 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -146,6 +146,7 @@ export const UPDATE_STATEMENT_VALIDATION_ERRORS_PAGE = "update-statement-validat export const REMOVE_SOLD_ALL_LAND_FILTER_PAGE = "remove-sold-all-land-filter"; export const REMOVE_IS_ENTITY_REGISTERED_OWNER_PAGE = "remove-is-entity-registered-owner"; export const REMOVE_CANNOT_USE_PAGE = "remove-cannot-use"; +export const REMOVE_NEED_MAKE_CHANGES_PAGE = "remove-need-to-make-changes-to-entity"; // URL PARAMS export const ROUTE_PARAM_TRUST_ID = "trustId"; @@ -304,6 +305,7 @@ export const UPDATE_PAYMENT_FAILED_URL = UPDATE_AN_OVERSEAS_ENTITY_URL + PAYMENT export const REMOVE_SOLD_ALL_LAND_FILTER_URL = UPDATE_AN_OVERSEAS_ENTITY_URL + REMOVE_SOLD_ALL_LAND_FILTER_PAGE; export const REMOVE_CANNOT_USE_URL = UPDATE_AN_OVERSEAS_ENTITY_URL + REMOVE_CANNOT_USE_PAGE; export const REMOVE_IS_ENTITY_REGISTERED_OWNER_URL = UPDATE_AN_OVERSEAS_ENTITY_URL + REMOVE_IS_ENTITY_REGISTERED_OWNER_PAGE; +export const REMOVE_NEED_MAKE_CHANGES_URL = UPDATE_AN_OVERSEAS_ENTITY_URL + REMOVE_NEED_MAKE_CHANGES_PAGE; // PAYMENT CONFIGs export const PAYMENT = "payment"; diff --git a/src/controllers/index.ts b/src/controllers/index.ts index a850e6804..a15e1fe71 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -101,3 +101,4 @@ export * as updateManageTrustsTellUsAboutTheLegalEntity from './update/update.ma export * as removeSoldAllLandFilter from './update/remove.sold.all.land.filter.controller'; export * as removeCannotUse from "./update/remove.cannot.use.controller"; export * as removeIsEntityRegisteredOwner from "./update/remove.is.entity.registered.owner.controller"; +export * as removeNeedMakeChanges from "./update/remove.need.to.make.changes.to.entity.controller"; diff --git a/src/controllers/update/remove.need.to.make.changes.to.entity.controller.ts b/src/controllers/update/remove.need.to.make.changes.to.entity.controller.ts new file mode 100644 index 000000000..96d4d6881 --- /dev/null +++ b/src/controllers/update/remove.need.to.make.changes.to.entity.controller.ts @@ -0,0 +1,30 @@ +import { NextFunction, Request, Response } from "express"; +import * as config from "../../config"; +import { logger } from "../../utils/logger"; + +export const get = (req: Request, res: Response, next: NextFunction) => { + try { + logger.debugRequest(req, `GET ${config.REMOVE_NEED_MAKE_CHANGES_PAGE}`); + return res.render(config.REMOVE_NEED_MAKE_CHANGES_PAGE, { + journey: config.JourneyType.remove, + backLinkUrl: `${config.OVERSEAS_ENTITY_PRESENTER_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`, + templateName: config.REMOVE_NEED_MAKE_CHANGES_PAGE + }); + } catch (error) { + next(error); + } +}; + +export const post = (req: Request, res: Response, next: NextFunction) => { + try { + logger.debugRequest(req, `POST ${config.REMOVE_NEED_MAKE_CHANGES_PAGE}`); + + if (req.body["make_changes"] === 'yes') { + return res.redirect(`${config.WHO_IS_MAKING_UPDATE_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + } + // TODO redirect to new component - Has the overseas entity identified any registrable beneficial owners? + return res.redirect(`${config.UPDATE_LANDING_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + } catch (error) { + next(error); + } +}; diff --git a/src/routes/index.ts b/src/routes/index.ts index 3a879d8cf..f0d652118 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -45,6 +45,7 @@ import { removeSoldAllLandFilter, removeIsEntityRegisteredOwner, resumeSubmission, + removeNeedMakeChanges, overseasName, startingNew, overseasEntityPayment, @@ -1098,6 +1099,14 @@ router.route(config.UPDATE_STATEMENT_VALIDATION_ERRORS_URL) .get(validateStatements, statementValidationErrorsGuard, updateStatementValidationErrors.get) .post(validateStatements, ...validator.statementResolution, updateStatementValidationErrors.post); +router.route(config.REMOVE_NEED_MAKE_CHANGES_URL) + .all( + authentication, + companyAuthentication, + navigation.hasUpdatePresenter) + .get(removeNeedMakeChanges.get) + .post(...validator.removeNeedMakeChanges, checkValidations, removeNeedMakeChanges.post); + router.get(config.REMOVE_CANNOT_USE_URL, authentication, removeCannotUse.get); export default router; diff --git a/src/utils/navigation.ts b/src/utils/navigation.ts index b2b5a7d05..0cf567252 100644 --- a/src/utils/navigation.ts +++ b/src/utils/navigation.ts @@ -519,4 +519,9 @@ export const NAVIGATION: Navigation = { previousPage: () => `${config.REMOVE_SOLD_ALL_LAND_FILTER_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`, nextPage: [`${config.SECURE_UPDATE_FILTER_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`] }, + [config.REMOVE_NEED_MAKE_CHANGES_URL]: { // TODO set next and previous to specification in ACs on UAR-1285 + currentPage: config.REMOVE_NEED_MAKE_CHANGES_PAGE, + previousPage: () => `${config.WHO_IS_MAKING_FILING_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`, + nextPage: [`${config.WHO_IS_MAKING_UPDATE_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`] + } }; diff --git a/src/validation/error.messages.ts b/src/validation/error.messages.ts index 385cb17ee..541deb74d 100644 --- a/src/validation/error.messages.ts +++ b/src/validation/error.messages.ts @@ -199,6 +199,7 @@ export enum ErrorMessages { SELECT_DO_YOU_WANT_TO_MAKE_CHANGES_UPDATE_STATEMENT = "Select yes if all the information in this update statement is correct", SELECT_UPDATE_STATEMENT_VALIDATION_RESOLUTION = "Select if you want to change your statements or change the information provided in this update", SELECT_IF_REMOVE_SOLD_ALL_LAND_FILTER = "Select yes if the entity has disposed of all its property or land in the UK", + SELECT_REMOVE_NEED_TO_MAKE_CHANGES = "Select yes if you need to make changes to this overseas entity before it is removed", // MAX Lengths MAX_FIRST_NAME_LENGTH = "First name must be 50 characters or less", diff --git a/src/validation/index.ts b/src/validation/index.ts index 46f8c4630..e81ccac2f 100644 --- a/src/validation/index.ts +++ b/src/validation/index.ts @@ -36,6 +36,7 @@ import { doYouWantToMakeOeChange } from "./update/do.you.want.to.make.oe.change. import { reviewUpdateStatementChange, statementResolution } from "./update/review.update.statement.validation"; import { removeSoldAllLandFilter } from "./update/remove.sold.all.land.filter.validation"; import { removeIsEntityRegisteredOwner } from "./update/remove.is.entity.registered.owner.validation"; +import { removeNeedMakeChanges } from "./update/remove.need.to.make.changes.to.entity.validation"; export const validator = { soldLandFilter, secureRegisterFilter, @@ -87,5 +88,6 @@ export const validator = { reviewUpdateStatementChange, statementResolution, removeSoldAllLandFilter, - removeIsEntityRegisteredOwner + removeIsEntityRegisteredOwner, + removeNeedMakeChanges }; diff --git a/src/validation/update/remove.need.to.make.changes.to.entity.validation.ts b/src/validation/update/remove.need.to.make.changes.to.entity.validation.ts new file mode 100644 index 000000000..afd8e8ac6 --- /dev/null +++ b/src/validation/update/remove.need.to.make.changes.to.entity.validation.ts @@ -0,0 +1,7 @@ +import { body } from "express-validator"; + +import { ErrorMessages } from "../error.messages"; + +export const removeNeedMakeChanges = [ + body("make_changes").not().isEmpty().withMessage(ErrorMessages.SELECT_REMOVE_NEED_TO_MAKE_CHANGES) +]; diff --git a/test/__mocks__/text.mock.ts b/test/__mocks__/text.mock.ts index 36224cd95..3c60e90e7 100644 --- a/test/__mocks__/text.mock.ts +++ b/test/__mocks__/text.mock.ts @@ -250,6 +250,7 @@ export const UPDATE_MANAGE_TRUSTS_REVIEWED_HEADING = "What you have reviewed"; export const REMOVE_SOLD_ALL_LAND_FILTER_PAGE_TITLE = "Has the overseas entity disposed of all its property or land in the UK?"; export const REMOVE_IS_ENTITY_REGISTERED_OWNER_TITLE = "Is the overseas entity currently listed on any land registry records as the registered owner of property or land in the UK?"; export const REMOVE_INTERRUPT_CARD_TEXT = "Once an overseas entity is removed"; +export const REMOVE_NEED_MAKE_CHANGES_TITLE = "Do you need to make any changes to this overseas entity before it is removed?"; // Manage Trusts export const UPDATE_MANAGE_TRUSTS_REVIEW_FORMER_BO_TITLE = "Review former beneficial owners"; diff --git a/test/controllers/update/remove.need.to.make.changes.to.entity.controller.spec.ts b/test/controllers/update/remove.need.to.make.changes.to.entity.controller.spec.ts new file mode 100644 index 000000000..f9f2486fc --- /dev/null +++ b/test/controllers/update/remove.need.to.make.changes.to.entity.controller.spec.ts @@ -0,0 +1,116 @@ +jest.mock("ioredis"); +jest.mock("../../../src/utils/logger"); +jest.mock('../../../src/middleware/authentication.middleware'); +jest.mock('../../../src/middleware/company.authentication.middleware'); +jest.mock('../../../src/middleware/service.availability.middleware'); +jest.mock('../../../src/middleware/navigation/update/has.presenter.middleware'); +jest.mock('../../../src/utils/application.data'); + +import { NextFunction, Request, Response } from "express"; +import * as config from "../../../src/config"; +import request from "supertest"; +import { logger } from "../../../src/utils/logger"; +import app from "../../../src/app"; +import { ErrorMessages } from '../../../src/validation/error.messages'; +import { hasUpdatePresenter } from "../../../src/middleware/navigation/update/has.presenter.middleware"; +import { serviceAvailabilityMiddleware } from "../../../src/middleware/service.availability.middleware"; +import { authentication } from "../../../src/middleware/authentication.middleware"; +import { companyAuthentication } from "../../../src/middleware/company.authentication.middleware"; +import { + ANY_MESSAGE_ERROR, + PAGE_TITLE_ERROR, + FOUND_REDIRECT_TO, + REMOVE_NEED_MAKE_CHANGES_TITLE, + SERVICE_UNAVAILABLE, +} from "../../__mocks__/text.mock"; +import { REMOVE_SERVICE_NAME } from "../../../src/config"; +import { getApplicationData } from "../../../src/utils/application.data"; +import { APPLICATION_DATA_CH_REF_UPDATE_MOCK } from "../../__mocks__/session.mock"; + +const mockGetApplicationData = getApplicationData as jest.Mock; + +const mockHasUpdatePresenter = hasUpdatePresenter as jest.Mock; +mockHasUpdatePresenter.mockImplementation((req: Request, res: Response, next: NextFunction) => next() ); + +const mockCompanyAuthenticationMiddleware = companyAuthentication as jest.Mock; +mockCompanyAuthenticationMiddleware.mockImplementation((req: Request, res: Response, next: NextFunction) => next() ); + +const mockAuthenticationMiddleware = authentication as jest.Mock; +mockAuthenticationMiddleware.mockImplementation((req: Request, res: Response, next: NextFunction) => next()); + +const mockServiceAvailabilityMiddleware = serviceAvailabilityMiddleware as jest.Mock; +mockServiceAvailabilityMiddleware.mockImplementation((req: Request, res: Response, next: NextFunction) => next()); + +const mockLoggerDebugRequest = logger.debugRequest as jest.Mock; + +describe("Remove need to make changes to entity controller", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe("GET tests", () => { + test(`renders the ${config.REMOVE_NEED_MAKE_CHANGES_URL} page`, async () => { + mockGetApplicationData.mockReturnValueOnce({ + ...APPLICATION_DATA_CH_REF_UPDATE_MOCK + }); + const resp = await request(app).get(`${config.REMOVE_NEED_MAKE_CHANGES_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + expect(resp.status).toEqual(200); + expect(resp.text).toContain(REMOVE_NEED_MAKE_CHANGES_TITLE); + expect(resp.text).toContain(REMOVE_SERVICE_NAME); + expect(resp.text).not.toContain(PAGE_TITLE_ERROR); + expect(mockLoggerDebugRequest).toHaveBeenCalledTimes(1); + }); + + test("catch error on current page for GET method", async () => { + mockLoggerDebugRequest.mockImplementationOnce(() => { throw new Error(ANY_MESSAGE_ERROR); }); + const resp = await request(app).get(`${config.REMOVE_NEED_MAKE_CHANGES_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + expect(resp.status).toEqual(500); + expect(resp.text).toContain(SERVICE_UNAVAILABLE); + }); + }); + + describe("POST tests", () => { + test(`redirects to the ${config.REMOVE_NEED_MAKE_CHANGES_URL} page when yes is selected`, async () => { + const resp = await request(app) + .post(`${config.REMOVE_NEED_MAKE_CHANGES_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`) + .send({ make_changes: 'yes' }); + expect(resp.status).toEqual(302); + expect(resp.text).toEqual(`${FOUND_REDIRECT_TO} ${config.WHO_IS_MAKING_UPDATE_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + expect(resp.header.location).toEqual(`${config.WHO_IS_MAKING_UPDATE_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + expect(mockLoggerDebugRequest).toHaveBeenCalledTimes(1); + }); + + test(`redirects to the ${config.REMOVE_NEED_MAKE_CHANGES_URL} page when no is selected`, async () => { + const resp = await request(app) + .post(`${config.REMOVE_NEED_MAKE_CHANGES_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`) + .send({ make_changes: 'no' }); + expect(resp.status).toEqual(302); + // TODO redirect to new component - Has the overseas entity identified any registrable beneficial owners? + expect(resp.text).toEqual(`${FOUND_REDIRECT_TO} ${config.UPDATE_LANDING_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + expect(resp.header.location).toEqual(`${config.UPDATE_LANDING_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + expect(mockLoggerDebugRequest).toHaveBeenCalledTimes(1); + }); + + test("renders the current page with error message and correct page title", async () => { + const resp = await request(app) + .post(`${config.REMOVE_NEED_MAKE_CHANGES_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`); + + expect(resp.status).toEqual(200); + expect(resp.text).toContain(REMOVE_NEED_MAKE_CHANGES_TITLE); + expect(resp.text).toContain(PAGE_TITLE_ERROR); + expect(resp.text).toContain(ErrorMessages.SELECT_REMOVE_NEED_TO_MAKE_CHANGES); + expect(resp.text).toContain(REMOVE_SERVICE_NAME); + }); + + test("catch error on current page for POST method", async () => { + mockLoggerDebugRequest.mockImplementationOnce(() => { throw new Error(ANY_MESSAGE_ERROR); }); + const resp = await request(app) + .post(`${config.REMOVE_SOLD_ALL_LAND_FILTER_URL}${config.JOURNEY_REMOVE_QUERY_PARAM}`) + .send({ disposed_all_land: 'yes' }); + + expect(resp.status).toEqual(500); + expect(resp.text).toContain(SERVICE_UNAVAILABLE); + }); + + }); +}); diff --git a/views/update/remove-need-to-make-changes-to-entity.html b/views/update/remove-need-to-make-changes-to-entity.html new file mode 100644 index 000000000..db61f3ecd --- /dev/null +++ b/views/update/remove-need-to-make-changes-to-entity.html @@ -0,0 +1,76 @@ +{% extends "update-layout.html" %} + +{% set title = "Do you need to make any changes to this overseas entity before it is removed?" %} + +{% block pageTitle %} + {% include "includes/update-page-title.html" %} +{% endblock %} + +{% block backLink %} + {% include "includes/back-link.html" %} +{% endblock %} + +{% block content %} + +