Skip to content

Commit

Permalink
Merge pull request #71 from ministryofjustice/CBA-111-search-by-crn
Browse files Browse the repository at this point in the history
Enable searching for an applicant via CRN
  • Loading branch information
libuk authored Mar 10, 2025
2 parents d9b61cd + d0a64ff commit 90aeb0d
Show file tree
Hide file tree
Showing 39 changed files with 1,347 additions and 76 deletions.
2 changes: 2 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { resetStubs } from './integration_tests/mockApis/wiremock'
import auth from './integration_tests/mockApis/auth'
import tokenVerification from './integration_tests/mockApis/tokenVerification'
import applications from './integration_tests/mockApis/applications'
import person from './integration_tests/mockApis/person'
import accessibilityViolations from './integration_tests/tasks/accessibilityViolations'

export default defineConfig({
Expand All @@ -22,6 +23,7 @@ export default defineConfig({
...auth,
...tokenVerification,
...applications,
...person,
...accessibilityViolations,
})
},
Expand Down
5 changes: 5 additions & 0 deletions e2e-tests/pages/apply/applicationOriginPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ export class ApplicationOriginPage extends BasePage {
await this.checkRadio('Prison bail')
await this.clickButton('Confirm')
}

async chooseCourtBail() {
await this.checkRadio('Court bail')
await this.clickButton('Confirm')
}
}
7 changes: 7 additions & 0 deletions e2e-tests/pages/apply/findByCrnPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { BasePage } from '../basePage'

export class FindByCrnPage extends BasePage {
async enterCrn(crn: string) {
await this.page.getByLabel("Enter the person's CRN").fill(crn)
}
}
2 changes: 2 additions & 0 deletions e2e-tests/pages/apply/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FindByPrisonNumberPage } from './findByPrisonNumberPage'
import { FindByCrnPage } from './findByCrnPage'
import { TaskListPage } from './taskListPage'
import { ApplyPage } from './applyPage'
import { DashboardPage } from './dashboardPage'
Expand All @@ -8,6 +9,7 @@ import { ApplicationOriginPage } from './applicationOriginPage'

export {
FindByPrisonNumberPage,
FindByCrnPage,
TaskListPage,
ApplyPage,
DashboardPage,
Expand Down
29 changes: 24 additions & 5 deletions e2e-tests/steps/apply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
BeforeYouStartPage,
DashboardPage,
FindByPrisonNumberPage,
FindByCrnPage,
TaskListPage,
ApplicationOriginPage,
} from '../pages/apply'
Expand Down Expand Up @@ -48,9 +49,13 @@ export const startAnApplication = async (page: Page) => {
await beforeYouStartPage.startNow()
}

