generated from ministryofjustice/hmpps-template-kotlin
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ground work: Additional prison controller and extended getPersonServi…
…ce with query for prisoner excluding probation people
- Loading branch information
Showing
13 changed files
with
337 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
...k/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/prison/PrisonController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.prison | ||
|
||
import io.swagger.v3.oas.annotations.Operation | ||
import io.swagger.v3.oas.annotations.Parameter | ||
import io.swagger.v3.oas.annotations.media.Content | ||
import io.swagger.v3.oas.annotations.media.Schema | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse | ||
import io.swagger.v3.oas.annotations.tags.Tag | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PathVariable | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError.Type.ENTITY_NOT_FOUND | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPersonService | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService | ||
|
||
@RestController | ||
@RequestMapping("/v1/prison") | ||
@Tag(name = "prison") | ||
class PrisonController( | ||
@Autowired val getPersonService: GetPersonService, | ||
@Autowired val auditService: AuditService, | ||
) { | ||
@GetMapping("/prisoners/{encodedHmppsId}") | ||
@Operation( | ||
summary = "Returns a single prisoners details given an hmppsId, does not query for a probation person.", | ||
responses = [ | ||
ApiResponse(responseCode = "200", useReturnTypeSchema = true, description = "Successfully found a prisoner with the provided HMPPS ID."), | ||
ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), | ||
ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), | ||
], | ||
) | ||
fun getPerson( | ||
@Parameter(description = "A HMPPS identifier", example = "2008%2F0545166T", required = true) @PathVariable encodedHmppsId: String, | ||
): DataResponse<Person?> { | ||
val decodedHmppsId = encodedHmppsId.decodeUrlCharacters() | ||
|
||
val response = getPersonService.getPrisoner(decodedHmppsId) | ||
|
||
if (response.hasErrorCausedBy(ENTITY_NOT_FOUND, causedBy = UpstreamApi.PROBATION_OFFENDER_SEARCH)) { | ||
throw EntityNotFoundException("Could not find person with hmppsId: $decodedHmppsId") | ||
} | ||
|
||
auditService.createEvent("GET_PERSON_DETAILS", mapOf("hmppsId" to decodedHmppsId)) | ||
val data = response.data | ||
return DataResponse(data) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
...v/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/prison/PrisonControllerTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.prison | ||
|
||
import io.kotest.core.spec.style.DescribeSpec | ||
import io.kotest.matchers.shouldBe | ||
import org.mockito.Mockito | ||
import org.mockito.kotlin.times | ||
import org.mockito.kotlin.verify | ||
import org.mockito.kotlin.whenever | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest | ||
import org.springframework.test.context.ActiveProfiles | ||
import org.springframework.test.context.bean.override.mockito.MockitoBean | ||
import org.springframework.test.web.servlet.MockMvc | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.removeWhitespaceAndNewlines | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.helpers.IntegrationAPIMockMvc | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError.Type.ENTITY_NOT_FOUND | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPersonService | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService | ||
import java.time.LocalDate | ||
|
||
@WebMvcTest(controllers = [PrisonController::class]) | ||
@ActiveProfiles("test") | ||
internal class PrisonControllerTest( | ||
@Autowired var springMockMvc: MockMvc, | ||
@MockitoBean val getPersonService: GetPersonService, | ||
@MockitoBean val auditService: AuditService, | ||
) : DescribeSpec({ | ||
val hmppsId = "200313116M" | ||
val basePath = "/v1/prison" | ||
val mockMvc = IntegrationAPIMockMvc(springMockMvc) | ||
|
||
describe("GET $basePath") { | ||
} | ||
|
||
afterTest { | ||
Mockito.reset(getPersonService) | ||
Mockito.reset(auditService) | ||
} | ||
|
||
it("returns 500 when service throws an exception") { | ||
whenever(getPersonService.getPrisoner(hmppsId)).thenThrow(RuntimeException("Service error")) | ||
|
||
val result = mockMvc.performAuthorised("$basePath/prisoners/$hmppsId") | ||
|
||
result.response.status.shouldBe(500) | ||
} | ||
|
||
it("returns a person with all fields populated") { | ||
whenever(getPersonService.getPrisoner(hmppsId)).thenReturn( | ||
Response( | ||
data = | ||
Person( | ||
firstName = "Barry", | ||
lastName = "Allen", | ||
middleName = "Jonas", | ||
dateOfBirth = LocalDate.parse("2023-03-01"), | ||
gender = "Male", | ||
ethnicity = "Caucasian", | ||
pncId = "PNC123456", | ||
), | ||
), | ||
) | ||
|
||
val result = mockMvc.performAuthorised("$basePath/prisoners/$hmppsId") | ||
|
||
result.response.contentAsString.shouldBe( | ||
""" | ||
{ | ||
"data":{ | ||
"firstName":"Barry", | ||
"lastName":"Allen", | ||
"middleName":"Jonas", | ||
"dateOfBirth":"2023-03-01", | ||
"gender":"Male", | ||
"ethnicity":"Caucasian", | ||
"aliases":[], | ||
"identifiers":{ | ||
"nomisNumber":null, | ||
"croNumber":null, | ||
"deliusCrn":null | ||
}, | ||
"pncId": "PNC123456", | ||
"hmppsId": null, | ||
"contactDetails": null | ||
} | ||
} | ||
""".removeWhitespaceAndNewlines(), | ||
) | ||
} | ||
|
||
it("logs audit event") { | ||
whenever(getPersonService.getPrisoner(hmppsId)).thenReturn( | ||
Response( | ||
data = | ||
Person( | ||
firstName = "Barry", | ||
lastName = "Allen", | ||
middleName = "Jonas", | ||
dateOfBirth = LocalDate.parse("2023-03-01"), | ||
gender = "Male", | ||
ethnicity = "Caucasian", | ||
pncId = "PNC123456", | ||
), | ||
), | ||
) | ||
|
||
mockMvc.performAuthorised("$basePath/prisoners/$hmppsId") | ||
verify( | ||
auditService, | ||
times(1), | ||
).createEvent( | ||
"GET_PERSON_DETAILS", | ||
mapOf("hmppsId" to hmppsId), | ||
) | ||
} | ||
|
||
it("returns 404 when prisoner is not found") { | ||
whenever(getPersonService.getPrisoner(hmppsId)).thenReturn( | ||
Response( | ||
data = null, | ||
errors = | ||
listOf( | ||
UpstreamApiError( | ||
type = ENTITY_NOT_FOUND, | ||
causedBy = UpstreamApi.PROBATION_OFFENDER_SEARCH, | ||
description = "Prisoner not found", | ||
), | ||
), | ||
), | ||
) | ||
|
||
val result = mockMvc.performAuthorised("$basePath/prisoners/$hmppsId") | ||
|
||
result.response.status.shouldBe(404) | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
...gov/justice/digital/hmpps/hmppsintegrationapi/integration/prison/PrisonIntegrationTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package uk.gov.justice.digital.hmpps.hmppsintegrationapi.integration.prison | ||
|
||
import org.junit.jupiter.api.Test | ||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content | ||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status | ||
import uk.gov.justice.digital.hmpps.hmppsintegrationapi.integration.IntegrationTestBase | ||
|
||
class PrisonIntegrationTest : IntegrationTestBase() { | ||
private final val hmppsId = "G2996UX" | ||
private final val basePrisonPath = "/v1/prison" | ||
|
||
@Test | ||
fun `return a prisoner with all fields populated`() { | ||
callApi("$basePrisonPath/prisoners/$hmppsId") | ||
.andExpect(status().isOk) | ||
.andExpect(content().json(getExpectedResponse("prisoner-response"))) | ||
} | ||
} |
Oops, something went wrong.