Skip to content

Commit

Permalink
APS-1702 Suitability search filter changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Bob Meredith committed Jan 8, 2025
1 parent a709cf2 commit fe06e13
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 85 deletions.
6 changes: 0 additions & 6 deletions integration_tests/pages/match/searchPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,21 @@ export default class SearchPage extends Page {
}

changeSearchParameters(newSearchParameters: SpaceSearchParametersUi): void {
this.clearDateInputs('startDate')
this.completeDateInputs('startDate', newSearchParameters.startDate)

this.getTextInputByIdAndClear('targetPostcodeDistrict')
this.getTextInputByIdAndEnterDetails('targetPostcodeDistrict', newSearchParameters.targetPostcodeDistrict)
cy.get('[type="checkbox"]').uncheck()

this.checkRadioByNameAndValue('requirements[apType]', newSearchParameters.requirements.apType)
this.checkRadioByNameAndValue('requirements[gender]', newSearchParameters.requirements.gender)

newSearchParameters.requirements.spaceCharacteristics.forEach(requirement => {
cy.get(`input[name="requirements[spaceCharacteristics][]"][value="${requirement}"]`).check()
})
}

shouldShowSearchParametersInInputs(newSearchParameters: SpaceSearchParametersUi): void {
this.dateInputsShouldContainDate('startDate', newSearchParameters.startDate)
this.verifyTextInputContentsById('targetPostcodeDistrict', newSearchParameters.targetPostcodeDistrict)

cy.get(`input[name="requirements[apType]"][value="${newSearchParameters.requirements.apType}"]`)
cy.get(`input[name="requirements[gender]"][value="${newSearchParameters.requirements.gender}"]`)

newSearchParameters.requirements.spaceCharacteristics.forEach(requirement => {
cy.get(`input[name="requirements[spaceCharacteristics][]"][value="${requirement}"]`).should('be.checked')
Expand Down
6 changes: 2 additions & 4 deletions integration_tests/tests/match/match.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ context('Placement Requests', () => {
targetPostcodeDistrict: placementRequest.location,
requirements: {
apTypes: [placementRequest.type],
genders: [placementRequest.gender],
spaceCharacteristics: filteredPlacementCriteria,
},
})
Expand All @@ -106,15 +105,14 @@ context('Placement Requests', () => {
expect(secondSearchRequestBody).to.contain({
applicationId: placementRequest.applicationId,
durationInDays: placementRequest.duration,
startDate: newSearchParameters.startDate,
startDate: placementRequest.expectedArrival,
targetPostcodeDistrict: newSearchParameters.targetPostcodeDistrict,
})

expect(secondSearchRequestBody.requirements.apTypes).to.contain.members([newSearchParameters.requirements.apType])
expect(secondSearchRequestBody.requirements.spaceCharacteristics).to.contain.members(
newSearchParameters.requirements.spaceCharacteristics,
)
expect(secondSearchRequestBody.requirements.genders).to.contain.members([newSearchParameters.requirements.gender])
})
})

Expand Down Expand Up @@ -305,7 +303,7 @@ context('Placement Requests', () => {

// And there is a placement request waiting for me to match
const person = personFactory.build()
const essentialCharacteristics: Array<PlacementCriteria> = ['acceptsHateCrimeOffenders']
const essentialCharacteristics: Array<PlacementCriteria> = ['isArsonDesignated']
const desirableCharacteristics: Array<PlacementCriteria> = ['isCatered', 'hasEnSuite']
const placementRequest = placementRequestDetailFactory.build({
person,
Expand Down
8 changes: 3 additions & 5 deletions server/@types/ui/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
Cas1PremisesBasicSummary,
Document,
FlagsEnvelope,
Gender,
Mappa,
OASysSection,
PersonAcctAlert,
Expand Down Expand Up @@ -111,7 +110,7 @@ export type TableCell =

export type TableRow = Array<TableCell>

export interface RadioItem {
export type RadioItem = {
text: string
value: string
checked?: boolean
Expand All @@ -131,9 +130,9 @@ export type CheckBoxItem =
}
behaviour?: 'exclusive'
}
| CheckBoxDivider
| Divider

export type CheckBoxDivider = { divider: string }
export type Divider = { divider: string }

export interface SelectOption {
text: string
Expand Down Expand Up @@ -385,7 +384,6 @@ export interface SpaceSearchParametersUi {
durationInDays: string
requirements: {
apType: ApType
gender: Gender
spaceCharacteristics: Array<SpaceCharacteristic>
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ export default class MatchingInformation implements TasklistPage {

this.placementRequirementCriteria.forEach(placementRequirementCriterion => {
if (!this.body[placementRequirementCriterion]) {
errors[placementRequirementCriterion] = `You must specify a preference for ${lowerCase(
placementCriteriaLabels[placementRequirementCriterion],
)}`
errors[placementRequirementCriterion] = `You must specify a preference for ${placementCriteriaLabels[
placementRequirementCriterion
].toLowerCase()}`
}
})

Expand Down
12 changes: 9 additions & 3 deletions server/testutils/factories/spaceSearchParameters.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { Factory } from 'fishery'
import { faker } from '@faker-js/faker/locale/en_GB'

import type { Cas1SpaceSearchParameters, Cas1SpaceSearchRequirements } from '@approved-premises/api'
import type {
Cas1SpaceCharacteristic,
Cas1SpaceSearchParameters,
Cas1SpaceSearchRequirements,
} from '@approved-premises/api'
import { DateFormats } from '../../utils/dateUtils'
import { filterOutAPTypes } from '../../utils/match'
import { placementCriteria } from './placementRequest'
import postcodeAreas from '../../etc/postcodeAreas.json'
import { SpaceSearchParametersUi } from '../../@types/ui'
import { spaceSearchCriteriaRoomLevelLabels } from '../../utils/placementCriteriaUtils'

const spaceBookingRequirements = Factory.define<Cas1SpaceSearchRequirements>(() => {
return {
Expand Down Expand Up @@ -35,8 +40,9 @@ export const spaceSearchParametersUiFactory = Factory.define<SpaceSearchParamete
durationInDays: faker.number.int({ max: 100, min: 1 }).toString(),
requirements: {
apType: faker.helpers.arrayElement(['pipe', 'esap', 'rfap', 'mhapStJosephs', 'mhapElliottHouse']),
spaceCharacteristics: faker.helpers.arrayElements(filterOutAPTypes(placementCriteria)),
gender: faker.helpers.arrayElement(['male', 'female']),
spaceCharacteristics: faker.helpers.arrayElements(
Object.keys(spaceSearchCriteriaRoomLevelLabels),
) as Array<Cas1SpaceCharacteristic>,
},
...startDateInputsValues,
}
Expand Down
13 changes: 1 addition & 12 deletions server/utils/assessments/acceptanceData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,9 @@ describe('acceptanceData', () => {
apType: 'isESAP',
isWheelchairDesignated: 'essential',
isStepFreeDesignated: 'essential',
isCatered: 'essential',
acceptsSexOffenders: 'relevant',
acceptsChildSexOffenders: 'relevant',
acceptsNonSexualChildOffenders: 'relevant',
isArsonSuitable: 'relevant',
acceptsHateCrimeOffenders: 'relevant',
isSuitableForVulnerable: 'relevant',
})

Expand All @@ -153,12 +150,9 @@ describe('acceptanceData', () => {
'isESAP',
'isWheelchairDesignated',
'isStepFreeDesignated',
'isCatered',
'acceptsSexOffenders',
'acceptsChildSexOffenders',
'acceptsNonSexualChildOffenders',
'isArsonSuitable',
'acceptsHateCrimeOffenders',
'isSuitableForVulnerable',
'isSuitedForSexOffenders',
].sort(),
Expand All @@ -170,14 +164,11 @@ describe('acceptanceData', () => {
apType: 'normal',
isWheelchairDesignated: 'desirable',
isStepFreeDesignated: 'desirable',
isCatered: 'desirable',
})

const result = criteriaFromMatchingInformation(matchingInformation)

expect(result.desirableCriteria.sort()).toEqual(
['isStepFreeDesignated', 'isWheelchairDesignated', 'isCatered'].sort(),
)
expect(result.desirableCriteria.sort()).toEqual(['isStepFreeDesignated', 'isWheelchairDesignated'].sort())
expect(result.essentialCriteria).toEqual([])
})

Expand All @@ -190,8 +181,6 @@ describe('acceptanceData', () => {
acceptsSexOffenders: 'notRelevant',
acceptsChildSexOffenders: 'notRelevant',
acceptsNonSexualChildOffenders: 'notRelevant',
isArsonSuitable: 'notRelevant',
acceptsHateCrimeOffenders: 'notRelevant',
isSuitableForVulnerable: 'notRelevant',
})

Expand Down
6 changes: 3 additions & 3 deletions server/utils/match/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ describe('matchUtils', () => {
durationInDays: Number(uiParams.durationInDays),
requirements: {
apTypes: [uiParams.requirements.apType],
genders: [uiParams.requirements.gender],
spaceCharacteristics: uiParams.requirements.spaceCharacteristics,
},
applicationId: uiParams.applicationId,
Expand Down Expand Up @@ -210,11 +209,11 @@ describe('matchUtils', () => {
describe('groupedCheckboxes', () => {
it('returns checkboxes grouped by category', () => {
expect(groupedCheckboxes()).toEqual({
'Risks and offences': {
'AP requirements': {
inputName: 'spaceCharacteristics',
items: groupedCriteria.offenceAndRisk.items,
},
'Access needs and additional features': {
'Room requirements': {
inputName: 'spaceCharacteristics',
items: groupedCriteria.accessNeeds.items,
},
Expand Down Expand Up @@ -567,6 +566,7 @@ describe('matchUtils', () => {
text: 'Standard AP',
value: 'normal',
},
{ divider: 'or' },
{
checked: false,
conditional: undefined,
Expand Down
22 changes: 13 additions & 9 deletions server/utils/match/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ import type {
Cas1SpaceSearchParameters as SpaceSearchParameters,
Cas1SpaceSearchResult as SpaceSearchResult,
} from '@approved-premises/api'
import type {
import {
KeyDetailsArgs,
ObjectWithDateParts,
RadioItem,
SpaceSearchParametersUi,
SummaryListItem,
} from '@approved-premises/ui'
import { DateFormats, daysToWeeksAndDays } from '../dateUtils'
import { createQueryString, sentenceCase } from '../utils'
import matchPaths from '../../paths/match'
import {
offenceAndRiskCriteriaLabels,
placementCriteriaLabels,
placementRequirementCriteriaLabels,
spaceSearchCriteriaApLevelLabels,
spaceSearchCriteriaRoomLevelLabels,
} from '../placementCriteriaUtils'
import { apTypeLabels } from '../apTypeLabels'
import { convertKeyValuePairToRadioItems } from '../formUtils'
Expand Down Expand Up @@ -56,7 +57,6 @@ export const mapUiParamsForApi = (query: SpaceSearchParametersUi): SpaceSearchPa
targetPostcodeDistrict: query.targetPostcodeDistrict,
requirements: {
apTypes: [query.requirements.apType],
genders: [query.requirements.gender],
spaceCharacteristics: query.requirements.spaceCharacteristics,
},
durationInDays: Number(query.durationInDays),
Expand Down Expand Up @@ -387,13 +387,13 @@ export const startDateObjFromParams = (params: { startDate: string } | ObjectWit

export const groupedCriteria = {
offenceAndRisk: {
title: 'Risks and offences',
items: offenceAndRiskCriteriaLabels,
title: 'AP requirements',
items: spaceSearchCriteriaApLevelLabels,
inputName: 'spaceCharacteristics',
},
accessNeeds: {
title: 'Access needs and additional features',
items: placementRequirementCriteriaLabels,
title: 'Room requirements',
items: spaceSearchCriteriaRoomLevelLabels,
inputName: 'spaceCharacteristics',
},
}
Expand Down Expand Up @@ -422,7 +422,11 @@ export const checkBoxesForCriteria = (criteria: Record<string, string>, selected
}

export const apTypeLabelsForRadioInput = (selectedValue: ApType) => {
return convertKeyValuePairToRadioItems(apTypeLabels, selectedValue)
const apTypeRadios = convertKeyValuePairToRadioItems(apTypeLabels, selectedValue) as Array<
RadioItem | { divider: 'or' }
>
apTypeRadios.splice(1, 0, { divider: 'or' })
return apTypeRadios
}

export const lengthOfStayRow = (lengthInDays: number) => ({
Expand Down
37 changes: 29 additions & 8 deletions server/utils/placementCriteriaUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,32 @@ export const apTypeCriteriaLabels: Record<ApTypeCriteria, string> = {
normal: 'Standard AP',
...specialistApTypeCriteriaLabels,
}
export const offenceAndRiskCriteriaLabels = filterByType<OffenceAndRiskCriteria>(
offenceAndRiskCriteria,
placementCriteriaLabels,
)
export const placementRequirementCriteriaLabels = filterByType<PlacementRequirementCriteria>(
placementRequirementCriteria,
placementCriteriaLabels,
)

type CriteriaLabelMap = Partial<Record<PlacementCriteria, string>>

const apLevelSearchCriteria: CriteriaLabelMap = {
acceptsSexOffenders: 'Sexual offences against adults',
acceptsChildSexOffenders: undefined,
acceptsNonSexualChildOffenders: undefined,
isSuitableForVulnerable: 'Vulnerable to exploitation (removes ESAP APs)',
isCatered: 'Catered',
}

const roomLevelSearchCriteria: CriteriaLabelMap = {
isWheelchairDesignated: 'Wheelchair',
isStepFreeDesignated: 'Step-free',
hasEnSuite: 'En-suite',
isSingle: undefined,
isArsonDesignated: 'Arson room',
isSuitedForSexOffenders: 'Suitable for sexual offences',
}

const filterByTypeOrder = (mapping: CriteriaLabelMap, defaultLabels: CriteriaLabelMap): CriteriaLabelMap =>
Object.entries(mapping).reduce(
(criteria, [key, value]) => ({ ...criteria, [key]: value || defaultLabels[key] }),
{} as CriteriaLabelMap,
)

export const spaceSearchCriteriaApLevelLabels = filterByTypeOrder(apLevelSearchCriteria, placementCriteriaLabels)

export const spaceSearchCriteriaRoomLevelLabels = filterByTypeOrder(roomLevelSearchCriteria, placementCriteriaLabels)
1 change: 0 additions & 1 deletion server/utils/placementRequests/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ describe('utils', () => {
...placementRequest.essentialCriteria,
]),
apType: placementRequest.type,
gender: placementRequest.gender,
},
})
})
Expand Down
2 changes: 0 additions & 2 deletions server/utils/placementRequests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export const mapPlacementRequestToSpaceSearchParams = ({
essentialCriteria,
desirableCriteria,
type,
gender,
}: PlacementRequest): SpaceSearchParametersUi => {
return {
applicationId,
Expand All @@ -28,7 +27,6 @@ export const mapPlacementRequestToSpaceSearchParams = ({
requirements: {
spaceCharacteristics: filterOutAPTypes([...desirableCriteria, ...essentialCriteria]),
apType: type,
gender,
},
}
}
Expand Down
Loading

0 comments on commit fe06e13

Please sign in to comment.