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

CDPS-778 update establishement roll page to use new endpoint #147

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 101 additions & 107 deletions integration_tests/e2e/establishmentRoll.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@ context('Establishment Roll Page', () => {
{ caseloadFunction: '', caseLoadId: 'LEI', currentlyActive: true, description: 'Leeds (HMP)', type: '' },
],
})
cy.task('stubRollCount', { payload: assignedRollCountWithSpursMock, query: '?wingOnly=false' })
cy.task('stubRollCountUnassigned')
cy.task('stubMovements')
cy.task('stubEnrouteRollCount')
cy.task('stubGetLocationsForPrison')
cy.task('getAttributesForLocation')
cy.task('stubPrisonRollCount')
cy.signIn({ redirectPath: '/establishment-roll' })
cy.visit('/establishment-roll')
})
Expand All @@ -28,130 +23,129 @@ context('Establishment Roll Page', () => {
Page.verifyOnPage(EstablishmentRollPage)
})

context('Outage Banner', () => {
it('should display todays stats', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)
page.todaysStats().unlockRoll().should('contain.text', '1815')
page.todaysStats().currentPopulation().should('contain.text', '1823')
page.todaysStats().arrivedToday().should('contain.text', '17')
page.todaysStats().inReception().should('contain.text', '23')
page.todaysStats().stillToArrive().should('contain.text', '1')
page.todaysStats().outToday().should('contain.text', '9')
page.todaysStats().noCellAllocated().should('contain.text', '31')
})
it('should display todays stats', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)
page.todaysStats().unlockRoll().should('contain.text', '100')
page.todaysStats().currentPopulation().should('contain.text', '200')
page.todaysStats().arrivedToday().should('contain.text', '300')
page.todaysStats().inReception().should('contain.text', '400')
page.todaysStats().stillToArrive().should('contain.text', '500')
page.todaysStats().outToday().should('contain.text', '600')
page.todaysStats().noCellAllocated().should('contain.text', '700')
})

it('should display a table row for each wing level assignedRollCount', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)
page.assignedRollCountRows().should('have.length', 6)

page.assignedRollCountRows().first().find('td').eq(0).should('contain.text', 'A')
page.assignedRollCountRows().first().find('td').eq(1).should('contain.text', '76')
page.assignedRollCountRows().first().find('td').eq(2).should('contain.text', '900')
page.assignedRollCountRows().first().find('td').eq(3).should('contain.text', '5')
page.assignedRollCountRows().first().find('td').eq(4).should('contain.text', '60')
page.assignedRollCountRows().first().find('td').eq(5).should('contain.text', '-16')
page.assignedRollCountRows().first().find('td').eq(6).should('contain.text', '0')
})
it('should display a table row for each wing level assignedRollCount', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)
page.assignedRollCountRows().should('have.length', 7)

page.assignedRollCountRows().first().find('td').eq(0).should('contain.text', 'B Wing')
page.assignedRollCountRows().first().find('td').eq(1).should('contain.text', '194')
page.assignedRollCountRows().first().find('td').eq(2).should('contain.text', '192')
page.assignedRollCountRows().first().find('td').eq(3).should('contain.text', '1')
page.assignedRollCountRows().first().find('td').eq(4).should('contain.text', '470')
page.assignedRollCountRows().first().find('td').eq(5).should('contain.text', '276')
page.assignedRollCountRows().first().find('td').eq(6).should('contain.text', '0')
})

it('should display a table row for totals', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)
it('should display a table row for totals', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)

page.assignedRollCountRows().last().find('td').eq(0).should('contain.text', 'Totals')
page.assignedRollCountRows().last().find('td').eq(1).should('contain.text', '152')
page.assignedRollCountRows().last().find('td').eq(2).should('contain.text', '1800')
page.assignedRollCountRows().last().find('td').eq(3).should('contain.text', '10')
page.assignedRollCountRows().last().find('td').eq(4).should('contain.text', '120')
page.assignedRollCountRows().last().find('td').eq(5).should('contain.text', '-32')
page.assignedRollCountRows().last().find('td').eq(6).should('contain.text', '0')
})
page.assignedRollCountRows().last().find('td').eq(0).should('contain.text', 'Totals')
page.assignedRollCountRows().last().find('td').eq(1).should('contain.text', '10')
page.assignedRollCountRows().last().find('td').eq(2).should('contain.text', '20')
page.assignedRollCountRows().last().find('td').eq(3).should('contain.text', '30')
page.assignedRollCountRows().last().find('td').eq(4).should('contain.text', '40')
page.assignedRollCountRows().last().find('td').eq(5).should('contain.text', '50')
page.assignedRollCountRows().last().find('td').eq(6).should('contain.text', '60')
})

