Skip to content

Commit

Permalink
VB-4898, add alerts to visitor page
Browse files Browse the repository at this point in the history
  • Loading branch information
hutcheonb-moj committed Dec 19, 2024
1 parent a22a42c commit e9eabfe
Show file tree
Hide file tree
Showing 14 changed files with 204 additions and 102 deletions.
29 changes: 29 additions & 0 deletions assets/sass/components/_restrictions.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,32 @@
margin-bottom: govuk-spacing(5);
padding: govuk-spacing(5) govuk-spacing(5) 0;
}

.alert-tag {
align-items: center;
background-color: #fff;
border-radius: 5px;
border: 3px solid;
color: #000;
font-size: 14pt;
line-height: 1;
margin-right: 0;
max-width: unset;
padding: 8px 8px;

&--R {
border-color: govuk-colour("red")
}

&--C {
border-color: govuk-colour("bright-purple");
}

&--S {
border-color: govuk-colour("purple");
}

&--U {
border-color: govuk-colour("light-blue");
}
}
9 changes: 9 additions & 0 deletions assets/sass/local.scss
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,12 @@
[data-module=moj-sortable-table] th {
color: #005ea5;
}

.fix-width-alert-restriction .govuk-table__row {
th:first-child {
width: 20%!important;
}
th:last-child {
width: 20%!important;
}
}
23 changes: 18 additions & 5 deletions integration_tests/e2e/bookAVisit.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,20 @@ context('Book a visit', () => {
const searchForAPrisonerResultsPage = Page.verifyOnPage(SearchForAPrisonerResultsPage)
searchForAPrisonerResultsPage.resultRows().should('have.length', 1)

const profile = TestData.prisonerProfile()
const profile = TestData.prisonerProfile({
alerts: [
{
alertType: 'U',
alertTypeDescription: 'COVID unit management',
alertCode: 'UPIU',
alertCodeDescription: 'Protective Isolation Unit',
comment: 'Alert comment',
dateCreated: '2023-01-02',
dateExpires: undefined,
active: true,
},
],
})

const { prisonerId } = profile
// Prisoner profile page
Expand All @@ -110,10 +123,10 @@ context('Book a visit', () => {
const selectVisitorsPage = Page.verifyOnPage(SelectVisitorsPage)
selectVisitorsPage.getPrisonerRestrictionType(1).contains(offenderRestrictions[0].restrictionTypeDescription)
selectVisitorsPage.getPrisonerRestrictionComment(1).contains(offenderRestrictions[0].comment)
selectVisitorsPage
.getPrisonerRestrictionStartDate(1)
.contains(format(new Date(offenderRestrictions[0].startDate), mediumDateFormat))
selectVisitorsPage.getPrisonerRestrictionEndDate(1).contains('Not entered')
selectVisitorsPage.getPrisonerRestrictionEndDate(1).contains('No end date')
selectVisitorsPage.getPrisonerAlertType(1).contains('COVID unit management')
selectVisitorsPage.getPrisonerAlertComment(1).contains('Alert comment')
selectVisitorsPage.getPrisonerAlertEndDate(1).contains('No end date')
selectVisitorsPage.getVisitorRestrictions(contacts[0].personId).within(() => {
cy.contains(contacts[0].restrictions[0].restrictionTypeDescription)
cy.contains('End date not entered')
Expand Down
7 changes: 7 additions & 0 deletions integration_tests/e2e/prisonerProfile.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ context('Prisoner profile page', () => {

// Active alerts tab
prisonerProfilePage.selectActiveAlertsTab()
prisonerProfilePage
.alertsLink()
.should(
'have.attr',
'href',
'https://prisoner-dev.digital.prison.service.justice.gov.uk/prisoner/A1234BC/alerts/active',
)
prisonerProfilePage.alertsTabType().eq(0).contains('COVID unit management (U)')
prisonerProfilePage.alertsTabCode().eq(0).contains('UPIU')
prisonerProfilePage.alertsTabComment().eq(0).contains('Alert comment')
Expand Down
2 changes: 2 additions & 0 deletions integration_tests/pages/prisonerProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export default class PrisonerProfilePage extends Page {

visitTabPVONextAdjustment = (): PageElement => cy.get('[data-test="tab-pvo-next-date"]')

alertsLink = (): PageElement => cy.get('[data-test="all-alerts-link"]')

alertsTabType = (): PageElement => cy.get('[data-test="tab-alerts-type-desc"]')

alertsTabCode = (): PageElement => cy.get('[data-test="tab-alerts-code-desc"]')
Expand Down
16 changes: 8 additions & 8 deletions integration_tests/pages/selectVisitors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ export default class SelectVisitorsPage extends Page {
super('Select visitors from the prisoner’s approved visitor list')
}

getPrisonerRestrictionType = (index: number): PageElement =>
cy.get(`.prisoner-restrictions .test-restrictions-type${index}`)
getPrisonerRestrictionType = (index: number): PageElement => cy.get(`.test-restrictions-type${index}`)

getPrisonerRestrictionComment = (index: number): PageElement =>
cy.get(`.prisoner-restrictions .test-restrictions-comment${index}`)
getPrisonerRestrictionComment = (index: number): PageElement => cy.get(`.test-restrictions-comment${index}`)

getPrisonerRestrictionStartDate = (index: number): PageElement =>
cy.get(`.prisoner-restrictions .test-restrictions-start-date${index}`)
getPrisonerRestrictionEndDate = (index: number): PageElement => cy.get(`.test-restrictions-end-date${index}`)

getPrisonerRestrictionEndDate = (index: number): PageElement =>
cy.get(`.prisoner-restrictions .test-restrictions-end-date${index}`)
getPrisonerAlertType = (index: number): PageElement => cy.get(`.test-alert-type${index}`)

getPrisonerAlertComment = (index: number): PageElement => cy.get(`.test-alert-comment${index}`)

getPrisonerAlertEndDate = (index: number): PageElement => cy.get(`.test-alert-end-date${index}`)

getVisitor = (visitorId: number): PageElement => cy.get(`#visitor-${visitorId}`)

Expand Down
1 change: 1 addition & 0 deletions server/@types/bapv.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export type VisitSessionData = {
offenderNo: string
dateOfBirth: string
location: string
activeAlerts?: Alert[]
restrictions?: OffenderRestriction[]
}
visitSlot?: VisitSlot
Expand Down
3 changes: 1 addition & 2 deletions server/routes/bookAVisit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type { Services } from '../services'

export default function routes({
auditService,
prisonerProfileService,
prisonerVisitorsService,
visitService,
visitSessionsService,
Expand All @@ -33,7 +32,7 @@ export default function routes({
handlers.map(handler => asyncMiddleware(handler)),
)

const selectVisitors = new SelectVisitors('book', prisonerVisitorsService, prisonerProfileService)
const selectVisitors = new SelectVisitors('book', prisonerVisitorsService)
const visitType = new VisitType('book', auditService)
const additionalSupport = new AdditionalSupport('book')
const dateAndTime = new DateAndTime('book', visitService, visitSessionsService, auditService)
Expand Down
54 changes: 43 additions & 11 deletions server/routes/prisoner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,19 @@ afterEach(() => {
describe('/prisoner/:offenderNo - Prisoner profile', () => {
let prisonerProfile: PrisonerProfilePage

const restriction = TestData.offenderRestriction()
const alert = TestData.alert({
alertType: 'X',
alertTypeDescription: 'Security',
alertCode: 'XR',
alertCodeDescription: 'Racist',
dateCreated: '2022-01-01',
dateExpires: '2022-01-02',
})

beforeEach(() => {
prisonerProfile = {
activeAlerts: [
TestData.alert({
alertType: 'X',
alertTypeDescription: 'Security',
alertCode: 'XR',
alertCodeDescription: 'Racist',
dateCreated: '2022-01-01',
dateExpires: '2022-01-02',
}),
],
activeAlerts: [alert],
activeAlertCount: 1,
flaggedAlerts: [TestData.alert({ alertCode: 'UPIU', alertCodeDescription: 'Protective Isolation Unit' })],
visitsByMonth: new Map(),
Expand Down Expand Up @@ -370,21 +371,26 @@ describe('/prisoner/:offenderNo - Prisoner profile', () => {

describe('POST /prisoner/A1234BC', () => {
it('should set up visitSessionData and redirect to select visitors page', () => {
prisonerProfileService.getRestrictions.mockResolvedValue([restriction])
return request(app)
.post('/prisoner/A1234BC')
.expect(302)
.expect('location', '/book-a-visit/select-visitors')
.expect(res => {
expect(prisonerProfileService.getProfile).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getProfile).toHaveBeenCalledWith(prisonId, 'A1234BC', 'user1')
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledWith('A1234BC', 'user1')
expect(auditService.overrodeZeroVO).not.toHaveBeenCalled()
expect(clearSession).toHaveBeenCalledTimes(1)
expect(visitSessionData).toEqual(<VisitSessionData>{
expect(visitSessionData).toStrictEqual(<VisitSessionData>{
prisoner: {
name: 'Smith, John',
offenderNo: 'A1234BC',
dateOfBirth: '2 April 1975',
location: '1-1-C-028, Hewell (HMP)',
activeAlerts: [alert],
restrictions: [restriction],
},
})
})
Expand All @@ -401,6 +407,8 @@ describe('/prisoner/:offenderNo - Prisoner profile', () => {
.expect(res => {
expect(prisonerProfileService.getProfile).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getProfile).toHaveBeenCalledWith(prisonId, 'A1234BC', 'user1')
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledWith('A1234BC', 'user1')
expect(auditService.overrodeZeroVO).toHaveBeenCalledTimes(1)
expect(auditService.overrodeZeroVO).toHaveBeenCalledWith({
prisonerId: 'A1234BC',
Expand All @@ -414,6 +422,16 @@ describe('/prisoner/:offenderNo - Prisoner profile', () => {
offenderNo: 'A1234BC',
dateOfBirth: '2 April 1975',
location: '1-1-C-028, Hewell (HMP)',
activeAlerts: [
TestData.alert({
alertType: 'X',
alertTypeDescription: 'Security',
alertCode: 'XR',
alertCodeDescription: 'Racist',
dateCreated: '2022-01-01',
dateExpires: '2022-01-02',
}),
],
},
})
})
Expand All @@ -434,13 +452,25 @@ describe('/prisoner/:offenderNo - Prisoner profile', () => {
.expect(res => {
expect(prisonerProfileService.getProfile).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getProfile).toHaveBeenCalledWith(prisonId, 'A1234BC', 'user1')
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledWith('A1234BC', 'user1')
expect(auditService.overrodeZeroVO).not.toHaveBeenCalled()
expect(visitSessionData).toEqual(<VisitSessionData>{
prisoner: {
name: 'Smith, John',
offenderNo: 'A1234BC',
dateOfBirth: '2 April 1975',
location: '1-1-C-028, Hewell (HMP)',
activeAlerts: [
TestData.alert({
alertType: 'X',
alertTypeDescription: 'Security',
alertCode: 'XR',
alertCodeDescription: 'Racist',
dateCreated: '2022-01-01',
dateExpires: '2022-01-02',
}),
],
},
})
})
Expand All @@ -456,6 +486,8 @@ describe('/prisoner/:offenderNo - Prisoner profile', () => {
.expect(res => {
expect(prisonerProfileService.getProfile).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getProfile).toHaveBeenCalledWith(prisonId, 'A1234BC', 'user1')
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledTimes(1)
expect(prisonerProfileService.getRestrictions).toHaveBeenCalledWith('A1234BC', 'user1')
expect(auditService.overrodeZeroVO).not.toHaveBeenCalled()
expect(visitSessionData).toEqual({})
expect(flashProvider).toHaveBeenCalledWith('errors', [
Expand Down
7 changes: 6 additions & 1 deletion server/routes/prisoner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ export default function routes({ auditService, prisonerProfileService }: Service
post('/:offenderNo', async (req, res) => {
const offenderNo = getOffenderNo(req)
const { prisonId } = req.session.selectedEstablishment
const { username } = res.locals.user

const { prisonerDetails } = await prisonerProfileService.getProfile(prisonId, offenderNo, res.locals.user.username)
const { prisonerDetails, activeAlerts } = await prisonerProfileService.getProfile(prisonId, offenderNo, username)

const restrictions = await prisonerProfileService.getRestrictions(offenderNo, username)

if (prisonerDetails.visitBalances?.remainingVo <= 0 && prisonerDetails.visitBalances?.remainingPvo <= 0) {
await body('vo-override').equals('override').withMessage('Select the box to book a prison visit').run(req)
Expand Down Expand Up @@ -73,6 +76,8 @@ export default function routes({ auditService, prisonerProfileService }: Service
offenderNo,
dateOfBirth: prisonerDetails.dateOfBirth,
location: prisonerDetails.cellLocation ? `${prisonerDetails.cellLocation}, ${prisonerDetails.prisonName}` : '',
activeAlerts,
restrictions,
}

req.session.visitSessionData = visitSessionData
Expand Down
3 changes: 1 addition & 2 deletions server/routes/visit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ const NO_UPDATE_NOTIFICATION_TYPES: NotificationType[] = ['PRISONER_RECEIVED_EVE

export default function routes({
auditService,
prisonerProfileService,
prisonerSearchService,
prisonerVisitorsService,
supportedPrisonsService,
Expand Down Expand Up @@ -269,7 +268,7 @@ export default function routes({
},
)

const selectVisitors = new SelectVisitors('update', prisonerVisitorsService, prisonerProfileService)
const selectVisitors = new SelectVisitors('update', prisonerVisitorsService)
const visitType = new VisitType('update', auditService)
const dateAndTime = new DateAndTime('update', visitService, visitSessionsService, auditService)
const additionalSupport = new AdditionalSupport('update')
Expand Down
Loading

0 comments on commit e9eabfe

Please sign in to comment.