From 23ccbe6b56b1c1d8b6c708f3c8fbde25b8da8e9b Mon Sep 17 00:00:00 2001 From: Gurnank Date: Tue, 10 Dec 2024 08:55:01 +0000 Subject: [PATCH 1/3] MAP-1745 redirect to change prison if agency id is TRN or OUT --- .../creatingReports/changePrison.test.ts | 33 ++++++++++++++++++- server/routes/creatingReports/changePrison.ts | 15 +++++++++ .../creatingReports/incidentDetails.test.ts | 23 +++++++++++++ .../routes/creatingReports/incidentDetails.ts | 16 +++++++-- 4 files changed, 84 insertions(+), 3 deletions(-) diff --git a/server/routes/creatingReports/changePrison.test.ts b/server/routes/creatingReports/changePrison.test.ts index 3530a5d3..2d9e9a28 100644 --- a/server/routes/creatingReports/changePrison.test.ts +++ b/server/routes/creatingReports/changePrison.test.ts @@ -17,9 +17,11 @@ const draftReportService = new DraftReportService( ) as jest.Mocked let app +const flash = jest.fn() beforeEach(() => { - app = appWithAllRoutes({ locationService, draftReportService }) + flash.mockReturnValue([]) + app = appWithAllRoutes({ locationService, draftReportService }, undefined, false, flash) locationService.getPrisons.mockResolvedValue([ { agencyId: 'BXI', @@ -79,4 +81,33 @@ describe('POST /change-prison', () => { expect(draftReportService.updateAgencyId).not.toHaveBeenCalled() }) }) + + it('Should process user input', () => { + flash.mockReturnValue([{ plannedUseOfForce: true, authorisedBy: 'the authoriser' }]) + + return request(app) + .post('/report/-19/change-prison') + .send({ agencyId: 'MDI', submit: 'save-and-continue' }) + .expect(302) + .expect(() => { + expect(draftReportService.process).toHaveBeenCalledWith( + { + activeCaseLoadId: 'MDI', + displayName: 'First Last', + firstName: 'first', + isReviewer: false, + lastName: 'last', + token: 'token', + userId: 'id', + username: 'user1', + }, + -19, + 'incidentDetails', + { authorisedBy: 'the authoriser', plannedUseOfForce: true, witnesses: undefined }, + null + ) + expect(draftReportService.updateAgencyId).toHaveBeenCalledWith('MDI', 'user1', -19) + expect(flash).toHaveBeenCalledTimes(1) + }) + }) }) diff --git a/server/routes/creatingReports/changePrison.ts b/server/routes/creatingReports/changePrison.ts index f7aa2d10..7f83d556 100755 --- a/server/routes/creatingReports/changePrison.ts +++ b/server/routes/creatingReports/changePrison.ts @@ -37,6 +37,21 @@ export default class ChangePrisonRoutes { return res.redirect(req.originalUrl) } + const userInput = req.flash('userInputForIncidentDetails') + + // this will create a new report record if it doesn't exist already (as will be the case for TRN and OUT) + await this.draftReportService.process( + res.locals.user, + parseInt(bookingId, 10), + 'incidentDetails', + { + plannedUseOfForce: userInput[0]?.plannedUseOfForce, + authorisedBy: userInput[0]?.authorisedBy, + witnesses: userInput[0]?.witnesses, + }, + null + ) + await this.draftReportService.updateAgencyId(agencyId, username, Number(bookingId)) } diff --git a/server/routes/creatingReports/incidentDetails.test.ts b/server/routes/creatingReports/incidentDetails.test.ts index f61659f9..ae6b04fc 100644 --- a/server/routes/creatingReports/incidentDetails.test.ts +++ b/server/routes/creatingReports/incidentDetails.test.ts @@ -125,6 +125,27 @@ describe('GET /section/form', () => { expect(locationService.getIncidentLocations).toBeCalledWith('user1-system-token', 'persisted-agency-id') }) }) + test('should redirect to /change-prison if agencyId is TRN', () => { + draftReportService.getCurrentDraft.mockResolvedValue({ id: '1', agencyId: 'TRN' }) + return request(app) + .get(`/report/1/incident-details`) + .expect(302) + .expect('Location', '/report/1/change-prison') + .expect(() => { + expect(locationService.getIncidentLocations).not.toHaveBeenCalled() + }) + }) + + test('should redirect to /change-prison if agencyId is OUT', () => { + draftReportService.getCurrentDraft.mockResolvedValue({ id: '1', agencyId: 'OUT' }) + return request(app) + .get(`/report/1/incident-details`) + .expect(302) + .expect('Location', '/report/1/change-prison') + .expect(() => { + expect(locationService.getIncidentLocations).not.toHaveBeenCalled() + }) + }) }) describe('POST save and continue /section/form', () => { @@ -145,6 +166,7 @@ describe('POST save and continue /section/form', () => { .expect(302) .expect('Location', '/report/1/staff-involved') .expect(() => { + expect(flash).toHaveBeenCalledTimes(2) expect(draftReportService.process).toBeCalledTimes(1) expect(draftReportService.process).toBeCalledWith( user, @@ -248,6 +270,7 @@ describe('POST save and return to tasklist', () => { .expect(302) .expect('Location', '/report/1/change-prison') .expect(() => { + expect(flash).toHaveBeenCalledTimes(1) expect(draftReportService.getPotentialDuplicates).not.toBeCalled() expect(draftReportService.process).toBeCalledTimes(1) expect(draftReportService.process).toBeCalledWith( diff --git a/server/routes/creatingReports/incidentDetails.ts b/server/routes/creatingReports/incidentDetails.ts index 853c5ecd..a30c5d00 100755 --- a/server/routes/creatingReports/incidentDetails.ts +++ b/server/routes/creatingReports/incidentDetails.ts @@ -77,11 +77,18 @@ export default class IncidentDetailsRoutes { // If report has been created, use persisted agency Id which is robust against offender moving establishments const prisonId = persistedAgencyId || offenderDetail.agencyId + + // if prisoner is currently being transferred or has left the prison, redirect user to select prison where the incident occured + if (prisonId === 'TRN' || prisonId === 'OUT') { + return res.redirect(`/report/${bookingId}/change-prison`) + } + const locations = await this.locationService.getIncidentLocations(token, prisonId) const { displayName, offenderNo } = offenderDetail - const input = firstItem(req.flash('userInput')) + const input = firstItem(req.flash('userInputForIncidentDetails')) + const pageData = input || form[formName] const prison = await this.locationService.getPrisonById(token, prisonId) @@ -121,9 +128,11 @@ export default class IncidentDetailsRoutes { const updatedSection = payloadFields + // flashing so data can be accessed in 'change prison' + req.flash('userInputForIncidentDetails', { ...payloadFields, incidentDate }) // merge all fields back together! + if (!isNilOrEmpty(errors)) { req.flash('errors', errors) - req.flash('userInput', { ...payloadFields, incidentDate }) // merge all fields back together! return res.redirect(req.originalUrl) } @@ -136,6 +145,9 @@ export default class IncidentDetailsRoutes { ) if (incidentDate && submitType !== SubmitType.SAVE_AND_CHANGE_PRISON) { + // clear content in flash when not going to 'change the prison' page + req.flash('userInputForIncidentDetails') + const duplicates = await this.draftReportService.getPotentialDuplicates( parseInt(bookingId, 10), moment(incidentDate.value), From e31f3eba0cdabf3c9ab7d1c92e54396f0e73825e Mon Sep 17 00:00:00 2001 From: Gurnank Date: Tue, 10 Dec 2024 09:16:37 +0000 Subject: [PATCH 2/3] MAP-1745 change endpoint name --- .../creatingReports/changePrison.test.ts | 18 +++++++++--------- .../creatingReports/incidentDetails.test.ts | 10 +++++----- .../routes/creatingReports/incidentDetails.ts | 4 ++-- server/routes/creatingReports/index.ts | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/server/routes/creatingReports/changePrison.test.ts b/server/routes/creatingReports/changePrison.test.ts index 2d9e9a28..c9b00e2a 100644 --- a/server/routes/creatingReports/changePrison.test.ts +++ b/server/routes/creatingReports/changePrison.test.ts @@ -34,10 +34,10 @@ afterEach(() => { jest.resetAllMocks() }) -describe('GET /change-prison', () => { +describe('GET /prison-of-incident', () => { test('should render content', () => { return request(app) - .get(`/report/-19/change-prison`) + .get(`/report/-19/prison-of-incident`) .expect('Content-Type', /html/) .expect(res => { expect(res.text).toContain('What prison did the use of force take place in?') @@ -45,10 +45,10 @@ describe('GET /change-prison', () => { }) }) }) -describe('POST /change-prison', () => { +describe('POST /prison-of-incident', () => { it('should redirect to incident-details page', () => { return request(app) - .post('/report/-19/change-prison') + .post('/report/-19/prison-of-incident') .send({ agencyId: 'MDI', submit: 'save-and-continue' }) .expect(302) .expect('Location', '/report/-19/incident-details') @@ -56,15 +56,15 @@ describe('POST /change-prison', () => { it('Not selecting a prison but selecting Continue should redirect to current page', () => { return request(app) - .post('/report/-19/change-prison') + .post('/report/-19/prison-of-incident') .send({ submit: 'save-and-continue' }) .expect(302) - .expect('Location', '/report/-19/change-prison') + .expect('Location', '/report/-19/prison-of-incident') }) it('Selecting a prison followed by Continue should call the location service', () => { return request(app) - .post('/report/-19/change-prison') + .post('/report/-19/prison-of-incident') .send({ agencyId: 'MDI', submit: 'save-and-continue' }) .expect(302) .expect(() => { @@ -74,7 +74,7 @@ describe('POST /change-prison', () => { it('Cancel should not call the location service', () => { return request(app) - .post('/report/-19/change-prison') + .post('/report/-19/prison-of-incident') .send({ agencyId: 'MDI', submit: 'cancel' }) .expect(302) .expect(() => { @@ -86,7 +86,7 @@ describe('POST /change-prison', () => { flash.mockReturnValue([{ plannedUseOfForce: true, authorisedBy: 'the authoriser' }]) return request(app) - .post('/report/-19/change-prison') + .post('/report/-19/prison-of-incident') .send({ agencyId: 'MDI', submit: 'save-and-continue' }) .expect(302) .expect(() => { diff --git a/server/routes/creatingReports/incidentDetails.test.ts b/server/routes/creatingReports/incidentDetails.test.ts index ae6b04fc..4405c0af 100644 --- a/server/routes/creatingReports/incidentDetails.test.ts +++ b/server/routes/creatingReports/incidentDetails.test.ts @@ -125,23 +125,23 @@ describe('GET /section/form', () => { expect(locationService.getIncidentLocations).toBeCalledWith('user1-system-token', 'persisted-agency-id') }) }) - test('should redirect to /change-prison if agencyId is TRN', () => { + test('should redirect to /prison-of-incident if agencyId is TRN', () => { draftReportService.getCurrentDraft.mockResolvedValue({ id: '1', agencyId: 'TRN' }) return request(app) .get(`/report/1/incident-details`) .expect(302) - .expect('Location', '/report/1/change-prison') + .expect('Location', '/report/1/prison-of-incident') .expect(() => { expect(locationService.getIncidentLocations).not.toHaveBeenCalled() }) }) - test('should redirect to /change-prison if agencyId is OUT', () => { + test('should redirect to /prison-of-incident if agencyId is OUT', () => { draftReportService.getCurrentDraft.mockResolvedValue({ id: '1', agencyId: 'OUT' }) return request(app) .get(`/report/1/incident-details`) .expect(302) - .expect('Location', '/report/1/change-prison') + .expect('Location', '/report/1/prison-of-incident') .expect(() => { expect(locationService.getIncidentLocations).not.toHaveBeenCalled() }) @@ -268,7 +268,7 @@ describe('POST save and return to tasklist', () => { witnesses: [{ name: 'User bob' }, { name: '' }], }) .expect(302) - .expect('Location', '/report/1/change-prison') + .expect('Location', '/report/1/prison-of-incident') .expect(() => { expect(flash).toHaveBeenCalledTimes(1) expect(draftReportService.getPotentialDuplicates).not.toBeCalled() diff --git a/server/routes/creatingReports/incidentDetails.ts b/server/routes/creatingReports/incidentDetails.ts index a30c5d00..4af7795e 100755 --- a/server/routes/creatingReports/incidentDetails.ts +++ b/server/routes/creatingReports/incidentDetails.ts @@ -40,7 +40,7 @@ export default class IncidentDetailsRoutes { private async getSubmitRedirectLocation(req: Request, bookingId: number, submitType) { if (submitType === SubmitType.SAVE_AND_CHANGE_PRISON) { - return `/report/${bookingId}/change-prison` + return `/report/${bookingId}/prison-of-incident` } if (await this.draftReportService.isDraftComplete(req.user.username, bookingId)) { @@ -80,7 +80,7 @@ export default class IncidentDetailsRoutes { // if prisoner is currently being transferred or has left the prison, redirect user to select prison where the incident occured if (prisonId === 'TRN' || prisonId === 'OUT') { - return res.redirect(`/report/${bookingId}/change-prison`) + return res.redirect(`/report/${bookingId}/prison-of-incident`) } const locations = await this.locationService.getIncidentLocations(token, prisonId) diff --git a/server/routes/creatingReports/index.ts b/server/routes/creatingReports/index.ts index f77b764c..77cd4498 100644 --- a/server/routes/creatingReports/index.ts +++ b/server/routes/creatingReports/index.ts @@ -64,8 +64,8 @@ export default function Index({ get(reportPath('staff-member-not-found'), addInvolvedStaff.viewStaffMemberNotFound) const changePrison = new ChangePrisonRoutes(locationService, draftReportService, systemToken) - get(reportPath('change-prison'), changePrison.viewPrisons) - post(reportPath('change-prison'), changePrison.submit) + get(reportPath('prison-of-incident'), changePrison.viewPrisons) + post(reportPath('prison-of-incident'), changePrison.submit) const whyWasUoFApplied = new WhyWasUoFAppliedRoutes(draftReportService) get(reportPath('why-was-uof-applied'), whyWasUoFApplied.view()) From b85a3a8dba1e1653dde7956b5978f2dac8f54d62 Mon Sep 17 00:00:00 2001 From: Gurnank Date: Tue, 10 Dec 2024 09:22:14 +0000 Subject: [PATCH 3/3] MAP-1745 change comment --- server/routes/creatingReports/changePrison.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/routes/creatingReports/changePrison.ts b/server/routes/creatingReports/changePrison.ts index 7f83d556..a3e60c4e 100755 --- a/server/routes/creatingReports/changePrison.ts +++ b/server/routes/creatingReports/changePrison.ts @@ -39,7 +39,7 @@ export default class ChangePrisonRoutes { const userInput = req.flash('userInputForIncidentDetails') - // this will create a new report record if it doesn't exist already (as will be the case for TRN and OUT) + // this will create a new report record if it doesn't exist already await this.draftReportService.process( res.locals.user, parseInt(bookingId, 10),