Skip to content

Commit

Permalink
CDPS-335 neurodiversity section (#255)
Browse files Browse the repository at this point in the history
* CDPS-335 - dev work and unit tests

* CDPS-335 - dev work and unit tests

* CDPS-335 - update overview files

* CDPS-335 - neurodiversity e2e tests

* CDPS-335 - add config for neurodiversity section
  • Loading branch information
jamesgrant-moj authored Aug 23, 2023
1 parent 78ecbbb commit 316bb63
Show file tree
Hide file tree
Showing 28 changed files with 242 additions and 26 deletions.
13 changes: 13 additions & 0 deletions assets/scss/pages/_personal-page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
}
}


.govuk-summary-list__row--no-border .govuk-summary-list__row {
border-bottom: none!important;
}

.govuk-body-s-dd {
font-size: 1rem;
}

.hmpps-recorded-on dd {
padding-top: 0;
}

.govuk-summary-list:not(.govuk-summary-list--bottom-border) {

// If it's the last-of-type that is not hidden remove bottom border
Expand Down
1 change: 1 addition & 0 deletions feature.env
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ MANAGE_ADJUDICATIONS_API_URL=http://localhost:9091/adjudications
CALCULATE_RELEASE_DATES_UI_URL=https://localhost:9091/calculateRelease
FEEDBACK_DISABLED_PRISONS=LEI
SYSTEM_PHASE=DEV
NEURODIVERSITY_ENABLED_PRISONS=MDI
1 change: 1 addition & 0 deletions helm_deploy/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ generic-service:
CALCULATE_RELEASE_DATES_UI_URL: "https://calculate-release-dates-dev.hmpps.service.justice.gov.uk"
FEEDBACK_DISABLED_PRISONS: "LEI,FNI,RSI"
SYSTEM_PHASE: "DEV"
NEURODIVERSITY_ENABLED_PRISONS: "BLI,NHI,LII,SLI"

generic-prometheus-alerts:
alertSeverity: digital-prison-service-dev
1 change: 1 addition & 0 deletions helm_deploy/values-preprod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ generic-service:
CALCULATE_RELEASE_DATES_UI_URL: "https://calculate-release-dates-preprod.hmpps.service.justice.gov.uk"
FEEDBACK_DISABLED_PRISONS: "LEI,FNI,RSI"
SYSTEM_PHASE: "PRE-PRODUCTION"
NEURODIVERSITY_ENABLED_PRISONS: "BLI,NHI,LII,SLI"

allowlist:
office: "217.33.148.210/32"
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ generic-service:
MANAGE_ADJUDICATIONS_API_URL: "https://manage-adjudications-api.hmpps.service.justice.gov.uk"
CALCULATE_RELEASE_DATES_UI_URL: "https://calculate-release-dates.hmpps.service.justice.gov.uk"
FEEDBACK_DISABLED_PRISONS: "LEI,FNI,RSI"
NEURODIVERSITY_ENABLED_PRISONS: "BLI,NHI,LII,SLI"

allowlist:
office: "217.33.148.210/32"
Expand Down
27 changes: 27 additions & 0 deletions integration_tests/e2e/personalPage.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,31 @@ context('When signed in', () => {
})
})
})