export const selectApplicationOrigin = async (page: Page) => {
export const selectApplicationOrigin = async (page: Page, applicationOrigin: 'courtBail' | 'prisonBail') => {
const applicationOriginPage = new ApplicationOriginPage(page)
await applicationOriginPage.choosePrisonBail()
if (applicationOrigin === 'prisonBail') {
await applicationOriginPage.choosePrisonBail()
} else {
await applicationOriginPage.chooseCourtBail()
}
}

export const enterPrisonerNumber = async (page: Page, prisonNumber: string) => {
Expand All @@ -59,6 +64,12 @@ export const enterPrisonerNumber = async (page: Page, prisonNumber: string) => {
await prisonNumberPage.clickButton('Search for applicant')
}

export const enterCrn = async (page: Page, crn: string) => {
const crnPage = new FindByCrnPage(page)
await crnPage.enterCrn(crn)
await crnPage.clickButton('Search for applicant')
}

export const confirmApplicant = async (page: Page) => {
const confirmApplicantPage = new TaskListPage(page)
await confirmApplicantPage.clickButton('Confirm and continue')
Expand Down Expand Up @@ -142,9 +153,17 @@ export const viewApplicationMadeByAnotherUser = async (page: Page, name: string)
await expect(page.locator('h2').first()).toContainText('Application history')
}

export const createAnInProgressApplication = async (page: Page, person: TestOptions['person']) => {
export const createAnInProgressApplication = async (
page: Page,
person: TestOptions['person'],
applicationOrigin: 'courtBail' | 'prisonBail',
) => {
await startAnApplication(page)
await selectApplicationOrigin(page)
await enterPrisonerNumber(page, person.nomsNumber)
await selectApplicationOrigin(page, applicationOrigin)
if (applicationOrigin === 'courtBail') {
await enterCrn(page, person.crn)
} else {
await enterPrisonerNumber(page, person.nomsNumber)
}
await confirmApplicant(page)
}
16 changes: 16 additions & 0 deletions e2e-tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ export const test = base.extend<TestOptions>({
},
{ option: true },
],
nomisCourtUser: [
{
name: 'Cas-two bail Test-nomis-court-user',
username: process.env.CAS2_BAIL_NOMIS_COURT_USERNAME as string,
password: process.env.CAS2_BAIL_NOMIS_COURT_PASSWORD as string,
},
{ option: true },
],
nomisPrisonUser: [
{
name: 'Cas-two bail Test-nomis-prison-user',
username: process.env.CAS2_BAIL_NOMIS_PRISON_USERNAME as string,
password: process.env.CAS2_BAIL_NOMIS_PRISON_PASSWORD as string,
},
{ option: true },
],
lcaUser: [
{
name: 'Licence Case-admin',
Expand Down
10 changes: 10 additions & 0 deletions e2e-tests/testOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,14 @@ export type TestOptions = {
username: string
password: string
}
nomisCourtUser: {
name: string
username: string
password: string
}
nomisPrisonUser: {
name: string
username: string
password: string
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import {
import { signIn } from '../steps/signIn'
import { cancelAnApplication, clickCancel } from '../steps/cancelInProgressApplication'

test('create a CAS-2 bail application', async ({ page, person, pomUser }) => {
await signIn(page, pomUser)
test('create a CAS-2 bail application', async ({ page, person, nomisPrisonUser }) => {
await signIn(page, nomisPrisonUser)
await startAnApplication(page)
await selectApplicationOrigin(page)
await selectApplicationOrigin(page, 'prisonBail')
await enterPrisonerNumber(page, person.nomsNumber)
await confirmApplicant(page)
await completeBeforeYouStartSection(page, person.name)
Expand All @@ -38,16 +38,16 @@ test('create a CAS-2 bail application', async ({ page, person, pomUser }) => {
await submitApplication(page)
})

test('add a note to a submitted application', async ({ page, person, pomUser }) => {
await signIn(page, pomUser)
test('add a note to a submitted application', async ({ page, person, nomisPrisonUser }) => {
await signIn(page, nomisPrisonUser)
await viewSubmittedApplication(page, person.name)
await addNote(page)
await expect(page.locator('.moj-timeline__title').first()).toContainText('Note')
})

test('cancel an in progress application from the task list', async ({ page, pomUser, person }) => {
await signIn(page, pomUser)
await createAnInProgressApplication(page, person)
test('cancel an in progress application from the task list', async ({ page, nomisPrisonUser, person }) => {
await signIn(page, nomisPrisonUser)
await createAnInProgressApplication(page, person, 'prisonBail')
await viewInProgressDashboard(page)
const numberOfApplicationsBeforeCancellation = (await page.locator('tr').all()).length
await clickCancel(page, person.name)
Expand Down
58 changes: 58 additions & 0 deletions e2e-tests/tests/02_apply_as_nomis_court_user.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { expect } from '@playwright/test'
import { test } from '../test'
import {
completeAboutThePersonSection,
completeAreaAndFundingSection,
completeBeforeYouStartSection,
completeCheckAnswersSection,
completeOffenceInformationSection,
completeRisksAndNeedsSection,
completeBailInformationSection,
confirmApplicant,
enterCrn,
selectApplicationOrigin,
startAnApplication,
submitApplication,
viewSubmittedApplication,
addNote,
viewInProgressDashboard,
createAnInProgressApplication,
} from '../steps/apply'
import { signIn } from '../steps/signIn'
import { cancelAnApplication, clickCancel } from '../steps/cancelInProgressApplication'

test('create a CAS-2 bail application', async ({ page, person, nomisCourtUser }) => {
await signIn(page, nomisCourtUser)
await startAnApplication(page)
await selectApplicationOrigin(page, 'courtBail')
await enterCrn(page, person.crn)
await confirmApplicant(page)
await completeBeforeYouStartSection(page, person.name)
await completeAreaAndFundingSection(page, person.name)
await completeAboutThePersonSection(page, person.name)
await completeRisksAndNeedsSection(page, person.name)
await completeOffenceInformationSection(page, person.name)
await completeBailInformationSection(page, person.name)
await completeCheckAnswersSection(page, person.name)
await expect(page.getByText('You have completed 17 of 17 tasks')).toBeVisible()
await submitApplication(page)
})

test('add a note to a submitted application', async ({ page, person, nomisCourtUser }) => {
await signIn(page, nomisCourtUser)
await viewSubmittedApplication(page, person.name)
await addNote(page)
await expect(page.locator('.moj-timeline__title').first()).toContainText('Note')
})

test('cancel an in progress application from the task list', async ({ page, nomisCourtUser, person }) => {
await signIn(page, nomisCourtUser)
await createAnInProgressApplication(page, person, 'courtBail')
await viewInProgressDashboard(page)
const numberOfApplicationsBeforeCancellation = (await page.locator('tr').all()).length
await clickCancel(page, person.name)
await cancelAnApplication(page, person.name)
const numberOfApplicationsAfterCancellation = (await page.locator('tr').all()).length
await expect(page.getByText('Your CAS-2 applications')).toBeVisible()
expect(numberOfApplicationsBeforeCancellation - numberOfApplicationsAfterCancellation).toEqual(1)
})
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions integration_tests/mockApis/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
stubFor({
request: {
method: 'POST',
url: paths.applications,
url: paths.applications.new.pattern,
},
response: {
status: 201,
Expand All @@ -32,7 +32,7 @@ export default {
stubFor({
request: {
method: 'GET',
url: paths.applications,
url: paths.applications.index.pattern,
},
response: {
status: 200,
Expand Down
46 changes: 40 additions & 6 deletions integration_tests/mockApis/person.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { stubFor } from './wiremock'
import paths from '../../server/paths/api'

export default {
stubFindPerson: (args: { person: FullPerson }) =>
stubFindPersonByPrisonNumber: (args: { person: FullPerson }) =>
stubFor({
request: {
method: 'GET',
url: paths.people.search({ nomsNumber: args.person.nomsNumber }),
url: paths.people.searchByPrisonNumber({ nomsNumber: args.person.nomsNumber }),
},
response: {
status: 201,
Expand All @@ -16,22 +16,56 @@ export default {
},
}),

stubPersonNotFound: (args: { person: FullPerson }) =>
stubPersonByPrisonNumberNotFound: (args: { person: FullPerson }) =>
stubFor({
request: {
method: 'GET',
url: paths.people.search({ nomsNumber: args.person.nomsNumber }),
url: paths.people.searchByPrisonNumber({ nomsNumber: args.person.nomsNumber }),
},
response: {
status: 404,
},
}),

stubFindPersonForbidden: (args: { person: FullPerson }) =>
stubFindPersonByPrisonNumberForbidden: (args: { person: FullPerson }) =>
stubFor({
request: {
method: 'GET',
url: paths.people.search({ nomsNumber: args.person.nomsNumber }),
url: paths.people.searchByPrisonNumber({ nomsNumber: args.person.nomsNumber }),
},
response: {
status: 403,
},
}),
stubFindPersonByCrn: (args: { person: FullPerson }) =>
stubFor({
request: {
method: 'GET',
url: paths.people.searchByCrn({ crn: args.person.crn }),
},
response: {
status: 201,
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
jsonBody: args.person,
},
}),

stubPersonByCrnNotFound: (args: { person: FullPerson }) =>
stubFor({
request: {
method: 'GET',
url: paths.people.searchByCrn({ crn: args.person.crn }),
},
response: {
status: 404,
},
}),

stubFindPersonByCrnForbidden: (args: { person: FullPerson }) =>
stubFor({
request: {
method: 'GET',
url: paths.people.searchByCrn({ crn: args.person.crn }),
},
response: {
status: 403,
Expand Down
12 changes: 12 additions & 0 deletions integration_tests/pages/apply/applicationOriginPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Page from '../page'

export default class ApplicationOriginPage extends Page {
constructor(name: string) {
super(`You are applying for:`, name)
}

static visit(name: string): ApplicationOriginPage {
cy.visit('/applications/application-type')
return new ApplicationOriginPage(name)
}
}
14 changes: 14 additions & 0 deletions integration_tests/pages/apply/beforeYouStartPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import paths from '../../../server/paths/apply'
import Page from '../page'

export default class BeforeYouStartPage extends Page {
constructor(name: string) {
super('Apply for Short-Term Accommodation (CAS-2)', name)
}

static visit(name: string): BeforeYouStartPage {
cy.visit(paths.applications.beforeYouStart({}))

return new BeforeYouStartPage(name)
}
}
37 changes: 37 additions & 0 deletions integration_tests/pages/apply/confirmApplicantPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { FullPerson } from '../../../server/@types/shared/models/FullPerson'
import { DateFormats } from '../../../server/utils/dateUtils'
import Page from '../page'

export default class ConfirmApplicantPage extends Page {
personName: string

constructor(name: string) {
super(`Confirm ${name}'s details`, name)
}

hasErrorDetails = (): void => {
cy.get('.govuk-error-summary').contains('There was an error creating the application, please try again')
}

hasApplicantInformation = (applicant: FullPerson): void => {
const expectedApplicantData = [
['Full name', applicant.name],
['Date of birth', DateFormats.isoDateToUIDate(applicant.dateOfBirth, { format: 'short' })],
['Nationality', applicant.nationality],
['Sex', applicant.sex],
['Prison number', applicant.nomsNumber],
['Prison', applicant.prisonName],
['PNC number', applicant.pncNumber],
['CRN from NDelius', applicant.crn],
['Status', applicant.status === 'InCommunity' ? 'In Community' : 'In Custody'],
]
cy.get('.govuk-summary-list').within(() => {
cy.get('.govuk-summary-list__row').each(($el, index) => {
cy.wrap($el).within(() => {
cy.get('.govuk-summary-list__key').should('contain', expectedApplicantData[index][0])
cy.get('.govuk-summary-list__value').should('contain', expectedApplicantData[index][1])
})
})
})
}
}
Loading

0 comments on commit 90aeb0d

Please sign in to comment.