it('should reveal spurs and landings when click on link', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)
it('should reveal spurs and landings when click on link', () => {
const page = Page.verifyOnPage(EstablishmentRollPage)

page.assignedRollCountRows().eq(0).find('td').eq(0).should('contain.text', 'A').should('be.visible')
page.assignedRollCountRows().eq(1).find('td').eq(0).should('contain.text', 'Spur A1').should('not.be.visible')
page.assignedRollCountRows().eq(2).find('td').eq(0).should('contain.text', 'Landing A1X').should('not.be.visible')
page.assignedRollCountRows().eq(3).find('td').eq(0).should('contain.text', 'B').should('be.visible')
page.assignedRollCountRows().eq(4).find('td').eq(0).should('contain.text', 'LANDING BY').should('not.be.visible')
page.assignedRollCountRows().eq(0).find('td').eq(0).should('contain.text', 'B Wing').should('be.visible')
page.assignedRollCountRows().eq(1).find('td').eq(0).should('contain.text', '1').should('not.be.visible')
page.assignedRollCountRows().eq(2).find('td').eq(0).should('contain.text', '2').should('not.be.visible')
page.assignedRollCountRows().eq(3).find('td').eq(0).should('contain.text', 'C Wing').should('be.visible')
page.assignedRollCountRows().eq(4).find('td').eq(0).should('contain.text', 'C-1').should('not.be.visible')
page.assignedRollCountRows().eq(5).find('td').eq(0).should('contain.text', 'C-1-1').should('not.be.visible')

const wing1Reveal = page.assignedRollCountRows().eq(0).find('td').eq(0).find('a')
wing1Reveal.click()
page.assignedRollCountRows().eq(1).find('td').eq(0).should('be.visible')
page.assignedRollCountRows().eq(2).find('td').eq(0).should('be.visible')
const wing1Reveal = page.assignedRollCountRows().eq(0).find('td').eq(0).find('a')
wing1Reveal.click()
page.assignedRollCountRows().eq(1).find('td').eq(0).should('be.visible')
page.assignedRollCountRows().eq(2).find('td').eq(0).should('be.visible')

wing1Reveal.click()
page.assignedRollCountRows().eq(1).find('td').eq(0).should('not.be.visible')
page.assignedRollCountRows().eq(2).find('td').eq(0).should('not.be.visible')
wing1Reveal.click()
page.assignedRollCountRows().eq(1).find('td').eq(0).should('not.be.visible')
page.assignedRollCountRows().eq(2).find('td').eq(0).should('not.be.visible')

const wing2Reveal = page.assignedRollCountRows().eq(3).find('td').eq(0).find('a')
wing2Reveal.click()
page.assignedRollCountRows().eq(4).find('td').eq(0).should('be.visible')
const wing2Reveal = page.assignedRollCountRows().eq(3).find('td').eq(0).find('a')
wing2Reveal.click()
page.assignedRollCountRows().eq(4).find('td').eq(0).should('be.visible')

wing2Reveal.click()
page.assignedRollCountRows().eq(4).find('td').eq(0).should('not.be.visible')
wing2Reveal.click()
page.assignedRollCountRows().eq(4).find('td').eq(0).should('not.be.visible')
})

