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-376: Get COM from Delius #355

Merged
merged 2 commits into from
Nov 13, 2023
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
3 changes: 2 additions & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import pathfinderApi from './integration_tests/mockApis/pathfinderApi'
import socApi from './integration_tests/mockApis/socApi'
import adjudicationsApi from './integration_tests/mockApis/adjudications'
import nonAssociationsApi from './integration_tests/mockApis/nonAssociationsApi'
import prisonerProfileDeliusApi from './integration_tests/mockApis/prisonerProfileDeliusApi'

export default defineConfig({
viewportWidth: 1152,
Expand All @@ -26,7 +27,6 @@ export default defineConfig({
reporterOptions: {
configFile: 'reporter-config.json',
},
videoUploadOnPasses: false,
taskTimeout: 60000,
e2e: {
// We've imported your old cypress plugins here.
Expand All @@ -49,6 +49,7 @@ export default defineConfig({
...socApi,
...adjudicationsApi,
...nonAssociationsApi,
...prisonerProfileDeliusApi,
})
},
baseUrl: 'http://localhost:3007',
Expand Down
4 changes: 2 additions & 2 deletions feature.env
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ PATHFINDER_UI_URL=http://localhost:9091/pathfinderui
MANAGE_SOC_CASES_UI_URL=http://localhost:9091/managesoccasesui
NON_ASSOCIATIONS_UI_URL=http://localhost:9091/nonassociationsui
NON_ASSOCIATIONS_PRISONS=MDI,LGI,FNI,ISI,RSI
WELCOME_PEOPLE_INTO_PRISON_UI_URL=https://welcome-dev.prison.service.justice.gov.uk
MANAGE_ADJUDICATIONS_API_URL=http://localhost:9091/adjudications
CALCULATE_RELEASE_DATES_UI_URL=https://localhost:9091/calculateRelease
CALCULATE_RELEASE_DATES_UI_URL=http://localhost:9091/calculateRelease
PRISONER_PROFILE_DELIUS_API_URL=http://localhost:9091/delius
FEEDBACK_DISABLED_PRISONS=LEI
SYSTEM_PHASE=DEV
NEURODIVERSITY_ENABLED_PRISONS=MDI
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ generic-service:
COMPONENT_API_URL: "https://frontend-components-dev.hmpps.service.justice.gov.uk"
COMPONENT_API_LATEST: "true"
PROFILE_ADD_APPOINTMENT_ENABLED: "true"
PRISONER_PROFILE_DELIUS_API_URL: "https://prisoner-profile-and-delius-dev.hmpps.service.justice.gov.uk"

generic-prometheus-alerts:
alertSeverity: hmpps-prisoner-profile-non-prod
1 change: 1 addition & 0 deletions helm_deploy/values-preprod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ generic-service:
COMPONENT_API_URL: "https://frontend-components-preprod.hmpps.service.justice.gov.uk"
COMPONENT_API_LATEST: "true"
PROFILE_ADD_APPOINTMENT_ENABLED: "true"
PRISONER_PROFILE_DELIUS_API_URL: "https://prisoner-profile-and-delius-preprod.hmpps.service.justice.gov.uk"

allowlist:
office: "217.33.148.210/32"
Expand Down
1 change: 1 addition & 0 deletions helm_deploy/values-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ generic-service:
COMPONENT_API_URL: "https://frontend-components.hmpps.service.justice.gov.uk"
COMPONENT_API_LATEST: "false"
PROFILE_ADD_APPOINTMENT_ENABLED: "false"
PRISONER_PROFILE_DELIUS_API_URL: "https://prisoner-profile-and-delius.hmpps.service.justice.gov.uk"

allowlist:
office: "217.33.148.210/32"
Expand Down
20 changes: 20 additions & 0 deletions integration_tests/mockApis/prisonerProfileDeliusApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { stubFor } from './wiremock'
import { communityManagerMock } from '../../server/data/localMockData/communityManagerMock'

export default {
stubGetCommunityManager: () => {
return stubFor({
request: {
method: 'GET',
urlPattern: `/delius/probation-cases/G6123VU/community-manager`,
},
response: {
status: 200,
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
jsonBody: communityManagerMock,
},
})
},
}
1 change: 1 addition & 0 deletions integration_tests/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Cypress.Commands.add(
cy.task('stubGetLearnerNeurodivergence', prisonerNumber)
cy.task('stubInmateDetail', bookingId)
cy.task('stubMovements', prisonerNumber)
cy.task('stubGetCommunityManager')
},
)

Expand Down
8 changes: 8 additions & 0 deletions server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ export default {
agent: new AgentConfig(Number(get('COMPONENT_API_TIMEOUT_SECONDS', 20000))),
latest: get('COMPONENT_API_LATEST', 'false') === 'true',
},
prisonerProfileDeliusApi: {
url: get('PRISONER_PROFILE_DELIUS_API_URL', 'http://localhost:8082', requiredInProduction),
timeout: {
response: Number(get('PRISONER_PROFILE_DELIUS_API_TIMEOUT_RESPONSE', 20000)),
deadline: Number(get('PRISONER_PROFILE_DELIUS_API_TIMEOUT_DEADLINE', 20000)),
},
agent: new AgentConfig(Number(get('PRISONER_PROFILE_DELIUS_API_TIMEOUT_DEADLINE', 20000))),
},
},
serviceUrls: {
offenderCategorisation: get('OFFENDER_CATEGORISATION_UI_URL', 'http://localhost:3001', requiredInProduction),
Expand Down
2 changes: 2 additions & 0 deletions server/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import AdjudicationsApiRestClient from './adjudicationsApiClient'
import NonAssociationsApiRestClient from './nonAssociationsApiClient'
import ComponentApiRestClient from './componentApiClient'
import WhereaboutsRestApiClient from './whereaboutsClient'
import PrisonerProfileDeliusApiRestClient from './prisonerProfileDeliusApiClient'

initialiseAppInsights()
buildAppInsightsClient()
Expand All @@ -44,6 +45,7 @@ export const dataAccess = {
nonAssociationsApiClientBuilder: (token: string) => new NonAssociationsApiRestClient(token),
componentApiClientBuilder: (token: string) => new ComponentApiRestClient(token),
whereaboutsApiClientBuilder: (token: string) => new WhereaboutsRestApiClient(token),
prisonerProfileDeliusApiClientBuilder: (token: string) => new PrisonerProfileDeliusApiRestClient(token),
}

export type DataAccess = typeof dataAccess
Expand Down
5 changes: 5 additions & 0 deletions server/data/interfaces/prisonerProfileDeliusApiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { CommunityManager } from '../../interfaces/prisonerProfileDeliusApi/communityManager'

export interface PrisonerProfileDeliusApiClient {
getCommunityManager(prisonerNumber: string): Promise<CommunityManager | null>
}
9 changes: 9 additions & 0 deletions server/data/localMockData/communityManagerMock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CommunityManager } from '../../interfaces/prisonerProfileDeliusApi/communityManager'

// eslint-disable-next-line import/prefer-default-export
export const communityManagerMock: CommunityManager = {
code: 'ABC',
name: { forename: 'Terry', surname: 'Scott', email: 'terry@email.com' },
team: { code: 'XYZ', description: 'Probation Team', email: 'team@email.com' },
unallocated: false,
}
2 changes: 1 addition & 1 deletion server/data/localMockData/staffContacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const StaffContactsMock = {
},
prisonOffenderManager: 'Andy Marke',
coworkingPrisonOffenderManager: 'Andy Hudson',
communityOffenderManager: 'Not assigned',
communityOffenderManager: 'Terry Scott',
}

export default {
Expand Down
41 changes: 41 additions & 0 deletions server/data/prisonerProfileDeliusApiClient.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import nock from 'nock'
import config from '../config'
import PrisonerProfileDeliusApiRestClient from './prisonerProfileDeliusApiClient'
import { PrisonerProfileDeliusApiClient } from './interfaces/prisonerProfileDeliusApiClient'
import { communityManagerMock } from './localMockData/communityManagerMock'

jest.mock('./tokenStore')

const token = { access_token: 'token-1', expires_in: 300 }

describe('prisonerProfileDeliusApiClient', () => {
let fakePrisonerProfileDeliusApi: nock.Scope
let prisonerProfileDeliusApiClient: PrisonerProfileDeliusApiClient

beforeEach(() => {
fakePrisonerProfileDeliusApi = nock(config.apis.prisonerProfileDeliusApi.url)
prisonerProfileDeliusApiClient = new PrisonerProfileDeliusApiRestClient(token.access_token)
})

afterEach(() => {
jest.resetAllMocks()
nock.cleanAll()
})

const mockSuccessfulApiCall = <TReturnData>(url: string, returnData: TReturnData) => {
fakePrisonerProfileDeliusApi
.get(url)
.matchHeader('authorization', `Bearer ${token.access_token}`)
.reply(200, returnData)
}

describe('getCommunityManager', () => {
it('Should return data from the API', async () => {
const prisonerNumber = 'AB1234Y'
mockSuccessfulApiCall(`/probation-cases/${prisonerNumber}/community-manager`, communityManagerMock)

const output = await prisonerProfileDeliusApiClient.getCommunityManager(prisonerNumber)
expect(output).toEqual(communityManagerMock)
})
})
})
19 changes: 19 additions & 0 deletions server/data/prisonerProfileDeliusApiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import RestClient from './restClient'
import config from '../config'
import { CommunityManager } from '../interfaces/prisonerProfileDeliusApi/communityManager'
import { PrisonerProfileDeliusApiClient } from './interfaces/prisonerProfileDeliusApiClient'

export default class PrisonerProfileDeliusApiRestClient implements PrisonerProfileDeliusApiClient {
private readonly restClient: RestClient

constructor(token: string) {
this.restClient = new RestClient('Prisoner Profile Delius API', config.apis.prisonerProfileDeliusApi, token)
}

async getCommunityManager(prisonerNumber: string): Promise<CommunityManager | null> {
return this.restClient.get<CommunityManager | null>({
path: `/probation-cases/${prisonerNumber}/community-manager`,
ignore404: true,
})
}
}
14 changes: 14 additions & 0 deletions server/interfaces/prisonerProfileDeliusApi/communityManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export interface CommunityManager {
code: string
name: {
forename: string
surname: string
email?: string
}
team: {
code: string
description: string
email?: string
}
unallocated: boolean
}
2 changes: 2 additions & 0 deletions server/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const services = () => {
nonAssociationsApiClientBuilder,
componentApiClientBuilder,
whereaboutsApiClientBuilder,
prisonerProfileDeliusApiClientBuilder,
} = dataAccess

const userService = new UserService(hmppsAuthClientBuilder, prisonApiClientBuilder)
Expand All @@ -48,6 +49,7 @@ export const services = () => {
offencesPageService,
curiousApiClientBuilder,
nonAssociationsApiClientBuilder,
prisonerProfileDeliusApiClientBuilder,
)
const personalPageService = new PersonalPageService(prisonApiClientBuilder, curiousApiClientBuilder)
const workAndSkillsPageService = new WorkAndSkillsPageService(curiousApiClientBuilder, prisonApiClientBuilder)
Expand Down
7 changes: 7 additions & 0 deletions server/services/overviewPageService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ import { LearnerGoalsMock } from '../data/localMockData/learnerGoalsMock'
import { NonAssociationsApiClient } from '../data/interfaces/nonAssociationsApiClient'
import movementsMock from '../data/localMockData/movementsData'
import config from '../config'
import { PrisonerProfileDeliusApiClient } from '../data/interfaces/prisonerProfileDeliusApiClient'
import { communityManagerMock } from '../data/localMockData/communityManagerMock'

describe('OverviewPageService', () => {
let prisonApiClient: PrisonApiClient
Expand Down Expand Up @@ -92,6 +94,10 @@ describe('OverviewPageService', () => {
getNonAssociationDetails: jest.fn(async () => nonAssociationDetailsDummyData),
}

const prisonerProfileDeliusApiClient: PrisonerProfileDeliusApiClient = {
getCommunityManager: jest.fn(async () => communityManagerMock),
}

const overviewPageServiceConstruct = jest.fn(() => {
return new OverviewPageService(
() => prisonApiClient,
Expand All @@ -102,6 +108,7 @@ describe('OverviewPageService', () => {
new OffencesPageService(null),
() => curiousApiClient,
() => nonAssociationsApiClient,
() => prisonerProfileDeliusApiClient,
)
})

Expand Down
32 changes: 11 additions & 21 deletions server/services/overviewPageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { PrisonApiClient } from '../data/interfaces/prisonApiClient'
import {
convertToTitleCase,
formatCategoryCodeDescription,
formatCommunityManager,
formatMoney,
formatName,
formatPrivilegedVisitsSummary,
Expand All @@ -23,7 +24,7 @@ import { Assessment } from '../interfaces/prisonApi/assessment'
import { AssessmentCode } from '../data/enums/assessmentCode'
import { Prisoner } from '../interfaces/prisoner'
import { PersonalDetails } from '../interfaces/personalDetails'
import { ContactDetail, StaffContacts } from '../interfaces/staffContacts'
import { StaffContacts } from '../interfaces/staffContacts'
import AllocationManagerClient from '../data/interfaces/allocationManagerClient'
import KeyWorkerClient from '../data/interfaces/keyWorkerClient'
import { Pom } from '../interfaces/pom'
Expand Down Expand Up @@ -56,6 +57,8 @@ import { NonAssociationDetails } from '../interfaces/nonAssociationDetails'
import { KeyWorker } from '../interfaces/keyWorker'
import { CaseNote } from '../interfaces/caseNote'
import { FullStatus } from '../interfaces/prisonApi/fullStatus'
import { CommunityManager } from '../interfaces/prisonerProfileDeliusApi/communityManager'
import { PrisonerProfileDeliusApiClient } from '../data/interfaces/prisonerProfileDeliusApiClient'

export default class OverviewPageService {
constructor(
Expand All @@ -67,6 +70,7 @@ export default class OverviewPageService {
private readonly offencesPageService: OffencesPageService,
private readonly curiousApiClientBuilder: RestClientBuilder<CuriousApiClient>,
private readonly nonAssociationsApiClientBuilder: RestClientBuilder<NonAssociationsApiClient>,
private readonly prisonerProfileDeliusApiClientBuilder: RestClientBuilder<PrisonerProfileDeliusApiClient>,
) {}

public async get(
Expand All @@ -86,33 +90,34 @@ export default class OverviewPageService {
const adjudicationsApiClient = this.adjudicationsApiClientBuilder(clientToken)
const curiousApiClient = this.curiousApiClientBuilder(clientToken)
const nonAssociationsApiClient = this.nonAssociationsApiClientBuilder(clientToken)
const prisonerProfileDeliusApiClient = this.prisonerProfileDeliusApiClientBuilder(clientToken)

const [
inmateDetail,
staffRoles,
learnerNeurodivergence,
movements,
nonAssociationDetails,
offenderContacts,
allocationManager,
offenderKeyWorker,
keyWorkerSessions,
mainOffence,
courtCaseData,
fullStatus,
communityManager,
] = await Promise.all([
prisonApiClient.getInmateDetail(prisonerData.bookingId),
prisonApiClient.getStaffRoles(staffId, prisonerData.prisonId),
curiousApiClient.getLearnerNeurodivergence(prisonerData.prisonerNumber),
prisonApiClient.getMovements([prisonerData.prisonerNumber], [MovementType.Transfer]),
nonAssociationsApiClient.getNonAssociationDetails(prisonerNumber),
prisonApiClient.getBookingContacts(prisonerData.bookingId),
allocationManagerClient.getPomByOffenderNo(prisonerData.prisonerNumber),
keyWorkerClient.getOffendersKeyWorker(prisonerData.prisonerNumber),
prisonApiClient.getCaseNoteSummaryByTypes({ type: 'KA', subType: 'KS', numMonths: 38, bookingId }),
prisonApiClient.getMainOffence(bookingId),
prisonApiClient.getCourtCases(bookingId),
prisonApiClient.getFullStatus(prisonerNumber),
prisonerProfileDeliusApiClient.getCommunityManager(prisonerNumber),
])

const [miniSummaryGroupA, miniSummaryGroupB, personalDetails, schedule, offencesOverview] = await Promise.all([
Expand Down Expand Up @@ -147,7 +152,7 @@ export default class OverviewPageService {
personalDetails,
staffContacts: this.getStaffContacts(
prisonerData,
offenderContacts,
communityManager,
allocationManager,
offenderKeyWorker,
keyWorkerSessions,
Expand Down Expand Up @@ -211,21 +216,11 @@ export default class OverviewPageService {

public getStaffContacts(
prisonerData: Prisoner,
offenderContacts: ContactDetail,
communityManager: CommunityManager,
allocationManager: Pom,
offenderKeyWorker: KeyWorker,
keyWorkerSessions: CaseNote[],
): StaffContacts {
const communityOffenderManager =
offenderContacts && offenderContacts.otherContacts !== undefined
? offenderContacts.otherContacts
.filter(contact => contact && contact.contactType === 'COM')
.map(contact => ({
firstName: contact ? contact?.firstName : undefined,
lastName: contact ? contact?.lastName : undefined,
}))
: []

const prisonOffenderManager =
allocationManager &&
(allocationManager as Pom).primary_pom &&
Expand Down Expand Up @@ -255,12 +250,7 @@ export default class OverviewPageService {
coworkingPrisonOffenderManager: coworkingPrisonOffenderManager
? `${coworkingPrisonOffenderManager[0]} ${coworkingPrisonOffenderManager[1]}`
: 'Not assigned',
communityOffenderManager:
communityOffenderManager && communityOffenderManager[0] !== undefined
? `${convertToTitleCase(communityOffenderManager[0].firstName)} ${convertToTitleCase(
communityOffenderManager[0].lastName,
)}`
: 'Not assigned',
communityOffenderManager: formatCommunityManager(communityManager),
linkUrl: `${config.serviceUrls.digitalPrison}/prisoner/${prisonerData.prisonerNumber}/professional-contacts`,
}
}
Expand Down
Loading