Skip to content

Commit

Permalink
Navigate to placeholder occupancy view
Browse files Browse the repository at this point in the history
  • Loading branch information
gregkhawkins committed Nov 22, 2024
1 parent 027a975 commit 6f32035
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 31 deletions.
11 changes: 11 additions & 0 deletions e2e/pages/match/occupancyViewScreen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Page, expect } from '@playwright/test'
import { BasePage } from '../basePage'
import { Premises } from '../../../server/@types/shared'

export class OccupancyViewScreen extends BasePage {
static async initialize(page: Page, premisesName: Premises['name']) {
await expect(page.locator('h1')).toContainText(`View spaces in ${premisesName}`)

return new OccupancyViewScreen(page)
}
}
28 changes: 4 additions & 24 deletions e2e/steps/match.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
import { Page } from '@playwright/test'
import { visitDashboard } from './apply'
import { ConfirmPage, ConfirmationPage } from '../pages/match'
import { E2EDatesOfPlacement } from './assess'
import { ListPage, PlacementRequestPage } from '../pages/workflow'
import { ApprovedPremisesApplication as Application, Premises } from '../../server/@types/shared'
import { ApTypeLabel } from '../../server/utils/apTypeLabels'
import { SearchScreen } from '../pages/match/searchScreen'
import { BookingScreen } from '../pages/match/bookingScreen'

export const confirmBooking = async (page: Page) => {
const confirmPage = new ConfirmPage(page)
await confirmPage.clickConfirm()
}

export const shouldShowBookingConfirmation = async (page: Page) => {
const confirmationPage = new ConfirmationPage(page)
await confirmationPage.shouldShowSuccessMessage()
}
import { OccupancyViewScreen } from '../pages/match/occupancyViewScreen'

