From c53803f12c2ea8916583896f9e219513d9bbb348 Mon Sep 17 00:00:00 2001 From: Patrick Fleming Date: Tue, 7 Jan 2025 11:03:20 +0000 Subject: [PATCH 1/6] Rename current offence task to include community supervision --- .../currentOffences.test.ts | 6 +++--- .../currentOffences.ts | 8 ++++---- .../custom-forms/currentOffenceData.test.ts | 0 .../custom-forms/currentOffenceData.ts | 8 +++++--- .../index.ts | 6 +++--- server/form-pages/apply/offence-information/index.ts | 4 ++-- server/form-pages/utils/questions.ts | 2 +- .../current-offence-data.njk | 2 +- .../current-offences.njk | 2 +- 9 files changed, 20 insertions(+), 18 deletions(-) rename server/form-pages/apply/offence-information/{current-offences => community-supervision-and-current-offences}/currentOffences.test.ts (94%) rename server/form-pages/apply/offence-information/{current-offences => community-supervision-and-current-offences}/currentOffences.ts (92%) rename server/form-pages/apply/offence-information/{current-offences => community-supervision-and-current-offences}/custom-forms/currentOffenceData.test.ts (100%) rename server/form-pages/apply/offence-information/{current-offences => community-supervision-and-current-offences}/custom-forms/currentOffenceData.ts (91%) rename server/form-pages/apply/offence-information/{current-offences => community-supervision-and-current-offences}/index.ts (61%) rename server/views/applications/pages/{current-offences => community-supervision-and-current-offences}/current-offence-data.njk (98%) rename server/views/applications/pages/{current-offences => community-supervision-and-current-offences}/current-offences.njk (97%) diff --git a/server/form-pages/apply/offence-information/current-offences/currentOffences.test.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/currentOffences.test.ts similarity index 94% rename from server/form-pages/apply/offence-information/current-offences/currentOffences.test.ts rename to server/form-pages/apply/offence-information/community-supervision-and-current-offences/currentOffences.test.ts index 99ca43e..5b2c87c 100644 --- a/server/form-pages/apply/offence-information/current-offences/currentOffences.test.ts +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/currentOffences.test.ts @@ -11,7 +11,7 @@ describe('CurrentOffences', () => { const applicationWithData = applicationFactory.build({ person: personFactory.build({ name: 'Roger Smith' }), data: { - 'current-offences': { + 'community-supervision-and-current-offences': { 'current-offence-data': [ { titleAndNumber: 'Stalking', @@ -63,7 +63,7 @@ describe('CurrentOffences', () => { summary: 'summary detail', outstandingCharges: 'Yes', outstandingChargesDetail: 'some detail', - removeLink: `/applications/${applicationWithData.id}/tasks/current-offences/pages/current-offence-data/0/removeFromList?redirectPage=current-offences`, + removeLink: `/applications/${applicationWithData.id}/tasks/community-supervision-and-current-offences/pages/current-offence-data/0/removeFromList?redirectPage=current-offences`, }, { titleAndNumber: 'Arson', @@ -74,7 +74,7 @@ describe('CurrentOffences', () => { summary: 'second summary detail', outstandingCharges: 'No', outstandingChargesDetail: '', - removeLink: `/applications/${applicationWithData.id}/tasks/current-offences/pages/current-offence-data/1/removeFromList?redirectPage=current-offences`, + removeLink: `/applications/${applicationWithData.id}/tasks/community-supervision-and-current-offences/pages/current-offence-data/1/removeFromList?redirectPage=current-offences`, }, ]) }) diff --git a/server/form-pages/apply/offence-information/current-offences/currentOffences.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/currentOffences.ts similarity index 92% rename from server/form-pages/apply/offence-information/current-offences/currentOffences.ts rename to server/form-pages/apply/offence-information/community-supervision-and-current-offences/currentOffences.ts index 7e3d7d6..d6eaba1 100644 --- a/server/form-pages/apply/offence-information/current-offences/currentOffences.ts +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/currentOffences.ts @@ -41,9 +41,9 @@ export default class CurrentOffences implements TaskListPage { dataPageName = 'current-offence-data' - taskName = 'current-offences' + taskName = 'community-supervision-and-current-offences' - currentOffenceQuestions = getQuestions('')['current-offences']['current-offence-data'] + currentOffenceQuestions = getQuestions('')['community-supervision-and-current-offences']['current-offence-data'] constructor( body: Partial, @@ -86,7 +86,7 @@ export default class CurrentOffences implements TaskListPage { } static async initialize(body: Partial, application: Application) { - if (!application.data['current-offences']?.['current-offence-data']) { + if (!application.data['community-supervision-and-current-offences']?.['current-offence-data']) { return new CurrentOffenceData(body, application) } return new CurrentOffences({}, application) @@ -103,7 +103,7 @@ export default class CurrentOffences implements TaskListPage { errors() { const errors: TaskListErrors = {} - if (!this.application.data['current-offences']?.['current-offence-data'].length) { + if (!this.application.data['community-supervision-and-current-offences']?.['current-offence-data'].length) { errors.offenceList = 'Current offences must be added to the application' } diff --git a/server/form-pages/apply/offence-information/current-offences/custom-forms/currentOffenceData.test.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/custom-forms/currentOffenceData.test.ts similarity index 100% rename from server/form-pages/apply/offence-information/current-offences/custom-forms/currentOffenceData.test.ts rename to server/form-pages/apply/offence-information/community-supervision-and-current-offences/custom-forms/currentOffenceData.test.ts diff --git a/server/form-pages/apply/offence-information/current-offences/custom-forms/currentOffenceData.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/custom-forms/currentOffenceData.ts similarity index 91% rename from server/form-pages/apply/offence-information/current-offences/custom-forms/currentOffenceData.ts rename to server/form-pages/apply/offence-information/community-supervision-and-current-offences/custom-forms/currentOffenceData.ts index 7b20ef4..d3f7dc4 100644 --- a/server/form-pages/apply/offence-information/current-offences/custom-forms/currentOffenceData.ts +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/custom-forms/currentOffenceData.ts @@ -42,11 +42,11 @@ export default class CurrentOffenceData implements TaskListPage { body: CurrentOffenceDataBody - taskName = 'current-offences' + taskName = 'community-supervision-and-current-offences' pageName = 'current-offence-data' - questions = getQuestions('')['current-offences']['current-offence-data'] + questions = getQuestions('')['community-supervision-and-current-offences']['current-offence-data'] offenceCategories: Array @@ -58,7 +58,9 @@ export default class CurrentOffenceData implements TaskListPage { ) { this.body = body as CurrentOffenceDataBody this.offenceCategories = this.getCategoriesAsItemsForSelect(this.body.offenceCategory) - this.hasPreviouslySavedACurrentOffence = Boolean(application.data['current-offences']?.['current-offence-data']) + this.hasPreviouslySavedACurrentOffence = Boolean( + application.data['community-supervision-and-current-offences']?.['current-offence-data'], + ) } private getCategoriesAsItemsForSelect(selectedItem: string): Array { diff --git a/server/form-pages/apply/offence-information/current-offences/index.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts similarity index 61% rename from server/form-pages/apply/offence-information/current-offences/index.ts rename to server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts index 08d5e35..e5dce01 100644 --- a/server/form-pages/apply/offence-information/current-offences/index.ts +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts @@ -5,8 +5,8 @@ import CurrentOffenceData from './custom-forms/currentOffenceData' import CurrentOffencesIndexPage from './currentOffences' @Task({ - name: 'Add current offences', - slug: 'current-offences', + name: 'Community supervision and current offences', + slug: 'community-supervision-and-current-offences', pages: [CurrentOffencesIndexPage, CurrentOffenceData], }) -export default class CurrentOffences {} +export default class CommunitySupervisionAndCurrentOffences {} diff --git a/server/form-pages/apply/offence-information/index.ts b/server/form-pages/apply/offence-information/index.ts index c687ef0..3a2de09 100644 --- a/server/form-pages/apply/offence-information/index.ts +++ b/server/form-pages/apply/offence-information/index.ts @@ -2,10 +2,10 @@ import { Section } from '../../utils/decorators' import OffendingHistory from './offending-history' -import CurrentOffences from './current-offences' +import CommunitySupervisionAndCurrentOffences from './community-supervision-and-current-offences' @Section({ title: 'Offence information', - tasks: [CurrentOffences, OffendingHistory], + tasks: [CommunitySupervisionAndCurrentOffences, OffendingHistory], }) export default class OffenceInformation {} diff --git a/server/form-pages/utils/questions.ts b/server/form-pages/utils/questions.ts index a136487..cf7ee82 100644 --- a/server/form-pages/utils/questions.ts +++ b/server/form-pages/utils/questions.ts @@ -741,7 +741,7 @@ export const getQuestions = (name: string) => { additionalInformationDetail: { question: 'Additional information' }, }, }, - 'current-offences': { + 'community-supervision-and-current-offences': { 'current-offence-data': { titleAndNumber: { question: 'Offence title', diff --git a/server/views/applications/pages/current-offences/current-offence-data.njk b/server/views/applications/pages/community-supervision-and-current-offences/current-offence-data.njk similarity index 98% rename from server/views/applications/pages/current-offences/current-offence-data.njk rename to server/views/applications/pages/community-supervision-and-current-offences/current-offence-data.njk index 23ad5a9..5b20034 100644 --- a/server/views/applications/pages/current-offences/current-offence-data.njk +++ b/server/views/applications/pages/community-supervision-and-current-offences/current-offence-data.njk @@ -199,7 +199,7 @@ }) }} {%if page.hasPreviouslySavedACurrentOffence %} - + Cancel {% endif %} diff --git a/server/views/applications/pages/current-offences/current-offences.njk b/server/views/applications/pages/community-supervision-and-current-offences/current-offences.njk similarity index 97% rename from server/views/applications/pages/current-offences/current-offences.njk rename to server/views/applications/pages/community-supervision-and-current-offences/current-offences.njk index 19a47d2..78240ac 100644 --- a/server/views/applications/pages/current-offences/current-offences.njk +++ b/server/views/applications/pages/community-supervision-and-current-offences/current-offences.njk @@ -16,7 +16,7 @@ {{ govukButton({ id: "add-a-current-offence", text: "Add a current offence", - href: paths.applications.pages.show({ id: applicationId, task: 'current-offences', page: 'current-offence-data' }), + href: paths.applications.pages.show({ id: applicationId, task: 'community-supervision-and-current-offences', page: 'current-offence-data' }), classes: "govuk-button--secondary" }) }} From 444c55bcf8eac3615604b0b0113bc32426463698 Mon Sep 17 00:00:00 2001 From: Patrick Fleming Date: Tue, 7 Jan 2025 12:04:20 +0000 Subject: [PATCH 2/6] Add community supervision page If the applicant is under community supervision, then there is a current offence which needs to be recorded. So we will use this page to determine whether the user needs to continue with the later pages of the task (adding CPP details current offence data). --- .../communitySupervision.test.ts | 45 ++++++++++++++ .../communitySupervision.ts | 61 +++++++++++++++++++ .../index.ts | 3 +- server/form-pages/utils/questions.ts | 6 ++ .../community-supervision.njk | 22 +++++++ 5 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.test.ts create mode 100644 server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.ts create mode 100644 server/views/applications/pages/community-supervision-and-current-offences/community-supervision.njk diff --git a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.test.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.test.ts new file mode 100644 index 0000000..c4ddb9d --- /dev/null +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.test.ts @@ -0,0 +1,45 @@ +import { itShouldHaveNextValue, itShouldHavePreviousValue } from '../../../shared-examples' +import { personFactory, applicationFactory } from '../../../../testutils/factories/index' +import CommunitySupervision from './communitySupervision' + +describe('Community supervision', () => { + const application = applicationFactory.build({ person: personFactory.build({ name: 'Roger Smith' }) }) + + describe('when the applicant is under probation supervision', () => { + itShouldHaveNextValue(new CommunitySupervision({ probationSupervision: 'yes' }, application), 'cpp-details') + }) + + describe('when the applicant is not under probation supervision', () => { + itShouldHaveNextValue(new CommunitySupervision({ probationSupervision: 'no' }, application), '') + }) + + itShouldHavePreviousValue(new CommunitySupervision({}, application), 'taskList') + + describe('items', () => { + it('returns the radio with the expected label text', () => { + const page = new CommunitySupervision({ probationSupervision: 'yes' }, application) + expect(page.items()).toEqual([ + { + checked: true, + text: 'Yes', + value: 'yes', + }, + { + checked: false, + text: 'No', + value: 'no', + }, + ]) + }) + }) + + describe('errors', () => { + it('should return errors when the questions are blank', () => { + const page = new CommunitySupervision({}, application) + + expect(page.errors()).toEqual({ + probationSupervision: 'Confirm whether the applicant is currently supervised by probation', + }) + }) + }) +}) diff --git a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.ts new file mode 100644 index 0000000..941f717 --- /dev/null +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/communitySupervision.ts @@ -0,0 +1,61 @@ +import { Radio, TaskListErrors, YesOrNo } from '@approved-premises/ui' +import { Cas2Application as Application } from '@approved-premises/api' +import { Page } from '../../../utils/decorators' +import TaskListPage from '../../../taskListPage' +import { nameOrPlaceholderCopy } from '../../../../utils/utils' +import { getQuestions } from '../../../utils/questions' +import { convertKeyValuePairToRadioItems } from '../../../../utils/formUtils' + +export type CommunitySupervisionBody = { + probationSupervision: YesOrNo +} + +@Page({ + name: 'community-supervision', + bodyProperties: ['probationSupervision'], +}) +export default class CommunitySupervision implements TaskListPage { + documentTitle = 'Is the person currently supervised by probation?' + + personName = nameOrPlaceholderCopy(this.application.person) + + title + + questions = getQuestions(this.personName)['community-supervision-and-current-offences']['community-supervision'] + + body: CommunitySupervisionBody + + constructor( + body: Partial, + private readonly application: Application, + ) { + this.body = body as CommunitySupervisionBody + this.title = this.questions.probationSupervision.question + } + + previous() { + return 'taskList' + } + + next() { + if (this.body.probationSupervision === 'yes') { + return 'cpp-details' + } + return '' + } + + items() { + return convertKeyValuePairToRadioItems( + this.questions.probationSupervision.answers, + this.body.probationSupervision, + ) as Array + } + + errors() { + const errors: TaskListErrors = {} + if (!this.body.probationSupervision) { + errors.probationSupervision = 'Confirm whether the applicant is currently supervised by probation' + } + return errors + } +} diff --git a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts index e5dce01..9edd794 100644 --- a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts @@ -1,12 +1,13 @@ /* istanbul ignore file */ import { Task } from '../../../utils/decorators' +import CommunitySupervision from './communitySupervision' import CurrentOffenceData from './custom-forms/currentOffenceData' import CurrentOffencesIndexPage from './currentOffences' @Task({ name: 'Community supervision and current offences', slug: 'community-supervision-and-current-offences', - pages: [CurrentOffencesIndexPage, CurrentOffenceData], + pages: [CommunitySupervision, CurrentOffencesIndexPage, CurrentOffenceData], }) export default class CommunitySupervisionAndCurrentOffences {} diff --git a/server/form-pages/utils/questions.ts b/server/form-pages/utils/questions.ts index cf7ee82..46b4cc8 100644 --- a/server/form-pages/utils/questions.ts +++ b/server/form-pages/utils/questions.ts @@ -742,6 +742,12 @@ export const getQuestions = (name: string) => { }, }, 'community-supervision-and-current-offences': { + 'community-supervision': { + probationSupervision: { + question: `Is ${name} currently supervised by probation?`, + answers: yesOrNo, + }, + }, 'current-offence-data': { titleAndNumber: { question: 'Offence title', diff --git a/server/views/applications/pages/community-supervision-and-current-offences/community-supervision.njk b/server/views/applications/pages/community-supervision-and-current-offences/community-supervision.njk new file mode 100644 index 0000000..1c530a3 --- /dev/null +++ b/server/views/applications/pages/community-supervision-and-current-offences/community-supervision.njk @@ -0,0 +1,22 @@ +{% extends "../layout.njk" %} + +{% block questions %} + + {{ + formPageRadios( + { + fieldset: { + legend: { + text: page.questions.probationSupervision.question, + isPageHeading: true, + classes: "govuk-fieldset__legend--l" + } + }, + fieldName: "probationSupervision", + items: page.items() + }, + fetchContext() + ) + }} + +{% endblock %} From 97fa6429b16859c89a5502b360d798d6218fe778 Mon Sep 17 00:00:00 2001 From: Patrick Fleming Date: Tue, 7 Jan 2025 14:50:11 +0000 Subject: [PATCH 3/6] Reintroduce CPP details page This has been brought back in from CAS2 HDC, albeit in a different task. --- .../cppDetails.test.ts | 50 +++++++++++++ .../cppDetails.ts | 70 +++++++++++++++++++ .../index.ts | 3 +- server/form-pages/utils/questions.ts | 6 ++ .../cpp-details.njk | 65 +++++++++++++++++ 5 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.test.ts create mode 100644 server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.ts create mode 100644 server/views/applications/pages/community-supervision-and-current-offences/cpp-details.njk diff --git a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.test.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.test.ts new file mode 100644 index 0000000..235b367 --- /dev/null +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.test.ts @@ -0,0 +1,50 @@ +import { itShouldHavePreviousValue, itShouldHaveNextValue } from '../../../shared-examples' +import { personFactory, applicationFactory } from '../../../../testutils/factories/index' +import CPPDetails from './cppDetails' + +describe('CPPDetails', () => { + const application = applicationFactory.build({ person: personFactory.build({ name: 'Roger Smith' }) }) + + describe('title', () => { + it('personalises the page title', () => { + const page = new CPPDetails({}, application) + + expect(page.title).toEqual("Who is Roger Smith's Community Probation Practitioner (CPP)?") + }) + }) + + itShouldHavePreviousValue(new CPPDetails({}, application), 'community-supervision') + itShouldHaveNextValue(new CPPDetails({}, application), 'current-offences') + + describe('errors', () => { + describe('when they have not provided any answer', () => { + it('returns errors', () => { + const page = new CPPDetails({}, application) + expect(page.errors()).toEqual({ + name: "Enter the CPP's full name", + probationRegion: 'Enter the probation region', + email: "Enter the CPP's email address", + telephone: "Enter the CPP's contact number", + }) + }) + }) + }) + + describe('response', () => { + it('returns data in expected format', () => { + const page = new CPPDetails( + { + name: 'a name', + probationRegion: 'a probation region', + email: 'an email address', + telephone: 'a phone number', + }, + application, + ) + + expect(page.response()).toEqual({ + "Who is Roger Smith's Community Probation Practitioner (CPP)?": `a name\r\na probation region\r\nan email address\r\na phone number`, + }) + }) + }) +}) diff --git a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.ts new file mode 100644 index 0000000..c31b87d --- /dev/null +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/cppDetails.ts @@ -0,0 +1,70 @@ +import { TaskListErrors } from '@approved-premises/ui' +import { Cas2Application as Application } from '@approved-premises/api' +import { Page } from '../../../utils/decorators' +import TaskListPage from '../../../taskListPage' +import { nameOrPlaceholderCopy } from '../../../../utils/utils' +import { getQuestions } from '../../../utils/questions' + +type CPPDetailsBody = { + name: string + probationRegion: string + email: string + telephone: string +} + +@Page({ + name: 'cpp-details', + bodyProperties: ['name', 'probationRegion', 'email', 'telephone'], +}) +export default class CPPDetails implements TaskListPage { + documentTitle = "Who is the person's Community Probation Practitioner (CPP)?" + + personName = nameOrPlaceholderCopy(this.application.person) + + title + + questions = getQuestions(this.personName)['community-supervision-and-current-offences']['cpp-details'] + + options: Record + + body: CPPDetailsBody + + constructor( + body: Partial, + private readonly application: Application, + ) { + this.body = body as CPPDetailsBody + this.title = this.questions.cppDetails.question + } + + previous() { + return 'community-supervision' + } + + next() { + return 'current-offences' + } + + response() { + return { + [this.title]: `${this.body.name}\r\n${this.body.probationRegion}\r\n${this.body.email}\r\n${this.body.telephone}`, + } + } + + errors() { + const errors: TaskListErrors = {} + if (!this.body.name) { + errors.name = "Enter the CPP's full name" + } + if (!this.body.probationRegion) { + errors.probationRegion = 'Enter the probation region' + } + if (!this.body.email) { + errors.email = "Enter the CPP's email address" + } + if (!this.body.telephone) { + errors.telephone = "Enter the CPP's contact number" + } + return errors + } +} diff --git a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts index 9edd794..a581855 100644 --- a/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts +++ b/server/form-pages/apply/offence-information/community-supervision-and-current-offences/index.ts @@ -2,12 +2,13 @@ import { Task } from '../../../utils/decorators' import CommunitySupervision from './communitySupervision' +import CPPDetails from './cppDetails' import CurrentOffenceData from './custom-forms/currentOffenceData' import CurrentOffencesIndexPage from './currentOffences' @Task({ name: 'Community supervision and current offences', slug: 'community-supervision-and-current-offences', - pages: [CommunitySupervision, CurrentOffencesIndexPage, CurrentOffenceData], + pages: [CommunitySupervision, CPPDetails, CurrentOffencesIndexPage, CurrentOffenceData], }) export default class CommunitySupervisionAndCurrentOffences {} diff --git a/server/form-pages/utils/questions.ts b/server/form-pages/utils/questions.ts index 46b4cc8..8c9f76a 100644 --- a/server/form-pages/utils/questions.ts +++ b/server/form-pages/utils/questions.ts @@ -748,6 +748,12 @@ export const getQuestions = (name: string) => { answers: yesOrNo, }, }, + 'cpp-details': { + cppDetails: { + question: `Who is ${name}'s Community Probation Practitioner (CPP)?`, + hint: 'A Community Probation Practitioner (CPP) is also known as Community Offender Manager (COM).', + }, + }, 'current-offence-data': { titleAndNumber: { question: 'Offence title', diff --git a/server/views/applications/pages/community-supervision-and-current-offences/cpp-details.njk b/server/views/applications/pages/community-supervision-and-current-offences/cpp-details.njk new file mode 100644 index 0000000..79c792b --- /dev/null +++ b/server/views/applications/pages/community-supervision-and-current-offences/cpp-details.njk @@ -0,0 +1,65 @@ +{% from "govuk/components/summary-list/macro.njk" import govukSummaryList %} +{% from "../../../components/formFields/form-page-input/macro.njk" import formPageInput %} + +{% extends "../layout.njk" %} + +{% block questions %} + +

{{ page.title }}

+ +

{{page.questions.cppDetails.hint}}

+ + {{ + formPageInput( + { + label: { + text: "Full name" + }, + fieldName: "name", + classes: "govuk-!-width-two-thirds" + }, + fetchContext() + ) + }} + + {{ + formPageInput( + { + label: { + text: "Probation region" + }, + fieldName: "probationRegion", + classes: "govuk-!-width-two-thirds" + }, + fetchContext() + ) + }} + + {{ + formPageInput( + { + label: { + text: "Contact email address" + }, + type: "email", + fieldName: "email", + classes: "govuk-!-width-two-thirds" + }, + fetchContext() + ) + }} + + {{ + formPageInput( + { + label: { + text: "Contact number" + }, + type: "tel", + fieldName: "telephone", + classes: "govuk-input--width-10" + }, + fetchContext() + ) + }} +{% endblock %} \ No newline at end of file From bb820bbd8d11ddef226302666b58aa02f00ff42b Mon Sep 17 00:00:00 2001 From: Patrick Fleming Date: Tue, 7 Jan 2025 16:11:17 +0000 Subject: [PATCH 4/6] Update E2E tests after community supervision / current offence task changes --- e2e-tests/steps/apply.ts | 7 +++++-- .../offenceAndLicenceInformationSection.ts | 21 +++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/e2e-tests/steps/apply.ts b/e2e-tests/steps/apply.ts index 7555898..8759939 100644 --- a/e2e-tests/steps/apply.ts +++ b/e2e-tests/steps/apply.ts @@ -15,7 +15,10 @@ import { } from './aboutThePersonSection' import { completeHealthNeedsTask, completeRiskToSelfTask, completeRoshTask } from './risksAndNeedsSection' import { completeAreaInformationTask, completeFundingInformationTask } from './areaAndFundingSection' -import { completeCurrentOffencesTask, completeOffenceHistoryTask } from './offenceAndLicenceInformationSection' +import { + completeCommunitySupervisionAndCurrentOffencesTask, + completeOffenceHistoryTask, +} from './offenceAndLicenceInformationSection' import { completeCheckAnswersTask } from './checkAnswersSection' import { TestOptions } from '../testOptions' import { @@ -75,7 +78,7 @@ export const completeRisksAndNeedsSection = async (page: Page, name: string) => } export const completeOffenceInformationSection = async (page: Page, name: string) => { - await completeCurrentOffencesTask(page, name) + await completeCommunitySupervisionAndCurrentOffencesTask(page, name) await completeOffenceHistoryTask(page, name) } diff --git a/e2e-tests/steps/offenceAndLicenceInformationSection.ts b/e2e-tests/steps/offenceAndLicenceInformationSection.ts index 761a070..5d24709 100644 --- a/e2e-tests/steps/offenceAndLicenceInformationSection.ts +++ b/e2e-tests/steps/offenceAndLicenceInformationSection.ts @@ -1,14 +1,31 @@ import { Page } from '@playwright/test' import { ApplyPage, TaskListPage } from '../pages/apply' -export const completeCurrentOffencesTask = async (page: Page, name: string) => { +export const completeCommunitySupervisionAndCurrentOffencesTask = async (page: Page, name: string) => { const taskListPage = new TaskListPage(page) - await taskListPage.clickTask('Add current offences') + await taskListPage.clickTask('Community supervision and current offences') + await completeCommunitySupervisionPage(page, name) + await completeCPPDetailsPage(page, name) await completeCurrentOffenceDetailsPage(page, name) await completeCurrentOffencesPage(page, name) } +async function completeCommunitySupervisionPage(page: Page, name: string) { + const communitySupervisionPage = await ApplyPage.initialize(page, `Is ${name} currently supervised by probation?`) + await communitySupervisionPage.checkRadio('Yes') + await communitySupervisionPage.clickButton('Save and continue') +} + +async function completeCPPDetailsPage(page: Page, name: string) { + const cppDetailsPage = await ApplyPage.initialize(page, `Who is ${name}'s Community Probation Practitioner (CPP)?`) + await cppDetailsPage.fillField('Full name', 'A. CPP') + await cppDetailsPage.fillField('Probation region', 'south') + await cppDetailsPage.fillField('Contact email address', 'an@email.gov.uk') + await cppDetailsPage.fillField('Contact number', '12345') + await cppDetailsPage.clickSave() +} + async function completeCurrentOffenceDetailsPage(page: Page, name: string) { const currentOffenceDetailsPage = await ApplyPage.initialize(page, `Add ${name}'s current offence details`) await currentOffenceDetailsPage.fillField('Offence title', 'Stalking') From 6efb7f784312243dc628920cb959f45f64309837 Mon Sep 17 00:00:00 2001 From: Daniel Liburd Date: Wed, 8 Jan 2025 17:01:45 +0000 Subject: [PATCH 5/6] Update test fixture with new question data --- integration_tests/fixtures/applicationData.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/integration_tests/fixtures/applicationData.json b/integration_tests/fixtures/applicationData.json index 882715c..bb74855 100644 --- a/integration_tests/fixtures/applicationData.json +++ b/integration_tests/fixtures/applicationData.json @@ -258,7 +258,18 @@ "additionalInformationDetail": "some information" } }, - "current-offences": { + "community-supervision-and-current-offences": { + "community-supervision": { + "probationSupervision": "yes" + }, + "cpp-details": { + "cppDetails": { + "name": "A. CPP", + "probationRegion": "some region", + "email": "cpp@moj.gov.uk", + "telephone": "012345" + } + }, "current-offence-data": [ { "titleAndNumber": "Arson", From 774ab28eb65347097b3a955b6fd54eafcc694873 Mon Sep 17 00:00:00 2001 From: Daniel Liburd Date: Wed, 8 Jan 2025 17:02:18 +0000 Subject: [PATCH 6/6] Delete orphaned CPP details and current offence data If a user answers yes to the community supervision question and fills in subsequent screens, the data will persist even after coming back to change the answer to 'no' and will show on the check your answers screen and be submitted with the application. This change ensures we remove that data when the answer is 'no. --- .../applications/deleteOrphanedData.test.ts | 53 +++++++++++++++++++ .../utils/applications/deleteOrphanedData.ts | 17 ++++++ 2 files changed, 70 insertions(+) diff --git a/server/utils/applications/deleteOrphanedData.test.ts b/server/utils/applications/deleteOrphanedData.test.ts index 6159c36..dc1f089 100644 --- a/server/utils/applications/deleteOrphanedData.test.ts +++ b/server/utils/applications/deleteOrphanedData.test.ts @@ -212,4 +212,57 @@ describe('deleteOrphanedFollowOnAnswers', () => { }) }) }) + describe('cpp-details and current offences', () => { + describe('when probation supervision is set to no', () => { + const applicationData = { + 'community-supervision-and-current-offences': { + 'community-supervision': { + probationSupervision: 'no', + }, + 'cpp-details': { + cppDetails: { + name: 'A. CPP', + probationRegion: 'some region', + email: 'cpp@moj.gov.uk', + telephone: '012345', + }, + }, + 'current-offence-data': [ + { + titleAndNumber: 'Arson', + offenceCategory: 'Arson', + 'offenceDate-day': '5', + 'offenceDate-month': '6', + 'offenceDate-year': '1940', + sentenceLength: '3 years', + summary: 'summary detail', + outstandingCharges: 'yes', + outstandingChargesDetail: 'outstanding charges detail', + }, + { + titleAndNumber: 'Stalking', + offenceCategory: 'Stalking', + 'offenceDate-day': '6', + 'offenceDate-month': '7', + 'offenceDate-year': '2023', + sentenceLength: '2 months', + summary: 'more summary detail', + outstandingCharges: 'no', + }, + ], + 'current-offences': {}, + }, + } + + it('removes cpp details and current offence data', () => { + expect(deleteOrphanedFollowOnAnswers(applicationData)).toEqual({ + 'community-supervision-and-current-offences': { + 'community-supervision': { + probationSupervision: 'no', + }, + }, + }) + }) + }) + }) }) diff --git a/server/utils/applications/deleteOrphanedData.ts b/server/utils/applications/deleteOrphanedData.ts index c4f005f..15d245d 100644 --- a/server/utils/applications/deleteOrphanedData.ts +++ b/server/utils/applications/deleteOrphanedData.ts @@ -28,6 +28,12 @@ export default function deleteOrphanedFollowOnAnswers(applicationData: AnyValue) } } + const deleteOrphanedCPPAndCurrentOffenceData = () => { + delete applicationData['community-supervision-and-current-offences']['cpp-details'] + delete applicationData['community-supervision-and-current-offences']['current-offence-data'] + delete applicationData['community-supervision-and-current-offences']['current-offences'] + } + const hasOrphanedInformation = ({ taskName, pageName, @@ -90,5 +96,16 @@ export default function deleteOrphanedFollowOnAnswers(applicationData: AnyValue) deleteAddressHistoryInformation() } + if ( + hasOrphanedInformation({ + taskName: 'community-supervision-and-current-offences', + pageName: 'community-supervision', + questionKey: 'probationSupervision', + answerToCheck: 'no', + }) + ) { + deleteOrphanedCPPAndCurrentOffenceData() + } + return applicationData }