From 0b5ca05ae1435f0b9c7153c83558f579f29c6e3a Mon Sep 17 00:00:00 2001 From: Jon Brighton Date: Wed, 18 Dec 2024 10:18:37 +0000 Subject: [PATCH] CDPS-1090: Edit country of birth --- .../common/client/PrisonApiClient.kt | 7 +++ .../client/request/UpdateBirthCountry.kt | 9 +++ ...h2ClientCredentialGrantRequestConverter.kt | 2 +- .../service/CorePersonRecordService.kt | 7 +++ .../CorePersonRecordV1ResourceIntTest.kt | 55 ++++++++++++------- .../service/CorePersonRecordServiceTest.kt | 11 ++++ .../wiremock/PrisonApiMockServer.kt | 13 +++++ 7 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/request/UpdateBirthCountry.kt diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/PrisonApiClient.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/PrisonApiClient.kt index 4f6e45e..1651d9e 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/PrisonApiClient.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/PrisonApiClient.kt @@ -5,6 +5,7 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.service.annotation.HttpExchange import org.springframework.web.service.annotation.PutExchange +import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.dto.UpdateBirthCountry import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateBirthPlace import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateNationality @@ -16,6 +17,12 @@ interface PrisonApiClient { @RequestBody updateBirthPlace: UpdateBirthPlace, ): ResponseEntity + @PutExchange("/{offenderNo}/birth-country") + fun updateBirthCountryForWorkingName( + @PathVariable offenderNo: String, + @RequestBody updateBirthCountry: UpdateBirthCountry, + ): ResponseEntity + @PutExchange("/{offenderNo}/nationality") fun updateNationalityForWorkingName( @PathVariable offenderNo: String, diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/request/UpdateBirthCountry.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/request/UpdateBirthCountry.kt new file mode 100644 index 0000000..e0d5dc4 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/client/request/UpdateBirthCountry.kt @@ -0,0 +1,9 @@ +package uk.gov.justice.digital.hmpps.personintegrationapi.common.client.dto + +import io.swagger.v3.oas.annotations.media.Schema + +@Schema(description = "Update to prisoner birth country") +data class UpdateBirthCountry( + @Schema(description = "Country code", example = "GBR", required = true, nullable = true) + val countryCode: String?, +) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/config/UserEnhancedOAuth2ClientCredentialGrantRequestConverter.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/config/UserEnhancedOAuth2ClientCredentialGrantRequestConverter.kt index 375dce6..f363493 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/config/UserEnhancedOAuth2ClientCredentialGrantRequestConverter.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/common/config/UserEnhancedOAuth2ClientCredentialGrantRequestConverter.kt @@ -7,7 +7,7 @@ import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentia import org.springframework.util.MultiValueMap import java.util.Objects -@SuppressWarnings("unchecked") +@Suppress("UNCHECKED_CAST") class UserEnhancedOAuth2ClientCredentialGrantRequestConverter : OAuth2ClientCredentialsGrantRequestEntityConverter() { diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordService.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordService.kt index ec9600a..86bc6cc 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordService.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordService.kt @@ -4,11 +4,13 @@ import org.springframework.http.ResponseEntity import org.springframework.stereotype.Service import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.PrisonApiClient import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.ReferenceDataClient +import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.dto.UpdateBirthCountry import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateBirthPlace import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateNationality import uk.gov.justice.digital.hmpps.personintegrationapi.common.dto.ReferenceDataCodeDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.BirthplaceUpdateDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.CorePersonRecordV1UpdateRequestDto +import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.CountryOfBirthUpdateDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.NationalityUpdateDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.exception.UnknownCorePersonFieldException @@ -25,6 +27,11 @@ class CorePersonRecordService( UpdateBirthPlace(updateRequestDto.value), ) + is CountryOfBirthUpdateDto -> prisonApiClient.updateBirthCountryForWorkingName( + prisonerNumber, + UpdateBirthCountry(updateRequestDto.value), + ) + is NationalityUpdateDto -> prisonApiClient.updateNationalityForWorkingName( prisonerNumber, UpdateNationality(updateRequestDto.value), diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/resource/CorePersonRecordV1ResourceIntTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/resource/CorePersonRecordV1ResourceIntTest.kt index 78a2ee4..be92513 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/resource/CorePersonRecordV1ResourceIntTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/resource/CorePersonRecordV1ResourceIntTest.kt @@ -51,40 +51,39 @@ class CorePersonRecordV1ResourceIntTest : IntegrationTestBase() { @Test fun `can patch core person record birthplace by prisoner number`() { - webTestClient.patch().uri("/v1/core-person-record?prisonerNumber=$PRISONER_NUMBER") - .contentType(MediaType.APPLICATION_JSON) - .headers(setAuthorisation(roles = listOf(CorePersonRecordRoleConstants.CORE_PERSON_RECORD_READ_WRITE_ROLE))) - .bodyValue(BIRTHPLACE_PATCH_REQUEST_BODY) - .exchange() - .expectStatus().isNoContent + expectSuccessfulRequestWith(BIRTHPLACE_PATCH_REQUEST_BODY) } @Test fun `patch core person record birthplace accepts null value`() { - webTestClient.patch().uri("/v1/core-person-record?prisonerNumber=$PRISONER_NUMBER") - .contentType(MediaType.APPLICATION_JSON) - .headers(setAuthorisation(roles = listOf(CorePersonRecordRoleConstants.CORE_PERSON_RECORD_READ_WRITE_ROLE))) - .bodyValue(NULL_BIRTHPLACE_PATCH_REQUEST_BODY) - .exchange() - .expectStatus().isNoContent + expectSuccessfulRequestWith(NULL_BIRTHPLACE_PATCH_REQUEST_BODY) + } + + @Test + fun `can patch core person record country of birth by prisoner number`() { + expectSuccessfulRequestWith(COUNTRY_OF_BIRTH_PATCH_REQUEST_BODY) + } + + @Test + fun `patch core person record country of birth accepts null value`() { + expectSuccessfulRequestWith(NULL_COUNTRY_OF_BIRTH_PATCH_REQUEST_BODY) } @Test fun `can patch core person record nationality by prisoner number`() { - webTestClient.patch().uri("/v1/core-person-record?prisonerNumber=$PRISONER_NUMBER") - .contentType(MediaType.APPLICATION_JSON) - .headers(setAuthorisation(roles = listOf(CorePersonRecordRoleConstants.CORE_PERSON_RECORD_READ_WRITE_ROLE))) - .bodyValue(NATIONALITY_PATCH_REQUEST_BODY) - .exchange() - .expectStatus().isNoContent + expectSuccessfulRequestWith(NATIONALITY_PATCH_REQUEST_BODY) } @Test fun `patch core person record nationality accepts null value`() { + expectSuccessfulRequestWith(NULL_NATIONALITY_PATCH_REQUEST_BODY) + } + + private fun expectSuccessfulRequestWith(body: Any) { webTestClient.patch().uri("/v1/core-person-record?prisonerNumber=$PRISONER_NUMBER") .contentType(MediaType.APPLICATION_JSON) .headers(setAuthorisation(roles = listOf(CorePersonRecordRoleConstants.CORE_PERSON_RECORD_READ_WRITE_ROLE))) - .bodyValue(NULL_NATIONALITY_PATCH_REQUEST_BODY) + .bodyValue(body) .exchange() .expectStatus().isNoContent } @@ -217,6 +216,24 @@ class CorePersonRecordV1ResourceIntTest : IntegrationTestBase() { } """.trimIndent() + val COUNTRY_OF_BIRTH_PATCH_REQUEST_BODY = + // language=json + """ + { + "fieldName": "COUNTRY_OF_BIRTH", + "value": "London" + } + """.trimIndent() + + val NULL_COUNTRY_OF_BIRTH_PATCH_REQUEST_BODY = + // language=json + """ + { + "fieldName": "BIRTHPLACE", + "value": null + } + """.trimIndent() + val NATIONALITY_PATCH_REQUEST_BODY = // language=json """ diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordServiceTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordServiceTest.kt index 970da1f..e6e8ee5 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordServiceTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/corepersonrecord/service/CorePersonRecordServiceTest.kt @@ -18,11 +18,13 @@ import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.PrisonApiClient import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.ReferenceDataClient +import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.dto.UpdateBirthCountry import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateBirthPlace import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.request.UpdateNationality import uk.gov.justice.digital.hmpps.personintegrationapi.common.client.response.ReferenceDataCode import uk.gov.justice.digital.hmpps.personintegrationapi.common.dto.ReferenceDataCodeDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.BirthplaceUpdateDto +import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.CountryOfBirthUpdateDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.DateOfBirthUpdateDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.dto.v1.request.NationalityUpdateDto import uk.gov.justice.digital.hmpps.personintegrationapi.corepersonrecord.exception.UnknownCorePersonFieldException @@ -51,6 +53,8 @@ class CorePersonRecordServiceTest { fun beforeEach() { whenever(prisonApiClient.updateBirthPlaceForWorkingName(PRISONER_NUMBER, TEST_BIRTHPLACE_BODY)) .thenReturn(ResponseEntity.noContent().build()) + whenever(prisonApiClient.updateBirthCountryForWorkingName(PRISONER_NUMBER, TEST_COUNTRY_OF_BIRTH_BODY)) + .thenReturn(ResponseEntity.noContent().build()) whenever(prisonApiClient.updateNationalityForWorkingName(PRISONER_NUMBER, TEST_NATIONALITY_BODY)) .thenReturn(ResponseEntity.noContent().build()) } @@ -60,6 +64,11 @@ class CorePersonRecordServiceTest { underTest.updateCorePersonRecordField(PRISONER_NUMBER, BirthplaceUpdateDto(TEST_BIRTHPLACE_VALUE)) } + @Test + fun `can update the country of birth field`() { + underTest.updateCorePersonRecordField(PRISONER_NUMBER, CountryOfBirthUpdateDto(TEST_COUNTRY_OF_BIRTH_VALUE)) + } + @Test fun `can update the nationality field`() { underTest.updateCorePersonRecordField(PRISONER_NUMBER, NationalityUpdateDto(TEST_NATIONALITY_VALUE)) @@ -113,8 +122,10 @@ class CorePersonRecordServiceTest { private companion object { const val PRISONER_NUMBER = "A1234AA" const val TEST_BIRTHPLACE_VALUE = "London" + const val TEST_COUNTRY_OF_BIRTH_VALUE = "ENG" const val TEST_NATIONALITY_VALUE = "BRIT" val TEST_BIRTHPLACE_BODY = UpdateBirthPlace("London") + val TEST_COUNTRY_OF_BIRTH_BODY = UpdateBirthCountry("ENG") val TEST_NATIONALITY_BODY = UpdateNationality("BRIT") } } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/integration/wiremock/PrisonApiMockServer.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/integration/wiremock/PrisonApiMockServer.kt index 05c8004..b44a01e 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/integration/wiremock/PrisonApiMockServer.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/personintegrationapi/integration/wiremock/PrisonApiMockServer.kt @@ -65,6 +65,18 @@ class PrisonApiMockServer : WireMockServer(8082) { ) } + fun stubUpdateBirthCountryForWorkingName() { + val endpoint = "birth-country" + stubOffenderEndpoint(endpoint, HttpStatus.NO_CONTENT, PRISONER_NUMBER) + stubOffenderEndpoint(endpoint, HttpStatus.INTERNAL_SERVER_ERROR, PRISONER_NUMBER_THROW_EXCEPTION) + stubOffenderEndpoint( + endpoint, + HttpStatus.NOT_FOUND, + PRISONER_NUMBER_NOT_FOUND, + PRISON_API_NOT_FOUND_RESPONSE.trimIndent(), + ) + } + fun stubUpdateNationalityForWorkingName() { val endpoint = "nationality" stubOffenderEndpoint(endpoint, HttpStatus.NO_CONTENT, PRISONER_NUMBER) @@ -108,6 +120,7 @@ class PrisonApiExtension : BeforeAllCallback, AfterAllCallback, BeforeEachCallba override fun beforeEach(context: ExtensionContext) { prisonApi.resetAll() prisonApi.stubUpdateBirthPlaceForWorkingName() + prisonApi.stubUpdateBirthCountryForWorkingName() prisonApi.stubUpdateNationalityForWorkingName() prisonApi.stubReferenceDataCodes() }