export const matchAndBookApplication = async ({
applicationId,
Expand All @@ -41,7 +30,7 @@ export const matchAndBookApplication = async ({
// And I click the link to the CRU Dashboard
await dashboard.clickCruDashboard()

let cruDashboard = new ListPage(page)
const cruDashboard = new ListPage(page)

// And I select the placement request
cruDashboard.choosePlacementApplicationWithId(applicationId)
Expand Down Expand Up @@ -79,15 +68,6 @@ export const matchAndBookApplication = async ({
const premisesName = await searchScreen.retrieveFirstAPName()
await searchScreen.selectFirstAP()

// Then I should see the booking screen for that AP
const bookingScreen = await BookingScreen.initialize(page, premisesName)

// Should show the booking details
await bookingScreen.shouldShowDatesOfPlacement(datesOfPlacement)

// And I confirm the booking
await bookingScreen.clickConfirm()

// Then I should see the CRU dashboard matched tab
cruDashboard = new ListPage(page)
// Then I should see the occupancy view screen for that AP
await OccupancyViewScreen.initialize(page, premisesName)
}
3 changes: 3 additions & 0 deletions server/controllers/match/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import PlacementRequestController from './placementRequestsController'
import SpaceSearchController from './search/spaceSearchController'
import BookingsController from './placementRequests/bookingsController'
import OccupancyViewController from './placementRequests/occupancyViewController'
import SpaceBookingsController from './placementRequests/spaceBookingsController'

import type { Services } from '../../services'
Expand All @@ -18,11 +19,13 @@ export const controllers = (services: Services) => {
const spaceSearchController = new SpaceSearchController(spaceService, placementRequestService)
const placementRequestBookingsController = new BookingsController(placementRequestService)
const spaceBookingsController = new SpaceBookingsController(placementRequestService, spaceService)
const occupancyViewController = new OccupancyViewController(placementRequestService)

return {
placementRequestController,
spaceSearchController,
placementRequestBookingsController,
spaceBookingsController,
occupancyViewController,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { NextFunction, Request, Response } from 'express'
import { DeepMocked, createMock } from '@golevelup/ts-jest'

import { PlacementRequestService } from '../../../services'
import { personFactory, placementRequestDetailFactory } from '../../../testutils/factories'
import OccupancyViewController from './occupancyViewController'

describe('OccupancyViewController', () => {
const token = 'SOME_TOKEN'

const request: DeepMocked<Request> = createMock<Request>({ user: { token } })
const response: DeepMocked<Response> = createMock<Response>({})
const next: DeepMocked<NextFunction> = createMock<NextFunction>({})

const placementRequestService = createMock<PlacementRequestService>({})

let occupancyViewController: OccupancyViewController

beforeEach(() => {
jest.resetAllMocks()
occupancyViewController = new OccupancyViewController(placementRequestService)
})

describe('view', () => {
it('should render the occupancy view template', async () => {
const person = personFactory.build({ name: 'John Wayne' })
const placementRequestDetail = placementRequestDetailFactory.build({ person })
const premisesName = 'Hope House'
const premisesId = 'abc123'

placementRequestService.getPlacementRequest.mockResolvedValue(placementRequestDetail)

const query = {
premisesName,
premisesId,
}

const params = { id: placementRequestDetail.id }

const requestHandler = occupancyViewController.view()

await requestHandler({ ...request, params, query }, response, next)

expect(response.render).toHaveBeenCalledWith('match/placementRequests/occupancyView/view', {
pageHeading: `View spaces in ${premisesName}`,
placementRequest: placementRequestDetail,
})
expect(placementRequestService.getPlacementRequest).toHaveBeenCalledWith(token, placementRequestDetail.id)
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Request, Response, TypedRequestHandler } from 'express'
import { ApType } from '@approved-premises/api'
import { PlacementRequestService } from '../../../services'

interface NewRequest extends Request {
params: { id: string }
query: { startDate: string; durationDays: string; premisesName: string; premisesId: string; apType: ApType }
}

export default class {
constructor(private readonly placementRequestService: PlacementRequestService) {}

view(): TypedRequestHandler<Request, Response> {
return async (req: NewRequest, res: Response) => {
const placementRequest = await this.placementRequestService.getPlacementRequest(req.user.token, req.params.id)
const { premisesName } = req.query

res.render('match/placementRequests/occupancyView/view', {
pageHeading: `View spaces in ${premisesName}`,
placementRequest,
})
}
}
}
1 change: 1 addition & 0 deletions server/paths/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const v2Match = {
},
spaceBookings: {
new: v2SpaceBookingsPath.path('new'),
viewSpaces: v2SpaceBookingsPath.path('view-spaces'),
create: v2SpaceBookingsPath,
},
},
Expand Down
5 changes: 5 additions & 0 deletions server/routes/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function routes(controllers: Controllers, router: Router, service
spaceSearchController,
placementRequestBookingsController,
spaceBookingsController,
occupancyViewController,
} = controllers

get(paths.placementRequests.show.pattern, placementRequestController.show(), { auditEvent: 'SHOW_PLACEMENT_REQUEST' })
Expand Down Expand Up @@ -46,6 +47,10 @@ export default function routes(controllers: Controllers, router: Router, service
auditEvent: 'NEW_SPACE_BOOKING',
})

get(paths.v2Match.placementRequests.spaceBookings.viewSpaces.pattern, occupancyViewController.view(), {
auditEvent: 'OCCUPANCY_VIEW',
})

post(paths.v2Match.placementRequests.spaceBookings.create.pattern, spaceBookingsController.create(), {
auditEvent: 'CREATE_SPACE_BOOKING',
})
Expand Down
8 changes: 1 addition & 7 deletions server/utils/match/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ export const summaryCardLink = ({
placementRequestId,
premisesName,
premisesId,
apType,
startDate,
durationDays,
}: {
placementRequestId: string
premisesName: string
Expand All @@ -85,13 +82,10 @@ export const summaryCardLink = ({
startDate: string
durationDays: string
}): string => {
return `${matchPaths.v2Match.placementRequests.spaceBookings.new({ id: placementRequestId })}${createQueryString(
return `${matchPaths.v2Match.placementRequests.spaceBookings.viewSpaces({ id: placementRequestId })}${createQueryString(
{
premisesName,
premisesId,
apType,
startDate,
durationDays,
},
{ addQueryPrefix: true },
)}`
Expand Down
24 changes: 24 additions & 0 deletions server/views/match/placementRequests/occupancyView/view.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{% from "govuk/components/summary-list/macro.njk" import govukSummaryList %}
{% from "govuk/components/button/macro.njk" import govukButton %}
{% from "govuk/components/back-link/macro.njk" import govukBackLink %}

{% extends "../../layout-with-details.njk" %}

{% set pageTitle = applicationName + " - " + pageHeading %}

{% block beforeContent %}
{{ govukBackLink({
text: "Back to other APs",
href: paths.v2Match.placementRequests.search.spaces({ id: placementRequest.id })
}) }}
{% endblock %}

{% block content %}
<div class="govuk-width-container">
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-l">{{ pageHeading }}</h1>
</div>
</div>
</div>
{% endblock %}

0 comments on commit 6f32035

Please sign in to comment.