diff --git a/assets/scss/application.scss b/assets/scss/application.scss
index 4a9e2ef0..f1606291 100644
--- a/assets/scss/application.scss
+++ b/assets/scss/application.scss
@@ -35,3 +35,4 @@ $govuk-page-width: $moj-page-width;
margin-bottom: govuk-spacing(3);
}
}
+
diff --git a/e2e-tests/steps/apply.ts b/e2e-tests/steps/apply.ts
index d61fa2fd..9aca2423 100644
--- a/e2e-tests/steps/apply.ts
+++ b/e2e-tests/steps/apply.ts
@@ -73,7 +73,7 @@ export const completeBeforeYouStartSection = async (page: Page, name: string) =>
export const completeAreaAndFundingSection = async (page: Page, name: string) => {
await completeAreaInformationTask(page, name)
- await completeFundingInformationTask(page, name)
+ await completeFundingInformationTask(page)
}
export const completeAboutThePersonSection = async (page: Page, name: string) => {
diff --git a/e2e-tests/steps/areaAndFundingSection.ts b/e2e-tests/steps/areaAndFundingSection.ts
index 25f9886a..1f03dfb6 100644
--- a/e2e-tests/steps/areaAndFundingSection.ts
+++ b/e2e-tests/steps/areaAndFundingSection.ts
@@ -1,25 +1,17 @@
import { Page } from '@playwright/test'
import { ApplyPage, TaskListPage } from '../pages/apply'
-export const completeFundingInformationTask = async (page: Page, name: string) => {
+export const completeFundingInformationTask = async (page: Page) => {
const taskListPage = new TaskListPage(page)
await taskListPage.clickTask('Confirm funding and ID')
- const fundingInformationPage = await ApplyPage.initialize(
- page,
- `How will ${name} pay for their accommodation and service charge?`,
- )
- await fundingInformationPage.checkRadio('Personal money or wages', true)
+ const fundingInformationPage = await ApplyPage.initialize(page, 'Funding CAS-2 accommodation')
+ await fundingInformationPage.checkRadio('Personal savings, salary or pension', true)
+ await fundingInformationPage.checkRadioInGroup('Does the applicant have a National Insurance number?', 'Yes')
+ await fundingInformationPage.checkRadioByTestId('receiving-benefits-radio-yes')
+ await fundingInformationPage.checkRadioByTestId('received-benefit-sanctions-radio-yes')
+ await fundingInformationPage.checkRadioInGroup('Is the applicant in education or receiving any training?', 'No')
await fundingInformationPage.clickSave()
- await completeNationalInsurancePage(page, name)
-}
-
-async function completeNationalInsurancePage(page: Page, name: string) {
- const willAnswerEqualityQuestionsPage = await ApplyPage.initialize(
- page,
- `What is ${name}'s National Insurance number? (Optional)`,
- )
- await willAnswerEqualityQuestionsPage.clickSave()
}
export const completeAreaInformationTask = async (page: Page, name: string) => {
diff --git a/integration_tests/fixtures/applicationData.json b/integration_tests/fixtures/applicationData.json
index d6f0b0dd..a77e1cba 100644
--- a/integration_tests/fixtures/applicationData.json
+++ b/integration_tests/fixtures/applicationData.json
@@ -42,14 +42,17 @@
}
},
"funding-information": {
- "funding-source": {
- "fundingSource": "benefits"
- },
- "identification": {
+ "funding-cas2-accommodation": {
+ "fundingSource": "personalSavings",
+ "fundingSourceDetail": "Personal savings details",
+ "hasNationalInsuranceNumber": "yes",
+ "nationalInsuranceNumber": "SF123456X",
+ "receivingBenefits": "yes",
+ "receivedBenefitSanctions": "no",
+ "inEducationOrTraining": "no"
+ },
+ "applicant-id": {
"idDocuments": "passport"
- },
- "national-insurance": {
- "nationalInsuranceNumber": "12345"
}
},
"solicitor-details": {
diff --git a/integration_tests/pages/apply/area-and-funding/funding-information/alternativeApplicantIdPage.ts b/integration_tests/pages/apply/area-and-funding/funding-information/alternativeApplicantIdPage.ts
new file mode 100644
index 00000000..7909ff4d
--- /dev/null
+++ b/integration_tests/pages/apply/area-and-funding/funding-information/alternativeApplicantIdPage.ts
@@ -0,0 +1,24 @@
+import { Cas2v2Application as Application } from '../../../../../server/@types/shared/models/Cas2v2Application'
+import ApplyPage from '../../applyPage'
+import paths from '../../../../../server/paths/apply'
+
+export default class AlternativeApplicantIdPage extends ApplyPage {
+ constructor(private readonly application: Application) {
+ super(
+ 'What other identification document (ID) does the applicant have?',
+ application,
+ 'funding-information',
+ 'alternative-applicant-id',
+ )
+ }
+
+ static visit(application: Application): void {
+ cy.visit(
+ paths.applications.pages.show({
+ id: application.id,
+ task: 'funding-information',
+ page: 'alternative-applicant-id',
+ }),
+ )
+ }
+}
diff --git a/integration_tests/pages/apply/area-and-funding/funding-information/applicantIdPage.ts b/integration_tests/pages/apply/area-and-funding/funding-information/applicantIdPage.ts
new file mode 100644
index 00000000..38f24aad
--- /dev/null
+++ b/integration_tests/pages/apply/area-and-funding/funding-information/applicantIdPage.ts
@@ -0,0 +1,19 @@
+import { Cas2v2Application as Application } from '../../../../../server/@types/shared/models/Cas2v2Application'
+import ApplyPage from '../../applyPage'
+import paths from '../../../../../server/paths/apply'
+
+export default class ApplicantIdPage extends ApplyPage {
+ constructor(private readonly application: Application) {
+ super(`What identity document (ID) does the applicant have?`, application, 'funding-information', 'applicant-id')
+ }
+
+ static visit(application: Application): void {
+ cy.visit(
+ paths.applications.pages.show({
+ id: application.id,
+ task: 'funding-information',
+ page: 'applicant-id',
+ }),
+ )
+ }
+}
diff --git a/integration_tests/pages/apply/area-and-funding/funding-information/fundingCas2AccommodationPage.ts b/integration_tests/pages/apply/area-and-funding/funding-information/fundingCas2AccommodationPage.ts
new file mode 100644
index 00000000..a48a78aa
--- /dev/null
+++ b/integration_tests/pages/apply/area-and-funding/funding-information/fundingCas2AccommodationPage.ts
@@ -0,0 +1,46 @@
+import { Cas2v2Application as Application } from '@approved-premises/api'
+import ApplyPage from '../../applyPage'
+import { FundingSources } from '../../../../../server/form-pages/apply/area-and-funding/funding-information/fundingCas2Accommodation'
+
+export default class FundingCas2AccommodationPage extends ApplyPage {
+ constructor(private readonly application: Application) {
+ super('Funding CAS-2 accommodation', application, 'funding-information', 'funding-cas2-accommodation')
+ }
+
+ completeWithPersonalSavings(): void {
+ this.selectFundingSource('personalSavings')
+ this.enterFundingSourceDetails()
+ this.enterNationalInsuranceNumber()
+ this.enterBenefitsDetails()
+ this.selectInEducationOrTraining()
+ }
+
+ completeWithHousingBenefits(): void {
+ this.selectFundingSource('benefits')
+ this.enterNationalInsuranceNumber()
+ this.enterBenefitsDetails()
+ this.selectInEducationOrTraining()
+ }
+
+ private selectFundingSource(fundingSource: FundingSources): void {
+ this.checkRadioByNameAndValue('fundingSource', fundingSource)
+ }
+
+ private enterFundingSourceDetails(): void {
+ this.getTextInputByIdAndEnterDetails('fundingSourceDetail', 'Funding source details')
+ }
+
+ private enterNationalInsuranceNumber(): void {
+ this.checkRadioByNameAndValue('hasNationalInsuranceNumber', 'yes')
+ this.getTextInputByIdAndEnterDetails('nationalInsuranceNumber', 'SF123456X')
+ }
+
+ private enterBenefitsDetails(): void {
+ this.checkRadioByNameAndValue('receivingBenefits', 'yes')
+ this.checkRadioByNameAndValue('receivedBenefitSanctions', 'no')
+ }
+
+ private selectInEducationOrTraining(): void {
+ this.checkRadioByNameAndValue('inEducationOrTraining', 'no')
+ }
+}
diff --git a/integration_tests/tests/apply/area-and-funding/funding-information/complete_alternative_applicant_id_page.cy.ts b/integration_tests/tests/apply/area-and-funding/funding-information/complete_alternative_applicant_id_page.cy.ts
new file mode 100644
index 00000000..d763a049
--- /dev/null
+++ b/integration_tests/tests/apply/area-and-funding/funding-information/complete_alternative_applicant_id_page.cy.ts
@@ -0,0 +1,68 @@
+// Feature: Referrer completes 'alternative applicant ID' page
+// So that I can complete the "Funding information" task
+// As a referrer
+// I want to complete the 'alternative applicant ID' page
+//
+// Background:
+// Given an application exists
+// And I am logged in
+// And I visit the 'alternative applicant ID' page
+//
+// Scenario: navigate to task list page
+// When I select a form of ID
+// And I continue to the next task / page
+// Then I am redirected to the task list page
+
+import Page from '../../../../pages/page'
+import { personFactory, applicationFactory } from '../../../../../server/testutils/factories/index'
+import AlternativeApplicantIdPage from '../../../../pages/apply/area-and-funding/funding-information/alternativeApplicantIdPage'
+import TaskListPage from '../../../../pages/apply/taskListPage'
+
+context('Visit alternative applicant ID page', () => {
+ const person = personFactory.build({ name: 'Roger Smith' })
+
+ beforeEach(function test() {
+ cy.task('reset')
+ cy.task('stubSignIn')
+ cy.task('stubAuthUser')
+
+ cy.fixture('applicationData.json').then(applicationData => {
+ applicationData['funding-information'] = {}
+ const application = applicationFactory.build({
+ id: 'abc123',
+ person,
+ data: applicationData,
+ })
+ cy.wrap(application).as('application')
+ })
+ })
+
+ beforeEach(function test() {
+ // And an application exists
+ // -------------------------
+ cy.task('stubApplicationGet', { application: this.application })
+ cy.task('stubApplicationUpdate', { application: this.application })
+
+ // Given I am logged in
+ //---------------------
+ cy.signIn()
+
+ // And I am on the alternative applicant ID page
+ // --------------------------------
+ AlternativeApplicantIdPage.visit(this.application)
+ })
+
+ // Scenario: navigate to task list page
+ // ----------------------------------------
+ it('redirects to the task list page', function test() {
+ // When I select a form of ID
+ const page = Page.verifyOnPage(AlternativeApplicantIdPage, this.application)
+ page.checkCheckboxByValue('contract')
+
+ // And I continue to the next task / page
+ page.clickSubmit()
+
+ // Then I am redirected to the task list page
+ Page.verifyOnPage(TaskListPage, this.application)
+ })
+})
diff --git a/integration_tests/tests/apply/area-and-funding/funding-information/complete_applicant_id_page.cy.ts b/integration_tests/tests/apply/area-and-funding/funding-information/complete_applicant_id_page.cy.ts
new file mode 100644
index 00000000..2928e0ae
--- /dev/null
+++ b/integration_tests/tests/apply/area-and-funding/funding-information/complete_applicant_id_page.cy.ts
@@ -0,0 +1,88 @@
+// Feature: Referrer completes 'applicant ID' page
+// So that I can complete the "Funding information" task
+// As a referrer
+// I want to complete the 'applicant ID' page
+//
+// Background:
+// Given an application exists
+// And I am logged in
+// And I visit the 'applicant ID' page
+//
+// Scenario: navigate to alternative applicant ID page
+// When I select 'none'
+// And I continue to the next task / page
+// Then I am redirected to the alternative applicant ID page
+//
+// Scenario: navigate to task list page
+// When I select a form of ID
+// And I continue to the next task / page
+// Then I am redirected to the task list page
+
+import Page from '../../../../pages/page'
+import ApplicantIdPage from '../../../../pages/apply/area-and-funding/funding-information/applicantIdPage'
+import TaskListPage from '../../../../pages/apply/taskListPage'
+import { personFactory, applicationFactory } from '../../../../../server/testutils/factories/index'
+import AlternativeApplicantIdPage from '../../../../pages/apply/area-and-funding/funding-information/alternativeApplicantIdPage'
+
+context('Visit applicant ID page', () => {
+ const person = personFactory.build({ name: 'Roger Smith' })
+
+ beforeEach(function test() {
+ cy.task('reset')
+ cy.task('stubSignIn')
+ cy.task('stubAuthUser')
+
+ cy.fixture('applicationData.json').then(applicationData => {
+ applicationData['funding-information'] = {}
+ const application = applicationFactory.build({
+ id: 'abc123',
+ person,
+ data: applicationData,
+ })
+ cy.wrap(application).as('application')
+ })
+ })
+
+ beforeEach(function test() {
+ // And an application exists
+ // -------------------------
+ cy.task('stubApplicationGet', { application: this.application })
+ cy.task('stubApplicationUpdate', { application: this.application })
+
+ // Given I am logged in
+ //---------------------
+ cy.signIn()
+
+ // And I am on the applicant ID page
+ // --------------------------------
+ ApplicantIdPage.visit(this.application)
+ })
+
+ // Scenario: navigate to alternative applicant ID page
+ // ----------------------------------------
+ it('redirects to the alternative applicant ID page', function test() {
+ // When I select 'none'
+ const page = Page.verifyOnPage(ApplicantIdPage, this.application)
+ page.checkCheckboxByValue('none')
+
+ // And I continue to the next task / page
+ page.clickSubmit()
+
+ // Then I am redirected to the alternative applicant ID page
+ Page.verifyOnPage(AlternativeApplicantIdPage, this.application)
+ })
+
+ // Scenario: navigate to the task list page
+ // ----------------------------------------
+ it('redirects to the task list page', function test() {
+ // When I select a form of ID
+ const page = Page.verifyOnPage(ApplicantIdPage, this.application)
+ page.checkCheckboxByValue('passport')
+
+ // And I continue to the next task / page
+ page.clickSubmit()
+
+ // Then I am redirected to the task list page
+ Page.verifyOnPage(TaskListPage, this.application)
+ })
+})
diff --git a/integration_tests/tests/apply/area-and-funding/funding-information/complete_funding_cas2_accommodation.cy.ts b/integration_tests/tests/apply/area-and-funding/funding-information/complete_funding_cas2_accommodation.cy.ts
new file mode 100644
index 00000000..91eb750f
--- /dev/null
+++ b/integration_tests/tests/apply/area-and-funding/funding-information/complete_funding_cas2_accommodation.cy.ts
@@ -0,0 +1,88 @@
+// Feature: Referrer completes 'Funding CAS-2 Accommodation' question page
+// As a referrer,
+// I want to confirm how the applicant is funding their CAS2 accommodation
+// So that I can get the applicant into accommodation as quickly as possible with no FIEs
+//
+// Scenario: When the applicant is using personal savings to fund the accommodation
+// Given I'm on the 'Funding CAS-2 Accommodation' question page
+// When I select personal savings and give valid answers for all other questions
+// Then I am taken to the task list page
+//
+// Scenario: When the applicant is using house benefits to fund the accommodation
+// Given I'm on the 'Funding CAS-2 Accommodation' question page
+// When I select housing benefits and give valid answers for all other questions
+// Then I am taken to the applicant ID page
+
+import FundingCas2AccommodationPage from '../../../../pages/apply/area-and-funding/funding-information/fundingCas2AccommodationPage'
+import Page from '../../../../pages/page'
+import TaskListPage from '../../../../pages/apply/taskListPage'
+import ApplicantIdPage from '../../../../pages/apply/area-and-funding/funding-information/applicantIdPage'
+import { personFactory, applicationFactory } from '../../../../../server/testutils/factories/index'
+
+context('Visit "Confirm funding and ID" section', () => {
+ const person = personFactory.build({ name: 'Roger Smith' })
+
+ beforeEach(function test() {
+ cy.task('reset')
+ cy.task('stubSignIn')
+ cy.task('stubAuthUser')
+
+ cy.fixture('applicationData.json').then(applicationData => {
+ applicationData['funding-information'] = {}
+ const application = applicationFactory.build({
+ id: 'abc123',
+ person,
+ })
+ application.data = applicationData
+ cy.wrap(application).as('application')
+ cy.wrap(application.data).as('applicationData')
+ })
+ })
+
+ beforeEach(function test() {
+ // And an application exists
+ cy.task('stubApplicationGet', { application: this.application })
+ cy.task('stubApplicationUpdate', { application: this.application })
+
+ // Given I am logged in
+ //---------------------
+ cy.signIn()
+
+ // And I am on the Funding CAS-2 accommodation page
+ // --------------------------------
+ cy.visit('applications/abc123/tasks/funding-information/pages/funding-cas2-accommodation')
+ Page.verifyOnPage(FundingCas2AccommodationPage, this.application)
+ })
+
+ // Scenario: When the applicant is using personal savings to fund the accommodation
+ // ----------------------------
+ it('continues to the task list page', function test() {
+ // Given I am on the Funding CAS-2 Accommodation
+ const page = Page.verifyOnPage(FundingCas2AccommodationPage, this.application)
+
+ // When I complete the answers on the page
+ page.completeWithPersonalSavings()
+
+ // And I click submit
+ page.clickSubmit()
+
+ // I am taken to the task list page
+ Page.verifyOnPage(TaskListPage, this.application)
+ })
+
+ // Scenario: When the applicant is using house benefits to fund the accommodation
+ // ----------------------------
+ it('continues to the applicant ID page', function test() {
+ // Given I am on the Funding CAS-2 Accommodation
+ const page = Page.verifyOnPage(FundingCas2AccommodationPage, this.application)
+
+ // When I complete the answers on the page
+ page.completeWithHousingBenefits()
+
+ // And I click submit
+ page.clickSubmit()
+
+ // I am taken to the applicant ID page
+ Page.verifyOnPage(ApplicantIdPage, this.application)
+ })
+})
diff --git a/server/form-pages/apply/area-and-funding/funding-information/alternativeID.test.ts b/server/form-pages/apply/area-and-funding/funding-information/alternativeApplicantID.test.ts
similarity index 95%
rename from server/form-pages/apply/area-and-funding/funding-information/alternativeID.test.ts
rename to server/form-pages/apply/area-and-funding/funding-information/alternativeApplicantID.test.ts
index dbfd33b5..78cc6fd5 100644
--- a/server/form-pages/apply/area-and-funding/funding-information/alternativeID.test.ts
+++ b/server/form-pages/apply/area-and-funding/funding-information/alternativeApplicantID.test.ts
@@ -1,19 +1,20 @@
import { itShouldHaveNextValue, itShouldHavePreviousValue } from '../../../shared-examples'
import { applicationFactory } from '../../../../testutils/factories/index'
-import AlternativeIdentification, { AlternativeIdentificationBody } from './alternativeID'
+import AlternativeIdentification, { AlternativeIdentificationBody } from './alternativeApplicantID'
describe('AlternativeIdentification', () => {
const application = applicationFactory.build({})
- itShouldHaveNextValue(new AlternativeIdentification({}, application), 'national-insurance')
- itShouldHavePreviousValue(new AlternativeIdentification({}, application), 'identification')
+ itShouldHaveNextValue(new AlternativeIdentification({}, application), '')
+ itShouldHavePreviousValue(new AlternativeIdentification({}, application), 'applicant-id')
describe('errors', () => {
it('returns error if no document is selected', () => {
const page = new AlternativeIdentification({}, application)
expect(page.errors()).toEqual({
- alternativeIDDocuments: "Select an ID document or 'Other type of identification'",
+ alternativeIDDocuments:
+ "Select other identity documents the applicant has, or select 'Other type of identification'",
})
})
diff --git a/server/form-pages/apply/area-and-funding/funding-information/alternativeID.ts b/server/form-pages/apply/area-and-funding/funding-information/alternativeApplicantID.ts
similarity index 89%
rename from server/form-pages/apply/area-and-funding/funding-information/alternativeID.ts
rename to server/form-pages/apply/area-and-funding/funding-information/alternativeApplicantID.ts
index 012ae6b7..11d2195b 100644
--- a/server/form-pages/apply/area-and-funding/funding-information/alternativeID.ts
+++ b/server/form-pages/apply/area-and-funding/funding-information/alternativeApplicantID.ts
@@ -7,7 +7,7 @@ import errorLookups from '../../../../i18n/en/errors.json'
import { nameOrPlaceholderCopy } from '../../../../utils/utils'
import { getQuestions } from '../../../utils/questions'
-const applicationQuestions = getQuestions('')['funding-information']['alternative-identification']
+const applicationQuestions = getQuestions('')['funding-information']['alternative-applicant-id']
const alternativeIDOptions = applicationQuestions.alternativeIDDocuments.answers
@@ -17,11 +17,11 @@ export type AlternativeIdentificationBody = {
}
@Page({
- name: 'alternative-identification',
+ name: 'alternative-applicant-id',
bodyProperties: ['alternativeIDDocuments', 'other'],
})
export default class AlternativeIdentification implements TaskListPage {
- documentTitle = 'What alternative identification documentation (ID) does the person have?'
+ documentTitle = 'What other identification document (ID) does the applicant have?'
title
@@ -31,8 +31,6 @@ export default class AlternativeIdentification implements TaskListPage {
body: AlternativeIdentificationBody
- guidanceHtml = `The applicant needs ID if they are applying for Universal Credit for financial support, and Housing Benefit to cover their rent.
If they want to receive an advance payment of Universal Credit on the day of release, they will need a bank account and photo ID.`
-
hintHtml = `
${applicationQuestions.alternativeIDDocuments.hint}
`
@@ -41,16 +39,16 @@ export default class AlternativeIdentification implements TaskListPage {
body: Partial,
private readonly application: Application,
) {
- this.questions = getQuestions(this.personName)['funding-information']['alternative-identification']
+ this.questions = getQuestions(this.personName)['funding-information']['alternative-applicant-id']
this.title = this.questions.alternativeIDDocuments.question
}
previous() {
- return 'identification'
+ return 'applicant-id'
}
next() {
- return 'national-insurance'
+ return ''
}
errors() {
diff --git a/server/form-pages/apply/area-and-funding/funding-information/identification.test.ts b/server/form-pages/apply/area-and-funding/funding-information/applicantID.test.ts
similarity index 76%
rename from server/form-pages/apply/area-and-funding/funding-information/identification.test.ts
rename to server/form-pages/apply/area-and-funding/funding-information/applicantID.test.ts
index 94a9e7bf..ab06a1e4 100644
--- a/server/form-pages/apply/area-and-funding/funding-information/identification.test.ts
+++ b/server/form-pages/apply/area-and-funding/funding-information/applicantID.test.ts
@@ -1,18 +1,18 @@
import { itShouldHaveNextValue, itShouldHavePreviousValue } from '../../../shared-examples'
import { applicationFactory } from '../../../../testutils/factories/index'
-import Identification from './identification'
+import ApplicantID from './applicantID'
describe('Identification', () => {
const application = applicationFactory.build({})
- itShouldHaveNextValue(new Identification({ idDocuments: ['none'] }, application), 'alternative-identification')
- itShouldHaveNextValue(new Identification({ idDocuments: ['travelPass'] }, application), 'national-insurance')
+ itShouldHaveNextValue(new ApplicantID({ idDocuments: ['none'] }, application), 'alternative-applicant-id')
+ itShouldHaveNextValue(new ApplicantID({ idDocuments: ['travelPass'] }, application), '')
- itShouldHavePreviousValue(new Identification({}, application), 'funding-source')
+ itShouldHavePreviousValue(new ApplicantID({}, application), 'funding-cas2-accommodation')
describe('errors', () => {
it('returns error if no document is selected', () => {
- const page = new Identification({}, application)
+ const page = new ApplicantID({}, application)
expect(page.errors()).toEqual({ idDocuments: "Select an ID document or 'None of these options'" })
})
@@ -20,7 +20,7 @@ describe('Identification', () => {
describe('items', () => {
it('returns items as expected', () => {
- const page = new Identification({}, application)
+ const page = new ApplicantID({}, application)
const expected = [
{
@@ -68,8 +68,7 @@ describe('Identification', () => {
'data-selector': 'documents',
},
checked: false,
- text: 'UK photo driving licence',
- hint: { text: 'Can be provisional' },
+ text: 'UK photo driving licence (full or provisional)',
value: 'drivingLicence',
},
{
@@ -77,8 +76,7 @@ describe('Identification', () => {
'data-selector': 'documents',
},
checked: false,
- text: 'Recent wage slip',
- hint: { text: 'With payee name and NI number' },
+ text: 'Recent wage slip (with payee name and NI number)',
value: 'wageSlip',
},
{
diff --git a/server/form-pages/apply/area-and-funding/funding-information/identification.ts b/server/form-pages/apply/area-and-funding/funding-information/applicantID.ts
similarity index 62%
rename from server/form-pages/apply/area-and-funding/funding-information/identification.ts
rename to server/form-pages/apply/area-and-funding/funding-information/applicantID.ts
index e47b738a..859f58bd 100644
--- a/server/form-pages/apply/area-and-funding/funding-information/identification.ts
+++ b/server/form-pages/apply/area-and-funding/funding-information/applicantID.ts
@@ -9,20 +9,20 @@ import { getQuestions } from '../../../utils/questions'
const applicationQuestions = getQuestions('')
-export const idDocumentOptions = applicationQuestions['funding-information'].identification.idDocuments.answers
+export const idDocumentOptions = applicationQuestions['funding-information']['applicant-id'].idDocuments.answers
export type IDDocumentOptions = keyof typeof idDocumentOptions
-export type IdentificationBody = {
+export type ApplicantIDBody = {
idDocuments: Array
}
@Page({
- name: 'identification',
+ name: 'applicant-id',
bodyProperties: ['idDocuments'],
})
-export default class Identification implements TaskListPage {
- documentTitle = 'What identification documentation (ID) does the person have?'
+export default class ApplicantID implements TaskListPage {
+ documentTitle = 'What identity document (ID) does the applicant have?'
title
@@ -30,27 +30,25 @@ export default class Identification implements TaskListPage {
questions
- body: IdentificationBody
-
- guidanceHtml = `The applicant needs ID if they are applying for Universal Credit for financial support, and Housing Benefit to cover their rent.
If they want to receive an advance payment of Universal Credit on the day of release, they will need a bank account and photo ID.`
+ body: ApplicantIDBody
constructor(
- body: Partial,
+ body: Partial,
private readonly application: Application,
) {
- this.questions = getQuestions(this.personName)['funding-information'].identification.idDocuments
+ this.questions = getQuestions(this.personName)['funding-information']['applicant-id'].idDocuments
this.title = this.questions.question
}
previous() {
- return 'funding-source'
+ return 'funding-cas2-accommodation'
}
next() {
if (this.body.idDocuments.includes('none')) {
- return 'alternative-identification'
+ return 'alternative-applicant-id'
}
- return 'national-insurance'
+ return ''
}
errors() {
@@ -68,11 +66,6 @@ export default class Identification implements TaskListPage {
items.forEach(item => {
item.attributes = { 'data-selector': 'documents' }
- if (item.value === 'wageSlip') {
- item.hint = { text: 'With payee name and NI number' }
- } else if (item.value === 'drivingLicence') {
- item.hint = { text: 'Can be provisional' }
- }
})
return [...items, { divider: 'or' }, { ...none }]
diff --git a/server/form-pages/apply/area-and-funding/funding-information/fundingCas2Accommodation.test.ts b/server/form-pages/apply/area-and-funding/funding-information/fundingCas2Accommodation.test.ts
new file mode 100644
index 00000000..7cd9ccf3
--- /dev/null
+++ b/server/form-pages/apply/area-and-funding/funding-information/fundingCas2Accommodation.test.ts
@@ -0,0 +1,78 @@
+import { itShouldHaveNextValue, itShouldHavePreviousValue } from '../../../shared-examples'
+import FundingCas2Accommodation, { FundingCas2AccommodationBody } from './fundingCas2Accommodation'
+import { personFactory, applicationFactory } from '../../../../testutils/factories/index'
+
+describe('FundingCas2Accommodation', () => {
+ const application = applicationFactory.build({ person: personFactory.build({ name: 'Roger Smith' }) })
+
+ describe('title', () => {
+ it('sets the title', () => {
+ const page = new FundingCas2Accommodation({ fundingSource: 'personalSavings' }, application)
+
+ expect(page.title).toEqual('Funding CAS-2 accommodation')
+ })
+ })
+
+ it('should set the body', () => {
+ const page = new FundingCas2Accommodation(
+ {
+ fundingSource: 'personalSavings',
+ fundingSourceDetail: 'Funding source details',
+ hasNationalInsuranceNumber: 'yes',
+ nationalInsuranceNumber: 'SF123456X',
+ receivingBenefits: 'yes',
+ receivedBenefitSanctions: 'no',
+ inEducationOrTraining: 'yes',
+ },
+ application,
+ )
+
+ expect(page.body).toEqual({
+ fundingSource: 'personalSavings',
+ fundingSourceDetail: 'Funding source details',
+ hasNationalInsuranceNumber: 'yes',
+ nationalInsuranceNumber: 'SF123456X',
+ receivingBenefits: 'yes',
+ receivedBenefitSanctions: 'no',
+ inEducationOrTraining: 'yes',
+ } as FundingCas2AccommodationBody)
+ })
+
+ itShouldHaveNextValue(new FundingCas2Accommodation({ fundingSource: 'personalSavings' }, application), '')
+ itShouldHaveNextValue(new FundingCas2Accommodation({ fundingSource: 'benefits' }, application), 'applicant-id')
+ itShouldHavePreviousValue(new FundingCas2Accommodation({ fundingSource: 'personalSavings' }, application), 'taskList')
+
+ describe('errors', () => {
+ it('should return errors when yes/no questions are blank', () => {
+ const page = new FundingCas2Accommodation({}, application)
+
+ expect(page.errors()).toEqual({
+ fundingSource: 'Select how the applicant will pay for their accommodation and the service charge',
+ hasNationalInsuranceNumber: 'Select if the applicant has a National Insurance number',
+ receivingBenefits: 'Select if the applicant is currently receiving any benefits',
+ inEducationOrTraining: 'Select if the applicant is currently in education or receiving any training',
+ })
+ })
+
+ describe('when receiving benefits question is answered', () => {
+ it('should return an error when benefit sanctions question is left blank', () => {
+ const page = new FundingCas2Accommodation(
+ {
+ fundingSource: 'personalSavings',
+ fundingSourceDetail: 'Funding source details',
+ hasNationalInsuranceNumber: 'yes',
+ nationalInsuranceNumber: 'SF123456X',
+ receivingBenefits: 'yes',
+ receivedBenefitSanctions: null,
+ inEducationOrTraining: 'yes',
+ },
+ application,
+ )
+
+ expect(page.errors()).toEqual({
+ receivedBenefitSanctions: 'Select if the applicant has received any benefit sanctions in the last 6 months',
+ })
+ })
+ })
+ })
+})
diff --git a/server/form-pages/apply/area-and-funding/funding-information/fundingCas2Accommodation.ts b/server/form-pages/apply/area-and-funding/funding-information/fundingCas2Accommodation.ts
new file mode 100644
index 00000000..cc9ec689
--- /dev/null
+++ b/server/form-pages/apply/area-and-funding/funding-information/fundingCas2Accommodation.ts
@@ -0,0 +1,100 @@
+import type { TaskListErrors, YesNoOrDontKnow, YesOrNo } from '@approved-premises/ui'
+import { Cas2v2Application 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 FundingSources = 'personalSavings' | 'benefits'
+
+const hasNationalInsuranceOptions =
+ getQuestions('')['funding-information']['funding-cas2-accommodation'].hasNationalInsuranceNumber.answers
+
+export type FundingCas2AccommodationBody = {
+ fundingSource: FundingSources
+ fundingSourceDetail: string
+ hasNationalInsuranceNumber: YesNoOrDontKnow
+ nationalInsuranceNumber: string
+ receivingBenefits: YesOrNo
+ receivedBenefitSanctions: YesOrNo
+ inEducationOrTraining: YesOrNo
+}
+
+@Page({
+ name: 'funding-cas2-accommodation',
+ bodyProperties: [
+ 'fundingSource',
+ 'fundingSourceDetail',
+ 'hasNationalInsuranceNumber',
+ 'nationalInsuranceNumber',
+ 'receivingBenefits',
+ 'receivedBenefitSanctions',
+ 'inEducationOrTraining',
+ ],
+})
+export default class FundingCas2Accommodation implements TaskListPage {
+ documentTitle = 'Funding CAS-2 accommodation'
+
+ personName = nameOrPlaceholderCopy(this.application.person)
+
+ title = 'Funding CAS-2 accommodation'
+
+ questions
+
+ options: Record
+
+ body: FundingCas2AccommodationBody
+
+ constructor(
+ body: Partial,
+ private readonly application: Application,
+ ) {
+ this.body = body as FundingCas2AccommodationBody
+
+ const applicationQuestions = getQuestions(this.personName)
+ this.questions = applicationQuestions['funding-information']['funding-cas2-accommodation']
+ }
+
+ previous() {
+ return 'taskList'
+ }
+
+ next() {
+ if (this.body.fundingSource === 'personalSavings') {
+ return ''
+ }
+ return 'applicant-id'
+ }
+
+ errors() {
+ const errors: TaskListErrors = {}
+ if (this.body.fundingSource !== 'personalSavings' && this.body.fundingSource !== 'benefits') {
+ errors.fundingSource = 'Select how the applicant will pay for their accommodation and the service charge'
+ }
+ if (!this.body.hasNationalInsuranceNumber) {
+ errors.hasNationalInsuranceNumber = 'Select if the applicant has a National Insurance number'
+ }
+ if (!this.body.receivingBenefits) {
+ errors.receivingBenefits = 'Select if the applicant is currently receiving any benefits'
+ }
+ if (this.body.receivingBenefits === 'yes' && !this.body.receivedBenefitSanctions) {
+ errors.receivedBenefitSanctions =
+ 'Select if the applicant has received any benefit sanctions in the last 6 months'
+ }
+ if (!this.body.inEducationOrTraining) {
+ errors.inEducationOrTraining = 'Select if the applicant is currently in education or receiving any training'
+ }
+ return errors
+ }
+
+ items(conditionalHtml: string) {
+ const items = convertKeyValuePairToRadioItems(hasNationalInsuranceOptions, this.body.hasNationalInsuranceNumber)
+
+ const yes = items.shift()
+ const dontKnow = items.pop()
+ items.push({ divider: 'or' })
+
+ return [{ ...yes, conditional: { html: conditionalHtml } }, ...items, { ...dontKnow }]
+ }
+}
diff --git a/server/form-pages/apply/area-and-funding/funding-information/fundingInformation.test.ts b/server/form-pages/apply/area-and-funding/funding-information/fundingInformation.test.ts
deleted file mode 100644
index fbedb0b1..00000000
--- a/server/form-pages/apply/area-and-funding/funding-information/fundingInformation.test.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { itShouldHaveNextValue, itShouldHavePreviousValue } from '../../../shared-examples'
-import FundingInformation, { FundingSources } from './fundingInformation'
-import { personFactory, applicationFactory } from '../../../../testutils/factories/index'
-
-describe('FundingInformation', () => {
- const application = applicationFactory.build({ person: personFactory.build({ name: 'Roger Smith' }) })
-
- describe('title', () => {
- it('sets the title', () => {
- const page = new FundingInformation({ fundingSource: 'personalSavings' }, application)
-
- expect(page.title).toEqual('Funding information for Roger Smith')
- })
- })
-
- it('should set the body', () => {
- const page = new FundingInformation(
- {
- fundingSource: 'personalSavings',
- },
- application,
- )
-
- expect(page.body).toEqual({
- fundingSource: 'personalSavings',
- })
- })
-
- itShouldHaveNextValue(new FundingInformation({ fundingSource: 'personalSavings' }, application), 'national-insurance')
- itShouldHaveNextValue(new FundingInformation({ fundingSource: 'benefits' }, application), 'identification')
- itShouldHavePreviousValue(new FundingInformation({ fundingSource: 'personalSavings' }, application), 'taskList')
-
- describe('errors', () => {
- it('should return errors when yes/no questions are blank', () => {
- const page = new FundingInformation({}, application)
-
- expect(page.errors()).toEqual({
- fundingSource: 'Select a funding source',
- })
- })
-
- it('should return an error when the answer is both', () => {
- const page = new FundingInformation(
- {
- fundingSource: 'both' as FundingSources,
- },
- application,
- )
-
- expect(page.errors()).toEqual({
- fundingSource: 'Select a funding source',
- })
- })
- })
-})
diff --git a/server/form-pages/apply/area-and-funding/funding-information/fundingInformation.ts b/server/form-pages/apply/area-and-funding/funding-information/fundingInformation.ts
deleted file mode 100644
index 1ef93900..00000000
--- a/server/form-pages/apply/area-and-funding/funding-information/fundingInformation.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import type { TaskListErrors } from '@approved-premises/ui'
-import { Cas2v2Application 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'
-
-export type FundingSources = 'personalSavings' | 'benefits'
-
-type FundingSourceBody = {
- fundingSource: FundingSources
-}
-
-@Page({
- name: 'funding-source',
- bodyProperties: ['fundingSource'],
-})
-export default class FundingSource implements TaskListPage {
- documentTitle = 'How will the person pay for their accommodation and service charge?'
-
- personName = nameOrPlaceholderCopy(this.application.person)
-
- title = `Funding information for ${this.personName}`
-
- questions
-
- options: Record
-
- body: FundingSourceBody
-
- constructor(
- body: Partial,
- private readonly application: Application,
- ) {
- this.body = body as FundingSourceBody
-
- const applicationQuestions = getQuestions(this.personName)
- this.questions = applicationQuestions['funding-information']['funding-source']
- }
-
- previous() {
- return 'taskList'
- }
-
- next() {
- if (this.body.fundingSource === 'personalSavings') {
- return 'national-insurance'
- }
- return 'identification'
- }
-
- errors() {
- const errors: TaskListErrors = {}
- if (this.body.fundingSource !== 'personalSavings' && this.body.fundingSource !== 'benefits') {
- errors.fundingSource = 'Select a funding source'
- }
- return errors
- }
-}
diff --git a/server/form-pages/apply/area-and-funding/funding-information/index.ts b/server/form-pages/apply/area-and-funding/funding-information/index.ts
index 772c711d..e9a0faed 100644
--- a/server/form-pages/apply/area-and-funding/funding-information/index.ts
+++ b/server/form-pages/apply/area-and-funding/funding-information/index.ts
@@ -1,14 +1,13 @@
/* istanbul ignore file */
import { Task } from '../../../utils/decorators'
-import FundingInformationPage from './fundingInformation'
-import NationalInsurance from './nationalInsurance'
-import Identification from './identification'
-import AlternativeIdentification from './alternativeID'
+import FundingCas2Accommodation from './fundingCas2Accommodation'
+import ApplicantID from './applicantID'
+import AlternativeIdentification from './alternativeApplicantID'
@Task({
name: 'Confirm funding and ID',
slug: 'funding-information',
- pages: [FundingInformationPage, NationalInsurance, Identification, AlternativeIdentification],
+ pages: [FundingCas2Accommodation, ApplicantID, AlternativeIdentification],
})
export default class FundingInformation {}
diff --git a/server/form-pages/apply/area-and-funding/funding-information/nationalInsurance.test.ts b/server/form-pages/apply/area-and-funding/funding-information/nationalInsurance.test.ts
deleted file mode 100644
index 43a353c3..00000000
--- a/server/form-pages/apply/area-and-funding/funding-information/nationalInsurance.test.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { itShouldHaveNextValue, itShouldHavePreviousValue } from '../../../shared-examples'
-import { applicationFactory } from '../../../../testutils/factories/index'
-import NationalInsurance from './nationalInsurance'
-
-describe('NationalInsurance', () => {
- const applicationWithPersonalSavings = applicationFactory.build({
- data: {
- 'funding-information': {
- 'funding-source': {
- fundingSource: 'personalSavings',
- },
- },
- },
- })
-
- const applicationWithAlternativeID = applicationFactory.build({
- data: {
- 'funding-information': {
- identification: {
- idDocuments: 'none',
- },
- },
- },
- })
-
- const applicationWithNoPreviousData = applicationFactory.build({
- data: null,
- })
- const applicationWithNoFundingSource = applicationFactory.build({
- data: {
- 'funding-information': {},
- },
- })
-
- const application = applicationFactory.build({})
-
- itShouldHaveNextValue(new NationalInsurance({}, applicationWithPersonalSavings), '')
- itShouldHavePreviousValue(new NationalInsurance({}, applicationWithNoPreviousData), 'identification')
- itShouldHavePreviousValue(new NationalInsurance({}, applicationWithNoFundingSource), 'identification')
- itShouldHavePreviousValue(new NationalInsurance({}, applicationWithPersonalSavings), 'funding-source')
- itShouldHavePreviousValue(new NationalInsurance({}, applicationWithAlternativeID), 'alternative-identification')
- itShouldHavePreviousValue(new NationalInsurance({}, application), 'identification')
-
- describe('errors', () => {
- it('not implemented', () => {
- const page = new NationalInsurance({}, applicationWithPersonalSavings)
-
- expect(page.errors()).toEqual({})
- })
- })
-})
diff --git a/server/form-pages/apply/area-and-funding/funding-information/nationalInsurance.ts b/server/form-pages/apply/area-and-funding/funding-information/nationalInsurance.ts
deleted file mode 100644
index 3e1df615..00000000
--- a/server/form-pages/apply/area-and-funding/funding-information/nationalInsurance.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import type { TaskListErrors } from '@approved-premises/ui'
-import { Cas2v2Application as Application } from '@approved-premises/api'
-import { nameOrPlaceholderCopy } from '../../../../utils/utils'
-import { Page } from '../../../utils/decorators'
-import TaskListPage from '../../../taskListPage'
-import { getQuestions } from '../../../utils/questions'
-
-type NationalInsuranceBody = { nationalInsuranceNumber: string }
-
-@Page({
- name: 'national-insurance',
- bodyProperties: ['nationalInsuranceNumber'],
-})
-export default class NationalInsurance implements TaskListPage {
- title
-
- documentTitle = "What is the person's National Insurance number?"
-
- questions
-
- body: NationalInsuranceBody
-
- constructor(
- body: Partial,
- private readonly application: Application,
- ) {
- this.body = body as NationalInsuranceBody
- this.questions = getQuestions(nameOrPlaceholderCopy(this.application.person))['funding-information'][
- 'national-insurance'
- ]
- this.title = this.questions.nationalInsuranceNumber.question
- }
-
- previous() {
- if (this.application.data?.['funding-information']?.['funding-source']?.fundingSource === 'personalSavings') {
- return 'funding-source'
- }
- if (this.application.data?.['funding-information']?.identification?.idDocuments === 'none') {
- return 'alternative-identification'
- }
- return 'identification'
- }
-
- next() {
- return ''
- }
-
- errors() {
- const errors: TaskListErrors = {}
-
- return errors
- }
-}
diff --git a/server/form-pages/utils/questions.ts b/server/form-pages/utils/questions.ts
index b6547d6d..3ed7b5fb 100644
--- a/server/form-pages/utils/questions.ts
+++ b/server/form-pages/utils/questions.ts
@@ -410,25 +410,46 @@ export const getQuestions = (name: string) => {
},
},
'funding-information': {
- 'funding-source': {
+ 'funding-cas2-accommodation': {
fundingSource: {
- question: `How will ${name} pay for their accommodation and service charge?`,
- hint: 'Applicants must pay for a weekly service charge using their personal money or wages. This service charge is not eligible to be covered by Housing Benefit.',
+ question: `How will the applicant pay for their accommodation and the service charge?`,
answers: {
- personalSavings: 'Personal money or wages',
- benefits: 'Housing Benefit and personal money or wages',
+ benefits: 'Housing Benefit',
+ personalSavings: 'Personal savings, salary or pension',
+ },
+ },
+ fundingSourceDetail: {
+ question: 'Enter details (optional)',
+ },
+ hasNationalInsuranceNumber: {
+ question: 'Does the applicant have a National Insurance number?',
+ answers: {
+ yes: 'Yes',
+ no: 'No, they do not have one',
+ dontKnow: "They have one but they don't know the number",
},
},
- },
- 'national-insurance': {
nationalInsuranceNumber: {
- question: `What is ${name}'s National Insurance number? (Optional)`,
- hint: 'We need this to set up a Universal Credit and Housing Benefit claim if required.',
+ question: 'Enter the number (optional)',
+ hint: 'For example, SF123456X',
+ },
+ receivingBenefits: {
+ question: 'Is the applicant currently receiving benefits?',
+ hint: 'For example, Universal Credit, Personal Independence Payments or Employment & Support Allowance',
+ answers: yesOrNo,
+ },
+ receivedBenefitSanctions: {
+ question: 'Have they received any benefit sanctions in the last 6 months?',
+ answers: yesOrNo,
+ },
+ inEducationOrTraining: {
+ question: 'Is the applicant in education or receiving any training?',
+ answers: yesOrNo,
},
},
- identification: {
+ 'applicant-id': {
idDocuments: {
- question: `What identification documentation (ID) does ${name} have?`,
+ question: `What identity document (ID) does the applicant have?`,
hint: 'Expired ID will be accepted. Select all that apply.',
answers: {
passport: 'Passport',
@@ -436,15 +457,15 @@ export const getQuestions = (name: string) => {
birthCertificate: 'Birth certificate',
bankOrDebitCard: 'Bank account or debit card',
bankStatements: 'Bank, building society or Post Office card account statements',
- drivingLicence: 'UK photo driving licence',
- wageSlip: 'Recent wage slip',
+ drivingLicence: 'UK photo driving licence (full or provisional)',
+ wageSlip: 'Recent wage slip (with payee name and NI number)',
none: 'None of these options',
},
},
},
- 'alternative-identification': {
+ 'alternative-applicant-id': {
alternativeIDDocuments: {
- question: `What alternative identification documentation (ID) does ${name} have?`,
+ question: 'What other identification document (ID) does the applicant have?',
hint: 'Expired ID will be accepted. Select all that apply.',
answers: {
contract: 'Employer letter/contract of employment',
diff --git a/server/i18n/en/errors.json b/server/i18n/en/errors.json
index e90e6906..f5bd55ef 100644
--- a/server/i18n/en/errors.json
+++ b/server/i18n/en/errors.json
@@ -57,7 +57,7 @@
"empty": "Select an ID document or 'None of these options'"
},
"alternativeIDDocuments": {
- "empty": "Select an ID document or 'Other type of identification'",
+ "empty": "Select other identity documents the applicant has, or select 'Other type of identification'",
"other": "Enter the other type of ID"
},
"hasPreviousAddress": {
diff --git a/server/services/applicationService.test.ts b/server/services/applicationService.test.ts
index 0c33aeaa..e84bffae 100644
--- a/server/services/applicationService.test.ts
+++ b/server/services/applicationService.test.ts
@@ -279,13 +279,13 @@ describe('ApplicationService', () => {
},
body: { fundingSource: 'personalSavings' },
})
- ;(getPageName as jest.Mock).mockImplementation(() => 'funding-source')
+ ;(getPageName as jest.Mock).mockImplementation(() => 'funding-cas2-accommodation')
;(getTaskName as jest.Mock).mockImplementation(() => 'funding-information')
application.data = {
'funding-information': {
- identification: { question: 'answer' },
- 'alternative-identification': { question: 'answer' },
+ 'applicant-id': { question: 'answer' },
+ 'alternative-applicant-id': { question: 'answer' },
},
}
@@ -295,7 +295,7 @@ describe('ApplicationService', () => {
expect(getApplicationUpdateData).toHaveBeenCalledWith({
...application,
data: {
- 'funding-information': { 'funding-source': { fundingSource: 'personalSavings' } },
+ 'funding-information': { 'funding-cas2-accommodation': { fundingSource: 'personalSavings' } },
},
})
})
diff --git a/server/utils/applications/deleteOrphanedData.test.ts b/server/utils/applications/deleteOrphanedData.test.ts
index dc1f0891..18c50755 100644
--- a/server/utils/applications/deleteOrphanedData.test.ts
+++ b/server/utils/applications/deleteOrphanedData.test.ts
@@ -5,13 +5,13 @@ describe('deleteOrphanedFollowOnAnswers', () => {
describe('when fundingSource is personalSavings', () => {
const applicationData = {
'funding-information': {
- 'funding-source': {
+ 'funding-cas2-accommodation': {
fundingSource: 'personalSavings',
},
- identification: {
+ 'applicant-id': {
idDocuments: 'passport',
},
- 'alternative-identification': {
+ 'alternative-applicant-id': {
alternativeIDDocuments: 'citizenCard',
},
},
@@ -20,13 +20,42 @@ describe('deleteOrphanedFollowOnAnswers', () => {
it('removes identification and alternative-identification data', () => {
expect(deleteOrphanedFollowOnAnswers(applicationData)).toEqual({
'funding-information': {
- 'funding-source': {
+ 'funding-cas2-accommodation': {
fundingSource: 'personalSavings',
},
},
})
})
})
+
+ describe('when fundingSource is benefits and applicant ID is not "None"', () => {
+ const applicationData = {
+ 'funding-information': {
+ 'funding-cas2-accommodation': {
+ fundingSource: 'benefits',
+ },
+ 'applicant-id': {
+ idDocuments: 'passport',
+ },
+ 'alternative-applicant-id': {
+ alternativeIDDocuments: 'citizenCard',
+ },
+ },
+ }
+
+ it('removes alternative-identification data', () => {
+ expect(deleteOrphanedFollowOnAnswers(applicationData)).toEqual({
+ 'funding-information': {
+ 'funding-cas2-accommodation': {
+ fundingSource: 'benefits',
+ },
+ 'applicant-id': {
+ idDocuments: 'passport',
+ },
+ },
+ })
+ })
+ })
})
describe('equality-and-diversity-monitoring', () => {
diff --git a/server/utils/applications/deleteOrphanedData.ts b/server/utils/applications/deleteOrphanedData.ts
index e2ef651d..52062bb5 100644
--- a/server/utils/applications/deleteOrphanedData.ts
+++ b/server/utils/applications/deleteOrphanedData.ts
@@ -4,8 +4,12 @@ import { PreviousConvictionsAnswers } from '../../form-pages/apply/offence-infor
export default function deleteOrphanedFollowOnAnswers(applicationData: Unit): Unit {
const deleteOrphanedFundingInformation = () => {
- delete applicationData['funding-information'].identification
- delete applicationData['funding-information']['alternative-identification']
+ delete applicationData['funding-information']['applicant-id']
+ delete applicationData['funding-information']['alternative-applicant-id']
+ }
+
+ const deleteOrphanedFundingAlternativeIdInformation = () => {
+ delete applicationData['funding-information']['alternative-applicant-id']
}
const deleteOrphanedEqualityInformation = () => {
@@ -51,7 +55,7 @@ export default function deleteOrphanedFollowOnAnswers(applicationData: Unit): Un
if (
hasOrphanedInformation({
taskName: 'funding-information',
- pageName: 'funding-source',
+ pageName: 'funding-cas2-accommodation',
questionKey: 'fundingSource',
answerToCheck: 'personalSavings',
})
@@ -59,6 +63,13 @@ export default function deleteOrphanedFollowOnAnswers(applicationData: Unit): Un
deleteOrphanedFundingInformation()
}
+ if (
+ applicationData['funding-information']?.['funding-cas2-accommodation']?.fundingSource === 'benefits' &&
+ applicationData['funding-information']?.['applicant-id']?.idDocuments !== 'none'
+ ) {
+ deleteOrphanedFundingAlternativeIdInformation()
+ }
+
if (
hasOrphanedInformation({
taskName: 'equality-and-diversity-monitoring',
diff --git a/server/views/applications/pages/funding-information/alternative-identification.njk b/server/views/applications/pages/funding-information/alternative-applicant-id.njk
similarity index 95%
rename from server/views/applications/pages/funding-information/alternative-identification.njk
rename to server/views/applications/pages/funding-information/alternative-applicant-id.njk
index 39e6d691..70c6828d 100644
--- a/server/views/applications/pages/funding-information/alternative-identification.njk
+++ b/server/views/applications/pages/funding-information/alternative-applicant-id.njk
@@ -38,11 +38,6 @@
)
}}
- {{ govukDetails({
- summaryText: "Why we need ID",
- html: page.guidanceHtml
- }) }}
-
{% endblock %}
{% block extraScripts %}
diff --git a/server/views/applications/pages/funding-information/identification.njk b/server/views/applications/pages/funding-information/applicant-id.njk
similarity index 94%
rename from server/views/applications/pages/funding-information/identification.njk
rename to server/views/applications/pages/funding-information/applicant-id.njk
index fea91cae..32b0c14e 100644
--- a/server/views/applications/pages/funding-information/identification.njk
+++ b/server/views/applications/pages/funding-information/applicant-id.njk
@@ -25,11 +25,6 @@
)
}}
- {{ govukDetails({
- summaryText: "Why we need ID",
- html: page.guidanceHtml
- }) }}
-
{% endblock %}
{% block extraScripts %}
@@ -73,4 +68,4 @@
})
});
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/server/views/applications/pages/funding-information/funding-cas2-accommodation.njk b/server/views/applications/pages/funding-information/funding-cas2-accommodation.njk
new file mode 100644
index 00000000..542f6674
--- /dev/null
+++ b/server/views/applications/pages/funding-information/funding-cas2-accommodation.njk
@@ -0,0 +1,200 @@
+{% from "govuk/components/inset-text/macro.njk" import govukInsetText %}
+{% from "../../../components/formFields/form-page-text-area/macro.njk" import formPageTextArea %}
+{% from "../../../components/formFields/form-page-input/macro.njk" import formPageInput %}
+{% from "../../../components/formFields/form-page-radios/macro.njk" import formPageRadios %}
+
+{% extends "../layout.njk" %}
+
+{% block beforeContent %}
+ {{ super() }}
+
+ Funding CAS-2 accommodation
+
+ {% call govukInsetText({
+ classes: "govuk-!-width-one-half govuk-!-margin-0 submission-guidance-panel"
+ }) %}
+ Applicants claiming Housing Benefit:
+
+ - must pay for a weekly service charge using their personal money or wages
+ - will need their National Insurance (NI) number and an identity document (ID) to set up a claim to cover their rent
+
+ Applicants using personal money or wages:
+
+ - will need to provide proof of personal funds to show they can afford the accommodation and service charge
+ - may be eligible for help with rent payments if they are in employment
+
+ {% endcall %}
+{% endblock %}
+
+{% set fundingSourceDetail %}
+ {{
+ formPageTextArea(
+ {
+ fieldName: 'fundingSourceDetail',
+ label: {
+ text: page.questions.fundingSourceDetail.question
+ }
+ },
+ fetchContext()
+ )
+ }}
+{% endset %}
+
+{% set nationalInsuranceNumber %}
+ {{
+ formPageInput(
+ {
+ fieldName: 'nationalInsuranceNumber',
+ classes: "govuk-input--width-10",
+ hint: {
+ text: page.questions.nationalInsuranceNumber.hint
+ },
+ label: {
+ text: page.questions.nationalInsuranceNumber.question
+ }
+ },
+ fetchContext()
+ )
+ }}
+{% endset %}
+
+{% set receivedBenefitSanctions %}
+ {{
+ formPageRadios(
+ {
+ fieldset: {
+ legend: {
+ text: page.questions.receivedBenefitSanctions.question
+ }
+ },
+ fieldName: 'receivedBenefitSanctions',
+ items: [
+ {
+ value: 'yes',
+ text: 'Yes',
+ attributes: {
+ "data-testid": "received-benefit-sanctions-radio-yes"
+ }
+ },
+ {
+ value: 'no',
+ text: 'No'
+ }
+ ]
+ },
+ fetchContext()
+ )
+ }}
+{% endset %}
+
+{% block questions %}
+ {{
+ formPageRadios(
+ {
+ fieldset: {
+ legend: {
+ text: page.questions.fundingSource.question,
+ classes: "govuk-fieldset__legend--m"
+ }
+ },
+ fieldName: "fundingSource",
+ items: [
+ {
+ value: "benefits",
+ text: page.questions.fundingSource.answers.benefits
+ },
+ {
+ value: "personalSavings",
+ text: page.questions.fundingSource.answers.personalSavings,
+ conditional: {
+ html: fundingSourceDetail
+ }
+ }
+ ]
+ },
+ fetchContext()
+ )
+ }}
+
+ {{
+ formPageRadios(
+ {
+ fieldset: {
+ legend: {
+ text: page.questions.hasNationalInsuranceNumber.question,
+ classes: "govuk-fieldset__legend--m"
+ }
+ },
+ fieldName: "hasNationalInsuranceNumber",
+ items: page.items(nationalInsuranceNumber)
+ },
+ fetchContext()
+ )
+ }}
+
+ {{
+ formPageRadios(
+ {
+ fieldset: {
+ legend: {
+ text: page.questions.receivingBenefits.question,
+ classes: "govuk-fieldset__legend--m"
+ }
+ },
+ fieldName: 'receivingBenefits',
+ hint: {
+ text: page.questions.receivingBenefits.hint
+ },
+ label: {
+ text: page.questions.receivingBenefits.question
+ },
+ items: [
+ {
+ value: 'yes',
+ text: 'Yes',
+ attributes: {
+ "data-testid": "receiving-benefits-radio-yes"
+ },
+ conditional: {
+ html: receivedBenefitSanctions
+ }
+ },
+ {
+ value: 'no',
+ text: 'No'
+ }
+ ]
+ },
+ fetchContext()
+ )
+ }}
+
+ {{
+ formPageRadios(
+ {
+ fieldset: {
+ legend: {
+ text: page.questions.inEducationOrTraining.question,
+ classes: "govuk-fieldset__legend--m"
+ }
+ },
+ fieldName: 'inEducationOrTraining',
+ label: {
+ text: page.questions.inEducationOrTraining.question
+ },
+ items: [
+ {
+ value: 'yes',
+ text: 'Yes'
+ },
+ {
+ value: 'no',
+ text: 'No'
+ }
+ ]
+ },
+ fetchContext()
+ )
+ }}
+
+{% endblock %}
diff --git a/server/views/applications/pages/funding-information/funding-source.njk b/server/views/applications/pages/funding-information/funding-source.njk
deleted file mode 100644
index 959a409e..00000000
--- a/server/views/applications/pages/funding-information/funding-source.njk
+++ /dev/null
@@ -1,34 +0,0 @@
-{% extends "../layout.njk" %}
-{% block questions %}
- {{
- formPageRadios(
- {
- fieldset: {
- legend: {
- text: page.questions.fundingSource.question,
- isPageHeading: true,
- classes: "govuk-fieldset__legend--l"
- }
- },
- fieldName: "fundingSource",
- hint: {
- text: page.questions.fundingSource.hint
- },
- items: [
- {
- value: "personalSavings",
- text: page.questions.fundingSource.answers.personalSavings,
- hint: { text: "Proof of personal money or wages is required to show the applicant can afford the accommodation and service charge" }
- },
- {
- value: "benefits",
- text: page.questions.fundingSource.answers.benefits,
- hint: { text: "Applicants must have recourse to public funds to claim Housing Benefit. Proof of personal money or wages is required" }
-
- }
- ]
- },
- fetchContext()
- )
- }}
-{% endblock %}
diff --git a/server/views/applications/pages/funding-information/national-insurance.njk b/server/views/applications/pages/funding-information/national-insurance.njk
deleted file mode 100644
index 7b278945..00000000
--- a/server/views/applications/pages/funding-information/national-insurance.njk
+++ /dev/null
@@ -1,23 +0,0 @@
-{% from "../../../components/formFields/form-page-input/macro.njk" import formPageInput %}
-
-{% extends "../layout.njk" %}
-{% block questions %}
- {{
- formPageInput(
- {
- label: {
- text: page.questions.nationalInsuranceNumber.question,
- classes: "govuk-label--l",
- isPageHeading: true
- },
- hint: {
- text: page.questions.nationalInsuranceNumber.hint
- },
- classes: "govuk-input--width-10",
- fieldName: "nationalInsuranceNumber"
- },
- fetchContext()
- )
- }}
-
-{% endblock %}
\ No newline at end of file