Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VB-3815 Show interruption card if visit will be CLOSED #156

Merged
merged 9 commits into from
Sep 9, 2024
1 change: 1 addition & 0 deletions assets/scss/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ $path: "/assets/images/";
// GOV.UK One Login components
@import './components/service-header-no-imports';

@import './components/interruptionCard.scss';
@import './components/visitsCalendar.scss';
@import './local';
8 changes: 8 additions & 0 deletions assets/scss/components/interruptionCard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.interruption-card {
background-color: govuk-colour('blue');
padding: govuk-spacing(8) govuk-spacing(5);
}

.interruption-card__heading, .interruption-card__text {
color: govuk-colour('white');
}
48 changes: 47 additions & 1 deletion integration_tests/e2e/bookingJourney.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SelectVisitorsPage from '../pages/bookVisit/selectVisitors'
import MainContactPage from '../pages/bookVisit/mainContact'
import CheckVisitDetailsPage from '../pages/bookVisit/checkVisitDetails'
import VisitBookedPage from '../pages/bookVisit/visitBooked'
import ClosedVisitPage from '../pages/bookVisit/closedVisit'

context('Booking journey', () => {
const today = new Date()
Expand Down Expand Up @@ -82,7 +83,7 @@ context('Booking journey', () => {
cy.task('stubHmppsAuthToken')
})

it('should complete the booking journey', () => {
it('should complete the booking journey (OPEN visit)', () => {
cy.task('stubGetBookerReference')
cy.task('stubGetPrisoners', { prisoners: [prisoner] })
cy.signIn()
Expand Down Expand Up @@ -111,6 +112,10 @@ context('Booking journey', () => {
selectVisitorsPage.getVisitorLabel(3).contains('Child Two (5 years old)')
selectVisitorsPage.selectVisitor(1)
selectVisitorsPage.selectVisitor(3)
cy.task('stubGetSessionRestriction', {
prisonerId: prisoner.prisoner.prisonerNumber,
visitorIds: [1000, 3000],
})

// Choose visit time
cy.task('stubGetVisitSessions', {
Expand Down Expand Up @@ -173,4 +178,45 @@ context('Booking journey', () => {
'A text message confirming the visit will be sent to the main contact. This will include the booking reference.',
)
})

it('should show closed visit interruption card (CLOSED visit)', () => {
cy.task('stubGetBookerReference')
cy.task('stubGetPrisoners', { prisoners: [prisoner] })
cy.signIn()

const bookerReference = TestData.bookerReference().value

// Home page - prisoner shown
const homePage = Page.verifyOnPage(HomePage)
homePage.prisonerName().contains('John Smith')

// Start booking journey
cy.task('stubGetPrison', prison)
cy.task('stubGetVisitors', { visitors })
homePage.startBooking()

// Select visitors page - choose visitors
const selectVisitorsPage = Page.verifyOnPage(SelectVisitorsPage)
selectVisitorsPage.selectVisitor(1)
cy.task('stubGetSessionRestriction', {
prisonerId: prisoner.prisoner.prisonerNumber,
visitorIds: [1000],
sessionRestriction: 'CLOSED',
})
selectVisitorsPage.continue()

// Closed visit interruption card page
const closedVisitPage = Page.verifyOnPage(ClosedVisitPage)

// Choose visit time
cy.task('stubGetVisitSessions', {
prisonId: prisoner.prisoner.prisonId,
prisonerId: prisoner.prisoner.prisonerNumber,
visitorIds: [1000],
bookerReference,
visitSessions,
})
closedVisitPage.continue()
Page.verifyOnPage(ChooseVisitTimePage)
})
})
8 changes: 8 additions & 0 deletions integration_tests/e2e/bookingJourneyDropOuts.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ context('Booking journey - drop-out points', () => {
// Select visitors page - choose visitors
const selectVisitorsPage = Page.verifyOnPage(SelectVisitorsPage)
selectVisitorsPage.selectVisitor(1)
cy.task('stubGetSessionRestriction', {
prisonerId: prisoner.prisoner.prisonerNumber,
visitorIds: [1000],
})

// Choose visit time
cy.task('stubGetVisitSessions', {
Expand Down Expand Up @@ -88,6 +92,10 @@ context('Booking journey - drop-out points', () => {
// Select visitors page - choose visitors
const selectVisitorsPage = Page.verifyOnPage(SelectVisitorsPage)
selectVisitorsPage.selectVisitor(1)
cy.task('stubGetSessionRestriction', {
prisonerId: prisoner.prisoner.prisonerNumber,
visitorIds: [1000],
})

// Choose visit time
cy.task('stubGetVisitSessions', {
Expand Down
28 changes: 27 additions & 1 deletion integration_tests/mockApis/orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
VisitDto,
VisitorInfoDto,
} from '../../server/data/orchestrationApiTypes'
import { SessionRestriction } from '../../server/data/orchestrationApiClient'

export default {
// orchestration-visits-controller
Expand Down Expand Up @@ -245,7 +246,7 @@ export default {
stubFor({
request: {
method: 'GET',
urlPath: `/orchestration/visit-sessions/available`,
urlPath: '/orchestration/visit-sessions/available',
queryParameters: {
prisonId: { equalTo: prisonId },
prisonerId: { equalTo: prisonerId },
Expand All @@ -270,6 +271,31 @@ export default {
},
}),

stubGetSessionRestriction: ({
prisonerId,
visitorIds,
sessionRestriction = 'OPEN',
}: {
prisonerId: string
visitorIds: number[]
sessionRestriction: SessionRestriction
}): SuperAgentRequest =>
stubFor({
request: {
method: 'GET',
urlPath: '/orchestration/visit-sessions/available/restriction',
queryParameters: {
prisonerId: { equalTo: prisonerId },
visitors: { equalTo: visitorIds.join(',') },
},
},
response: {
status: 200,
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
jsonBody: { sessionRestriction },
},
}),

// orchestration-prisons-config-controller

stubGetPrison: (prisonDto: PrisonDto = TestData.prisonDto()): SuperAgentRequest =>
Expand Down
11 changes: 11 additions & 0 deletions integration_tests/pages/bookVisit/closedVisit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Page from '../page'

export default class ClosedVisitPage extends Page {
constructor() {
super('This will be a closed visit')
}

continue = (): void => {
cy.get('[data-test=closed-visit-continue]').click()
}
}
4 changes: 4 additions & 0 deletions server/@types/bapv.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SessionRestriction } from '../data/orchestrationApiClient'
import { AvailableVisitSessionDto, PrisonDto } from '../data/orchestrationApiTypes'
import { Prisoner, Visitor } from '../services/bookerService'

Expand All @@ -20,6 +21,9 @@ export type BookingJourney = {
// selected visitors for this visit
selectedVisitors?: Visitor[]

// session restriction (OPEN/CLOSED) for this visit
sessionRestriction?: SessionRestriction

// all available visit sessions
allVisitSessionIds?: string[] // e.g. ['2024-05-28_session-ref']
allVisitSessions?: AvailableVisitSessionDto[]
Expand Down
110 changes: 100 additions & 10 deletions server/@types/orchestration-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,26 @@ export interface paths {
patch?: never
trace?: never
}
'/visit-sessions/available/restriction': {
parameters: {
query?: never
header?: never
path?: never
cookie?: never
}
/**
* Returns the restriction type of available sessions
* @description Returns the restriction of available sessions given a prisoner and optionally a list of visitors [OPEN / CLOSED]
*/
get: operations['getSessionRestrictionType']
put?: never
post?: never
delete?: never
options?: never
head?: never
patch?: never
trace?: never
}
'/queue-admin/get-dlq-messages/{dlqName}': {
parameters: {
query?: never
Expand Down Expand Up @@ -1061,9 +1081,13 @@ export interface components {
| 'CANCELLED_VISIT'
| 'NON_ASSOCIATION_EVENT'
| 'PRISONER_RELEASED_EVENT'
| 'PRISONER_RECEIVED_EVENT'
| 'PRISONER_RESTRICTION_CHANGE_EVENT'
| 'PRISONER_ALERTS_UPDATED_EVENT'
| 'PRISON_VISITS_BLOCKED_FOR_DATE'
| 'IGNORE_VISIT_NOTIFICATIONS_EVENT'
| 'PERSON_RESTRICTION_UPSERTED_EVENT'
| 'VISITOR_RESTRICTION_UPSERTED_EVENT'
/**
* @description What was the application method for this event
* @enum {string}
Expand Down Expand Up @@ -1150,14 +1174,14 @@ export interface components {
totalPages?: number
/** Format: int64 */
totalElements?: number
first?: boolean
last?: boolean
/** Format: int32 */
size?: number
content?: components['schemas']['VisitDto'][]
/** Format: int32 */
number?: number
sort?: components['schemas']['SortObject'][]
first?: boolean
last?: boolean
/** Format: int32 */
numberOfElements?: number
pageable?: components['schemas']['PageableObject']
Expand Down Expand Up @@ -1197,6 +1221,10 @@ export interface components {
| 'PRISONER_RELEASED_EVENT'
| 'PRISONER_RESTRICTION_CHANGE_EVENT'
| 'PRISON_VISITS_BLOCKED_FOR_DATE'
| 'PRISONER_RECEIVED_EVENT'
| 'PRISONER_ALERTS_UPDATED_EVENT'
| 'PERSON_RESTRICTION_UPSERTED_EVENT'
| 'VISITOR_RESTRICTION_UPSERTED_EVENT'
/** @description List of details of affected visits */
affectedVisits: components['schemas']['OrchestrationPrisonerVisitsNotificationDto'][]
}
Expand Down Expand Up @@ -1384,9 +1412,18 @@ export interface components {
*/
sessionRestriction: 'OPEN' | 'CLOSED'
}
/** @description Visit Session restriction type */
AvailableVisitSessionRestrictionDto: {
/**
* @description Session Restriction
* @example OPEN
* @enum {string}
*/
sessionRestriction: 'OPEN' | 'CLOSED'
}
DlqMessage: {
body: {
[key: string]: Record<string, never> | undefined
[key: string]: Record<string, never>
}
messageId: string
}
Expand Down Expand Up @@ -1588,7 +1625,7 @@ export interface components {
*/
dateOfBirth?: string
}
/** @description Alert */
/** @description AlertDto returned from orchestration, made of fields from AlertResponseDto from Alerts API call */
AlertDto: {
/**
* @description Alert Type
Expand Down Expand Up @@ -1627,11 +1664,6 @@ export interface components {
* @example 2020-08-20
*/
dateExpires?: string
/**
* @description True / False based on presence of expiry date
* @example true
*/
expired: boolean
/**
* @description True / False based on alert status
* @example false
Expand Down Expand Up @@ -2796,6 +2828,10 @@ export interface operations {
| 'PRISONER_RELEASED_EVENT'
| 'PRISONER_RESTRICTION_CHANGE_EVENT'
| 'PRISON_VISITS_BLOCKED_FOR_DATE'
| 'PRISONER_RECEIVED_EVENT'
| 'PRISONER_ALERTS_UPDATED_EVENT'
| 'PERSON_RESTRICTION_UPSERTED_EVENT'
| 'VISITOR_RESTRICTION_UPSERTED_EVENT'
)[]
}
}
Expand Down Expand Up @@ -2880,6 +2916,11 @@ export interface operations {
* @example 28
*/
max?: number
/**
* @description Username for the user making the request. Used to exclude user's pending applications from session capacity count. Optional, ignored if not passed in.
* @example user-1
*/
username?: string
}
header?: never
path?: never
Expand Down Expand Up @@ -3066,7 +3107,7 @@ export interface operations {
/** @description Advances the available visits slots sought from date by n days. Defaults to 0 if not passed. */
advanceFromDateByDays?: number
/**
* @description Username for the user making the request. Optional, ignored if not passed in.
* @description Username for the user making the request. Used to exclude user's pending applications from session capacity count. Optional, ignored if not passed in.
* @example user-1
*/
username?: string
Expand Down Expand Up @@ -3106,6 +3147,55 @@ export interface operations {
}
}
}
getSessionRestrictionType: {
parameters: {
query: {
/**
* @description Filter results by prisoner id
* @example A12345DC
*/
prisonerId: string
/**
* @description List of visitors who require visit sessions
* @example 4729510,4729220
*/
visitors?: number[]
}
header?: never
path?: never
cookie?: never
}
requestBody?: never
responses: {
/** @description Available visit session restriction returned */
200: {
headers: {
[name: string]: unknown
}
content: {
'*/*': components['schemas']['AvailableVisitSessionRestrictionDto']
}
}
/** @description Incorrect request to Get available visit session restriction */
400: {
headers: {
[name: string]: unknown
}
content: {
'application/json': components['schemas']['ErrorResponse']
}
}
/** @description Unauthorized to access this endpoint */
401: {
headers: {
[name: string]: unknown
}
content: {
'application/json': components['schemas']['ErrorResponse']
}
}
}
}
getDlqMessages: {
parameters: {
query?: {
Expand Down
Loading