it('should show link to landing pages when wing has spur', () => {
cy.task('stubGetLocation', { locationId: 20000, payload: { ...locationMock, description: 'WING 1' } })
cy.task('stubGetLocation', { locationId: 100, payload: { ...locationMock, description: 'Spur 1' } })
cy.task('stubGetLocation', { locationId: 12729, payload: { ...locationMock, description: 'Landing 1' } })
cy.task('stubRollCount', {
payload: assignedRollCountWithSpursMock,
query: '?wingOnly=false&showCells=true&parentLocationId=12729',
})

it('should show link to landing pages when wing has spur', () => {
cy.task('stubGetLocation', { locationId: 1, payload: { ...locationMock, description: 'WING 1' } })
cy.task('stubGetLocation', { locationId: 2, payload: { ...locationMock, description: 'Spur 1' } })
cy.task('stubGetLocation', { locationId: 3, payload: { ...locationMock, description: 'Landing 1' } })
cy.task('stubRollCount', {
payload: assignedRollCountWithSpursMock,
query: '?wingOnly=false&showCells=true&parentLocationId=3',
})
const page = Page.verifyOnPage(EstablishmentRollPage)

const page = Page.verifyOnPage(EstablishmentRollPage)
const wing2Reveal = page.assignedRollCountRows().eq(3).find('td').eq(0).find('a')
wing2Reveal.click()
page.assignedRollCountRows().eq(5).find('td').eq(0).find('a').click()

const wing1Reveal = page.assignedRollCountRows().eq(0).find('td').eq(0).find('a')
wing1Reveal.click()
page.assignedRollCountRows().eq(2).find('td').eq(0).find('a').click()
const landingPage = Page.verifyOnPageWithTitle(LandingRollPage, 'WING 1 - Spur 1 - Landing 1')

const landingPage = Page.verifyOnPageWithTitle(LandingRollPage, 'WING 1 - Spur 1 - Landing 1')
landingPage.rollCountRows().should('have.length', 5)

landingPage.rollCountRows().should('have.length', 5)
landingPage.rollCountRows().eq(0).find('td').eq(0).should('contain.text', 'A')
landingPage.rollCountRows().eq(1).find('td').eq(0).should('contain.text', 'Spur A1')
landingPage.rollCountRows().eq(2).find('td').eq(0).should('contain.text', 'Landing A1X')
landingPage.rollCountRows().eq(3).find('td').eq(0).should('contain.text', 'B')
landingPage.rollCountRows().eq(4).find('td').eq(0).should('contain.text', 'LANDING BY')

landingPage.rollCountRows().eq(0).find('td').eq(0).should('contain.text', 'A')
landingPage.rollCountRows().eq(1).find('td').eq(0).should('contain.text', 'Spur A1')
landingPage.rollCountRows().eq(2).find('td').eq(0).should('contain.text', 'Landing A1X')
landingPage.rollCountRows().eq(3).find('td').eq(0).should('contain.text', 'B')
landingPage.rollCountRows().eq(4).find('td').eq(0).should('contain.text', 'LANDING BY')
landingPage.rollCountRows().first().find('td').eq(1).should('contain.text', '76')
landingPage.rollCountRows().first().find('td').eq(2).should('contain.text', '900')
landingPage.rollCountRows().first().find('td').eq(3).should('contain.text', '5')
landingPage.rollCountRows().first().find('td').eq(4).should('contain.text', '60')
landingPage.rollCountRows().first().find('td').eq(5).should('contain.text', '-16')
})

landingPage.rollCountRows().first().find('td').eq(1).should('contain.text', '76')
landingPage.rollCountRows().first().find('td').eq(2).should('contain.text', '900')
landingPage.rollCountRows().first().find('td').eq(3).should('contain.text', '5')
landingPage.rollCountRows().first().find('td').eq(4).should('contain.text', '60')
landingPage.rollCountRows().first().find('td').eq(5).should('contain.text', '-16')
it('should show link to landing pages when wing does not have spur', () => {
cy.task('stubGetLocation', { locationId: 10000, payload: { ...locationMock, description: 'WING 1' } })
cy.task('stubGetLocation', { locationId: 12714, payload: { ...locationMock, description: 'Landing 1' } })
cy.task('stubRollCount', {
payload: assignedRollCountWithSpursMock,
query: '?wingOnly=false&showCells=true&parentLocationId=12714',
})

it('should show link to landing pages when wing does not have spur', () => {
cy.task('stubGetLocation', { locationId: 4, payload: { ...locationMock, description: 'WING 1' } })
cy.task('stubGetLocation', { locationId: 5, payload: { ...locationMock, description: 'Landing 1' } })
cy.task('stubRollCount', {
payload: assignedRollCountWithSpursMock,
query: '?wingOnly=false&showCells=true&parentLocationId=5',
})
const page = Page.verifyOnPage(EstablishmentRollPage)

const page = Page.verifyOnPage(EstablishmentRollPage)
const wing2Reveal = page.assignedRollCountRows().eq(0).find('td').eq(0).find('a')
wing2Reveal.click()
page.assignedRollCountRows().eq(1).find('td').eq(0).find('a').click()

const wing2Reveal = page.assignedRollCountRows().eq(3).find('td').eq(0).find('a')
wing2Reveal.click()
page.assignedRollCountRows().eq(4).find('td').eq(0).find('a').click()
const landingPage = Page.verifyOnPageWithTitle(LandingRollPage, 'WING 1 - Landing 1')

const landingPage = Page.verifyOnPageWithTitle(LandingRollPage, 'WING 1 - Landing 1')
landingPage.rollCountRows().should('have.length', 5)

landingPage.rollCountRows().should('have.length', 5)
landingPage.rollCountRows().eq(0).find('td').eq(0).should('contain.text', 'A')
landingPage.rollCountRows().eq(1).find('td').eq(0).should('contain.text', 'Spur A1')
landingPage.rollCountRows().eq(2).find('td').eq(0).should('contain.text', 'Landing A1X')
landingPage.rollCountRows().eq(3).find('td').eq(0).should('contain.text', 'B')
landingPage.rollCountRows().eq(4).find('td').eq(0).should('contain.text', 'LANDING BY')

landingPage.rollCountRows().eq(0).find('td').eq(0).should('contain.text', 'A')
landingPage.rollCountRows().eq(1).find('td').eq(0).should('contain.text', 'Spur A1')
landingPage.rollCountRows().eq(2).find('td').eq(0).should('contain.text', 'Landing A1X')
landingPage.rollCountRows().eq(3).find('td').eq(0).should('contain.text', 'B')
landingPage.rollCountRows().eq(4).find('td').eq(0).should('contain.text', 'LANDING BY')

landingPage.rollCountRows().first().find('td').eq(1).should('contain.text', '76')
landingPage.rollCountRows().first().find('td').eq(2).should('contain.text', '900')
landingPage.rollCountRows().first().find('td').eq(3).should('contain.text', '5')
landingPage.rollCountRows().first().find('td').eq(4).should('contain.text', '60')
landingPage.rollCountRows().first().find('td').eq(5).should('contain.text', '-16')
})
landingPage.rollCountRows().first().find('td').eq(1).should('contain.text', '76')
landingPage.rollCountRows().first().find('td').eq(2).should('contain.text', '900')
landingPage.rollCountRows().first().find('td').eq(3).should('contain.text', '5')
landingPage.rollCountRows().first().find('td').eq(4).should('contain.text', '60')
landingPage.rollCountRows().first().find('td').eq(5).should('contain.text', '-16')
})
})
17 changes: 17 additions & 0 deletions integration_tests/mockApis/prison.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { movementsRecentMock } from '../../server/test/mocks/movementsRecentMock
import { offenderCellHistoryMock } from '../../server/test/mocks/offenderCellHistoryMock'
import { userDetailsMock } from '../../server/test/mocks/userDetailsMock'
import { pagedListMock } from '../../server/test/mocks/pagedListMock'
import { prisonRollCountMock } from '../../server/mocks/prisonRollCountMock'