context('Neurodiversity', () => {
beforeEach(() => {
cy.task('reset')
cy.setupUserAuth({
caseLoads: [{ caseloadFunction: '', caseLoadId: 'MDI', currentlyActive: true, description: '', type: '' }],
activeCaseLoadId: 'MDI',
roles: [Role.GlobalSearch],
})
cy.task('stubSignIn')
cy.task('stubAuthUser')
cy.setupPersonalPageSubs({ prisonerNumber, bookingId })
visitPersonalDetailsPage()
})

context('Page section', () => {
it('Displays neurodiversity sections', () => {
const page = Page.verifyOnPage(PersonalPage)
page.neurodiversity().fromNeurodiversityAssessment().should('be.visible')
page.neurodiversity().neurodivergenceExists().should('be.visible')
page.neurodiversity().neurodivergenceSupport().should('be.visible')
page.neurodiversity().neurodiversitySelfAssessment().should('be.visible')
page.neurodiversity().neurodiversityAssessed().should('be.visible')
page.neurodiversity().neurodiversityTitle().should('be.visible')
})
})
})
})
1 change: 1 addition & 0 deletions integration_tests/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ declare global {
prisonerNumber: string
bookingId: number
prisonerDataOverrides?: Partial<Prisoner>
caseLoads?: CaseLoad[]
})
setupWorkAndSkillsPageStubs(options: { prisonerNumber: string; emptyStates: boolean }): Chainable<AUTWindow>
setupOffencesPageSentencedStubs(options: { prisonerNumber: string; bookingId: number }): Chainable<AUTWindow>
Expand Down
11 changes: 11 additions & 0 deletions integration_tests/pages/personalPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,15 @@ export default class PersonalPage extends Page {
backToTopLink = (): PageElement => cy.get('[data-module=hmpps-back-to-top] a')

backToTopLinkHidden = (): PageElement => cy.get('.hmpps-back-to-top--hidden')

neurodiversity = () => {
return {
neurodivergenceExists: () => cy.get('#neurodiversity'),
neurodivergenceSupport: () => cy.get('[data-qa="neurodivergence-support"] > [data-qa="-row"] > [data-qa="-key"]'),
neurodiversityTitle: () => cy.get(':nth-child(5) > [data-qa="-row"] > [data-qa="-key"]'),
neurodiversitySelfAssessment: () => cy.get(':nth-child(5) > [data-qa="-row"] > .govuk-summary-list__value'),
fromNeurodiversityAssessment: () => cy.get(':nth-child(9) > [data-qa="-row"] > .govuk-summary-list__value'),
neurodiversityAssessed: () => cy.get(':nth-child(9) > [data-qa="-row"] > .govuk-summary-list__value'),
}
}
}
1 change: 1 addition & 0 deletions integration_tests/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,5 @@ Cypress.Commands.add('setupPersonalPageSubs', ({ bookingId, prisonerNumber, pris
cy.task('stubReasonableAdjustments', bookingId)
cy.task('stubPersonalCareNeeds', bookingId)
cy.task('stubGetIdentifiers', bookingId)
cy.task('stubGetLearnerNeurodivergence', prisonerNumber)
})
1 change: 1 addition & 0 deletions server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,5 @@ export default {
localMockData: get('LOCAL_MOCK_DATA', false),
feedbackDisabledPrisons: get('FEEDBACK_DISABLED_PRISONS', [], requiredInProduction),
phaseName: get('SYSTEM_PHASE', ''),
neurodiversityEnabledPrisons: process.env.NEURODIVERSITY_ENABLED_PRISONS || [],
}
2 changes: 1 addition & 1 deletion server/data/curiousApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { LearnerEducation } from '../interfaces/learnerEducation'
import { LearnerLatestAssessment } from '../interfaces/learnerLatestAssessments'
import { LearnerGoals } from '../interfaces/learnerGoals'
import { LearnerNeurodivergence } from '../interfaces/learnerNeurodivergence'
import CuriousApiClient from './interfaces/curiousApiClient'
import { CuriousApiClient } from './interfaces/curiousApiClient'

export default class CuriousRestApiClient implements CuriousApiClient {
constructor(private readonly restClient: RestClient) {}
Expand Down
2 changes: 1 addition & 1 deletion server/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import HmppsAuthClient, { systemTokenBuilder } from './hmppsAuthClient'
import IncentivesApiRestClient from './incentivesApiClient'
import AllocationManagerClient from './interfaces/allocationManagerClient'
import { CaseNotesApiClient } from './interfaces/caseNotesApiClient'
import CuriousApiClient from './interfaces/curiousApiClient'
import { CuriousApiClient } from './interfaces/curiousApiClient'
import { IncentivesApiClient } from './interfaces/incentivesApiClient'
import KeyWorkerClient from './interfaces/keyWorkerClient'
import { ManageSocCasesApiClient } from './interfaces/manageSocCasesApiClient'
Expand Down
2 changes: 1 addition & 1 deletion server/data/interfaces/curiousApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { LearnerLatestAssessment } from '../../interfaces/learnerLatestAssessmen
import { LearnerNeurodivergence } from '../../interfaces/learnerNeurodivergence'
import { LearnerProfile } from '../../interfaces/learnerProfile'

export default interface CuriousApiClient {
export interface CuriousApiClient {
getLearnerEmployabilitySkills(prisonerNumber: string): Promise<LearnerEmployabilitySkills>
getLearnerProfile(prisonerNumber: string): Promise<LearnerProfile[]>
getLearnerEducation(prisonerNumber: string): Promise<LearnerEducation>
Expand Down
2 changes: 1 addition & 1 deletion server/data/localMockData/learnerNeurodivergenceMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { LearnerNeurodivergence } from '../../interfaces/learnerNeurodivergence'
export const LearnerNeurodivergenceMock: LearnerNeurodivergence[] = [
{
prn: 'G6123VU',
establishmentId: 'string',
establishmentId: 'MDI',
establishmentName: 'string',
neurodivergenceSelfDeclared: ['string'],
selfDeclaredDate: '2023-03-02',
Expand Down
2 changes: 2 additions & 0 deletions server/interfaces/pages/personalPage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Address } from '../address'
import { GovSummaryItem } from '../govSummaryItem'
import { LearnerNeurodivergence } from '../learnerNeurodivergence'

export interface PersonalDetails {
age: string
Expand Down Expand Up @@ -132,4 +133,5 @@ export interface PersonalPage {
physicalCharacteristics: PhysicalCharacteristics
security: Security
careNeeds: CareNeeds
learnerNeurodivergence: LearnerNeurodivergence[]
}
2 changes: 1 addition & 1 deletion server/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const services = () => {
offencesPageService,
curiousApiClientBuilder,
)
const personalPageService = new PersonalPageService(prisonApiClientBuilder)
const personalPageService = new PersonalPageService(prisonApiClientBuilder, curiousApiClientBuilder)
const workAndSkillsPageService = new WorkAndSkillsPageService(curiousApiClientBuilder, prisonApiClientBuilder)
const activePunishmentsPageService = new ActivePunishmentsService(adjudicationsApiClientBuilder)

Expand Down
2 changes: 1 addition & 1 deletion server/services/overviewPageService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import { Role } from '../data/enums/role'
import OffencesPageService from './offencesPageService'
import { AdjudicationsApiClient } from '../data/interfaces/adjudicationsApiClient'
import { adjudicationsApiClientMock } from '../../tests/mocks/adjudicationsApiClientMock'
import CuriousApiClient from '../data/interfaces/curiousApiClient'
import { CuriousApiClient } from '../data/interfaces/curiousApiClient'
import { LearnerNeurodivergenceMock } from '../data/localMockData/learnerNeurodivergenceMock'
import { learnerEmployabilitySkills } from '../data/localMockData/learnerEmployabilitySkills'
import { LearnerProfiles } from '../data/localMockData/learnerProfiles'
Expand Down
2 changes: 1 addition & 1 deletion server/services/overviewPageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { MainOffence } from '../interfaces/prisonApi/mainOffence'
import { RestClientBuilder } from '../data'
import { AdjudicationsApiClient } from '../data/interfaces/adjudicationsApiClient'
import { LearnerNeurodivergence } from '../interfaces/learnerNeurodivergence'
import CuriousApiClient from '../data/interfaces/curiousApiClient'
import { CuriousApiClient } from '../data/interfaces/curiousApiClient'
import { InmateDetail } from '../interfaces/prisonApi/inmateDetail'
import { PersonalCareNeeds } from '../interfaces/personalCareNeeds'

Expand Down
22 changes: 21 additions & 1 deletion server/services/personalPageService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ import { personalCareNeedsMock } from '../data/localMockData/personalCareNeedsMo
import { formatDate } from '../utils/dateHelpers'
import { identifiersMock } from '../data/localMockData/identifiersMock'
import { addressSummaryMock } from '../data/localMockData/addressSummary'
import { CuriousApiClient } from '../data/interfaces/curiousApiClient'
import { curiousApiClientMock } from '../../tests/mocks/curiousApiClientMock'
import { LearnerNeurodivergenceMock } from '../data/localMockData/learnerNeurodivergenceMock'

describe('PersonalPageService', () => {
let prisonApiClient: PrisonApiClient
let curiousApiClient: CuriousApiClient

beforeEach(() => {
prisonApiClient = prisonApiClientMock()
Expand All @@ -36,6 +40,10 @@ describe('PersonalPageService', () => {
prisonApiClient.getPersonalCareNeeds = jest.fn(async () => personalCareNeedsMock)
prisonApiClient.getReasonableAdjustments = jest.fn(async () => mockReasonableAdjustments)
prisonApiClient.getIdentifiers = jest.fn(async () => identifiersMock)

curiousApiClient = curiousApiClientMock()

curiousApiClient.getLearnerNeurodivergence = jest.fn(async () => LearnerNeurodivergenceMock)
})

const setPersonalCareNeeds = (careNeeds: PersonalCareNeed[]) => {
Expand All @@ -49,7 +57,11 @@ describe('PersonalPageService', () => {
prisonApiClient.getReferenceCodesByDomain = jest.fn(async () => referenceCodes)
}

const constructService = () => new PersonalPageService(() => prisonApiClient)
const constructService = () =>
new PersonalPageService(
() => prisonApiClient,
() => curiousApiClient,
)

describe('Getting information from the Prison API', () => {
it('Gets inmate details from the api', async () => {
Expand Down Expand Up @@ -723,4 +735,12 @@ describe('PersonalPageService', () => {
expect(addresses).toBeUndefined()
})
})

describe('Get Learner Neurodivergence information', () => {
it('Sets the address to empty', async () => {
curiousApiClient.getLearnerNeurodivergence = jest.fn(async () => LearnerNeurodivergenceMock)
const data = await constructService().get('token', PrisonerMockDataA)
expect(data.learnerNeurodivergence).toBe(LearnerNeurodivergenceMock)
})
})
})
19 changes: 18 additions & 1 deletion server/services/personalPageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,23 @@ import { GovSummaryItem } from '../interfaces/govSummaryItem'
import { HealthDomainReferenceCode, PersonalCareNeed } from '../interfaces/personalCareNeeds'
import { ReasonableAdjustment } from '../interfaces/prisonApi/reasonableAdjustment'
import { RestClientBuilder } from '../data'
import { CuriousApiClient } from '../data/interfaces/curiousApiClient'
import { LearnerNeurodivergence } from '../interfaces/learnerNeurodivergence'

export default class PersonalPageService {
private prisonApiClient: PrisonApiClient

constructor(private readonly prisonApiClientBuilder: RestClientBuilder<PrisonApiClient>) {}
private curiousApiClient: CuriousApiClient

constructor(
private readonly prisonApiClientBuilder: RestClientBuilder<PrisonApiClient>,
private readonly curiousApiClientBuilder: RestClientBuilder<CuriousApiClient>,
) {}

public async get(token: string, prisonerData: Prisoner): Promise<PersonalPage> {
this.prisonApiClient = this.prisonApiClientBuilder(token)
this.curiousApiClient = this.curiousApiClientBuilder(token)

const { bookingId, prisonerNumber } = prisonerData
const [
inmateDetail,
Expand Down Expand Up @@ -90,6 +99,7 @@ export default class PersonalPageService {
xrays: this.xrays(personalCareNeeds),
},
careNeeds: await this.careNeeds(healthReferenceCodes, personalCareNeeds, reasonableAdjustments),
learnerNeurodivergence: await this.getLearnerNeurodivergence(prisonerNumber),
}
}

Expand Down Expand Up @@ -354,4 +364,11 @@ export default class PersonalPageService {
since: xrayNeeds.length > 0 ? yearStart.toISOString() : undefined,
}
}

private async getLearnerNeurodivergence(prisonerNumber: string) {
const learnerNeurodivergence: LearnerNeurodivergence[] = await this.curiousApiClient.getLearnerNeurodivergence(
prisonerNumber,
)
return learnerNeurodivergence
}
}
2 changes: 1 addition & 1 deletion server/services/workAndSkillsPageService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { prisonerDetailMock } from '../data/localMockData/prisonerDetailMock'
import { inmateDetailMock } from '../data/localMockData/inmateDetailMock'
import { personalCareNeedsMock } from '../data/localMockData/personalCareNeedsMock'
import CuriousApiClient from '../data/interfaces/curiousApiClient'
import { CuriousApiClient } from '../data/interfaces/curiousApiClient'
import WorkAndSkillsPageService from './workAndSkillsPageService'
import { OffenderActivitiesMock } from '../data/localMockData/offenderActivitiesMock'
import { OffenderAttendanceHistoryMock } from '../data/localMockData/offenderAttendanceHistoryMock'
Expand Down
4 changes: 2 additions & 2 deletions server/services/workAndSkillsPageService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { format, startOfToday, sub } from 'date-fns'
import { AbsenceOutcomeCodes } from '../data/enums/absenceOutcomeCodes'
import CuriousApiClient from '../data/interfaces/curiousApiClient'
import { CuriousApiClient } from '../data/interfaces/curiousApiClient'
import { PrisonApiClient } from '../data/interfaces/prisonApiClient'
import { GovSummaryGroup, GovSummaryItem } from '../interfaces/govSummaryItem'
import { LearnerEducation } from '../interfaces/learnerEducation'
Expand Down Expand Up @@ -191,7 +191,7 @@ export default class WorkAndSkillsPageService {
return govList
}

private async getLearnerNeurodivergence(prisonerNumber: string) {
public async getLearnerNeurodivergence(prisonerNumber: string) {
const learnerNeurodivergence: LearnerNeurodivergence[] = await this.curiousApiClient.getLearnerNeurodivergence(
prisonerNumber,
)
Expand Down
3 changes: 3 additions & 0 deletions server/utils/nunjucksSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
prependHmppsAuthBaseUrl,
prisonerIsOut,
prisonerIsTRN,
neurodiversityEnabled,
} from './utils'
import { pluralise } from './pluralise'
import { formatDate, formatDateTime } from './dateHelpers'
Expand Down Expand Up @@ -66,6 +67,8 @@ export default function nunjucksSetup(app: express.Express, path: pathModule.Pla
njkEnv.addGlobal('prisonerIsTRN', prisonerIsTRN)
njkEnv.addGlobal('prisonerIsOut', prisonerIsOut)

njkEnv.addGlobal('neurodiversityEnabled', neurodiversityEnabled)

njkEnv.addFilter('initialiseName', initialiseName)
njkEnv.addFilter('formatDate', formatDate)
njkEnv.addFilter('formatDateTime', formatDateTime)
Expand Down
26 changes: 26 additions & 0 deletions server/utils/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
getNamesFromString,
initialiseName,
mapToQueryString,
neurodiversityEnabled,
prependBaseUrl,
prependHmppsAuthBaseUrl,
prisonerBelongsToUsersCaseLoad,
Expand Down Expand Up @@ -395,4 +396,29 @@ describe('findError', () => {
)
})
})

describe('sortArrayOfObjectsByDate', () => {
it('Should return array of objects sorted in ascending order', () => {
expect(sortArrayOfObjectsByDate(xrayCareNeedsMock.personalCareNeeds, 'startDate', SortType.ASC)).toEqual(
xrayCareNeedsASCMock.personalCareNeeds,
)
})
it('Should return array of objects sorted in descending order', () => {
expect(sortArrayOfObjectsByDate(xrayCareNeedsMock.personalCareNeeds, 'startDate', SortType.DESC)).toEqual(
xrayCareNeedsDESCMock.personalCareNeeds,
)
})
})

describe.skip('neuroDiversityEnabledPrisons', () => {
it('Should return true', () => {
expect(neurodiversityEnabled('NHI')).toEqual(true)
})
})

describe('neuroDiversityDisabledPrisons', () => {
it('Should return false', () => {
expect(neurodiversityEnabled('MDI')).toEqual(false)
})
})
})
7 changes: 7 additions & 0 deletions server/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,3 +451,10 @@ export const sortArrayOfObjectsByDate = (arrayOfObjects: object[], dateKey: stri
})
return array
}

export const { neurodiversityEnabledPrisons } = config

export const neurodiversityEnabled = (agencyId: string): boolean => {
const isEnabled = neurodiversityEnabledPrisons?.includes(agencyId)
return isEnabled
}
11 changes: 6 additions & 5 deletions server/views/pages/personalPage.njk
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@
{% include "../partials/personalPage/careNeeds.njk" %}
</div>
</div>
{# This is hidden deliberately for now #}
{# <div class="govuk-grid-row">
<div class="govuk-grid-column-full">
{% include "../partials/personalPage/neurodiversity.njk" %}
{%- call conditionallyShow({condition: neurodiversityEnabled(user.activeCaseLoad.caseLoadId ), id: 'neurodiversity'}) -%}
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
{% include "../partials/personalPage/neurodiversity.njk" %}
</div>
</div>
</div> #}
{%- endcall -%}
{%- call conditionallyShow({condition: prisonerBelongsToUsersCaseLoad(prisonId, user.caseLoads), id: 'appearance'}) -%}
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
Expand Down
Loading

0 comments on commit 316bb63

Please sign in to comment.