diff --git a/build.gradle b/build.gradle index fad90c64f8..e32d663a7f 100644 --- a/build.gradle +++ b/build.gradle @@ -324,6 +324,7 @@ sonarqube { "**/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/**/*.java," + "**/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java," + "**/uk/gov/hmcts/reform/pcs/ccd/domain/**/*.java," + + "**/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java," + "**/uk/gov/hmcts/reform/pcs/ccd/page/**/*.java," + "**/uk/gov/hmcts/reform/pcs/ccd/entity/**/*.java," + "**/entities/**," + "**/model/**," + "**/uk/gov/hmcts/reform/pcs/testingsupport/**/*.java" diff --git a/charts/pcs-api/values.ccd.preview.template.yaml b/charts/pcs-api/values.ccd.preview.template.yaml index 8006dddd18..fd85fd55a5 100644 --- a/charts/pcs-api/values.ccd.preview.template.yaml +++ b/charts/pcs-api/values.ccd.preview.template.yaml @@ -193,7 +193,7 @@ xui-webapp: SERVICES_CCD_DATA_STORE_API: http://${SERVICE_NAME}-ccd-data-store-api SERVICES_TERMS_AND_CONDITIONS: http://xui-terms-and-conditions-aat.service.core-compute-aat.internal SERVICES_HEARINGS_COMPONENT_API: http://jurisdiction-hearings-api-aat.service.core-compute-aat.internal - JURISDICTIONS: PCS + JURISDICTIONS: PCS,CIVIL FEATURE_REDIS_ENABLED: false REDISCLOUD_URL: http://dummyrediscloudurl FEATURE_APP_INSIGHTS_ENABLED: false diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java index 0c17c09c93..fa45b3062e 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java @@ -88,5 +88,10 @@ public void configure(final ConfigBuilder builder) { builder.tab("serviceRequest", "Service Request") .showCondition(ShowConditions.stateNotEquals(AWAITING_SUBMISSION_TO_HMCTS)) .field("waysToPay"); + + builder.tab("caseLinks", "Linked cases") + .forRoles(UserRole.PCS_SOLICITOR) + .field(PCSCase::getLinkedCasesComponentLauncher, null, "#ARGUMENT(LinkedCases)") + .field(PCSCase::getCaseLinks, "LinkedCasesComponentLauncher!=\"\"", "#ARGUMENT(LinkedCases)"); } } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java index bf3d8e6bbc..097cdb1ae0 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java @@ -8,8 +8,8 @@ import uk.gov.hmcts.ccd.sdk.type.AddressUK; import uk.gov.hmcts.ccd.sdk.type.Document; import uk.gov.hmcts.ccd.sdk.type.ListValue; -import uk.gov.hmcts.ccd.sdk.type.SearchCriteria; import uk.gov.hmcts.ccd.sdk.type.YesOrNo; +import uk.gov.hmcts.ccd.sdk.type.SearchCriteria; import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; import uk.gov.hmcts.reform.pcs.ccd.domain.Party; import uk.gov.hmcts.reform.pcs.ccd.domain.State; @@ -34,6 +34,7 @@ import uk.gov.hmcts.reform.pcs.ccd.view.RentDetailsView; import uk.gov.hmcts.reform.pcs.ccd.view.StatementOfTruthView; import uk.gov.hmcts.reform.pcs.ccd.view.TenancyLicenceView; +import uk.gov.hmcts.reform.pcs.ccd.view.CaseLinkView; import uk.gov.hmcts.reform.pcs.exception.CaseNotFoundException; import uk.gov.hmcts.reform.pcs.security.SecurityContextService; @@ -69,6 +70,7 @@ public class PCSCaseView implements CaseView { private final NoticeOfPossessionView noticeOfPossessionView; private final StatementOfTruthView statementOfTruthView; private final CaseNameHmctsFormatter caseNameHmctsFormatter; + private final CaseLinkView caseLinkView; /** @@ -129,6 +131,7 @@ private PCSCase getSubmittedCase(long caseReference) { rentArrearsView.setCaseFields(pcsCase, pcsCaseEntity); noticeOfPossessionView.setCaseFields(pcsCase, pcsCaseEntity); statementOfTruthView.setCaseFields(pcsCase, pcsCaseEntity); + caseLinkView.setCaseFields(pcsCase, pcsCaseEntity); return pcsCase; } @@ -253,5 +256,4 @@ private List> mapAndWrapDocuments(PcsCaseEntity pcsCaseEntit .build()) .collect(Collectors.toList()); } - } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/CaseLinkingAccess.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/CaseLinkingAccess.java new file mode 100644 index 0000000000..0b51c55a03 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/CaseLinkingAccess.java @@ -0,0 +1,23 @@ +package uk.gov.hmcts.reform.pcs.ccd.accesscontrol; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.SetMultimap; +import uk.gov.hmcts.ccd.sdk.api.HasAccessControl; +import uk.gov.hmcts.ccd.sdk.api.HasRole; +import uk.gov.hmcts.ccd.sdk.api.Permission; + +import static uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole.PCS_CASE_WORKER; +import static uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole.PCS_SOLICITOR; + +public class CaseLinkingAccess implements HasAccessControl { + + + @Override + public SetMultimap getGrants() { + SetMultimap grants = HashMultimap.create(); + grants.putAll(PCS_SOLICITOR, Permission.CRU); + grants.put(PCS_CASE_WORKER, Permission.R); + + return grants; + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java index bcf12830fc..3bc56605da 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/PCSCase.java @@ -7,17 +7,20 @@ import uk.gov.hmcts.ccd.sdk.External; import uk.gov.hmcts.ccd.sdk.api.CCD; import uk.gov.hmcts.ccd.sdk.type.AddressUK; +import uk.gov.hmcts.ccd.sdk.type.CaseLink; +import uk.gov.hmcts.ccd.sdk.type.ComponentLauncher; import uk.gov.hmcts.ccd.sdk.type.Document; import uk.gov.hmcts.ccd.sdk.type.DynamicList; import uk.gov.hmcts.ccd.sdk.type.FieldType; import uk.gov.hmcts.ccd.sdk.type.ListValue; -import uk.gov.hmcts.ccd.sdk.type.SearchCriteria; import uk.gov.hmcts.ccd.sdk.type.WaysToPay; import uk.gov.hmcts.ccd.sdk.type.YesOrNo; +import uk.gov.hmcts.ccd.sdk.type.SearchCriteria; +import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.CaseLinkingAccess; +import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.GlobalSearchAccess; import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.CitizenAccess; import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.ClaimantAccess; import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.DefendantAccess; -import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.GlobalSearchAccess; import uk.gov.hmcts.reform.pcs.ccd.domain.enforcetheorder.EnforcementOrder; import uk.gov.hmcts.reform.pcs.ccd.domain.grounds.AssuredNoArrearsPossessionGrounds; import uk.gov.hmcts.reform.pcs.ccd.domain.grounds.AssuredRentArrearsPossessionGrounds; @@ -40,6 +43,7 @@ import uk.gov.hmcts.reform.pcs.ccd.type.DynamicStringList; import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry; +import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -110,6 +114,20 @@ public class PCSCase { @External private String crossBorderCountry2; + @CCD(access = {CaseLinkingAccess.class}, + typeOverride = FieldType.Collection, + label = "Linked cases", + typeParameterOverride = "CaseLink") + @Builder.Default + private List> caseLinks = new ArrayList<>(); + + @CCD( + access = {CaseLinkingAccess.class}, + label = "Component Launcher (for displaying Linked Cases data)" + ) + @JsonProperty("LinkedCasesComponentLauncher") + private ComponentLauncher linkedCasesComponentLauncher; + @CCD( searchable = false, access = {CitizenAccess.class} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkEntity.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkEntity.java new file mode 100644 index 0000000000..a00ae4f4ae --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkEntity.java @@ -0,0 +1,52 @@ +package uk.gov.hmcts.reform.pcs.ccd.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "case_link") +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CaseLinkEntity { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "case_id") + private PcsCaseEntity pcsCase; + + @Column(name = "linked_case_reference", nullable = false) + private Long linkedCaseReference; + + @Column(name = "ccd_list_id") + private String ccdListId; + + @OneToMany(mappedBy = "caseLink", + cascade = CascadeType.ALL, + orphanRemoval = true) + @Builder.Default + private List reasons = new ArrayList<>(); +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkReasonEntity.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkReasonEntity.java new file mode 100644 index 0000000000..296de7c6f0 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkReasonEntity.java @@ -0,0 +1,40 @@ +package uk.gov.hmcts.reform.pcs.ccd.entity; + + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.UUID; + +@Entity +@Table(name = "case_link_reason") +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CaseLinkReasonEntity { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "case_link_id") + private CaseLinkEntity caseLink; + + @Column(name = "reason_code", nullable = false) + private String reasonCode; +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java index 7bb52e8974..820b362222 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntity.java @@ -83,6 +83,12 @@ public class PcsCaseEntity { @JsonManagedReference private List documents = new ArrayList<>(); + @OneToMany(mappedBy = "pcsCase", + cascade = ALL, + orphanRemoval = true) + @Builder.Default + private List caseLinks = new ArrayList<>(); + public void setTenancyLicence(TenancyLicenceEntity tenancyLicence) { if (this.tenancyLicence != null) { this.tenancyLicence.setPcsCase(null); diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/CreateCaseLink.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/CreateCaseLink.java new file mode 100644 index 0000000000..37917ea8cf --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/CreateCaseLink.java @@ -0,0 +1,52 @@ +package uk.gov.hmcts.reform.pcs.ccd.event; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.ccd.sdk.api.CCDConfig; +import uk.gov.hmcts.ccd.sdk.api.DecentralisedConfigBuilder; +import uk.gov.hmcts.ccd.sdk.api.EventPayload; +import uk.gov.hmcts.ccd.sdk.api.Permission; +import uk.gov.hmcts.ccd.sdk.api.callback.SubmitResponse; +import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole; +import uk.gov.hmcts.reform.pcs.ccd.common.PageBuilder; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.State; +import uk.gov.hmcts.reform.pcs.ccd.service.PcsCaseService; + +@Component +@Slf4j +@AllArgsConstructor +public class CreateCaseLink implements CCDConfig { + + private final PcsCaseService pcsCaseService; + + + @Override + public void configureDecentralised(DecentralisedConfigBuilder configBuilder) { + new PageBuilder(configBuilder + .decentralisedEvent(EventId.createCaseLink.name(), this::submit) + .forAllStates() + .name("Link cases") + .description("To link related cases") + .grant(Permission.R, UserRole.PCS_CASE_WORKER) + .grant(Permission.CRU,UserRole.PCS_SOLICITOR)) + .page("createCaseLink") + .pageLabel("Case Link") + .optional(PCSCase::getCaseLinks,"LinkedCasesComponentLauncher = \"DONOTSHOW\"",null,true) + .optional(PCSCase::getLinkedCasesComponentLauncher, + null,null,null,null,"#ARGUMENT(CREATE,LinkedCases)"); + + } + + private SubmitResponse submit(EventPayload eventPayload) { + long caseReference = eventPayload.caseReference(); + PCSCase pcsCase = eventPayload.caseData(); + + log.info("Caseworker created case link for {}", caseReference); + + pcsCaseService.patchCaseLinks(caseReference, pcsCase); + + return SubmitResponse.defaultResponse(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java index 3a84e15878..0be6cc3aac 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/EventId.java @@ -7,5 +7,7 @@ public enum EventId { enforceTheOrder, respondPossessionClaim, submitDefendantResponse, - createTestCase + createTestCase, + createCaseLink, + maintainCaseLink } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/MaintainLinkCase.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/MaintainLinkCase.java new file mode 100644 index 0000000000..b34bd7f3d1 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/event/MaintainLinkCase.java @@ -0,0 +1,54 @@ +package uk.gov.hmcts.reform.pcs.ccd.event; + + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import uk.gov.hmcts.ccd.sdk.api.CCDConfig; +import uk.gov.hmcts.ccd.sdk.api.DecentralisedConfigBuilder; +import uk.gov.hmcts.ccd.sdk.api.EventPayload; +import uk.gov.hmcts.ccd.sdk.api.Permission; +import uk.gov.hmcts.ccd.sdk.api.callback.SubmitResponse; +import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole; +import uk.gov.hmcts.reform.pcs.ccd.common.PageBuilder; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.domain.State; +import uk.gov.hmcts.reform.pcs.ccd.service.PcsCaseService; + +@Component +@Slf4j +@AllArgsConstructor +public class MaintainLinkCase implements CCDConfig { + + private final PcsCaseService pcsCaseService; + + @Override + public void configureDecentralised(DecentralisedConfigBuilder configBuilder) { + new PageBuilder(configBuilder + .decentralisedEvent(EventId.maintainCaseLink.name(), this::submit) + .forAllStates() + .name("Manage case links") + .description("To manage link related cases") + .grant(Permission.R, UserRole.PCS_CASE_WORKER) + .grant(Permission.CRUD, UserRole.PCS_SOLICITOR)) + .page("maintainCaseLink") + .pageLabel("Case Link") + .optional(PCSCase::getCaseLinks, "LinkedCasesComponentLauncher = \"DONOTSHOW\"", null, true) + .optional(PCSCase::getLinkedCasesComponentLauncher, + null, null, null, null, "#ARGUMENT(UPDATE,LinkedCases)"); + } + + + private SubmitResponse submit(EventPayload eventPayload) { + long caseReference = eventPayload.caseReference(); + PCSCase pcsCase = eventPayload.caseData(); + + log.info("Caseworker updated case link for {}", caseReference); + + pcsCaseService.patchCaseLinks(caseReference, pcsCase); + + return SubmitResponse.defaultResponse(); + } + + +} diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/CaseLinkService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/CaseLinkService.java new file mode 100644 index 0000000000..52d22fd6f9 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/CaseLinkService.java @@ -0,0 +1,67 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +import org.springframework.stereotype.Service; +import uk.gov.hmcts.ccd.sdk.type.CaseLink; +import uk.gov.hmcts.ccd.sdk.type.LinkReason; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.entity.CaseLinkEntity; +import uk.gov.hmcts.reform.pcs.ccd.entity.CaseLinkReasonEntity; +import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class CaseLinkService { + + public void mergeCaseLinks(List> incomingLinkedCases, PcsCaseEntity pcsCaseEntity) { + + Map existingLinkedCases = + pcsCaseEntity.getCaseLinks().stream() + .collect(Collectors.toMap(CaseLinkEntity::getLinkedCaseReference, + Function.identity() + )); + + List mergedCaseLinkEntities = new ArrayList<>(); + + for (ListValue caseLinkListValue : incomingLinkedCases) { + CaseLink dto = caseLinkListValue.getValue(); + Long incomingCaseRef = Long.valueOf(dto.getCaseReference()); + + CaseLinkEntity caseLinkEntity = existingLinkedCases.remove(incomingCaseRef); + + if (caseLinkEntity == null) { + caseLinkEntity = new CaseLinkEntity(); + caseLinkEntity.setPcsCase(pcsCaseEntity); + caseLinkEntity.setLinkedCaseReference(incomingCaseRef); + } + + caseLinkEntity.setCcdListId(dto.getCaseType()); + + caseLinkEntity.getReasons().clear(); + + if (dto.getReasonForLink() != null) { + List caseLinkReasonEntities = new ArrayList<>(); + for (ListValue incomingLinkReason : dto.getReasonForLink()) { + CaseLinkReasonEntity caseLinkReasonEntity = CaseLinkReasonEntity.builder() + .caseLink(caseLinkEntity) + .reasonCode(incomingLinkReason.getValue().getReason()) + .build(); + caseLinkReasonEntities.add(caseLinkReasonEntity); + } + caseLinkEntity.getReasons().clear(); + caseLinkEntity.getReasons().addAll(caseLinkReasonEntities); + } + + mergedCaseLinkEntities.add(caseLinkEntity); + } + + pcsCaseEntity.getCaseLinks().clear(); + pcsCaseEntity.getCaseLinks().addAll(mergedCaseLinkEntities); + + } +} + diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java index d85e73223d..d9ad85e848 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseService.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.reform.pcs.ccd.service; import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import uk.gov.hmcts.ccd.sdk.type.AddressUK; import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; @@ -17,6 +18,7 @@ import java.util.Objects; @Service +@Slf4j @AllArgsConstructor public class PcsCaseService { @@ -26,6 +28,7 @@ public class PcsCaseService { private final DocumentService documentService; private final TenancyLicenceService tenancyLicenceService; private final AddressMapper addressMapper; + private final CaseLinkService caseLinkService; public PcsCaseEntity createCase(long caseReference, AddressUK propertyAddress, @@ -61,4 +64,12 @@ public PcsCaseEntity loadCase(long caseReference) { .orElseThrow(() -> new CaseNotFoundException(caseReference)); } + public void patchCaseLinks(long caseReference, PCSCase pcsCase) { + PcsCaseEntity pcsCaseEntity = loadCase(caseReference); + + log.info("Patching linked cases for {}", caseReference); + if (pcsCase.getCaseLinks() != null) { + caseLinkService.mergeCaseLinks(pcsCase.getCaseLinks(), pcsCaseEntity); + } + } } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/view/CaseLinkView.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/view/CaseLinkView.java new file mode 100644 index 0000000000..0ce225123d --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/view/CaseLinkView.java @@ -0,0 +1,54 @@ +package uk.gov.hmcts.reform.pcs.ccd.view; + +import org.springframework.stereotype.Component; +import uk.gov.hmcts.ccd.sdk.type.CaseLink; +import uk.gov.hmcts.ccd.sdk.type.LinkReason; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class CaseLinkView { + + public void setCaseFields(PCSCase pcsCase, PcsCaseEntity pcsCaseEntity) { + if (!pcsCaseEntity.getCaseLinks().isEmpty()) { + setCaseLinks(pcsCase, pcsCaseEntity); + } + } + + private void setCaseLinks(PCSCase pcsCase, PcsCaseEntity pcsCaseEntity) { + List> caseLinks = new ArrayList<>(); + + if (!pcsCaseEntity.getCaseLinks().isEmpty()) { + caseLinks = pcsCaseEntity.getCaseLinks().stream() + .map(linkEntity -> ListValue.builder() + .id(linkEntity.getLinkedCaseReference().toString()) + .value( + CaseLink.builder() + .caseReference(linkEntity.getLinkedCaseReference().toString()) + .caseType(linkEntity.getCcdListId()) + .reasonForLink( + linkEntity.getReasons().stream() + .map(reasonEntity -> ListValue.builder() + .id(reasonEntity.getId().toString()) + .value( + LinkReason.builder() + .reason(reasonEntity.getReasonCode()) + .build() + ) + .build() + ) + .toList() + ) + .build() + ) + .build() + ) + .toList(); + } + pcsCase.setCaseLinks(caseLinks); + } +} diff --git a/src/main/resources/db/migration/V073__create_case_link_and_link_reason_tables.sql b/src/main/resources/db/migration/V073__create_case_link_and_link_reason_tables.sql new file mode 100644 index 0000000000..ac650702f5 --- /dev/null +++ b/src/main/resources/db/migration/V073__create_case_link_and_link_reason_tables.sql @@ -0,0 +1,23 @@ +-- ============================================ +-- PCS CASE LINK + LINK REASONS +-- ============================================ +CREATE TABLE case_link ( + id UUID PRIMARY KEY, + case_id UUID NOT NULL REFERENCES pcs_case(id) ON DELETE CASCADE, + linked_case_reference BIGINT NOT NULL, + ccd_list_id VARCHAR(50), + created_at TIMESTAMP DEFAULT now() +); + +CREATE UNIQUE INDEX ux_case_link_unique + ON case_link(case_id, linked_case_reference); + + +CREATE TABLE case_link_reason ( + id UUID PRIMARY KEY, + case_link_id UUID NOT NULL REFERENCES case_link(id) ON DELETE CASCADE, + reason_code VARCHAR(100) NOT NULL +); + +CREATE INDEX idx_case_link_reason_link + ON case_link_reason(case_link_id); diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java index 204263c825..00f7fdcb2a 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseViewTest.java @@ -18,9 +18,9 @@ import uk.gov.hmcts.reform.pcs.ccd.entity.DocumentEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.party.ClaimPartyEntity; -import uk.gov.hmcts.reform.pcs.ccd.entity.party.ClaimPartyId; import uk.gov.hmcts.reform.pcs.ccd.entity.party.PartyEntity; import uk.gov.hmcts.reform.pcs.ccd.entity.party.PartyRole; +import uk.gov.hmcts.reform.pcs.ccd.entity.party.ClaimPartyId; import uk.gov.hmcts.reform.pcs.ccd.repository.PcsCaseRepository; import uk.gov.hmcts.reform.pcs.ccd.service.CaseTitleService; import uk.gov.hmcts.reform.pcs.ccd.service.DraftCaseDataService; @@ -35,6 +35,7 @@ import uk.gov.hmcts.reform.pcs.ccd.view.RentDetailsView; import uk.gov.hmcts.reform.pcs.ccd.view.StatementOfTruthView; import uk.gov.hmcts.reform.pcs.ccd.view.TenancyLicenceView; +import uk.gov.hmcts.reform.pcs.ccd.view.CaseLinkView; import uk.gov.hmcts.reform.pcs.exception.CaseNotFoundException; import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry; import uk.gov.hmcts.reform.pcs.security.SecurityContextService; @@ -96,6 +97,8 @@ class PCSCaseViewTest { private ClaimEntity claimEntity; @Mock private CaseNameHmctsFormatter caseNameHmctsFormatter; + @Mock + private CaseLinkView caseLinkView; private PCSCaseView underTest; @@ -108,7 +111,7 @@ void setUp() { caseTitleService, claimView, tenancyLicenceView, claimGroundsView, rentDetailsView, alternativesToPossessionView, housingActWalesView, asbProhibitedConductView, rentArrearsView, noticeOfPossessionView, - statementOfTruthView, caseNameHmctsFormatter + statementOfTruthView, caseNameHmctsFormatter, caseLinkView ); } @@ -332,6 +335,7 @@ void shouldSetCaseFieldsInViewHelpers() { verify(rentArrearsView).setCaseFields(pcsCase, pcsCaseEntity); verify(noticeOfPossessionView).setCaseFields(pcsCase, pcsCaseEntity); verify(statementOfTruthView).setCaseFields(pcsCase, pcsCaseEntity); + verify(caseLinkView).setCaseFields(pcsCase, pcsCaseEntity); } @Test diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/CaseLinkingAccessTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/CaseLinkingAccessTest.java new file mode 100644 index 0000000000..819e5eebc0 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/CaseLinkingAccessTest.java @@ -0,0 +1,29 @@ +package uk.gov.hmcts.reform.pcs.ccd.accesscontrol; + +import com.google.common.collect.SetMultimap; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import uk.gov.hmcts.ccd.sdk.api.HasRole; +import uk.gov.hmcts.ccd.sdk.api.Permission; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole.PCS_SOLICITOR; +import static uk.gov.hmcts.reform.pcs.ccd.accesscontrol.UserRole.PCS_CASE_WORKER; + +class CaseLinkingAccessTest { + + private CaseLinkingAccess underTest; + + @BeforeEach + void setup() { + underTest = new CaseLinkingAccess(); + } + + @Test + void shouldGrantCaseLinkingAccess() { + SetMultimap grants = underTest.getGrants(); + assertThat(grants.asMap()).contains(entry(PCS_SOLICITOR, Permission.CRU)); + assertThat(grants.get(PCS_CASE_WORKER)).contains(Permission.R); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkEntityTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkEntityTest.java new file mode 100644 index 0000000000..03e97347f8 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkEntityTest.java @@ -0,0 +1,41 @@ +package uk.gov.hmcts.reform.pcs.ccd.entity; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + + + +class CaseLinkEntityTest { + + private CaseLinkEntity underTest; + + + @BeforeEach + void setUp() { + underTest = new CaseLinkEntity(); + } + + @Test + void shouldAddCaseLinkReason() { + // Given + String reasonCode = "CLR003"; + CaseLinkEntity caseLinkEntity = CaseLinkEntity.builder().build(); + CaseLinkReasonEntity caseLinkReasonEntity = CaseLinkReasonEntity.builder() + .caseLink(caseLinkEntity) + .reasonCode(reasonCode) + .build(); + + + // When + underTest.setReasons(List.of(caseLinkReasonEntity)); + + // Then + assertThat(underTest.getReasons()).hasSize(1); + assertThat(underTest.getReasons().getFirst().getReasonCode()).isEqualTo("CLR003"); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkReasonEntityTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkReasonEntityTest.java new file mode 100644 index 0000000000..03bb586501 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/CaseLinkReasonEntityTest.java @@ -0,0 +1,31 @@ +package uk.gov.hmcts.reform.pcs.ccd.entity; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.mockito.Mockito.mock; +import static org.assertj.core.api.Assertions.assertThat; + + +class CaseLinkReasonEntityTest { + + private CaseLinkReasonEntity underTest; + + + @BeforeEach + void setUp() { + underTest = new CaseLinkReasonEntity(); + } + + @Test + void shouldUpdateCaseLinkEntity() { + // Given + CaseLinkEntity updatedCaseLinkEntity = mock(CaseLinkEntity.class); + + // When + underTest.setCaseLink(updatedCaseLinkEntity); + + // Then + assertThat(underTest.getCaseLink()).isSameAs(updatedCaseLinkEntity); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntityTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntityTest.java index eb82cae83c..fae4b13195 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntityTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/entity/PcsCaseEntityTest.java @@ -29,5 +29,4 @@ void shouldUpdateCaseOnTenancyLicenceWhenSet() { verify(existingTenancyLicence).setPcsCase(null); verify(updatedTenancyLicence).setPcsCase(underTest); } - } diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/CreateCaseLinkTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/CreateCaseLinkTest.java new file mode 100644 index 0000000000..7a0be5e7e3 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/CreateCaseLinkTest.java @@ -0,0 +1,57 @@ +package uk.gov.hmcts.reform.pcs.ccd.event; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.ccd.sdk.type.CaseLink; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.service.PcsCaseService; + +import java.util.List; +import java.util.UUID; + + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.doNothing; + +@ExtendWith(MockitoExtension.class) +class CreateCaseLinkTest extends BaseEventTest { + + @Mock + private PcsCaseService pcsCaseService; + + + @InjectMocks + private CreateCaseLink underTest; + + + @BeforeEach + void setUp() { + setEventUnderTest(underTest); + } + + + @Test + void shouldCreateCaseLinksInSubmitCallback() { + // Given + CaseLink caseLink = CaseLink.builder().build(); + List> caseLists = List.of( + ListValue.builder() + .id(UUID.randomUUID().toString()) + .value(caseLink) + .build()); + + PCSCase pcsCase = PCSCase.builder().caseLinks(caseLists).build(); + doNothing().when(pcsCaseService).patchCaseLinks(TEST_CASE_REFERENCE, pcsCase); + + // When + callSubmitHandler(pcsCase); + + // Then + verify(pcsCaseService).patchCaseLinks(TEST_CASE_REFERENCE, pcsCase); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/MaintainLinkCaseTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/MaintainLinkCaseTest.java new file mode 100644 index 0000000000..ca9e212196 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/event/MaintainLinkCaseTest.java @@ -0,0 +1,55 @@ +package uk.gov.hmcts.reform.pcs.ccd.event; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.ccd.sdk.type.CaseLink; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.service.PcsCaseService; + +import java.util.List; +import java.util.UUID; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.verify; + +@ExtendWith(MockitoExtension.class) +class MaintainLinkCaseTest extends BaseEventTest { + + + @Mock + private PcsCaseService pcsCaseService; + + @InjectMocks + private MaintainLinkCase underTest; + + @BeforeEach + void setUp() { + + setEventUnderTest(underTest); + } + + @Test + void shouldModifyCaseLinksInSubmitCallback() { + // Given + CaseLink caseLink = CaseLink.builder().build(); + List> caseLists = List.of( + ListValue.builder() + .id(UUID.randomUUID().toString()) + .value(caseLink) + .build()); + + PCSCase pcsCase = PCSCase.builder().caseLinks(caseLists).build(); + doNothing().when(pcsCaseService).patchCaseLinks(TEST_CASE_REFERENCE, pcsCase); + + // When + callSubmitHandler(pcsCase); + + // Then + verify(pcsCaseService).patchCaseLinks(TEST_CASE_REFERENCE, pcsCase); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/CaseLinkServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/CaseLinkServiceTest.java new file mode 100644 index 0000000000..d1906c8168 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/CaseLinkServiceTest.java @@ -0,0 +1,97 @@ +package uk.gov.hmcts.reform.pcs.ccd.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import uk.gov.hmcts.ccd.sdk.type.CaseLink; +import uk.gov.hmcts.ccd.sdk.type.LinkReason; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.entity.CaseLinkEntity; +import uk.gov.hmcts.reform.pcs.ccd.entity.CaseLinkReasonEntity; +import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; + +import java.util.List; +import java.util.UUID; + +import static org.mockito.Mockito.mock; +import static org.assertj.core.api.Assertions.assertThat; + +class CaseLinkServiceTest { + + private PcsCaseEntity pcsCaseEntity; + private CaseLinkService underTest; + + @BeforeEach + void setUp() { + pcsCaseEntity = PcsCaseEntity.builder().build(); + underTest = new CaseLinkService(); + } + + @Test + void shouldMergeCaseLinks() { + //Given + CaseLinkReasonEntity caseLinkReasonEntity = createCaseLinkReasonEntity(); + + CaseLinkEntity caseLinkEntity = createCaseLinkEntity(List.of(caseLinkReasonEntity)); + + LinkReason linkReason = createLinkReason(caseLinkReasonEntity.getReasonCode()); + List> linkReasons = List.of( + ListValue.builder() + .id(caseLinkReasonEntity.getId().toString()) + .value(linkReason) + .build()); + CaseLink caseLink = creatCaseLink(String.valueOf(caseLinkEntity.getLinkedCaseReference()), + caseLinkEntity.getCcdListId(), linkReasons); + + List> caseLists = List.of( + ListValue.builder() + .id(UUID.randomUUID().toString()) + .value(caseLink) + .build()); + + // When + underTest.mergeCaseLinks(caseLists, pcsCaseEntity); + + // Then + assertThat(pcsCaseEntity.getCaseLinks()).hasSize(1); + assertThat(pcsCaseEntity.getCaseLinks().getFirst().getCcdListId()).isEqualTo("PCS"); + assertThat(pcsCaseEntity.getCaseLinks().getFirst().getReasons().getFirst().getReasonCode()).isEqualTo("CLR003"); + } + + private CaseLinkReasonEntity createCaseLinkReasonEntity() { + + CaseLinkEntity caseLinkEntity = mock(CaseLinkEntity.class); + + return CaseLinkReasonEntity.builder() + .id(UUID.randomUUID()) + .reasonCode("CLR003") + .caseLink(caseLinkEntity) + .build(); + } + + private CaseLinkEntity createCaseLinkEntity(List linkReasonEntities) { + + return CaseLinkEntity.builder() + .id(UUID.randomUUID()) + .linkedCaseReference(1234L) + .ccdListId("PCS") + .reasons(linkReasonEntities) + .build(); + } + + private CaseLink creatCaseLink(String ref, String caseType, List> reasons) { + + return CaseLink.builder() + .caseReference(ref) + .caseType(caseType) + .reasonForLink(reasons) + .build(); + } + + private LinkReason createLinkReason(String reason) { + + return LinkReason.builder() + .reason(reason) + .build(); + } + +} diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DraftCaseJsonMergerTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DraftCaseJsonMergerTest.java index be649c4cec..e80499af77 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DraftCaseJsonMergerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/DraftCaseJsonMergerTest.java @@ -71,6 +71,7 @@ void shouldKeepExistingFieldsWhenMerging() throws JsonProcessingException { "claimantType", "noRentArrearsReasonForGrounds.holidayLet", "waysToPay", + "caseLinks", "claimGroundSummaries", "enforcementOrder.showChangeNameAddressPage", "enforcementOrder.showPeopleWhoWillBeEvictedPage", diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java index 2bcbc91b4c..3d18137c8a 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/service/PcsCaseServiceTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.atLeastOnce; @ExtendWith(MockitoExtension.class) class PcsCaseServiceTest { @@ -47,6 +48,8 @@ class PcsCaseServiceTest { private TenancyLicenceService tenancyLicenceService; @Mock private AddressMapper addressMapper; + @Mock + private CaseLinkService caseLinkService; @Captor private ArgumentCaptor pcsCaseEntityCaptor; @@ -61,7 +64,8 @@ void setUp() { partyService, documentService, tenancyLicenceService, - addressMapper + addressMapper, + caseLinkService ); } @@ -182,6 +186,20 @@ void shouldCreateTenancyLicenceWithMainClaimOnCase() { verify(pcsCaseEntity).setTenancyLicence(tenancyLicenceEntity); } + @Test + void shouldPatchCaseData() { + // Given + PcsCaseEntity pcsCaseEntity = mock(PcsCaseEntity.class); + PCSCase caseData = PCSCase.builder().build(); + when(pcsCaseRepository.findByCaseReference(CASE_REFERENCE)).thenReturn(java.util.Optional.of(pcsCaseEntity)); + + // When + underTest.patchCaseLinks(CASE_REFERENCE, caseData); + + // Then + verify(caseLinkService, atLeastOnce()).mergeCaseLinks(caseData.getCaseLinks(), pcsCaseEntity); + } + private PcsCaseEntity stubFindCase() { PcsCaseEntity pcsCaseEntity = mock(PcsCaseEntity.class); when(pcsCaseRepository.findByCaseReference(CASE_REFERENCE)).thenReturn(Optional.of(pcsCaseEntity)); diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/view/CaseLinkViewTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/view/CaseLinkViewTest.java new file mode 100644 index 0000000000..89b6a2a5b0 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/view/CaseLinkViewTest.java @@ -0,0 +1,70 @@ +package uk.gov.hmcts.reform.pcs.ccd.view; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.ccd.sdk.type.CaseLink; +import uk.gov.hmcts.ccd.sdk.type.ListValue; +import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase; +import uk.gov.hmcts.reform.pcs.ccd.entity.CaseLinkEntity; +import uk.gov.hmcts.reform.pcs.ccd.entity.CaseLinkReasonEntity; +import uk.gov.hmcts.reform.pcs.ccd.entity.PcsCaseEntity; + +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mock.Strictness.LENIENT; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class CaseLinkViewTest { + + private PCSCase pcsCase; + + @Mock + private PcsCaseEntity pcsCaseEntity; + @Mock(strictness = LENIENT) + private CaseLinkEntity caseLinkEntity; + private CaseLinkView underTest; + + @BeforeEach + void setUp() { + pcsCase = PCSCase.builder().build(); + underTest = new CaseLinkView(); + } + + + @Test + void shouldMapAndWrapCaseLinks() { + // Given + CaseLinkReasonEntity caseLinkReasonEntity1 = createCaseLinkReasonEntity(UUID.randomUUID(), "CLR003"); + CaseLinkReasonEntity caseLinkReasonEntity2 = createCaseLinkReasonEntity(UUID.randomUUID(), "CLR010"); + when(pcsCaseEntity.getCaseLinks()).thenReturn(List.of(caseLinkEntity)); + when(caseLinkEntity.getLinkedCaseReference()).thenReturn(1234L); + when(caseLinkEntity.getReasons()).thenReturn(List.of(caseLinkReasonEntity1, caseLinkReasonEntity2)); + when(caseLinkEntity.getCcdListId()).thenReturn("PCS"); + + // When + underTest.setCaseFields(pcsCase, pcsCaseEntity); + + // Then + List> mappedCaseLinks = pcsCase.getCaseLinks(); + assertThat(mappedCaseLinks).hasSize(1); + assertThat(mappedCaseLinks.getFirst().getValue().getCaseReference()).isEqualTo("1234"); + assertThat(mappedCaseLinks.getFirst().getValue().getCaseType()).isEqualTo("PCS"); + assertThat(mappedCaseLinks.getFirst().getValue().getReasonForLink().getFirst().getValue().getReason()) + .isEqualTo("CLR003"); + } + + private CaseLinkReasonEntity createCaseLinkReasonEntity(UUID id, String reasonCode) { + + return CaseLinkReasonEntity.builder() + .id(id) + .reasonCode(reasonCode) + .caseLink(caseLinkEntity) + .build(); + } +}