Skip to content

Commit

Permalink
WIP - Adding radio buttons for occupancy attributes
Browse files Browse the repository at this point in the history
The main functionality seems to be working and should be a case of tidying up the types, adding tests and modify existing tests to pass
  • Loading branch information
aliuk2012 committed Nov 27, 2024
1 parent 225cf21 commit 080ee55
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import {
TemporaryAccommodationBedSearchParameters as BedSearchParameters,
BedSearchResults,
Room,
TemporaryAccommodationBedSearchResult,
} from '../../../../server/@types/shared'
import { PlaceContext } from '../../../../server/@types/ui'
import { BedSearchResults, Room, TemporaryAccommodationBedSearchResult } from '../../../../server/@types/shared'
import { BedspaceSearchFormParameters, PlaceContext } from '../../../../server/@types/ui'

import paths from '../../../../server/paths/temporary-accommodation/manage'
import BedspaceSearchResult from '../../../components/bedspaceSearchResult'
import Page from '../../page'
import { addPlaceContext } from '../../../../server/utils/placeUtils'
import { bedspaceSearchFormParametersFactory } from '../../../../server/testutils/factories'

Check warning on line 8 in cypress_shared/pages/temporary-accommodation/manage/bedspaceSearch.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

'bedspaceSearchFormParametersFactory' is defined but never used

