Skip to content

Commit 1d90052

Browse files
GetPerson service - added another method (#409)
* GetPerson service - added another method * Controller code and smoke test * Adding data to test response * Fixed import
1 parent 7138b03 commit 1d90052

File tree

5 files changed

+204
-81
lines changed

5 files changed

+204
-81
lines changed

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,17 @@ class PersonController(
6161
@GetMapping("{encodedHmppsId}")
6262
fun getPerson(
6363
@PathVariable encodedHmppsId: String,
64-
): Map<String, Person?> {
64+
): Map<String, Map<String, Person?>> {
6565
val hmppsId = encodedHmppsId.decodeUrlCharacters()
66-
val response = getPersonService.execute(hmppsId)
66+
val response = getPersonService.getCombinedDataForPerson(hmppsId)
6767

6868
if (response.hasErrorCausedBy(ENTITY_NOT_FOUND, causedBy = UpstreamApi.PROBATION_OFFENDER_SEARCH)) {
6969
throw EntityNotFoundException("Could not find person with id: $hmppsId")
7070
}
7171

7272
auditService.createEvent("GET_PERSON_DETAILS", mapOf("hmppsId" to hmppsId))
73-
return mapOf("data" to response.data)
73+
val data = response.data.mapValues { it.value }
74+
return mapOf("data" to data)
7475
}
7576

7677
@GetMapping("{encodedHmppsId}/images")

src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetPersonService.kt

+31
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,48 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.services
22

33
import org.springframework.beans.factory.annotation.Autowired
44
import org.springframework.stereotype.Service
5+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.PrisonerOffenderSearchGateway
56
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.ProbationOffenderSearchGateway
67
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person
78
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
89

910
@Service
1011
class GetPersonService(
1112
@Autowired val probationOffenderSearchGateway: ProbationOffenderSearchGateway,
13+
@Autowired val prisonerOffenderSearchGateway: PrisonerOffenderSearchGateway,
1214
) {
1315
fun execute(hmppsId: String): Response<Person?> {
1416
val personFromProbationOffenderSearch = probationOffenderSearchGateway.getPerson(id = hmppsId)
1517

1618
return Response(data = personFromProbationOffenderSearch.data, errors = personFromProbationOffenderSearch.errors)
1719
}
20+
21+
fun getCombinedDataForPerson(hmppsId: String): Response<Map<String, Person?>> {
22+
val probationResponse = probationOffenderSearchGateway.getPerson(id = hmppsId)
23+
24+
val prisonResponse =
25+
probationResponse.data?.identifiers?.nomisNumber?.let {
26+
prisonerOffenderSearchGateway.getPrisonOffender(nomsNumber = it)
27+
}
28+
29+
return if (prisonResponse != null) {
30+
Response(
31+
data =
32+
mapOf(
33+
"prisonerOffenderSearch" to prisonResponse.data?.toPerson(),
34+
"probationOffenderSearch" to probationResponse.data,
35+
),
36+
errors = prisonResponse.errors + probationResponse.errors,
37+
)
38+
} else {
39+
Response(
40+
data =
41+
mapOf(
42+
"prisonerOffenderSearch" to null,
43+
"probationOffenderSearch" to probationResponse.data,
44+
),
45+
errors = probationResponse.errors,
46+
)
47+
}
48+
}
1849
}

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonControllerTest.kt

+67-26
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ import org.springframework.web.reactive.function.client.WebClientResponseExcepti
2020
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.removeWhitespaceAndNewlines
2121
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc
2222
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.ContactDetailsWithEmailAndPhone
23+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Identifiers
2324
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.ImageMetadata
2425
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person
2526
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PhoneNumber
2627
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
2728
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi
2829
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError
30+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.prisoneroffendersearch.POSPrisoner
2931
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetImageMetadataForPersonService
3032
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPersonService
3133
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPersonsService
@@ -222,12 +224,20 @@ internal class PersonControllerTest(
222224
}
223225

224226
describe("GET $basePath/{id}") {
225-
val person = Person("Silly", "Sobbers")
227+
val probationOffenderSearch = Person("Sam", "Smith", identifiers = Identifiers(nomisNumber = "1234ABC"))
228+
val prisonOffenderSearch = POSPrisoner("Kim", "Kardashian")
229+
val prisonResponse = Response(data = prisonOffenderSearch, errors = emptyList())
226230

227231
beforeTest {
228232
Mockito.reset(getPersonService)
229233
Mockito.reset(auditService)
230-
whenever(getPersonService.execute(hmppsId)).thenReturn(Response(data = person))
234+
235+
val personMap =
236+
mapOf(
237+
"probationOffenderSearch" to probationOffenderSearch,
238+
"prisonerOffenderSearch" to prisonResponse.data.toPerson(),
239+
)
240+
whenever(getPersonService.getCombinedDataForPerson(hmppsId)).thenReturn(Response(data = personMap))
231241
}
232242

233243
it("returns a 200 OK status code") {
@@ -248,9 +258,13 @@ internal class PersonControllerTest(
248258
val idThatDoesNotExist = "9999/11111Z"
249259

250260
it("returns a 404 status code when a person cannot be found in both upstream APIs") {
251-
whenever(getPersonService.execute(idThatDoesNotExist)).thenReturn(
261+
whenever(getPersonService.getCombinedDataForPerson(idThatDoesNotExist)).thenReturn(
252262
Response(
253-
data = null,
263+
data =
264+
mapOf(
265+
"prisonerOffenderSearch" to null,
266+
"probationOffenderSearch" to null,
267+
),
254268
errors =
255269
listOf(
256270
UpstreamApiError(
@@ -268,9 +282,13 @@ internal class PersonControllerTest(
268282
}
269283

270284
it("does not return a 404 status code when a person was found in one upstream API") {
271-
whenever(getPersonService.execute(idThatDoesNotExist)).thenReturn(
285+
whenever(getPersonService.getCombinedDataForPerson(idThatDoesNotExist)).thenReturn(
272286
Response(
273-
data = Person("someFirstName", "someLastName"),
287+
data =
288+
mapOf(
289+
"prisonerOffenderSearch" to null,
290+
"probationOffenderSearch" to Person("someFirstName", "someLastName"),
291+
),
274292
errors =
275293
listOf(
276294
UpstreamApiError(
@@ -291,33 +309,56 @@ internal class PersonControllerTest(
291309
it("gets a person with the matching ID") {
292310
mockMvc.performAuthorised("$basePath/$encodedHmppsId")
293311

294-
verify(getPersonService, times(1)).execute(hmppsId)
312+
verify(getPersonService, times(1)).getCombinedDataForPerson(hmppsId)
295313
}
296314

297315
it("returns a person with the matching ID") {
298316
val result = mockMvc.performAuthorised("$basePath/$encodedHmppsId")
299317

300318
result.response.contentAsString.shouldBe(
301319
"""
302-
{
303-
"data": {
304-
"firstName": "Silly",
305-
"lastName": "Sobbers",
306-
"middleName": null,
307-
"dateOfBirth": null,
308-
"gender": null,
309-
"ethnicity": null,
310-
"aliases": [],
311-
"identifiers": {
312-
"nomisNumber": null,
313-
"croNumber": null,
314-
"deliusCrn": null
315-
},
316-
"pncId": null,
317-
"hmppsId": null,
318-
"contactDetails": null
319-
}
320-
}
320+
{
321+
"data":{
322+
"probationOffenderSearch":{
323+
"firstName":"Sam",
324+
"lastName":"Smith",
325+
"middleName":null,
326+
"dateOfBirth":null,
327+
"gender":null,
328+
"ethnicity":null,
329+
"aliases":[
330+
331+
],
332+
"identifiers":{
333+
"nomisNumber":"1234ABC",
334+
"croNumber":null,
335+
"deliusCrn":null
336+
},
337+
"pncId":null,
338+
"hmppsId":null,
339+
"contactDetails":null
340+
},
341+
"prisonerOffenderSearch":{
342+
"firstName":"Kim",
343+
"lastName":"Kardashian",
344+
"middleName":null,
345+
"dateOfBirth":null,
346+
"gender":null,
347+
"ethnicity":null,
348+
"aliases":[
349+
350+
],
351+
"identifiers":{
352+
"nomisNumber":null,
353+
"croNumber":null,
354+
"deliusCrn":null
355+
},
356+
"pncId":null,
357+
"hmppsId":null,
358+
"contactDetails":null
359+
}
360+
}
361+
}
321362
""".removeWhitespaceAndNewlines(),
322363
)
323364
}

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/services/GetPersonServiceTest.kt

+22
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.gateways.ProbationOffend
1414
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Identifiers
1515
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person
1616
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response
17+
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.prisoneroffendersearch.POSPrisoner
1718

1819
@ContextConfiguration(
1920
initializers = [ConfigDataApplicationContextInitializer::class],
@@ -36,6 +37,9 @@ internal class GetPersonServiceTest(
3637
whenever(probationOffenderSearchGateway.getPerson(id = hmppsId)).thenReturn(
3738
Response(data = Person(firstName = "Qui-gon", lastName = "Jin", identifiers = Identifiers(nomisNumber = "A1234AA"))),
3839
)
40+
whenever(prisonerOffenderSearchGateway.getPrisonOffender(nomsNumber = "A1234AA")).thenReturn(
41+
Response(data = POSPrisoner(firstName = "Sam", lastName = "Mills")),
42+
)
3943
}
4044

4145
it("gets a person from Probation Offender Search") {
@@ -66,4 +70,22 @@ internal class GetPersonServiceTest(
6670

6771
result.data.shouldBe(expectedResult)
6872
}
73+
74+
it("returns a person with both probation and prison data when prison data exists") {
75+
val personFromProbationOffenderSearch = Person("Paula", "First", identifiers = Identifiers(nomisNumber = "A1234AA"))
76+
val personFromPrisonOffenderSearch = POSPrisoner("Sam", "Mills")
77+
78+
whenever(probationOffenderSearchGateway.getPerson(hmppsId)).thenReturn(
79+
Response(data = personFromProbationOffenderSearch),
80+
)
81+
whenever(prisonerOffenderSearchGateway.getPrisonOffender("A1234AA")).thenReturn(
82+
Response(data = personFromPrisonOffenderSearch),
83+
)
84+
85+
val result = getPersonService.getCombinedDataForPerson(hmppsId)
86+
val expectedResult = result.data
87+
88+
result.data.shouldBe(expectedResult)
89+
result.errors shouldBe emptyList()
90+
}
6991
})

src/test/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/smoke/person/PersonSmokeTest.kt

+80-52
Original file line numberDiff line numberDiff line change
@@ -45,60 +45,88 @@ class PersonSmokeTest : DescribeSpec(
4545
response.body().shouldBe(
4646
"""
4747
{
48-
"data": {
49-
"firstName": "string",
50-
"lastName": "string",
51-
"middleName": "string",
52-
"dateOfBirth": "2019-08-24",
53-
"gender": "string",
54-
"ethnicity": "string",
55-
"aliases": [
56-
{
57-
"firstName": "string",
58-
"lastName": "string",
59-
"middleName": "string",
60-
"dateOfBirth": "2019-08-24",
61-
"gender": "string",
62-
"ethnicity": null
63-
}
64-
],
65-
"identifiers": {
66-
"nomisNumber": "G5555TT",
67-
"croNumber": "123456/24A",
68-
"deliusCrn": "A123456"
48+
"data":{
49+
"prisonerOffenderSearch":{
50+
"firstName":"Robert",
51+
"lastName":"Larsen",
52+
"middleName":"John James",
53+
"dateOfBirth":"1975-04-02",
54+
"gender":"Female",
55+
"ethnicity":"White: Eng./Welsh/Scot./N.Irish/British",
56+
"aliases":[
57+
{
58+
"firstName":"Robert",
59+
"lastName":"Lorsen",
60+
"middleName":"Trevor",
61+
"dateOfBirth":"1975-04-02",
62+
"gender":"Male",
63+
"ethnicity":"White : Irish"
64+
}
65+
],
66+
"identifiers":{
67+
"nomisNumber":"A1234AA",
68+
"croNumber":"29906/12J",
69+
"deliusCrn":null
70+
},
71+
"pncId":"12/394773H",
72+
"hmppsId":null,
73+
"contactDetails":null
6974
},
70-
"pncId": "2012/0052494Q",
71-
"hmppsId": "A123456",
72-
"contactDetails": {
73-
"addresses": [
74-
{
75-
"addressNumber": "string",
76-
"district": "string",
77-
"buildingName": "string",
78-
"county": "string",
79-
"from": "2019-08-24",
80-
"postcode": "string",
81-
"streetName": "string",
82-
"type": {
83-
"code": "string",
84-
"description": "string"
85-
},
86-
"to": "2019-08-24",
87-
"town": "string",
88-
"noFixedAbode": true,
89-
"notes": "string"
90-
}
91-
],
92-
"phoneNumbers": [
93-
{
94-
"number": "string",
95-
"type": "TELEPHONE"
96-
}
97-
],
98-
"emails":null
75+
"probationOffenderSearch":{
76+
"firstName":"string",
77+
"lastName":"string",
78+
"middleName":"string",
79+
"dateOfBirth":"2019-08-24",
80+
"gender":"string",
81+
"ethnicity":"string",
82+
"aliases":[
83+
{
84+
"firstName":"string",
85+
"lastName":"string",
86+
"middleName":"string",
87+
"dateOfBirth":"2019-08-24",
88+
"gender":"string",
89+
"ethnicity":null
90+
}
91+
],
92+
"identifiers":{
93+
"nomisNumber":"G5555TT",
94+
"croNumber":"123456/24A",
95+
"deliusCrn":"A123456"
96+
},
97+
"pncId":"2012/0052494Q",
98+
"hmppsId":"A123456",
99+
"contactDetails":{
100+
"addresses":[
101+
{
102+
"addressNumber":"string",
103+
"district":"string",
104+
"buildingName":"string",
105+
"county":"string",
106+
"from":"2019-08-24",
107+
"postcode":"string",
108+
"streetName":"string",
109+
"type":{
110+
"code":"string",
111+
"description":"string"
112+
},
113+
"to":"2019-08-24",
114+
"town":"string",
115+
"noFixedAbode":true,
116+
"notes":"string"
117+
}
118+
],
119+
"phoneNumbers":[
120+
{
121+
"number":"string",
122+
"type":"TELEPHONE"
123+
}
124+
],
125+
"emails":null
126+
}
99127
}
100-
}
101-
}
128+
}
129+
}
102130
""".removeWhitespaceAndNewlines(),
103131
)
104132
}

0 commit comments

Comments
 (0)