export default {
stubUserCaseLoads: (caseLoads: CaseLoad[] = []) => {
Expand Down Expand Up @@ -63,6 +64,22 @@ export default {
})
},

stubPrisonRollCount: ({ prisonCode = 'LEI', payload = prisonRollCountMock } = {}) => {
return stubFor({
request: {
method: 'GET',
url: `/prison/api/prison/roll-count/${prisonCode}`,
},
response: {
status: 200,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
jsonBody: payload,
},
})
},

stubRollCountUnassigned: (prisonCode = 'LEI') => {
return stubFor({
request: {
Expand Down
4 changes: 2 additions & 2 deletions server/data/interfaces/prisonApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { OffenderInReception } from './offenderInReception'
import { PagedList } from './pagedList'
import { BedAssignment } from './bedAssignment'
import { UserDetail } from './userDetail'
import PrisonRollCount from './prisonRollCount'

export interface PrisonApiClient {
getUserCaseLoads(): Promise<CaseLoad[]>
Expand All @@ -20,8 +21,6 @@ export interface PrisonApiClient {
prisonId: string,
options?: { unassigned?: boolean; wingOnly?: boolean; showCells?: boolean; parentLocationId?: number },
): Promise<BlockRollCount[]>
getEnrouteRollCount(prisonId: string): Promise<number>
getLocationsForPrison(prisonId: string): Promise<Location[]>
getLocation(locationId: string): Promise<Location>
getAttributesForLocation(locationId: number): Promise<OffenderCell>
getMovements(prisonId: string): Promise<Movements>
Expand All @@ -37,4 +36,5 @@ export interface PrisonApiClient {
getUserDetailsList(usernames: string[]): Promise<UserDetail[]>
getPrisonersCurrentlyOutOfLivingUnit(livingUnitId: string): Promise<OffenderOut[]>
getPrisonersCurrentlyOutOfPrison(prisonId: string): Promise<OffenderOut[]>
getPrisonRollCount(prisonId: string): Promise<PrisonRollCount>
}
39 changes: 39 additions & 0 deletions server/data/interfaces/prisonRollCount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export default interface PrisonRollCount {
prisonId: string
numUnlockRollToday: number
numCurrentPopulation: number
numArrivedToday: number
numInReception: number
numStillToArrive: number
numOutToday: number
numNoCellAllocated: number
totals: {
bedsInUse: number
currentlyInCell: number
currentlyOut: number
workingCapacity: number
netVacancies: number
outOfOrder: number
}
locations: ResidentialLocation[]
}

export interface ResidentialLocation {
locationId: string
locationType: 'WING' | 'LAND' | 'SPUR' | 'CELL' | 'ROOM'
locationCode: string
fullLocationPath: string
certified: boolean
localName?: string
rollCount: LocationRollCount
subLocations: ResidentialLocation[]
}

interface LocationRollCount {
bedsInUse: number
currentlyInCell: number
currentlyOut: number
workingCapacity: number
netVacancies: number
outOfOrder: number
}
13 changes: 5 additions & 8 deletions server/data/prisonApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { OffenderInReception } from './interfaces/offenderInReception'
import { UserDetail } from './interfaces/userDetail'
import { BedAssignment } from './interfaces/bedAssignment'
import { PagedList } from './interfaces/pagedList'
import PrisonRollCount from './interfaces/prisonRollCount'

export default class PrisonApiRestClient implements PrisonApiClient {
constructor(private restClient: RestClient) {}
Expand Down Expand Up @@ -73,14 +74,6 @@ export default class PrisonApiRestClient implements PrisonApiClient {
return this.get<OffenderInReception[]>({ path: `/api/movements/rollcount/${prisonId}/in-reception` })
}

getEnrouteRollCount(prisonId: string): Promise<number> {
return this.get<number>({ path: `/api/movements/rollcount/${prisonId}/enroute` })
}

getLocationsForPrison(prisonId: string): Promise<Location[]> {
return this.get<Location[]>({ path: `/api/agencies/${prisonId}/locations` })
}

getLocation(locationId: string): Promise<Location> {
return this.get<Location>({ path: `/api/locations/${locationId}` })
}
Expand Down Expand Up @@ -132,4 +125,8 @@ export default class PrisonApiRestClient implements PrisonApiClient {
getPrisonersCurrentlyOutOfPrison(prisonId: string): Promise<OffenderOut[]> {
return this.get<OffenderOut[]>({ path: `/api/movements/agency/${prisonId}/currently-out` })
}

getPrisonRollCount(prisonId: string): Promise<PrisonRollCount> {
return this.get<PrisonRollCount>({ path: `/api/prison/roll-count/${prisonId}` })
}
}
Loading