export default class BedspaceSearchPage extends Page {
private readonly bedspaceSearchResults: Map<string, BedspaceSearchResult>
Expand Down Expand Up @@ -44,7 +40,7 @@ export default class BedspaceSearchPage extends Page {
cy.get('h2').should('contain', 'There are no available bedspaces')
}

shouldShowPrefilledSearchParameters(searchParameters: BedSearchParameters) {
shouldShowPrefilledSearchParameters(searchParameters: BedspaceSearchFormParameters) {
this.shouldShowDateInputsByLegend('Available from', searchParameters.startDate)
this.shouldShowTextInputByLabel('Number of days required', `${searchParameters.durationDays}`)
searchParameters.probationDeliveryUnits.forEach(pduId => {
Expand All @@ -56,7 +52,7 @@ export default class BedspaceSearchPage extends Page {
this.shouldShowDateInputsByLegend('Available from', placeContext.assessment.accommodationRequiredFromDate)
}

completeForm(searchParameters: BedSearchParameters) {
completeForm(searchParameters: BedspaceSearchFormParameters) {
this.completeDateInputsByLegend('Available from', searchParameters.startDate)
this.completeTextInputByLabel('Number of days required', `${searchParameters.durationDays}`)

Expand All @@ -65,7 +61,7 @@ export default class BedspaceSearchPage extends Page {
})

this.getLegend('Property attributes')
this.getLegend('Occupancy (optional)')
this.getLegend('Occupancy')
searchParameters.attributes
.filter(attribute => attribute === 'wheelchairAccessible')
.forEach(attribute => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import BedspaceShowPage from '../../../../cypress_shared/pages/temporary-accommo
import BookingShowPage from '../../../../cypress_shared/pages/temporary-accommodation/manage/bookingShow'
import { setupTestUser } from '../../../../cypress_shared/utils/setupTestUser'
import {
bedSearchParametersFactory,
bedSearchResultFactory,
bedSearchResultsFactory,
bedspaceSearchFormParametersFactory,
bookingFactory,
overlapFactory,
personFactory,
Expand Down Expand Up @@ -55,7 +55,7 @@ context('Bedspace Search', () => {
const results = bedSearchResultsFactory.build()
cy.task('stubBedSearch', results)

const searchParameters = bedSearchParametersFactory.build()
const searchParameters = bedspaceSearchFormParametersFactory.build()
preSearchPage.completeForm(searchParameters)
preSearchPage.clickSubmit()

Expand All @@ -67,7 +67,8 @@ context('Bedspace Search', () => {
expect(requestBody.startDate).equal(searchParameters.startDate)
expect(requestBody.durationDays).equal(searchParameters.durationDays)
expect(requestBody.probationDeliveryUnits).to.have.members(searchParameters.probationDeliveryUnits)
expect(requestBody.attributes).to.have.members(searchParameters.attributes)
cy.task('log', searchParameters.occupancyAttribute)
expect(requestBody.occupancyAttributes).equal(searchParameters.occupancyAttribute)
})

// And I should see the search results
Expand Down Expand Up @@ -95,7 +96,7 @@ context('Bedspace Search', () => {
})
cy.task('stubBedSearch', results)

const searchParameters = bedSearchParametersFactory.build()
const searchParameters = bedspaceSearchFormParametersFactory.build()
preSearchPage.completeForm(searchParameters)
preSearchPage.clickSubmit()

Expand All @@ -107,7 +108,7 @@ context('Bedspace Search', () => {
expect(requestBody.startDate).equal(searchParameters.startDate)
expect(requestBody.durationDays).equal(searchParameters.durationDays)
expect(requestBody.probationDeliveryUnits).to.include.members(searchParameters.probationDeliveryUnits)
expect(requestBody.attributes).to.have.members(searchParameters.attributes)
expect(requestBody.occupancyAttributes).equal(searchParameters.occupancyAttribute)
})

// And I should see empty search results
Expand Down Expand Up @@ -137,7 +138,7 @@ context('Bedspace Search', () => {
cy.task('stubSinglePremises', premises)
cy.task('stubSingleRoom', { premisesId: premises.id, room })

const searchParameters = bedSearchParametersFactory.build()
const searchParameters = bedspaceSearchFormParametersFactory.build()
preSearchPage.completeForm(searchParameters)
preSearchPage.clickSubmit()

Expand Down Expand Up @@ -188,7 +189,7 @@ context('Bedspace Search', () => {
cy.task('stubBooking', { premisesId: premises.id, booking })

// And when I fill out the form
const searchParameters = bedSearchParametersFactory.build()
const searchParameters = BedspaceSearchFormParametersFactory.build()
preSearchPage.completeForm(searchParameters)
preSearchPage.clickSubmit()

Expand Down Expand Up @@ -236,7 +237,7 @@ context('Bedspace Search', () => {
const results = bedSearchResultsFactory.build()
cy.task('stubBedSearch', results)

const searchParameters = bedSearchParametersFactory.build()
const searchParameters = BedspaceSearchFormParametersFactory.build()
preSearchPage.completeForm(searchParameters)
preSearchPage.clickSubmit()

Expand Down Expand Up @@ -269,7 +270,7 @@ context('Bedspace Search', () => {
const results = bedSearchResultsFactory.build()
cy.task('stubBedSearch', results)

const searchParameters = bedSearchParametersFactory.build()
const searchParameters = bedspaceSearchFormParametersFactory.build()
preSearchPage.completeForm(searchParameters)
preSearchPage.clickSubmit()

Expand Down
7 changes: 7 additions & 0 deletions server/@types/ui/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
SortDirection,
TemporaryAccommodationApplication,
TemporaryAccommodationAssessmentStatus,
TemporaryAccommodationBedSearchParameters,
User,
} from '@approved-premises/api'
import { CallConfig } from '../../data/restClient'
Expand Down Expand Up @@ -340,3 +341,9 @@ export type PrimaryNavigationItem = {
text: string
active?: boolean
}

export type BedspaceSearchFormParameters = Omit<TemporaryAccommodationBedSearchParameters, 'serviceName'> & {
occupancyAttribute: OccupancyAttribute
}

export type OccupancyAttribute = 'all' | 'sharedProperty' | 'singleOccupancy'
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Request, RequestHandler, Response } from 'express'
import { BedSearchResults } from '../../../@types/shared'
import { ObjectWithDateParts } from '../../../@types/ui'
import { BedspaceSearchFormParameters, ObjectWithDateParts } from '../../../@types/ui'

import paths from '../../../paths/temporary-accommodation/manage'
import { AssessmentsService } from '../../../services'
Expand All @@ -13,8 +13,10 @@ import { catchValidationErrorOrPropogate, fetchErrorsAndUserInput, setUserInput

export const DEFAULT_DURATION_DAYS = 84

type BedspaceSearchQuery = ObjectWithDateParts<'startDate'> & {
probationDeliveryUnits: Array<string>
type APISearchQuery = Omit<BedspaceSearchFormParameters, 'occupancyAttribute'> & {
/**
* The number of days the Bed will need to be free from the start_date until
*/
durationDays: string
}

Expand All @@ -35,7 +37,17 @@ export default class BedspaceSearchController {
const { pdus: allPdus } = await this.searchService.getReferenceData(callConfig)

const query =
(req.query as BedspaceSearchQuery).durationDays !== undefined ? (req.query as BedspaceSearchQuery) : undefined
(req.query as unknown as BedspaceSearchFormParameters).durationDays !== undefined
? (req.query as unknown as BedspaceSearchFormParameters)
: undefined

const apiQueryParams: APISearchQuery = (query !== undefined)?

Check failure on line 44 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Integration testing 🧪

Type '{ startDate: string; durationDays: number; probationDeliveryUnits: string[]; }' is not assignable to type 'APISearchQuery'.

Check failure on line 44 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

Replace `··(query·!==·undefined)?` with `⏎········query·!==·undefined`

Check failure on line 44 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Type check 🔎

Type '{ startDate: string; durationDays: number; probationDeliveryUnits: string[]; }' is not assignable to type 'APISearchQuery'.
{

Check failure on line 45 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

Insert `···?`
startDate: query?.startDate,

Check failure on line 46 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

Insert `······`
durationDays: query?.durationDays,

Check failure on line 47 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

Insert `······`
probationDeliveryUnits: query?.probationDeliveryUnits,

Check failure on line 48 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

Replace `········` with `··············`
...Object.fromEntries(Object.entries(query).filter(([key]) => key !== 'occupancyAttribute')),

Check failure on line 49 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

Insert `······`
} : undefined

Check failure on line 50 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Linting 🔎

Replace `}` with `······}⏎·········`

const placeContextArrivalDate = placeContext?.assessment.accommodationRequiredFromDate
const startDatePrefill = placeContextArrivalDate
Expand All @@ -46,17 +58,21 @@ export default class BedspaceSearchController {
let startDate: string

try {
if (query) {
if (apiQueryParams) {
startDate = DateFormats.dateAndTimeInputsToIsoString(
query as ObjectWithDateParts<'startDate'>,
apiQueryParams as ObjectWithDateParts<'startDate'>,

Check failure on line 63 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Integration testing 🧪

Conversion of type 'APISearchQuery' to type 'ObjectWithDateParts<"startDate">' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

Check failure on line 63 in server/controllers/temporary-accommodation/manage/bedspaceSearchController.ts

View workflow job for this annotation

GitHub Actions / Type check 🔎

Conversion of type 'APISearchQuery' to type 'ObjectWithDateParts<"startDate">' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
'startDate',
).startDate

const durationDays = parseNumber(query.durationDays)
if (query.occupancyAttribute !== 'all') {
apiQueryParams.attributes = [query.occupancyAttribute, ...(apiQueryParams?.attributes || [])]
}

const durationDays = parseNumber(apiQueryParams.durationDays as APISearchQuery['durationDays'])

results = (
await this.searchService.search(callConfig, {
...query,
...apiQueryParams,
startDate,
durationDays,
})
Expand All @@ -76,6 +92,7 @@ export default class BedspaceSearchController {
errors,
errorSummary,
durationDays: req.query.durationDays || DEFAULT_DURATION_DAYS,
occupancyAttribute: req.query.occupancyAttribute || 'all',
...startDatePrefill,
...query,
...userInput,
Expand Down
15 changes: 15 additions & 0 deletions server/testutils/factories/bedspaceSearchFormParameters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { fakerEN_GB as faker } from '@faker-js/faker'
import { Factory } from 'fishery'

import { BedspaceSearchFormParameters, OccupancyAttribute } from '../../@types/ui'
import { DateFormats } from '../../utils/dateUtils'
import referenceData from './referenceData'

const occupancyAttributes: Array<OccupancyAttribute> = ['all', 'singleOccupancy', 'sharedProperty']

export default Factory.define<BedspaceSearchFormParameters>(() => ({
startDate: DateFormats.dateObjToIsoDate(faker.date.soon()),
durationDays: faker.number.int({ min: 1, max: 10 }),
probationDeliveryUnits: [referenceData.pdu().build().id, referenceData.pdu().build().id],
occupancyAttribute: faker.helpers.arrayElement(occupancyAttributes),
}))
2 changes: 2 additions & 0 deletions server/testutils/factories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import bedFactory from './bed'
import bedSearchParametersFactory from './bedSearchParameters'
import bedSearchResultFactory from './bedSearchResult'
import bedSearchResultsFactory from './bedSearchResults'
import bedspaceSearchFormParametersFactory from './bedspaceSearchFormParameters'
import bookingFactory from './booking'
import bookingSearchParametersFactory from './bookingSearchParameters'
import bookingSearchResultFactory from './bookingSearchResult'
Expand Down Expand Up @@ -83,6 +84,7 @@ export {
bedSearchParametersFactory,
bedSearchResultFactory,
bedSearchResultsFactory,
bedspaceSearchFormParametersFactory,
bookingFactory,
bookingSearchParametersFactory,
bookingSearchResultBedSummaryFactory,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{% from "govuk/components/fieldset/macro.njk" import govukFieldset %}
{% from "../../../components/formFields/form-page-checkboxes/macro.njk" import formPageCheckboxes %}
{% from "../../../components/formFields/form-page-radios/macro.njk" import formPageRadios %}
{% from "../../../components/formFields/form-page-date-input/macro.njk" import formPageDateInput %}
{% from "../../../components/formFields/form-page-input/macro.njk" import formPageInput %}
{% from "../../../components/formFields/form-page-select/macro.njk" import formPageSelect %}
Expand Down Expand Up @@ -65,23 +66,21 @@
classes: "govuk-fieldset__legend--m"
}
}) %}
{{ formPageCheckboxes({
classes: "govuk-checkboxes--small",
fieldName: "attributes",
fieldset: {
legend: {
text: "Occupancy (optional)",
classes: "govuk-fieldset__legend--s"
}
},
hint: {
text: "Select all that apply"
},
items: [
{ text: "Single", value: "singleOccupancy" },
{ text: "Shared", value: "sharedProperty" }
]
}, fetchContext()) }}
{{ formPageRadios({
classes: "govuk-radios--small",
fieldName: "occupancyAttribute",
fieldset: {
legend: {
text: "Occupancy",
classes: "govuk-fieldset__legend--s"
}
},
items: [
{ text: "All", value: "all" },
{ text: "Single", value: "singleOccupancy" },
{ text: "Shared", value: "sharedProperty" }
]
}, fetchContext()) }}
{% endcall %}
</div>
<div class="govuk-form-group">
Expand Down

0 comments on commit 080ee55

Please sign in to comment.