From 17573b5c4a7d03afefbf98e9f05a1006a8682fff Mon Sep 17 00:00:00 2001 From: davidatkinsuk Date: Tue, 24 Sep 2024 08:04:29 +0100 Subject: [PATCH] Add CAS1 CRU Management Area to User API Model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds CRU Management Area fields to the ApprovedPremisesUser API Model to support: * Determining which CRU Management Area the user is in (when retrieved via /profile/v2) * Logic to determine/set/get override configuration for the user management page This commit is quite large because i had fix existing test data where entries in the users table were created for CAS1 testing and the CRU Management Area was not set, something which wouldn’t be the case in production (it’s logically mandatory for CAS1 users) --- .../jpa/entity/UserEntity.kt | 1 - .../transformer/UserTransformer.kt | 41 ++++++++++++------- src/main/resources/static/_shared.yml | 14 +++++++ .../static/codegen/built-api-spec.yml | 14 +++++++ .../static/codegen/built-cas1-api-spec.yml | 14 +++++++ .../static/codegen/built-cas2-api-spec.yml | 14 +++++++ .../static/codegen/built-cas3-api-spec.yml | 14 +++++++ .../factory/UserEntityFactory.kt | 8 ++++ .../events/ApprovedPremisesUserFactory.kt | 11 +++++ .../integration/PersonalTimelineTest.kt | 35 +++++++++++++--- .../integration/PlacementRequestsTest.kt | 10 ++--- .../integration/ProfileTest.kt | 19 +++++++++ .../integration/UsersTest.kt | 16 +++++--- ...s1PlacementMatchingOutcomesV2ReportTest.kt | 5 ++- .../givens/GivenACas1CruManagementArea.kt | 2 +- .../givens/GivenAPlacementApplication.kt | 11 ++--- .../integration/givens/GivenAUser.kt | 19 ++++----- .../integration/givens/GivenAnApArea.kt | 2 +- .../unit/transformer/UserTransformerTest.kt | 30 +++++++++++++- 19 files changed, 221 insertions(+), 59 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/UserEntity.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/UserEntity.kt index baae3e8ba6f..9a9354158ae 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/UserEntity.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/jpa/entity/UserEntity.kt @@ -315,7 +315,6 @@ data class UserEntity( ) { fun hasRole(userRole: UserRole) = roles.any { it.role == userRole } fun hasAnyRole(vararg userRoles: UserRole) = userRoles.any(::hasRole) - fun hasAnyRole(userRoles: List) = userRoles.any(::hasRole) fun hasQualification(userQualification: UserQualification) = qualifications.any { it.qualification === userQualification } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/UserTransformer.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/UserTransformer.kt index 98f047d42cf..364359a889d 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/UserTransformer.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/transformer/UserTransformer.kt @@ -3,12 +3,14 @@ package uk.gov.justice.digital.hmpps.approvedpremisesapi.transformer import org.springframework.stereotype.Component import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUser import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUserRole +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.NamedId import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ProfileResponse import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ServiceName import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.TemporaryAccommodationUser import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.TemporaryAccommodationUserRole import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.UserSummary import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.UserWithWorkload +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.Cas1CruManagementAreaEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserPermission import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserQualification @@ -54,21 +56,28 @@ class UserTransformer( ) fun transformJpaToApi(jpa: UserEntity, serviceName: ServiceName) = when (serviceName) { - ServiceName.approvedPremises -> ApprovedPremisesUser( - id = jpa.id, - deliusUsername = jpa.deliusUsername, - roles = jpa.roles.distinctBy { it.role }.mapNotNull(::transformApprovedPremisesRoleToApi), - email = jpa.email, - name = jpa.name, - telephoneNumber = jpa.telephoneNumber, - isActive = jpa.isActive, - qualifications = jpa.qualifications.map(::transformQualificationToApi), - permissions = jpa.roles.distinctBy { it.role }.mapNotNull(::transformApprovedPremisesRoleToPermissionApi).flatten().distinct(), - region = probationRegionTransformer.transformJpaToApi(jpa.probationRegion), - service = "CAS1", - apArea = jpa.apArea?.let { apAreaTransformer.transformJpaToApi(it) } ?: throw InternalServerErrorProblem("CAS1 user ${jpa.id} should have AP Area Set"), - version = UserEntity.getVersionHashCode((jpa.roles.map { it.role })), - ) + ServiceName.approvedPremises -> { + val apArea = jpa.apArea ?: throw InternalServerErrorProblem("CAS1 user ${jpa.id} should have AP Area Set") + val cruManagementArea = jpa.cruManagementArea ?: throw InternalServerErrorProblem("CAS1 user ${jpa.id} should have CRU Management Area Set") + ApprovedPremisesUser( + id = jpa.id, + deliusUsername = jpa.deliusUsername, + roles = jpa.roles.distinctBy { it.role }.mapNotNull(::transformApprovedPremisesRoleToApi), + email = jpa.email, + name = jpa.name, + telephoneNumber = jpa.telephoneNumber, + isActive = jpa.isActive, + qualifications = jpa.qualifications.map(::transformQualificationToApi), + permissions = jpa.roles.distinctBy { it.role }.map(::transformApprovedPremisesRoleToPermissionApi).flatten().distinct(), + region = probationRegionTransformer.transformJpaToApi(jpa.probationRegion), + service = "CAS1", + apArea = apArea.let { apAreaTransformer.transformJpaToApi(it) }, + cruManagementArea = cruManagementArea.toNamedId(), + cruManagementAreaDefault = apArea.defaultCruManagementArea.toNamedId(), + cruManagementAreaOverride = jpa.cruManagementAreaOverride?.toNamedId(), + version = UserEntity.getVersionHashCode((jpa.roles.map { it.role })), + ) + } ServiceName.temporaryAccommodation -> TemporaryAccommodationUser( id = jpa.id, deliusUsername = jpa.deliusUsername, @@ -84,6 +93,8 @@ class UserTransformer( ServiceName.cas2 -> throw RuntimeException("CAS2 not supported") } + fun Cas1CruManagementAreaEntity.toNamedId() = NamedId(id, name) + fun transformProfileResponseToApi(userName: String, userResponse: UserService.GetUserResponse, xServiceName: ServiceName): ProfileResponse { return when (userResponse) { UserService.GetUserResponse.StaffRecordNotFound -> ProfileResponse(userName, ProfileResponse.LoadError.staffRecordNotFound) diff --git a/src/main/resources/static/_shared.yml b/src/main/resources/static/_shared.yml index 262af612148..3feda899f61 100644 --- a/src/main/resources/static/_shared.yml +++ b/src/main/resources/static/_shared.yml @@ -3075,12 +3075,26 @@ components: $ref: '#/components/schemas/ApprovedPremisesUserPermission' apArea: $ref: '#/components/schemas/ApArea' + cruManagementArea: + description: CRU Management Area to use. This will be the same as cruManagementAreaDefault unless cruManagementAreaOverride is defined + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaDefault: + description: The CRU Management Area used if no override is defined. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaOverride: + description: The CRU Management Area manually set on this user. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" version: type: integer required: - qualifications - roles - apArea + - cruManagementArea + - cruManagementAreaDefault UserRolesAndQualifications: type: object properties: diff --git a/src/main/resources/static/codegen/built-api-spec.yml b/src/main/resources/static/codegen/built-api-spec.yml index a5396a0f09e..a29a803b87b 100644 --- a/src/main/resources/static/codegen/built-api-spec.yml +++ b/src/main/resources/static/codegen/built-api-spec.yml @@ -7543,12 +7543,26 @@ components: $ref: '#/components/schemas/ApprovedPremisesUserPermission' apArea: $ref: '#/components/schemas/ApArea' + cruManagementArea: + description: CRU Management Area to use. This will be the same as cruManagementAreaDefault unless cruManagementAreaOverride is defined + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaDefault: + description: The CRU Management Area used if no override is defined. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaOverride: + description: The CRU Management Area manually set on this user. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" version: type: integer required: - qualifications - roles - apArea + - cruManagementArea + - cruManagementAreaDefault UserRolesAndQualifications: type: object properties: diff --git a/src/main/resources/static/codegen/built-cas1-api-spec.yml b/src/main/resources/static/codegen/built-cas1-api-spec.yml index c8f76cffe18..eaadec62391 100644 --- a/src/main/resources/static/codegen/built-cas1-api-spec.yml +++ b/src/main/resources/static/codegen/built-cas1-api-spec.yml @@ -4121,12 +4121,26 @@ components: $ref: '#/components/schemas/ApprovedPremisesUserPermission' apArea: $ref: '#/components/schemas/ApArea' + cruManagementArea: + description: CRU Management Area to use. This will be the same as cruManagementAreaDefault unless cruManagementAreaOverride is defined + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaDefault: + description: The CRU Management Area used if no override is defined. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaOverride: + description: The CRU Management Area manually set on this user. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" version: type: integer required: - qualifications - roles - apArea + - cruManagementArea + - cruManagementAreaDefault UserRolesAndQualifications: type: object properties: diff --git a/src/main/resources/static/codegen/built-cas2-api-spec.yml b/src/main/resources/static/codegen/built-cas2-api-spec.yml index 63a02537dd3..05534a52135 100644 --- a/src/main/resources/static/codegen/built-cas2-api-spec.yml +++ b/src/main/resources/static/codegen/built-cas2-api-spec.yml @@ -3666,12 +3666,26 @@ components: $ref: '#/components/schemas/ApprovedPremisesUserPermission' apArea: $ref: '#/components/schemas/ApArea' + cruManagementArea: + description: CRU Management Area to use. This will be the same as cruManagementAreaDefault unless cruManagementAreaOverride is defined + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaDefault: + description: The CRU Management Area used if no override is defined. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaOverride: + description: The CRU Management Area manually set on this user. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" version: type: integer required: - qualifications - roles - apArea + - cruManagementArea + - cruManagementAreaDefault UserRolesAndQualifications: type: object properties: diff --git a/src/main/resources/static/codegen/built-cas3-api-spec.yml b/src/main/resources/static/codegen/built-cas3-api-spec.yml index 068453fff3d..34f095c4385 100644 --- a/src/main/resources/static/codegen/built-cas3-api-spec.yml +++ b/src/main/resources/static/codegen/built-cas3-api-spec.yml @@ -3166,12 +3166,26 @@ components: $ref: '#/components/schemas/ApprovedPremisesUserPermission' apArea: $ref: '#/components/schemas/ApArea' + cruManagementArea: + description: CRU Management Area to use. This will be the same as cruManagementAreaDefault unless cruManagementAreaOverride is defined + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaDefault: + description: The CRU Management Area used if no override is defined. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" + cruManagementAreaOverride: + description: The CRU Management Area manually set on this user. This is provided to support the user configuration page. + allOf: + - $ref: "#/components/schemas/NamedId" version: type: integer required: - qualifications - roles - apArea + - cruManagementArea + - cruManagementAreaDefault UserRolesAndQualifications: type: object properties: diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/UserEntityFactory.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/UserEntityFactory.kt index f1de94241bf..c1423117636 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/UserEntityFactory.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/UserEntityFactory.kt @@ -150,6 +150,14 @@ class UserEntityFactory : Factory { this.apArea = { apArea } } + fun withCruManagementArea(cruManagementArea: Cas1CruManagementAreaEntity?) = apply { + this.cruManagementArea = { cruManagementArea } + } + + fun withCruManagementAreaOverride(cruManagementAreaOverride: Cas1CruManagementAreaEntity?) = apply { + this.cruManagementAreaOverride = { cruManagementAreaOverride } + } + fun withTeamCodes(teamCodes: List) = apply { this.teamCodes = { teamCodes } } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/events/ApprovedPremisesUserFactory.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/events/ApprovedPremisesUserFactory.kt index 9b4d19f00b9..ca3fbe11988 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/events/ApprovedPremisesUserFactory.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/factory/events/ApprovedPremisesUserFactory.kt @@ -5,6 +5,7 @@ import io.github.bluegroundltd.kfactory.Yielded import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApArea import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUser import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUserRole +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.NamedId import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ProbationRegion import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.UserQualification import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.randomStringMultiCaseWithNumbers @@ -21,6 +22,13 @@ class ApprovedPremisesUserFactory : Factory { randomStringMultiCaseWithNumbers(20), ) } + private var cruManagementArea: Yielded = { + NamedId(UUID.randomUUID(), randomStringUpperCase(6)) + } + private var cruManagementAreaDefault: Yielded = { + NamedId(UUID.randomUUID(), randomStringUpperCase(6)) + } + private var cruManagementAreaOverride: Yielded = { null } private var service: Yielded = { randomStringMultiCaseWithNumbers(10) } private var id: Yielded = { UUID.randomUUID() } private var name: Yielded = { randomStringMultiCaseWithNumbers(20) } @@ -83,6 +91,9 @@ class ApprovedPremisesUserFactory : Factory { qualifications = this.qualifications(), roles = this.roles(), apArea = this.apArea(), + cruManagementArea = this.cruManagementArea(), + cruManagementAreaDefault = this.cruManagementAreaDefault(), + cruManagementAreaOverride = this.cruManagementAreaOverride(), service = this.service(), id = this.id(), name = this.name(), diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PersonalTimelineTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PersonalTimelineTest.kt index 6badebf9f19..5b371be44a6 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PersonalTimelineTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PersonalTimelineTest.kt @@ -9,6 +9,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApArea import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApplicationTimeline import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesApplicationStatus import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUser +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.NamedId import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.PersonalTimeline import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ProbationRegion import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.TimelineEvent @@ -133,6 +134,8 @@ class PersonalTimelineTest : IntegrationTestBase() { inmateDetail = inmateDetails, ) + val apArea = userEntity.apArea!! + webTestClient.get() .uri("/people/${offenderDetails.otherIds.crn}/timeline") .header("Authorization", "Bearer $jwt") @@ -155,9 +158,9 @@ class PersonalTimelineTest : IntegrationTestBase() { roles = emptyList(), permissions = emptyList(), apArea = ApArea( - id = userEntity.apArea!!.id, - identifier = userEntity.apArea!!.identifier, - name = userEntity.apArea!!.name, + id = apArea.id, + identifier = apArea.identifier, + name = apArea.name, ), service = "CAS1", id = userEntity.id, @@ -171,6 +174,15 @@ class PersonalTimelineTest : IntegrationTestBase() { telephoneNumber = userEntity.telephoneNumber, isActive = userEntity.isActive, version = 993, + cruManagementArea = NamedId( + id = userEntity.cruManagementArea!!.id, + name = userEntity.cruManagementArea!!.name, + ), + cruManagementAreaDefault = NamedId( + id = apArea.defaultCruManagementArea.id, + name = apArea.defaultCruManagementArea.name, + ), + cruManagementAreaOverride = null, ), timelineEvents = listOf( TimelineEvent( @@ -259,6 +271,8 @@ class PersonalTimelineTest : IntegrationTestBase() { inmateDetail = null, ) + val apArea = userEntity.apArea!! + webTestClient.get() .uri("/people/${offenderDetails.otherIds.crn}/timeline") .header("Authorization", "Bearer $jwt") @@ -281,9 +295,9 @@ class PersonalTimelineTest : IntegrationTestBase() { roles = emptyList(), permissions = emptyList(), apArea = ApArea( - id = userEntity.apArea!!.id, - identifier = userEntity.apArea!!.identifier, - name = userEntity.apArea!!.name, + id = apArea.id, + identifier = apArea.identifier, + name = apArea.name, ), service = "CAS1", id = userEntity.id, @@ -297,6 +311,15 @@ class PersonalTimelineTest : IntegrationTestBase() { telephoneNumber = userEntity.telephoneNumber, isActive = userEntity.isActive, version = 993, + cruManagementArea = NamedId( + id = userEntity.cruManagementArea!!.id, + name = userEntity.cruManagementArea!!.name, + ), + cruManagementAreaDefault = NamedId( + id = apArea.defaultCruManagementArea.id, + name = apArea.defaultCruManagementArea.name, + ), + cruManagementAreaOverride = null, ), timelineEvents = listOf( TimelineEvent( diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PlacementRequestsTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PlacementRequestsTest.kt index 5cda14a1ddb..30c3b534764 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PlacementRequestsTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/PlacementRequestsTest.kt @@ -17,13 +17,13 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.WithdrawPlacem import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.WithdrawPlacementRequestReason import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.CaseAccessFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.PersonRisksFactory +import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a CAS1 CRU Management Area` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a Placement Application` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a Placement Request` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a Probation Region` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a User` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an AP Area` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an Application` -import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an CAS1 CRU Management Area` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an Offender` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.httpmocks.ApDeliusContext_addResponseToUserAccessCall import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.httpmocks.CommunityAPI_mockOffenderUserAccessCall @@ -652,8 +652,8 @@ class PlacementRequestsTest : IntegrationTestBase() { `Given a User`(roles = listOf(UserRole.CAS1_WORKFLOW_MANAGER)) { user, jwt -> `Given an Offender` { offenderDetails, inmateDetails -> - val cruArea1 = `Given an CAS1 CRU Management Area`() - val cruArea2 = `Given an CAS1 CRU Management Area`() + val cruArea1 = `Given a CAS1 CRU Management Area`() + val cruArea2 = `Given a CAS1 CRU Management Area`() createPlacementRequest(offenderDetails, user, cruManagementArea = cruArea1) val placementRequestA1 = createPlacementRequest(offenderDetails, user, cruManagementArea = cruArea2) @@ -783,8 +783,8 @@ class PlacementRequestsTest : IntegrationTestBase() { `Given an Offender` { offender1Details, inmate1Details -> `Given an Offender` { offender2Details, _ -> - val cruArea1 = `Given an CAS1 CRU Management Area`() - val cruArea2 = `Given an CAS1 CRU Management Area`() + val cruArea1 = `Given a CAS1 CRU Management Area`() + val cruArea2 = `Given a CAS1 CRU Management Area`() createPlacementRequest(offender1Details, user, expectedArrival = LocalDate.of(2022, 1, 1), tier = RiskTierLevel.a2) createPlacementRequest(offender1Details, user, expectedArrival = LocalDate.of(2022, 1, 5), tier = RiskTierLevel.a1) diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ProfileTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ProfileTest.kt index 60462c2f4a3..6afc1d57d0c 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ProfileTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/ProfileTest.kt @@ -10,6 +10,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApArea import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUser import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUserPermission import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ApprovedPremisesUserRole +import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.NamedId import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ProbationRegion import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ProfileResponse import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.ServiceName @@ -78,6 +79,15 @@ class ProfileTest : IntegrationTestBase() { service = "CAS1", isActive = true, apArea = ApArea(userApArea.id, userApArea.identifier, userApArea.name), + cruManagementArea = NamedId( + id = userEntity.cruManagementArea!!.id, + name = userEntity.cruManagementArea!!.name, + ), + cruManagementAreaDefault = NamedId( + id = userApArea.defaultCruManagementArea.id, + name = userApArea.defaultCruManagementArea.name, + ), + cruManagementAreaOverride = null, permissions = listOf( ApprovedPremisesUserPermission.assessApplication, ApprovedPremisesUserPermission.assessAppealedApplication, @@ -290,6 +300,15 @@ class ProfileTest : IntegrationTestBase() { service = "CAS1", isActive = true, apArea = ApArea(userApArea.id, userApArea.identifier, userApArea.name), + cruManagementArea = NamedId( + id = userEntity.cruManagementArea!!.id, + name = userEntity.cruManagementArea!!.name, + ), + cruManagementAreaDefault = NamedId( + id = userApArea.defaultCruManagementArea.id, + name = userApArea.defaultCruManagementArea.name, + ), + cruManagementAreaOverride = null, permissions = listOf( ApprovedPremisesUserPermission.assessApplication, ApprovedPremisesUserPermission.assessAppealedApplication, diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/UsersTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/UsersTest.kt index 8bbac1c2c4b..a58faebfb19 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/UsersTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/UsersTest.kt @@ -17,6 +17,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.TemporaryAccom import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.UserRolesAndQualifications import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.StaffUserDetailsFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.StaffUserTeamMembershipFactory +import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a CAS1 CRU Management Area` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a Probation Region` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a User` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an AP Area` @@ -429,11 +430,13 @@ class UsersTest : InitialiseDatabasePerClassTestBase() { val userOne = userEntityFactory.produceAndPersist { withProbationRegion(probationRegion) withApArea(apArea) + withCruManagementArea(`Given a CAS1 CRU Management Area`()) } val userTwo = userEntityFactory.produceAndPersist { withProbationRegion(probationRegion) withApArea(apArea) + withCruManagementArea(`Given a CAS1 CRU Management Area`()) } webTestClient.get() @@ -478,11 +481,13 @@ class UsersTest : InitialiseDatabasePerClassTestBase() { val userOne = userEntityFactory.produceAndPersist { withProbationRegion(probationRegion) withApArea(apArea) + withCruManagementArea(`Given a CAS1 CRU Management Area`()) } val userTwo = userEntityFactory.produceAndPersist { withProbationRegion(probationRegion) withApArea(apArea) + withCruManagementArea(`Given a CAS1 CRU Management Area`()) } webTestClient.get() @@ -1193,12 +1198,11 @@ class UsersTest : InitialiseDatabasePerClassTestBase() { ) val region = `Given a Probation Region`() - userEntityFactory.produceAndPersist { - withId(id) - withIsActive(false) - withYieldedProbationRegion { region } - withYieldedApArea { `Given an AP Area`() } - } + `Given a User`( + id = id, + isActive = false, + probationRegion = region, + ) `Given a User`(roles = listOf(role)) { _, jwt -> webTestClient.put() diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PlacementMatchingOutcomesV2ReportTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PlacementMatchingOutcomesV2ReportTest.kt index 686793c9b39..f2774d5c3e0 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PlacementMatchingOutcomesV2ReportTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/cas1/Cas1PlacementMatchingOutcomesV2ReportTest.kt @@ -43,6 +43,7 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.cas1.Cas1Pla import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.cas1.Cas1PlacementMatchingOutcomesV2ReportTest.Constants.REPORT_YEAR import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a Probation Region` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given a User` +import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an AP Area` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens.`Given an Offender` import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.httpmocks.APDeliusContext_mockSuccessfulCaseDetailCall import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.httpmocks.GovUKBankHolidaysAPI_mockSuccessfullCallWithEmptyResponse @@ -450,7 +451,7 @@ class Cas1PlacementMatchingOutcomesV2ReportTest : InitialiseDatabasePerClassTest staffUserDetailsConfigBlock = { withUsername(matcherUsername) }, - apAreaName = matcherApAreaName, + probationRegion = `Given a Probation Region`(apArea = `Given an AP Area`(name = matcherApAreaName)), ).second val premises = approvedPremisesEntityFactory.produceAndPersist { @@ -481,7 +482,7 @@ class Cas1PlacementMatchingOutcomesV2ReportTest : InitialiseDatabasePerClassTest staffUserDetailsConfigBlock = { withUsername(matcherUsername) }, - apAreaName = matcherApAreaName, + probationRegion = `Given a Probation Region`(apArea = `Given an AP Area`(name = matcherApAreaName)), ).second cas1SimpleApiClient.placementRequestBookingNotMade( diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenACas1CruManagementArea.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenACas1CruManagementArea.kt index c36ed9ba0cb..dc54d6982a6 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenACas1CruManagementArea.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenACas1CruManagementArea.kt @@ -3,6 +3,6 @@ package uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.givens import uk.gov.justice.digital.hmpps.approvedpremisesapi.integration.IntegrationTestBase import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.Cas1CruManagementAreaEntity -fun IntegrationTestBase.`Given an CAS1 CRU Management Area`(): Cas1CruManagementAreaEntity { +fun IntegrationTestBase.`Given a CAS1 CRU Management Area`(): Cas1CruManagementAreaEntity { return cas1CruManagementAreaEntityFactory.produceAndPersist() } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAPlacementApplication.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAPlacementApplication.kt index 69f42073ed1..15f4271a86f 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAPlacementApplication.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAPlacementApplication.kt @@ -35,14 +35,9 @@ fun IntegrationTestBase.`Given a Placement Application`( ): PlacementApplicationEntity { val userApArea = `Given an AP Area`() - val assessmentAllocatedToUser = userEntityFactory.produceAndPersist { - withYieldedProbationRegion { - probationRegionEntityFactory.produceAndPersist { - withApArea(userApArea) - } - } - withApArea(userApArea) - } + val (assessmentAllocatedToUser) = `Given a User`( + probationRegion = `Given a Probation Region`(apArea = userApArea), + ) val assessmentCreatedByUser = userEntityFactory.produceAndPersist { withYieldedProbationRegion { diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAUser.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAUser.kt index cf096e1d923..dc306f8e8d8 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAUser.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAUser.kt @@ -13,7 +13,6 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ProbationRegi import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserQualification import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRole -import uk.gov.justice.digital.hmpps.approvedpremisesapi.util.randomStringMultiCaseWithNumbers import java.util.UUID @SuppressWarnings("LongParameterList") @@ -25,7 +24,6 @@ fun IntegrationTestBase.`Given a User`( probationRegion: ProbationRegionEntity? = null, isActive: Boolean = true, mockStaffUserDetailsCall: Boolean = true, - apAreaName: String = randomStringMultiCaseWithNumbers(8), ): Pair { val staffUserDetailsFactory = StaffUserDetailsFactory() @@ -35,10 +33,10 @@ fun IntegrationTestBase.`Given a User`( val staffUserDetails = staffUserDetailsFactory.produce() - val yieldedProbationRegion = probationRegion - ?: probationRegionEntityFactory.produceAndPersist { - withYieldedApArea { `Given an AP Area`(name = apAreaName) } - } + val resolvedProbationRegion = probationRegion ?: probationRegionEntityFactory.produceAndPersist { + withYieldedApArea { `Given an AP Area`() } + } + val apArea = resolvedProbationRegion.apArea!! val user = userEntityFactory.produceAndPersist { withId(id) @@ -48,12 +46,9 @@ fun IntegrationTestBase.`Given a User`( withTelephoneNumber(staffUserDetails.telephoneNumber) withName("${staffUserDetails.staff.forenames} ${staffUserDetails.staff.surname}") withIsActive(isActive) - withYieldedProbationRegion { - yieldedProbationRegion - } - withYieldedApArea { - yieldedProbationRegion.apArea!! - } + withYieldedProbationRegion { resolvedProbationRegion } + withYieldedApArea { apArea } + withCruManagementArea(apArea.defaultCruManagementArea) } roles.forEach { role -> diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAnApArea.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAnApArea.kt index e2963fc59b5..1fdf69df7bc 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAnApArea.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/integration/givens/GivenAnApArea.kt @@ -17,6 +17,6 @@ fun IntegrationTestBase.`Given an AP Area`( if (emailAddress != null) { withEmailAddress(emailAddress) } - withDefaultCruManagementArea(`Given an CAS1 CRU Management Area`()) + withDefaultCruManagementArea(`Given a CAS1 CRU Management Area`()) } } diff --git a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/UserTransformerTest.kt b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/UserTransformerTest.kt index 5774b918dd2..c33d2f20f38 100644 --- a/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/UserTransformerTest.kt +++ b/src/test/kotlin/uk/gov/justice/digital/hmpps/approvedpremisesapi/unit/transformer/UserTransformerTest.kt @@ -43,7 +43,9 @@ import uk.gov.justice.digital.hmpps.approvedpremisesapi.api.model.UserWithWorklo import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ApAreaEntityFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.ProbationRegionEntityFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.UserEntityFactory +import uk.gov.justice.digital.hmpps.approvedpremisesapi.factory.cas1.Cas1CruManagementAreaEntityFactory import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.ApAreaEntity +import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.Cas1CruManagementAreaEntity import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRole import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRole.CAS1_APPEALS_MANAGER import uk.gov.justice.digital.hmpps.approvedpremisesapi.jpa.entity.UserRole.CAS1_JANITOR @@ -122,12 +124,20 @@ class UserTransformerTest { } @Test - fun `transformJpaToApi CAS1 Should successfully transfer user entity with role CAS1_MATCHER to matcher`() { - val apAreaEntity = ApAreaEntityFactory().produce() + fun `transformJpaToApi CAS1 should map successfully`() { + val cruManagementArea = Cas1CruManagementAreaEntityFactory().produce() + val defaultCruManagementArea = Cas1CruManagementAreaEntityFactory().produce() + val overriddenCruManagementArea = Cas1CruManagementAreaEntityFactory().produce() + + val apAreaEntity = ApAreaEntityFactory() + .withDefaultCruManagementArea(defaultCruManagementArea) + .produce() val user = buildUserEntity( role = CAS1_MATCHER, apArea = apAreaEntity, + cruManagementArea = cruManagementArea, + cruManagementAreaOverride = overriddenCruManagementArea, ) every { apAreaTransformer.transformJpaToApi(apAreaEntity) } returns apArea @@ -138,6 +148,12 @@ class UserTransformerTest { assertThat(result.service).isEqualTo("CAS1") verify(exactly = 1) { probationRegionTransformer.transformJpaToApi(any()) } assertThat(result.apArea).isEqualTo(apArea) + assertThat(result.cruManagementArea.id).isEqualTo(cruManagementArea.id) + assertThat(result.cruManagementArea.name).isEqualTo(cruManagementArea.name) + assertThat(result.cruManagementAreaDefault.id).isEqualTo(defaultCruManagementArea.id) + assertThat(result.cruManagementAreaDefault.name).isEqualTo(defaultCruManagementArea.name) + assertThat(result.cruManagementAreaOverride!!.id).isEqualTo(overriddenCruManagementArea.id) + assertThat(result.cruManagementAreaOverride!!.name).isEqualTo(overriddenCruManagementArea.name) } @Test @@ -145,6 +161,7 @@ class UserTransformerTest { val user = buildUserEntity( role = CAS1_MATCHER, apArea = ApAreaEntityFactory().produce(), + cruManagementArea = Cas1CruManagementAreaEntityFactory().produce(), ) user.addRoleForUnitTest(CAS1_MATCHER) user.addRoleForUnitTest(CAS1_MATCHER) @@ -172,6 +189,7 @@ class UserTransformerTest { val user = buildUserEntity( role = role, apArea = ApAreaEntityFactory().produce(), + cruManagementArea = Cas1CruManagementAreaEntityFactory().produce(), ) every { apAreaTransformer.transformJpaToApi(any()) } returns apArea @@ -209,6 +227,7 @@ class UserTransformerTest { val user = buildUserEntity( role = role, apArea = ApAreaEntityFactory().produce(), + cruManagementArea = Cas1CruManagementAreaEntityFactory().produce(), ) every { apAreaTransformer.transformJpaToApi(any()) } returns apArea @@ -224,6 +243,7 @@ class UserTransformerTest { val user = buildUserEntity( role = CAS1_JANITOR, apArea = ApAreaEntityFactory().produce(), + cruManagementArea = Cas1CruManagementAreaEntityFactory().produce(), ) user.addRoleForUnitTest(CAS1_APPEALS_MANAGER) @@ -260,6 +280,7 @@ class UserTransformerTest { val user = buildUserEntity( role = CAS1_JANITOR, apArea = ApAreaEntityFactory().produce(), + cruManagementArea = Cas1CruManagementAreaEntityFactory().produce(), ) every { apAreaTransformer.transformJpaToApi(any()) } returns apArea @@ -381,6 +402,7 @@ class UserTransformerTest { val user = buildUserEntity( role = CAS1_MATCHER, apArea = apAreaEntity, + cruManagementArea = Cas1CruManagementAreaEntityFactory().produce(), ) every { apAreaTransformer.transformJpaToApi(apAreaEntity) } returns apArea @@ -401,6 +423,8 @@ class UserTransformerTest { role: UserRole, apArea: ApAreaEntity? = null, updatedAt: OffsetDateTime? = null, + cruManagementArea: Cas1CruManagementAreaEntity? = null, + cruManagementAreaOverride: Cas1CruManagementAreaEntity? = null, ) = UserEntityFactory() .withId(randomUUID()) .withName("username") @@ -410,6 +434,8 @@ class UserTransformerTest { .withIsActive(true) .withProbationRegion(buildProbationRegionEntity()) .withApArea(apArea) + .withCruManagementArea(cruManagementArea) + .withCruManagementAreaOverride(cruManagementAreaOverride) .withUpdatedAt(updatedAt) .produce() .addRoleForUnitTest(role)