From e2e47d78113d429cfb17e850add1bc1a047fcb56 Mon Sep 17 00:00:00 2001 From: pliao-hmcts <113367232+pliao-hmcts@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:51:57 +0000 Subject: [PATCH 01/29] CIV-11511 Witness name (#3575) (#3585) * CIV-11511 add witness name to UploadEvidenceDocumentType * CIV-11511 CIV-11515 Naming Updates (CFV) * CIV-11515 deep copy and bundle Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../user/EvidenceUploadHandlerBase.java | 21 +++++++++- .../UploadEvidenceDocumentType.java | 1 + .../EvidenceUploadApplicantHandlerTest.java | 41 ++++++++++--------- .../EvidenceUploadRespondentHandlerTest.java | 41 ++++++++++--------- 4 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java index 5277c8351c6..c5ef42454a2 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadHandlerBase.java @@ -455,8 +455,8 @@ private void renameDocuments(List> documentUpload, String theId) RESPONDENT_TWO_WITNESS_REFERRED, APPLICANT_WITNESS_REFERRED, APPLICANT_TWO_WITNESS_REFERRED: - prefix = "Referred Document"; - renameUploadEvidenceDocumentType(documentUpload, prefix); + prefix = " referred to in the statement of "; + renameUploadEvidenceDocumentTypeWithName(documentUpload, prefix); break; case RESPONDENT_ONE_TRIAL_DOC_CORRESPONDENCE, RESPONDENT_TWO_TRIAL_DOC_CORRESPONDENCE, @@ -564,6 +564,21 @@ private void renameUploadEvidenceExpert(final List> documentUploa }); } + private void renameUploadEvidenceDocumentTypeWithName(final List> documentUpload, String body) { + documentUpload.forEach(x -> { + UploadEvidenceDocumentType type = (UploadEvidenceDocumentType) x.getValue(); + String ext = FilenameUtils.getExtension(type.getDocumentUpload().getDocumentFileName()); + String newName = type.getTypeOfDocument() + + body + + type.getWitnessOptionName() + + SPACE + + type.getDocumentIssuedDate() + .format(DateTimeFormatter.ofPattern(DATE_FORMAT, Locale.UK)) + + END + ext; + type.getDocumentUpload().setDocumentFileName(newName); + }); + } + private void renameUploadEvidenceDocumentType(final List> documentUpload, String prefix) { documentUpload.forEach(x -> { UploadEvidenceDocumentType type = (UploadEvidenceDocumentType) x.getValue(); @@ -1010,6 +1025,7 @@ private List> deepCopyUploadEvidenceDocument .documentUrl(from.getValue().getDocumentUpload().getDocumentUrl()) .build(); UploadEvidenceDocumentType type = UploadEvidenceDocumentType.builder() + .witnessOptionName(from.getValue().getWitnessOptionName()) .documentIssuedDate(from.getValue().getDocumentIssuedDate()) .typeOfDocument(from.getValue().getTypeOfDocument()) .createdDatetime(from.getValue().getCreatedDatetime()) @@ -1149,6 +1165,7 @@ void addUploadDocList(List> uploadedEvidence && uploadEvidenceDocumentType.getValue().getCreatedDatetime() .isAfter(bundleDetails.get().getCreatedOn().get())) { uploadedEvidenceAfterBundle.add(ElementUtils.element(UploadEvidenceDocumentType.builder() + .witnessOptionName(uploadEvidenceDocumentType.getValue().getWitnessOptionName()) .typeOfDocument(docType) .createdDatetime(uploadEvidenceDocumentType.getValue().getCreatedDatetime()) .documentUpload(uploadEvidenceDocumentType.getValue().getDocumentUpload()) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/caseprogression/UploadEvidenceDocumentType.java b/src/main/java/uk/gov/hmcts/reform/civil/model/caseprogression/UploadEvidenceDocumentType.java index 3d02a3d2e44..6dffcc43598 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/caseprogression/UploadEvidenceDocumentType.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/caseprogression/UploadEvidenceDocumentType.java @@ -16,6 +16,7 @@ @AllArgsConstructor public class UploadEvidenceDocumentType { + private String witnessOptionName; private String typeOfDocument; private LocalDate documentIssuedDate; private Document documentUpload; diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java index 3704297d425..25b666d5e08 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadApplicantHandlerTest.java @@ -725,14 +725,14 @@ void should_do_naming_convention(String selected) { .documentJointStatement(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .documentQuestions(createExpertDocs("expertName", witnessDate, null, null, "other", "question", null)) .documentAnswers(createExpertDocs("expertName", witnessDate, null, null, "other", null, "answer")) - .documentForDisclosure(createEvidenceDocs("typeDisclosure", witnessDate)) - .documentReferredInStatement(createEvidenceDocs("typeReferred", witnessDate)) - .documentEvidenceForTrial(createEvidenceDocs("typeForTrial", witnessDate)) - .documentDisclosureList(createEvidenceDocs(null, null)) - .documentCaseSummary(createEvidenceDocs(null, null)) - .documentSkeletonArgument(createEvidenceDocs(null, null)) - .documentAuthorities(createEvidenceDocs(null, null)) - .documentCosts(createEvidenceDocs(null, null)) + .documentForDisclosure(createEvidenceDocs(null, "typeDisclosure", witnessDate)) + .documentReferredInStatement(createEvidenceDocs("witness", "typeReferred", witnessDate)) + .documentEvidenceForTrial(createEvidenceDocs(null, "typeForTrial", witnessDate)) + .documentDisclosureList(createEvidenceDocs(null, null, null)) + .documentCaseSummary(createEvidenceDocs(null, null, null)) + .documentSkeletonArgument(createEvidenceDocs(null, null, null)) + .documentAuthorities(createEvidenceDocs(null, null, null)) + .documentCosts(createEvidenceDocs(null, null, null)) .build(); CaseData caseDataBefore = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addApplicant2(YES) @@ -768,7 +768,7 @@ void should_do_naming_convention(String selected) { assertThat(updatedData.getDocumentForDisclosure().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Document for disclosure typeDisclosure 10-02-2023.pdf"); assertThat(updatedData.getDocumentReferredInStatement().get(0).getValue() - .getDocumentUpload().getDocumentFileName()).isEqualTo("Referred Document typeReferred 10-02-2023.pdf"); + .getDocumentUpload().getDocumentFileName()).isEqualTo("typeReferred referred to in the statement of witness 10-02-2023.pdf"); assertThat(updatedData.getDocumentEvidenceForTrial().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Documentary Evidence typeForTrial 10-02-2023.pdf"); assertThat(updatedData.getDocumentDisclosureList().get(0).getValue() @@ -817,7 +817,7 @@ void should_do_naming_convention(String selected) { assertThat(updatedData.getDocumentForDisclosureApp2().get(0).getValue() .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.APPLICANT_TWO_DISCLOSURE); assertThat(updatedData.getDocumentReferredInStatementApp2().get(0).getValue() - .getDocumentUpload().getDocumentFileName()).isEqualTo("Referred Document typeReferred 10-02-2023.pdf"); + .getDocumentUpload().getDocumentFileName()).isEqualTo("typeReferred referred to in the statement of witness 10-02-2023.pdf"); assertThat(updatedData.getDocumentReferredInStatementApp2().get(0).getValue() .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.APPLICANT_TWO_WITNESS_REFERRED); assertThat(updatedData.getDocumentEvidenceForTrialApp2().get(0).getValue() @@ -869,14 +869,14 @@ void should_do_naming_convention_app2() { .documentJointStatementApp2(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .documentQuestionsApp2(createExpertDocs("expertName", witnessDate, null, null, "other", "question", null)) .documentAnswersApp2(createExpertDocs("expertName", witnessDate, null, null, "other", null, "answer")) - .documentForDisclosureApp2(createEvidenceDocs("typeDisclosure", witnessDate)) - .documentReferredInStatementApp2(createEvidenceDocs("typeReferred", witnessDate)) - .documentEvidenceForTrialApp2(createEvidenceDocs("typeForTrial", witnessDate)) - .documentDisclosureListApp2(createEvidenceDocs(null, null)) - .documentCaseSummaryApp2(createEvidenceDocs(null, null)) - .documentSkeletonArgumentApp2(createEvidenceDocs(null, null)) - .documentAuthoritiesApp2(createEvidenceDocs(null, null)) - .documentCostsApp2(createEvidenceDocs(null, null)) + .documentForDisclosureApp2(createEvidenceDocs(null, "typeDisclosure", witnessDate)) + .documentReferredInStatementApp2(createEvidenceDocs("witness", "typeReferred", witnessDate)) + .documentEvidenceForTrialApp2(createEvidenceDocs(null, "typeForTrial", witnessDate)) + .documentDisclosureListApp2(createEvidenceDocs(null, null, null)) + .documentCaseSummaryApp2(createEvidenceDocs(null, null, null)) + .documentSkeletonArgumentApp2(createEvidenceDocs(null, null, null)) + .documentAuthoritiesApp2(createEvidenceDocs(null, null, null)) + .documentCostsApp2(createEvidenceDocs(null, null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); @@ -906,7 +906,7 @@ void should_do_naming_convention_app2() { assertThat(updatedData.getDocumentForDisclosureApp2().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Document for disclosure typeDisclosure 10-02-2023.pdf"); assertThat(updatedData.getDocumentReferredInStatementApp2().get(0).getValue() - .getDocumentUpload().getDocumentFileName()).isEqualTo("Referred Document typeReferred 10-02-2023.pdf"); + .getDocumentUpload().getDocumentFileName()).isEqualTo("typeReferred referred to in the statement of witness 10-02-2023.pdf"); assertThat(updatedData.getDocumentEvidenceForTrialApp2().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Documentary Evidence typeForTrial 10-02-2023.pdf"); assertThat(updatedData.getDocumentDisclosureListApp2().get(0).getValue() @@ -974,13 +974,14 @@ void shouldNotPopulateNotificationWithOldDocument_whenNewDocumentUploadAdded() { assertThat(updatedData.getNotificationText()).isEqualTo("\nClaimant 1 - Witness summary"); } - private List> createEvidenceDocs(String type, LocalDate issuedDate) { + private List> createEvidenceDocs(String name, String type, LocalDate issuedDate) { Document document = Document.builder().documentBinaryUrl( TEST_URL) .documentFileName(TEST_FILE_NAME).build(); List> evidenceDocs = new ArrayList<>(); evidenceDocs.add(ElementUtils.element(UploadEvidenceDocumentType .builder() + .witnessOptionName(name) .typeOfDocument(type) .documentIssuedDate(issuedDate) .documentUpload(document) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java index d5c32eeac09..b1ab3690b13 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadRespondentHandlerTest.java @@ -1332,14 +1332,14 @@ void should_do_naming_convention_resp1(String selected) { .documentJointStatementRes(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .documentQuestionsRes(createExpertDocs("expertName", witnessDate, null, null, "other", "question", null)) .documentAnswersRes(createExpertDocs("expertName", witnessDate, null, null, "other", null, "answer")) - .documentForDisclosureRes(createEvidenceDocs("typeDisclosure", witnessDate)) - .documentReferredInStatementRes(createEvidenceDocs("typeReferred", witnessDate)) - .documentEvidenceForTrialRes(createEvidenceDocs("typeForTrial", witnessDate)) - .documentDisclosureListRes(createEvidenceDocs(null, null)) - .documentCaseSummaryRes(createEvidenceDocs(null, null)) - .documentSkeletonArgumentRes(createEvidenceDocs(null, null)) - .documentAuthoritiesRes(createEvidenceDocs(null, null)) - .documentCostsRes(createEvidenceDocs(null, null)) + .documentForDisclosureRes(createEvidenceDocs(null, "typeDisclosure", witnessDate)) + .documentReferredInStatementRes(createEvidenceDocs("witness", "typeReferred", witnessDate)) + .documentEvidenceForTrialRes(createEvidenceDocs(null, "typeForTrial", witnessDate)) + .documentDisclosureListRes(createEvidenceDocs(null, null, null)) + .documentCaseSummaryRes(createEvidenceDocs(null, null, null)) + .documentSkeletonArgumentRes(createEvidenceDocs(null, null, null)) + .documentAuthoritiesRes(createEvidenceDocs(null, null, null)) + .documentCostsRes(createEvidenceDocs(null, null, null)) .build(); CaseData caseDataBefore = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .addRespondent2(YES) @@ -1376,7 +1376,7 @@ void should_do_naming_convention_resp1(String selected) { assertThat(updatedData.getDocumentForDisclosureRes().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Document for disclosure typeDisclosure 10-02-2023.pdf"); assertThat(updatedData.getDocumentReferredInStatementRes().get(0).getValue() - .getDocumentUpload().getDocumentFileName()).isEqualTo("Referred Document typeReferred 10-02-2023.pdf"); + .getDocumentUpload().getDocumentFileName()).isEqualTo("typeReferred referred to in the statement of witness 10-02-2023.pdf"); assertThat(updatedData.getDocumentEvidenceForTrialRes().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Documentary Evidence typeForTrial 10-02-2023.pdf"); assertThat(updatedData.getDocumentDisclosureListRes().get(0).getValue() @@ -1425,7 +1425,7 @@ void should_do_naming_convention_resp1(String selected) { assertThat(updatedData.getDocumentForDisclosureRes2().get(0).getValue() .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.RESPONDENT_TWO_DISCLOSURE); assertThat(updatedData.getDocumentReferredInStatementRes2().get(0).getValue() - .getDocumentUpload().getDocumentFileName()).isEqualTo("Referred Document typeReferred 10-02-2023.pdf"); + .getDocumentUpload().getDocumentFileName()).isEqualTo("typeReferred referred to in the statement of witness 10-02-2023.pdf"); assertThat(updatedData.getDocumentReferredInStatementRes2().get(0).getValue() .getDocumentUpload().getCategoryID()).isEqualTo(EvidenceUploadHandlerBase.RESPONDENT_TWO_WITNESS_REFERRED); assertThat(updatedData.getDocumentEvidenceForTrialRes2().get(0).getValue() @@ -1473,14 +1473,14 @@ void should_do_naming_convention_resp2() { .documentJointStatementRes2(createExpertDocs("expertsName", witnessDate, null, "expertises", null, null, null)) .documentQuestionsRes2(createExpertDocs("expertName", witnessDate, null, null, "other", "question", null)) .documentAnswersRes2(createExpertDocs("expertName", witnessDate, null, null, "other", null, "answer")) - .documentForDisclosureRes2(createEvidenceDocs("typeDisclosure", witnessDate)) - .documentReferredInStatementRes2(createEvidenceDocs("typeReferred", witnessDate)) - .documentEvidenceForTrialRes2(createEvidenceDocs("typeForTrial", witnessDate)) - .documentDisclosureListRes2(createEvidenceDocs(null, null)) - .documentCaseSummaryRes2(createEvidenceDocs(null, null)) - .documentSkeletonArgumentRes2(createEvidenceDocs(null, null)) - .documentAuthoritiesRes2(createEvidenceDocs(null, null)) - .documentCostsRes2(createEvidenceDocs(null, null)) + .documentForDisclosureRes2(createEvidenceDocs(null, "typeDisclosure", witnessDate)) + .documentReferredInStatementRes2(createEvidenceDocs("witness", "typeReferred", witnessDate)) + .documentEvidenceForTrialRes2(createEvidenceDocs(null, "typeForTrial", witnessDate)) + .documentDisclosureListRes2(createEvidenceDocs(null, null, null)) + .documentCaseSummaryRes2(createEvidenceDocs(null, null, null)) + .documentSkeletonArgumentRes2(createEvidenceDocs(null, null, null)) + .documentAuthoritiesRes2(createEvidenceDocs(null, null, null)) + .documentCostsRes2(createEvidenceDocs(null, null, null)) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); given(userService.getUserInfo(anyString())).willReturn(UserInfo.builder().uid("uid").build()); @@ -1510,7 +1510,7 @@ void should_do_naming_convention_resp2() { assertThat(updatedData.getDocumentForDisclosureRes2().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Document for disclosure typeDisclosure 10-02-2023.pdf"); assertThat(updatedData.getDocumentReferredInStatementRes2().get(0).getValue() - .getDocumentUpload().getDocumentFileName()).isEqualTo("Referred Document typeReferred 10-02-2023.pdf"); + .getDocumentUpload().getDocumentFileName()).isEqualTo("typeReferred referred to in the statement of witness 10-02-2023.pdf"); assertThat(updatedData.getDocumentEvidenceForTrialRes2().get(0).getValue() .getDocumentUpload().getDocumentFileName()).isEqualTo("Documentary Evidence typeForTrial 10-02-2023.pdf"); assertThat(updatedData.getDocumentDisclosureListRes2().get(0).getValue() @@ -1594,13 +1594,14 @@ void should_compareAndCopy() { assertThat(handler.compareAndCopy(before, after, target)).hasSize(1); } - private List> createEvidenceDocs(String type, LocalDate issuedDate) { + private List> createEvidenceDocs(String name, String type, LocalDate issuedDate) { Document document = Document.builder().documentBinaryUrl( TEST_URL) .documentFileName(TEST_FILE_NAME).build(); List> evidenceDocs = new ArrayList<>(); evidenceDocs.add(ElementUtils.element(UploadEvidenceDocumentType .builder() + .witnessOptionName(name) .typeOfDocument(type) .documentIssuedDate(issuedDate) .documentUpload(document) From 2f921e08808a74dab67735999883c78b77cceb2f Mon Sep 17 00:00:00 2001 From: Harry H <33700332+HarryH96@users.noreply.github.com> Date: Mon, 20 Nov 2023 14:18:45 +0000 Subject: [PATCH 02/29] CIV-0000 - Branch for PRs to be merged after Case Progression Releases Freeze is lifted (#3580) * added changes for claimant response cui event. * add case status case dismissed * add case status case settled and unit tests * modify handler and unit tests for state change * remove unused import * CIV-11158 Save hearing location in case data (#3524) * CIV-11158 Save hearing location in case data --------- Co-authored-by: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Co-authored-by: Hemanth Potipati Co-authored-by: douglasrice Co-authored-by: Harry H <33700332+HarryH96@users.noreply.github.com> * Feat/civ 9025 notification ccj (#3582) * CIV-9023 Claimant Intent: CCJ after Part Admit or Full Admit Pay Immediately - Submit Function * CIV-9023 Claimant Intent: CCJ after Part Admit or Full Admit Pay Immediately - Submit Function * CIV-9023 Claimant Intent: CCJ after Part Admit or Full Admit Pay Immediately - Submit Function * CIV-9025: Set Up Event and Controller * CIV-9025: Set Up Unit Test * CIV-9025: Set Up config for testing * CIV-9025: Fix unused import * CIV-9025: Fix gradle * CIV-9025: Update template * CIV-9025: Update class name * CIV-9025: Remove not related comment * Update FeatureToggleService.java * CIV-9025: Update gradle * CIV-9025: Update gradle * CIV-9025: Update gradle * CIV-9025: Update gradle * CIV-9025: Update gradle * CIV-9025: Update gradle * CIV-9025: Update templates * Update build.gradle --------- Co-authored-by: jeswanth Co-authored-by: jeswanth-hmcts <134285996+jeswanth-hmcts@users.noreply.github.com> Co-authored-by: annika-moorthy <85934693+annika-moorthy@users.noreply.github.com> Co-authored-by: Raja Mani Co-authored-by: kenneth-hmcts Co-authored-by: kenneth-hmcts <91327278+kenneth-hmcts@users.noreply.github.com> Co-authored-by: neeta-hmcts <115545612+neeta-hmcts@users.noreply.github.com> * Feat/civ 9112 rpa mediation lip (#3584) * CIV-9112: Set Up RPA for Lip Claimant * CIV-9112: Update for unit test --------- Co-authored-by: kenneth-hmcts Co-authored-by: kenneth-hmcts <91327278+kenneth-hmcts@users.noreply.github.com> Co-authored-by: annika-moorthy <85934693+annika-moorthy@users.noreply.github.com> * CIV-10124 Update internal and public case name (#3224) * CIV-10124 update internal and public case name --------- Co-authored-by: GarethLancaster <31533575+Gareth40342@users.noreply.github.com> Co-authored-by: sherlynkhaw Co-authored-by: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Co-authored-by: TurkingtonL Co-authored-by: Harry H <33700332+HarryH96@users.noreply.github.com> Co-authored-by: HarryH * fixed ClaimantResponseCuiCallbackHandler * Civ 8938 claimant intent submit function change state to judicial referral (#3577) * CIV-8938 Claimant Intent: Submit Function - Change state to JUDICIAL_REFERRAL * CIV-8938 Claimant Intent: Submit Function - Change state to JUDICIAL_REFERRAL * CIV-8938 Claimant Intent: Submit Function - Change state to JUDICIAL_REFERRAL * CIV-8938 changed name convention * CIV-8938 refactored the code * CIV-8938 refactored the code * CIV-8938 refactored the code * CIV-8938 refactored as commented * CIV-8938 refactored as commented * CIV-8938 refactored as commented * CIV-8938 refactored as commented * CIV-8938 refactored as commented * Update FlowStateAllowedEventService.java * Update FlowStateAllowedEventService.java * Update ClaimantResponseCuiCallbackHandlerTest.java fixed conflict * Update ClaimantResponseCuiCallbackHandler.java fixed merge conflict * Update FlowStateAllowedEventService.java fixed merge conflict * Update ClaimantResponseCuiCallbackHandlerTest.java fixed test failure * Update ClaimantResponseCuiCallbackHandlerTest.java * fixed ubnit test failure. --------- Co-authored-by: jeswanth Co-authored-by: jeswanth-hmcts <134285996+jeswanth-hmcts@users.noreply.github.com> Co-authored-by: neeta-hmcts Co-authored-by: neeta-hmcts <115545612+neeta-hmcts@users.noreply.github.com> * Update ManageContactInformationCallbackHandler.java removed un-used import --------- Co-authored-by: neeta-hmcts Co-authored-by: sankhajuria Co-authored-by: hmcts-version1-domini Co-authored-by: Raja Mani Co-authored-by: hmcts-version1-domini <107860057+hmcts-version1-domini@users.noreply.github.com> Co-authored-by: jarekPierchala Co-authored-by: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Co-authored-by: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Co-authored-by: Hemanth Potipati Co-authored-by: douglasrice Co-authored-by: jarekPierchala <118526007+jarekPierchala@users.noreply.github.com> Co-authored-by: jeswanth Co-authored-by: jeswanth-hmcts <134285996+jeswanth-hmcts@users.noreply.github.com> Co-authored-by: annika-moorthy <85934693+annika-moorthy@users.noreply.github.com> Co-authored-by: kenneth-hmcts Co-authored-by: kenneth-hmcts <91327278+kenneth-hmcts@users.noreply.github.com> Co-authored-by: neeta-hmcts <115545612+neeta-hmcts@users.noreply.github.com> Co-authored-by: GarethLancaster <31533575+Gareth40342@users.noreply.github.com> Co-authored-by: sherlynkhaw Co-authored-by: TurkingtonL --- build.gradle | 2 +- .../reform/civil/callback/CaseEvent.java | 4 +- .../GenerateHearingNoticeHmcHandler.java | 36 ++++++- ...AdmissionApplicantNotificationHandler.java | 83 ++++++++++++++++ ...dmissionRespondentNotificationHandler.java | 83 ++++++++++++++++ .../ClaimantResponseCuiCallbackHandler.java | 29 +++++- .../user/CreateClaimCallbackHandler.java | 29 +----- .../user/CreateClaimSpecCallbackHandler.java | 28 +----- ...nageContactInformationCallbackHandler.java | 9 ++ .../hearing/HearingNoticeHmcGenerator.java | 24 ++--- .../FlowStateAllowedEventService.java | 11 ++- .../robotics/mapper/EventHistoryMapper.java | 2 +- .../reform/civil/utils/CaseNameUtils.java | 26 +++++ .../reform/civil/utils/HmcDataUtils.java | 15 +++ src/main/resources/application.yaml | 3 + .../GenerateHearingNoticeHmcHandlerTest.java | 16 +++- ...ssionApplicantNotificationHandlerTest.java | 96 +++++++++++++++++++ ...sionRespondentNotificationHandlerTest.java | 96 +++++++++++++++++++ ...laimantResponseCuiCallbackHandlerTest.java | 93 +++++++++++++++++- .../HearingNoticeHmcGeneratorTest.java | 15 ++- .../FlowStateAllowedEventServiceTest.java | 3 +- .../reform/civil/utils/CaseNameUtilsTest.java | 42 ++++++++ .../reform/civil/utils/HmcDataUtilsTest.java | 44 +++++++++ 23 files changed, 691 insertions(+), 98 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandlerTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandlerTest.java diff --git a/build.gradle b/build.gradle index 7035befae45..e840aa8b239 100644 --- a/build.gradle +++ b/build.gradle @@ -369,7 +369,7 @@ configurations.all { } dependencies { - implementation 'com.github.hmcts:civil-commons:1.0.33' + implementation 'com.github.hmcts:civil-commons:1.0.34' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop' diff --git a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java index 6ac5788bf56..a54355cea51 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java @@ -298,7 +298,9 @@ public enum CaseEvent { SEND_CVP_JOIN_LINK(USER), SET_LIP_RESPONDENT_RESPONSE_DEADLINE(CAMUNDA), NOTIFY_LIP_RESPONDENT_CLAIMANT_CONFIRM_TO_PROCEED(CAMUNDA), - NOTIFY_LIP_APPLICANT_CLAIMANT_CONFIRM_TO_PROCEED(CAMUNDA); + NOTIFY_LIP_APPLICANT_CLAIMANT_CONFIRM_TO_PROCEED(CAMUNDA), + NOTIFY_APPLICANT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT(CAMUNDA), + NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT(CAMUNDA); private final UserType userType; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandler.java index 51e1cfaef56..92666ce2608 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandler.java @@ -11,7 +11,11 @@ import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.common.DynamicList; +import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.service.docmosis.hearing.HearingNoticeHmcGenerator; import uk.gov.hmcts.reform.civil.service.hearingnotice.HearingNoticeCamundaService; import uk.gov.hmcts.reform.civil.utils.HearingFeeUtils; @@ -30,6 +34,7 @@ import static uk.gov.hmcts.reform.civil.utils.DateUtils.convertFromUTC; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; import static uk.gov.hmcts.reform.civil.utils.HmcDataUtils.getHearingDays; +import static uk.gov.hmcts.reform.civil.utils.HmcDataUtils.getLocationRefData; @Service @RequiredArgsConstructor @@ -45,6 +50,7 @@ public class GenerateHearingNoticeHmcHandler extends CallbackHandler { private final HearingsService hearingsService; private final HearingNoticeHmcGenerator hearingNoticeHmcGenerator; private final ObjectMapper objectMapper; + private final LocationRefDataService locationRefDataService; @Override protected Map callbacks() { @@ -65,17 +71,20 @@ private CallbackResponse generateHearingNotice(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); String processInstanceId = caseData.getBusinessProcess().getProcessInstanceId(); + String bearerToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); var camundaVars = camundaService.getProcessVariables(processInstanceId); var hearing = hearingsService.getHearingResponse( - callbackParams.getParams().get(BEARER_TOKEN).toString(), + bearerToken, camundaVars.getHearingId() ); var hearingStartDay = HmcDataUtils.getHearingStartDay(hearing); var hearingStartDate = convertFromUTC(hearingStartDay.getHearingStartDateTime()); + String hearingLocation = getHearingLocation(camundaVars.getHearingId(), hearing, + bearerToken, locationRefDataService); - buildDocument(callbackParams, caseDataBuilder, hearing); + buildDocument(callbackParams, caseDataBuilder, hearing, hearingLocation, camundaVars.getHearingId()); camundaService.setProcessVariables( processInstanceId, @@ -93,16 +102,22 @@ private CallbackResponse generateHearingNotice(CallbackParams callbackParams) { .data(caseDataBuilder .hearingDate(hearingStartDate.toLocalDate()) .hearingDueDate(HearingFeeUtils.calculateHearingDueDate(LocalDate.now(), hearingStartDate.toLocalDate())) + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder() + .label(hearingLocation) + .build()).build()) .build().toMap(objectMapper)) .build(); } - private void buildDocument(CallbackParams callbackParams, CaseData.CaseDataBuilder caseDataBuilder, HearingGetResponse hearing) { + private void buildDocument(CallbackParams callbackParams, CaseData.CaseDataBuilder caseDataBuilder, HearingGetResponse hearing, + String hearingLocation, String hearingId) { CaseData caseData = callbackParams.getCaseData(); List caseDocuments = hearingNoticeHmcGenerator.generate( caseData, hearing, - callbackParams.getParams().get(BEARER_TOKEN).toString() + callbackParams.getParams().get(BEARER_TOKEN).toString(), + hearingLocation, + hearingId ); List> systemGeneratedCaseDocuments = new ArrayList<>(); systemGeneratedCaseDocuments.add(element(caseDocuments.get(0))); @@ -111,4 +126,17 @@ private void buildDocument(CallbackParams callbackParams, CaseData.CaseDataBuild } caseDataBuilder.hearingDocuments(systemGeneratedCaseDocuments); } + + private String getHearingLocation(String hearingId, HearingGetResponse hearing, + String bearerToken, LocationRefDataService locationRefDataService) { + LocationRefData hearingLocation = getLocationRefData( + hearingId, + HmcDataUtils.getHearingStartDay(hearing).getHearingVenueId(), + bearerToken, + locationRefDataService); + if (hearingLocation != null) { + return LocationRefDataService.getDisplayEntry(hearingLocation); + } + return null; + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler.java new file mode 100644 index 00000000000..28b0d028c8f --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler.java @@ -0,0 +1,83 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.notification; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; +import uk.gov.hmcts.reform.civil.callback.Callback; +import uk.gov.hmcts.reform.civil.callback.CallbackHandler; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.config.PinInPostConfiguration; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; + +import java.util.List; +import java.util.Map; + +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_APPLICANT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT; +import static uk.gov.hmcts.reform.civil.utils.PartyUtils.getPartyNameBasedOnType; + +@Service +@RequiredArgsConstructor +public class ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler extends CallbackHandler implements NotificationData { + + private static final List EVENTS = List.of( + NOTIFY_APPLICANT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT); + public static final String TASK_ID = "RequestJudgementByAdmissionLipClaimantNotifyRespondent1"; + private static final String REFERENCE_TEMPLATE = "request-judgement-by-admission-applicant-notification-%s"; + + private final NotificationService notificationService; + private final NotificationsProperties notificationsProperties; + private final PinInPostConfiguration pipInPostConfiguration; + + @Override + protected Map callbacks() { + return Map.of( + callbackKey(ABOUT_TO_SUBMIT), + this::notifyApplicant1ForRequestJudgementByAdmission + ); + } + + @Override + public String camundaActivityId(CallbackParams callbackParams) { + return TASK_ID; + } + + @Override + public List handledEvents() { + return EVENTS; + } + + private CallbackResponse notifyApplicant1ForRequestJudgementByAdmission(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + + if (!caseData.isLipvLipOneVOne() || caseData.getApplicant1Email() == null) { + return AboutToStartOrSubmitCallbackResponse.builder().build(); + } + + notificationService.sendMail( + addEmail(caseData), + notificationsProperties.getNotifyApplicantLipRequestJudgementByAdmissionNotificationTemplate(), + addProperties(caseData), + String.format(REFERENCE_TEMPLATE, caseData.getLegacyCaseReference()) + ); + return AboutToStartOrSubmitCallbackResponse.builder().build(); + } + + @Override + public Map addProperties(CaseData caseData) { + return Map.of( + CLAIMANT_NAME, getPartyNameBasedOnType(caseData.getApplicant1()), + RESPONDENT_NAME, getPartyNameBasedOnType(caseData.getRespondent1()), + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + FRONTEND_URL, pipInPostConfiguration.getCuiFrontEndUrl() + ); + } + + private String addEmail(CaseData caseData) { + return caseData.getApplicant1Email(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler.java new file mode 100644 index 00000000000..11ea01de632 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler.java @@ -0,0 +1,83 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.notification; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; +import uk.gov.hmcts.reform.civil.callback.Callback; +import uk.gov.hmcts.reform.civil.callback.CallbackHandler; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.config.PinInPostConfiguration; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; + +import java.util.List; +import java.util.Map; + +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT; +import static uk.gov.hmcts.reform.civil.utils.PartyUtils.getPartyNameBasedOnType; + +@Service +@RequiredArgsConstructor +public class ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler extends CallbackHandler implements NotificationData { + + private static final List EVENTS = List.of( + NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT); + public static final String TASK_ID = "RequestJudgementByAdmissionLipClaimantNotifyRespondent1"; + private static final String REFERENCE_TEMPLATE = "request-judgement-by-admission-respondent-notification-%s"; + + private final NotificationService notificationService; + private final NotificationsProperties notificationsProperties; + private final PinInPostConfiguration pipInPostConfiguration; + + @Override + protected Map callbacks() { + return Map.of( + callbackKey(ABOUT_TO_SUBMIT), + this::notifyRespondent1ForRequestJudgementByAdmission + ); + } + + @Override + public String camundaActivityId(CallbackParams callbackParams) { + return TASK_ID; + } + + @Override + public List handledEvents() { + return EVENTS; + } + + private CallbackResponse notifyRespondent1ForRequestJudgementByAdmission(CallbackParams callbackParams) { + CaseData caseData = callbackParams.getCaseData(); + + if (!caseData.isLipvLipOneVOne() || caseData.getRespondent1().getPartyEmail() == null) { + return AboutToStartOrSubmitCallbackResponse.builder().build(); + } + + notificationService.sendMail( + addEmail(caseData), + notificationsProperties.getNotifyRespondentLipRequestJudgementByAdmissionNotificationTemplate(), + addProperties(caseData), + String.format(REFERENCE_TEMPLATE, caseData.getLegacyCaseReference()) + ); + return AboutToStartOrSubmitCallbackResponse.builder().build(); + } + + @Override + public Map addProperties(CaseData caseData) { + return Map.of( + CLAIMANT_NAME, getPartyNameBasedOnType(caseData.getApplicant1()), + RESPONDENT_NAME, getPartyNameBasedOnType(caseData.getRespondent1()), + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + FRONTEND_URL, pipInPostConfiguration.getCuiFrontEndUrl() + ); + } + + private String addEmail(CaseData caseData) { + return caseData.getRespondent1().getPartyEmail(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java index b42f274c8df..00186af4da0 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java @@ -15,11 +15,13 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; +import uk.gov.hmcts.reform.civil.service.Time; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; @@ -36,6 +38,7 @@ public class ClaimantResponseCuiCallbackHandler extends CallbackHandler { private final ResponseOneVOneShowTagService responseOneVOneService; private final ObjectMapper objectMapper; + private final Time time; private final UpdateCaseManagementDetailsService updateCaseManagementLocationDetailsService; @Override @@ -72,21 +75,37 @@ private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { CaseData updatedData = builder.build(); AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response = - AboutToStartOrSubmitCallbackResponse.builder() - .data(updatedData.toMap(objectMapper)); + AboutToStartOrSubmitCallbackResponse.builder() + .data(updatedData.toMap(objectMapper)); + updateClaimStateJudicialReferral(response, updatedData); updateClaimEndState(response, updatedData); return response.build(); } + private void updateClaimStateJudicialReferral( + AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, + CaseData caseData) { + if (isJudicialReferralAllowed(caseData)) { + response.state(CaseState.JUDICIAL_REFERRAL.name()); + } + } + + private boolean isJudicialReferralAllowed(CaseData caseData) { + return (caseData.isClaimantNotSettlePartAdmitClaim() || caseData.isFullDefence()) + && (Objects.nonNull(caseData.getCaseDataLiP()) && caseData.getCaseDataLiP().hasClaimantNotAgreedToFreeMediation()); + } + private void updateClaimEndState(AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, CaseData updatedData) { - if (updatedData.hasClaimantAgreedToFreeMediation()) { + if (updatedData.hasClaimantAgreedToFreeMediation() && updatedData.hasDefendantAgreedToFreeMediation()) { response.state(CaseState.IN_MEDIATION.name()); + } else if (!updatedData.hasApplicantProceededWithClaim()) { + response.state(updatedData.isClaimantConfirmAmountPaidPartAdmit() || updatedData.hasDefendantPayedTheAmountClaimed() + ? CaseState.CASE_SETTLED.name() + : CaseState.CASE_DISMISSED.name()); } else if (updatedData.hasApplicantRejectedRepaymentPlan() && updatedData.getRespondent1().isCompanyOROrganisation()) { response.state(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()); - } else { - response.state(CaseState.JUDICIAL_REFERRAL.name()); } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java index 2f19c71c23e..9b273d650af 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java @@ -19,7 +19,6 @@ import uk.gov.hmcts.reform.civil.config.ToggleConfiguration; import uk.gov.hmcts.reform.civil.enums.CaseCategory; import uk.gov.hmcts.reform.civil.enums.CaseState; -import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.helpers.LocationHelper; import uk.gov.hmcts.reform.civil.model.BusinessProcess; @@ -78,11 +77,11 @@ import static uk.gov.hmcts.reform.civil.enums.AllocatedTrack.getAllocatedTrack; import static uk.gov.hmcts.reform.civil.enums.CaseRole.APPLICANTSOLICITORONE; import static uk.gov.hmcts.reform.civil.enums.CaseRole.RESPONDENTSOLICITORTWO; -import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.CaseListSolicitorReferenceUtils.getAllDefendantSolicitorReferences; import static uk.gov.hmcts.reform.civil.utils.CaseListSolicitorReferenceUtils.getAllOrganisationPolicyReferences; +import static uk.gov.hmcts.reform.civil.utils.CaseNameUtils.buildCaseNameInternal; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.getAllPartyNames; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.populateWithPartyIds; @@ -499,7 +498,7 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { //assign casemanagementcategory to the case and assign casenamehmctsinternal //casename - dataBuilder.caseNameHmctsInternal(caseParticipants(caseData).toString()); + dataBuilder.caseNameHmctsInternal(buildCaseNameInternal(caseData)); //case management category CaseManagementCategoryElement civil = @@ -639,30 +638,6 @@ private List validateCourtChoice(CaseData caseData) { return errorsMessages; } - public StringBuilder caseParticipants(CaseData caseData) { - StringBuilder participantString = new StringBuilder(); - MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); - if (multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP) - || multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP)) { - participantString.append(caseData.getApplicant1().getPartyName()) - .append(" v ").append(caseData.getRespondent1().getPartyName()) - .append(" and ").append(caseData.getRespondent2().getPartyName()); - - } else if (multiPartyScenario.equals(MultiPartyScenario.TWO_V_ONE)) { - participantString.append(caseData.getApplicant1().getPartyName()) - .append(" and ").append(caseData.getApplicant2().getPartyName()).append(" v ") - .append(caseData.getRespondent1() - .getPartyName()); - - } else { - participantString.append(caseData.getApplicant1().getPartyName()).append(" v ") - .append(caseData.getRespondent1() - .getPartyName()); - } - return participantString; - - } - private void handleCourtLocationData(CaseData caseData, CaseData.CaseDataBuilder dataBuilder, CallbackParams callbackParams) { // data for court location diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java index 7dc8d457b95..5ecd44f42bb 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java @@ -18,7 +18,6 @@ import uk.gov.hmcts.reform.civil.config.ClaimUrlsConfiguration; import uk.gov.hmcts.reform.civil.enums.CaseCategory; import uk.gov.hmcts.reform.civil.enums.ClaimType; -import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.Address; import uk.gov.hmcts.reform.civil.model.BusinessProcess; @@ -88,6 +87,7 @@ import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.helpers.DateFormatHelper.DATE_TIME_AT; import static uk.gov.hmcts.reform.civil.helpers.DateFormatHelper.formatLocalDateTime; +import static uk.gov.hmcts.reform.civil.utils.CaseNameUtils.buildCaseNameInternal; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.populateWithPartyIds; @@ -461,7 +461,7 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { dataBuilder.featureToggleWA(toggleConfiguration.getFeatureToggle()); //assign case management category to the case and caseNameHMCTSinternal - dataBuilder.caseNameHmctsInternal(caseParticipants(caseData).toString()); + dataBuilder.caseNameHmctsInternal(buildCaseNameInternal(caseData)); CaseManagementCategoryElement civil = CaseManagementCategoryElement.builder().code("Civil").label("Civil").build(); @@ -945,28 +945,4 @@ private boolean areRespondentsRepresentedAndRegistered(CaseData caseData) { || caseData.getRespondent2Represented() == NO || caseData.getRespondent2OrgRegistered() == NO); } - - public StringBuilder caseParticipants(CaseData caseData) { - StringBuilder participantString = new StringBuilder(); - MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); - if (multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP) - || multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP)) { - participantString.append(caseData.getApplicant1().getPartyName()) - .append(" v ").append(caseData.getRespondent1().getPartyName()) - .append(" and ").append(caseData.getRespondent2().getPartyName()); - - } else if (multiPartyScenario.equals(MultiPartyScenario.TWO_V_ONE)) { - participantString.append(caseData.getApplicant1().getPartyName()) - .append(" and ").append(caseData.getApplicant2().getPartyName()).append(" v ") - .append(caseData.getRespondent1() - .getPartyName()); - - } else { - participantString.append(caseData.getApplicant1().getPartyName()).append(" v ") - .append(caseData.getRespondent1() - .getPartyName()); - } - return participantString; - - } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java index 1ce5e75b370..9c2bc676748 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java @@ -51,6 +51,8 @@ import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addApplicantExpertAndWitnessFlagsStructure; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addRespondentDQPartiesFlagStructure; +import static uk.gov.hmcts.reform.civil.utils.CaseNameUtils.buildCaseNameInternal; +import static uk.gov.hmcts.reform.civil.utils.CaseNameUtils.buildCaseNamePublic; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; @@ -343,10 +345,17 @@ private Boolean isLitigationFriend(String partyChosen) { private CallbackResponse submitChanges(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder builder = caseData.toBuilder(); + String partyChosen = caseData.getUpdateDetailsForm().getPartyChosen().getValue().getCode(); updateExperts(caseData.getUpdateDetailsForm().getPartyChosenId(), caseData, builder); updateWitnesses(caseData.getUpdateDetailsForm().getPartyChosenId(), caseData, builder); + if (isParty(partyChosen) || isLitigationFriend(partyChosen)) { + // update case name for hmc if applicant/respondent/litigation friend was updated + builder.caseNameHmctsInternal(buildCaseNameInternal(caseData)); + builder.caseNamePublic(buildCaseNamePublic(caseData)); + } + // last step before clearing update details form caseFlagsInitialiser.initialiseCaseFlags(MANAGE_CONTACT_INFORMATION, builder); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGenerator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGenerator.java index 9cbf7fc5e24..80113bc4d14 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGenerator.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGenerator.java @@ -1,7 +1,6 @@ package uk.gov.hmcts.reform.civil.service.docmosis.hearing; import lombok.RequiredArgsConstructor; -import org.jetbrains.annotations.Nullable; import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.civil.documentmanagement.DocumentManagementService; import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; @@ -31,6 +30,7 @@ import static java.util.Objects.nonNull; import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_NOTICE_HMC; import static uk.gov.hmcts.reform.civil.utils.HmcDataUtils.getHearingDaysText; +import static uk.gov.hmcts.reform.civil.utils.HmcDataUtils.getLocationRefData; import static uk.gov.hmcts.reform.civil.utils.HmcDataUtils.getTotalHearingDurationText; @Service @@ -43,10 +43,10 @@ public class HearingNoticeHmcGenerator implements TemplateDataGenerator generate(CaseData caseData, HearingGetResponse hearing, String authorisation) { + public List generate(CaseData caseData, HearingGetResponse hearing, String authorisation, String hearingLocation, String hearingId) { List caseDocuments = new ArrayList<>(); - HearingNoticeHmc templateData = getHearingNoticeTemplateData(caseData, hearing, authorisation); + HearingNoticeHmc templateData = getHearingNoticeTemplateData(caseData, hearing, authorisation, hearingLocation, hearingId); DocmosisTemplates template = getTemplate(caseData); DocmosisDocument document = documentGeneratorService.generateDocmosisDocument(templateData, template); @@ -61,7 +61,8 @@ public List generate(CaseData caseData, HearingGetResponse hearing return caseDocuments; } - public HearingNoticeHmc getHearingNoticeTemplateData(CaseData caseData, HearingGetResponse hearing, String bearerToken) { + public HearingNoticeHmc getHearingNoticeTemplateData(CaseData caseData, HearingGetResponse hearing, String bearerToken, + String hearingLocation, String hearingId) { var paymentFailed = caseData.getHearingFeePaymentDetails() == null || caseData.getHearingFeePaymentDetails().getStatus().equals(PaymentStatus.FAILED); var feeAmount = paymentFailed @@ -69,15 +70,13 @@ public HearingNoticeHmc getHearingNoticeTemplateData(CaseData caseData, HearingG var hearingDueDate = paymentFailed ? HearingFeeUtils .calculateHearingDueDate(LocalDate.now(), HmcDataUtils.getHearingStartDay(hearing) .getHearingStartDateTime().toLocalDate()) : null; - LocationRefData hearingLocation = getLocationRefData( - HmcDataUtils.getHearingStartDay(hearing).getHearingVenueId(), - bearerToken); + LocationRefData caseManagementLocation = - getLocationRefData(caseData.getCaseManagementLocation().getBaseLocation(), bearerToken); + getLocationRefData(hearingId, caseData.getCaseManagementLocation().getBaseLocation(), bearerToken, locationRefDataService); return HearingNoticeHmc.builder() .hearingSiteName(nonNull(caseManagementLocation) ? caseManagementLocation.getSiteName() : null) - .hearingLocation(LocationRefDataService.getDisplayEntry(hearingLocation)) + .hearingLocation(hearingLocation) .caseNumber(caseData.getCcdCaseReference()) .creationDate(LocalDate.now()) .hearingType(getHearingType(hearing)) @@ -107,13 +106,6 @@ private DocmosisTemplates getTemplate(CaseData caseData) { return HEARING_NOTICE_HMC; } - @Nullable - private LocationRefData getLocationRefData(String venueId, String bearerToken) { - List locations = locationRefDataService.getCourtLocationsForDefaultJudgments(bearerToken); - var matchedLocations = locations.stream().filter(loc -> loc.getEpimmsId().equals(venueId)).toList(); - return matchedLocations.size() > 0 ? matchedLocations.get(0) : null; - } - private String getHearingType(HearingGetResponse hearing) { if (hearing.getHearingDetails().getHearingType().contains("TRI")) { return "trial"; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java index 85c31fb7330..9e6f7feac1c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java @@ -14,9 +14,6 @@ import static java.util.Collections.emptyList; import static java.util.Map.entry; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIFT_BREATHING_SPACE_LIP; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.asyncStitchingComplete; -import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ACKNOWLEDGEMENT_OF_SERVICE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ACKNOWLEDGE_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ADD_CASE_NOTE; @@ -60,6 +57,7 @@ import static uk.gov.hmcts.reform.civil.callback.CaseEvent.INFORM_AGREED_EXTENSION_DATE_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.INITIATE_GENERAL_APPLICATION; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.JUDGMENT_PAID_IN_FULL; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIFT_BREATHING_SPACE_LIP; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIFT_BREATHING_SPACE_SPEC; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.LIP_CLAIM_SETTLED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MANAGE_CONTACT_INFORMATION; @@ -86,11 +84,11 @@ import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READINESS; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READY_CHECK; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIAL_READY_NOTIFICATION; +import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.UPLOAD_TRANSLATED_DOCUMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.WITHDRAW_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.asyncStitchingComplete; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.migrateCase; -import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.AWAITING_RESPONSES_NOT_FULL_DEFENCE_RECEIVED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.CLAIM_DETAILS_NOTIFIED; @@ -544,6 +542,7 @@ public class FlowStateAllowedEventService { JUDGMENT_PAID_IN_FULL, RECORD_JUDGMENT, TRANSFER_ONLINE_CASE, + CLAIMANT_RESPONSE_CUI, asyncStitchingComplete ) ), @@ -1105,7 +1104,9 @@ public class FlowStateAllowedEventService { RECORD_JUDGMENT, LIP_CLAIM_SETTLED, TRANSFER_ONLINE_CASE, - asyncStitchingComplete + asyncStitchingComplete, + CLAIMANT_RESPONSE_CUI + ) ), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java index f393162c526..75ecdc725a7 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java @@ -1422,7 +1422,7 @@ private void buildRespondentFullDefence(EventHistory.EventHistoryBuilder builder Respondent1DQ respondent1DQ = caseData.getRespondent1DQ(); LocalDateTime respondent1ResponseDate = caseData.getRespondent1ResponseDate(); - if (caseData.isLRvLipOneVOne()) { + if (caseData.isLRvLipOneVOne() || caseData.isLipvLipOneVOne()) { buildLrVLipFullDefenceEvent(builder, caseData, defenceFiledEvents, statesPaidEvents); } else { if (isAllPaid(caseData.getTotalClaimAmount(), caseData.getRespondToClaim())) { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtils.java index 2e06b1e26b4..0fbd650094f 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtils.java @@ -1,9 +1,12 @@ package uk.gov.hmcts.reform.civil.utils; +import uk.gov.hmcts.reform.civil.enums.MultiPartyScenario; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.LitigationFriend; import uk.gov.hmcts.reform.civil.model.Party; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; + public class CaseNameUtils { private CaseNameUtils() { @@ -38,4 +41,27 @@ public static String getFormattedLitigationFriendName(LitigationFriend litigatio litigationFriend.getLastName() ) : ""; } + + public static String buildCaseNameInternal(CaseData caseData) { + StringBuilder participantString = new StringBuilder(); + MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); + if (multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_ONE_LEGAL_REP) + || multiPartyScenario.equals(MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP)) { + participantString.append(caseData.getApplicant1().getPartyName()) + .append(" v ").append(caseData.getRespondent1().getPartyName()) + .append(" and ").append(caseData.getRespondent2().getPartyName()); + + } else if (multiPartyScenario.equals(MultiPartyScenario.TWO_V_ONE)) { + participantString.append(caseData.getApplicant1().getPartyName()) + .append(" and ").append(caseData.getApplicant2().getPartyName()).append(" v ") + .append(caseData.getRespondent1() + .getPartyName()); + + } else { + participantString.append(caseData.getApplicant1().getPartyName()).append(" v ") + .append(caseData.getRespondent1() + .getPartyName()); + } + return participantString.toString(); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtils.java index 20de01439ea..ab7cf85cf11 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtils.java @@ -1,5 +1,8 @@ package uk.gov.hmcts.reform.civil.utils; +import org.jetbrains.annotations.Nullable; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.hmc.model.hearing.HearingDaySchedule; import uk.gov.hmcts.reform.hmc.model.hearing.HearingGetResponse; import uk.gov.hmcts.reform.hmc.model.hearings.CaseHearing; @@ -204,4 +207,16 @@ public static boolean includesVideoHearing(HearingsResponse hearings) { && hearings.getCaseHearings().stream() .filter(hearing -> includesVideoHearing(hearing)).count() > 0; } + + @Nullable + public static LocationRefData getLocationRefData(String hearingId, String venueId, + String bearerToken, LocationRefDataService locationRefDataService) { + List locations = locationRefDataService.getCourtLocationsForDefaultJudgments(bearerToken); + var matchedLocations = locations.stream().filter(loc -> loc.getEpimmsId().equals(venueId)).toList(); + if (matchedLocations.size() > 0) { + return matchedLocations.get(0); + } else { + throw new IllegalArgumentException("Hearing location data not available for hearing " + hearingId); + } + } } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 187c0e2b2f9..e0f7be8b390 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -319,6 +319,9 @@ notifications: notifyLiPApplicantBreathingSpaceLifted: "b6dbc714-210e-475d-a1db-bf5ea28de98b" notifyLiPRespondentBreathingSpaceLifted: "4ca3017b-b2fa-4ac0-a867-9bfada50a80c" + notifyApplicantLipRequestJudgementByAdmissionNotificationTemplate: "d6625ee3-f794-4a87-b0a3-bef7dd0663b9" + notifyRespondentLipRequestJudgementByAdmissionNotificationTemplate: "6ced7f9c-b0fd-4fad-a76c-745873b9a3a2" + sendgrid: api-key: ${SENDGRID_API_KEY:false} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandlerTest.java index d67db158add..17b08b9e12b 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateHearingNoticeHmcHandlerTest.java @@ -16,6 +16,8 @@ import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.CaseDocumentBuilder; import uk.gov.hmcts.reform.civil.service.docmosis.hearing.HearingNoticeHmcGenerator; import uk.gov.hmcts.reform.civil.service.hearingnotice.HearingNoticeCamundaService; @@ -62,6 +64,8 @@ public class GenerateHearingNoticeHmcHandlerTest extends BaseCallbackHandlerTest private HearingNoticeCamundaService camundaService; @MockBean private HearingNoticeHmcGenerator hearingNoticeHmcGenerator; + @MockBean + private LocationRefDataService locationRefDataService; private static Long CASE_ID = 1L; private static String HEARING_ID = "1234"; @@ -108,9 +112,13 @@ public void shouldPopulateCamundaProcessVariables_andReturnExpectedCaseData() { .caseId(CASE_ID) .build(); + List locations = List.of(LocationRefData.builder() + .epimmsId(EPIMS).build()); + when(locationRefDataService.getCourtLocationsForDefaultJudgments(anyString())) + .thenReturn(locations); when(camundaService.getProcessVariables(PROCESS_INSTANCE_ID)).thenReturn(inputVariables); when(hearingsService.getHearingResponse(anyString(), anyString())).thenReturn(hearing); - when(hearingNoticeHmcGenerator.generate(eq(caseData), eq(hearing), anyString())).thenReturn(List.of(CASE_DOCUMENT)); + when(hearingNoticeHmcGenerator.generate(eq(caseData), eq(hearing), anyString(), anyString(), anyString())).thenReturn(List.of(CASE_DOCUMENT)); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); params.getRequest().setEventId(GENERATE_HEARING_NOTICE_HMC.name()); @@ -168,9 +176,13 @@ public void shouldPopulateCamundaProcessVariables_andReturnExpectedCaseData_BstH .caseId(CASE_ID) .build(); + List locations = List.of(LocationRefData.builder() + .epimmsId(EPIMS).build()); + when(locationRefDataService.getCourtLocationsForDefaultJudgments(anyString())) + .thenReturn(locations); when(camundaService.getProcessVariables(PROCESS_INSTANCE_ID)).thenReturn(inputVariables); when(hearingsService.getHearingResponse(anyString(), anyString())).thenReturn(hearing); - when(hearingNoticeHmcGenerator.generate(eq(caseData), eq(hearing), anyString())).thenReturn(List.of(CASE_DOCUMENT)); + when(hearingNoticeHmcGenerator.generate(eq(caseData), eq(hearing), anyString(), anyString(), anyString())).thenReturn(List.of(CASE_DOCUMENT)); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); params.getRequest().setEventId(GENERATE_HEARING_NOTICE_HMC.name()); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandlerTest.java new file mode 100644 index 00000000000..227cfcb1707 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandlerTest.java @@ -0,0 +1,96 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.notification; + +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.config.PinInPostConfiguration; +import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; +import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; +import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler.TASK_ID; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIMANT_NAME; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIM_REFERENCE_NUMBER; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.FRONTEND_URL; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.RESPONDENT_NAME; +import static uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder.LEGACY_CASE_REFERENCE; + +@SpringBootTest(classes = { + ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler.class, + JacksonAutoConfiguration.class +}) + +class ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandlerTest extends BaseCallbackHandlerTest { + + @MockBean + private NotificationService notificationService; + @MockBean + private NotificationsProperties notificationsProperties; + @MockBean + private PinInPostConfiguration pinInPostConfiguration; + @Autowired + private ClaimantLipRequestJudgementByAdmissionApplicantNotificationHandler handler; + + @Nested + class AboutToSubmitCallback { + + @BeforeEach + void setup() { + when(notificationsProperties.getNotifyApplicantLipRequestJudgementByAdmissionNotificationTemplate()).thenReturn("template-id"); + when(pinInPostConfiguration.getRespondToClaimUrl()).thenReturn("dummy_respond_to_claim_url"); + when(pinInPostConfiguration.getCuiFrontEndUrl()).thenReturn("dummy_cui_front_end_url"); + } + + @Test + void shouldNotifyLipApplicant_whenInvoked() { + CaseData caseData = CaseDataBuilder.builder().atStateClaimIssued1v1LiP() + .applicant1Represented(NO) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( + CallbackRequest.builder().eventId("NOTIFY_APPLICANT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT") + .build()).build(); + + handler.handle(params); + + verify(notificationService).sendMail( + "rambo@email.com", + "template-id", + getNotificationDataMap(caseData), + "request-judgement-by-admission-applicant-notification-000DC001" + ); + } + + @Test + void shouldReturnCorrectCamundaActivityId_whenInvoked() { + assertThat(handler.camundaActivityId(CallbackParamsBuilder.builder().request(CallbackRequest.builder().eventId( + "NOTIFY_APPLICANT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT").build()).build())).isEqualTo(TASK_ID); + } + + @NotNull + private Map getNotificationDataMap(CaseData caseData) { + return Map.of( + RESPONDENT_NAME, "Mr. Sole Trader", + CLAIMANT_NAME, "Mr. John Rambo", + CLAIM_REFERENCE_NUMBER, LEGACY_CASE_REFERENCE, + FRONTEND_URL, "dummy_cui_front_end_url" + ); + } + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandlerTest.java new file mode 100644 index 00000000000..9cc9ff4aad7 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandlerTest.java @@ -0,0 +1,96 @@ +package uk.gov.hmcts.reform.civil.handler.callback.camunda.notification; + +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.config.PinInPostConfiguration; +import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.notify.NotificationService; +import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; +import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; +import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler.TASK_ID; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIMANT_NAME; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIM_REFERENCE_NUMBER; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.FRONTEND_URL; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.RESPONDENT_NAME; +import static uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder.LEGACY_CASE_REFERENCE; + +@SpringBootTest(classes = { + ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler.class, + JacksonAutoConfiguration.class +}) + +class ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandlerTest extends BaseCallbackHandlerTest { + + @MockBean + private NotificationService notificationService; + @MockBean + private NotificationsProperties notificationsProperties; + @MockBean + private PinInPostConfiguration pinInPostConfiguration; + @Autowired + private ClaimantLipRequestJudgementByAdmissionRespondentNotificationHandler handler; + + @Nested + class AboutToSubmitCallback { + + @BeforeEach + void setup() { + when(notificationsProperties.getNotifyRespondentLipRequestJudgementByAdmissionNotificationTemplate()).thenReturn("template-id"); + when(pinInPostConfiguration.getRespondToClaimUrl()).thenReturn("dummy_respond_to_claim_url"); + when(pinInPostConfiguration.getCuiFrontEndUrl()).thenReturn("dummy_cui_front_end_url"); + } + + @Test + void shouldNotifyLipRespondent_whenInvoked() { + CaseData caseData = CaseDataBuilder.builder().atStateClaimIssued1v1LiP() + .applicant1Represented(NO) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).request( + CallbackRequest.builder().eventId("NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT") + .build()).build(); + + handler.handle(params); + + verify(notificationService).sendMail( + "sole.trader@email.com", + "template-id", + getNotificationDataMap(caseData), + "request-judgement-by-admission-respondent-notification-000DC001" + ); + } + + @Test + void shouldReturnCorrectCamundaActivityId_whenInvoked() { + assertThat(handler.camundaActivityId(CallbackParamsBuilder.builder().request(CallbackRequest.builder().eventId( + "NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT").build()).build())).isEqualTo(TASK_ID); + } + + @NotNull + private Map getNotificationDataMap(CaseData caseData) { + return Map.of( + RESPONDENT_NAME, "Mr. Sole Trader", + CLAIMANT_NAME, "Mr. John Rambo", + CLAIM_REFERENCE_NUMBER, LEGACY_CASE_REFERENCE, + FRONTEND_URL, "dummy_cui_front_end_url" + ); + } + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java index 8c889304389..238deb1dace 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java @@ -27,10 +27,12 @@ import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; +import uk.gov.hmcts.reform.civil.service.Time; import uk.gov.hmcts.reform.civil.service.citizen.UpdateCaseManagementDetailsService; import uk.gov.hmcts.reform.civil.service.citizenui.ResponseOneVOneShowTagService; import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -38,10 +40,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.junit.jupiter.api.Assertions.assertEquals; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.CLAIMANT_RESPONSE_CUI; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; +import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.model.Party.Type.COMPANY; import static uk.gov.hmcts.reform.civil.model.Party.Type.ORGANISATION; @@ -73,6 +77,8 @@ class ClaimantResponseCuiCallbackHandlerTest extends BaseCallbackHandlerTest { @MockBean private ResponseOneVOneShowTagService responseOneVOneShowTagService; + @MockBean + private Time time; @Nested class AboutToStartCallback { @@ -91,6 +97,8 @@ void shouldReturnNoError_WhenAboutToStartIsInvoked() { @Nested class AboutToSubmitCallback { + private final LocalDateTime submittedDate = LocalDateTime.now(); + @BeforeEach void before() { LocationRefData locationRefData = LocationRefData.builder().siteName("Site 1").courtAddress("Adr 1").postcode("AAA 111") @@ -99,13 +107,13 @@ void before() { .epimmsId("111").build(); given(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) .willReturn(getSampleCourLocationsRefObject()); + given(time.now()).willReturn(submittedDate); given(locationHelper.updateCaseManagementLocation(any(), any(), any())).willReturn(Optional.ofNullable(locationRefData)); } @Test void shouldUpdateBusinessProcess() { CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued1v1LiP() .caseDataLip( CaseDataLiP.builder() .applicant1ClaimMediationSpecRequiredLip( @@ -113,6 +121,7 @@ void shouldUpdateBusinessProcess() { .hasAgreedFreeMediation(MediationDecision.Yes) .build()) .build()) + .atStateClaimIssued() .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -148,6 +157,7 @@ void shouldOnlyUpdateClaimStatus_whenPartAdmitNotSettled_NoMediation() { .build()).build(); CaseData caseData = CaseDataBuilder.builder() .atStateClaimIssued() + .applicant1ProceedWithClaim(YES) .applicant1PartAdmitConfirmAmountPaidSpec(NO) .applicant1PartAdmitIntentionToSettleClaimSpec(NO) .applicant1DQ(applicant1DQ) @@ -176,6 +186,76 @@ void shouldOnlyUpdateClaimStatus_whenPartAdmitNotSettled_NoMediation() { assertThat(data.getCaseNameHmctsInternal()).isEqualTo(data.getApplicant1().getPartyName() + " v " + data.getRespondent1().getPartyName()); } + @Test + void shouldUpdateCaseStateToJudicialReferral_WhenPartAdmitNoSettle_NoMediation() { + CaseDataLiP caseDataLiP = CaseDataLiP.builder() + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() + .hasAgreedFreeMediation(MediationDecision.No).build()) + .build(); + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(caseDataLiP) + .applicant1AcceptAdmitAmountPaidSpec(NO) + .applicant1ProceedWithClaim(YES) + .atStateClaimIssued().build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertEquals(CaseState.JUDICIAL_REFERRAL.name(), response.getState()); + + } + + @Test + void shouldUpdateCaseStateToJudicialReferral_WhenNotReceivedPayment_NoMediation_ForPartAdmit() { + CaseDataLiP caseDataLiP = CaseDataLiP.builder() + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() + .hasAgreedFreeMediation(MediationDecision.No).build()) + .build(); + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(caseDataLiP) + .applicant1ProceedWithClaim(YES) + .applicant1PartAdmitConfirmAmountPaidSpec(NO) + .atStateClaimIssued().build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertEquals(CaseState.JUDICIAL_REFERRAL.name(), response.getState()); + + } + + @Test + void shouldUpdateCaseStateToJudicialReferral_WhenFullDefence_NotPaid_NoMediation() { + CaseDataLiP caseDataLiP = CaseDataLiP.builder() + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() + .hasAgreedFreeMediation(MediationDecision.No).build()) + .build(); + CaseData caseData = + CaseDataBuilder.builder().caseDataLip(caseDataLiP).applicant1PartAdmitIntentionToSettleClaimSpec(NO) + .atStateClaimIssued() + .applicant1ProceedWithClaim(YES) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertEquals(CaseState.JUDICIAL_REFERRAL.name(), response.getState()); + + } + + @Test + void shouldUpdateCaseStateToJudicialReferral_WhenFullDefence() { + CaseDataLiP caseDataLiP = CaseDataLiP.builder() + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() + .hasAgreedFreeMediation(MediationDecision.No).build()) + .build(); + CaseData caseData = + CaseDataBuilder.builder().caseDataLip(caseDataLiP).applicant1ProceedWithClaim(YES) + .atStateClaimIssued() + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + assertEquals(CaseState.JUDICIAL_REFERRAL.name(), response.getState()); + } + @Test void shouldChangeCaseState_whenApplicantRejectClaimSettlementAndAgreeToMediation() { CaseData caseData = CaseDataBuilder.builder() @@ -184,7 +264,8 @@ void shouldChangeCaseState_whenApplicantRejectClaimSettlementAndAgreeToMediation .caseDataLip(CaseDataLiP.builder().applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder().hasAgreedFreeMediation( MediationDecision.Yes).build()) .build()) - .build(); + .build().toBuilder() + .responseClaimMediationSpecRequired(YES).build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); @@ -209,8 +290,11 @@ protected List getSampleCourLocationsRefObject() { @Test void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsCompany_toAllFinalOrdersIssued() { CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued() .applicant1AcceptPartAdmitPaymentPlanSpec(NO) + .caseDataLip(CaseDataLiP.builder().applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder().hasAgreedFreeMediation( + MediationDecision.No).build()).build()) + .applicant1ProceedWithClaim(YES) + .applicant1(Party.builder().type(Party.Type.COMPANY).companyName("CLAIMANT_ORG_NAME").build()) .respondent1(Party.builder() .type(COMPANY) .companyName("Test Inc") @@ -226,7 +310,8 @@ void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsCompany_toAllFin @Test void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsOrganisation_toAllFinalOrdersIssued() { CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued() + .applicant1(Party.builder().type(Party.Type.COMPANY).companyName("CLAIMANT_ORG_NAME").build()) + .applicant1ProceedWithClaim(YES) .applicant1AcceptPartAdmitPaymentPlanSpec(NO) .respondent1(Party.builder() .type(ORGANISATION) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGeneratorTest.java index c7ab605231c..ebae86ffe38 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGeneratorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingNoticeHmcGeneratorTest.java @@ -159,7 +159,8 @@ void shouldGenerateHearingNoticeHmc_1v1_whenHearingFeeHasBeenPaid() { .calculatedAmountInPence(new BigDecimal(123)) .build()); - var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN); + var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN, + "SiteName - CourtAddress - Postcode", "hearingId"); var expected = HearingNoticeHmc.builder() .caseNumber(caseData.getCcdCaseReference()) .creationDate(LocalDate.now()) @@ -212,7 +213,8 @@ void shouldGenerateHearingNoticeHmc_1v1_whenHearingFeeHasNotBeenPaid() { .calculatedAmountInPence(new BigDecimal(123)) .build()); - var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN); + var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN, + "SiteName - CourtAddress - Postcode", "hearingId"); var expected = HearingNoticeHmc.builder() .caseNumber(caseData.getCcdCaseReference()) .creationDate(LocalDate.now()) @@ -265,7 +267,8 @@ void shouldGenerateHearingNoticeHmc_1v2DS_whenHearingFeeHasBeenPaid() { .calculatedAmountInPence(new BigDecimal(123)) .build()); - var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN); + var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN, + "SiteName - CourtAddress - Postcode", "hearingId"); var expected = HearingNoticeHmc.builder() .caseNumber(caseData.getCcdCaseReference()) .creationDate(LocalDate.now()) @@ -322,7 +325,8 @@ void shouldGenerateHearingNoticeHmc_2v1_whenHearingFeeHasBeenPaid() { .calculatedAmountInPence(new BigDecimal(123)) .build()); - var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN); + var actual = generator.getHearingNoticeTemplateData(caseData, hearing, BEARER_TOKEN, + "SiteName - CourtAddress - Postcode", "hearingId"); var expected = HearingNoticeHmc.builder() .caseNumber(caseData.getCcdCaseReference()) .creationDate(LocalDate.now()) @@ -377,7 +381,8 @@ void shouldReturnListOfExpectedCaseDocuments() { .calculatedAmountInPence(new BigDecimal(123)) .build()); - var actual = generator.generate(caseData, hearing, BEARER_TOKEN); + var actual = generator.generate(caseData, hearing, BEARER_TOKEN, + "SiteName - CourtAddress - Postcode", "hearingId"); var expected = List.of(CASE_DOCUMENT); verify(documentManagementService) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java index f1dd6858eae..fd68c866dc9 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventServiceTest.java @@ -571,7 +571,8 @@ public Stream provideArguments(ExtensionContext context) { JUDGMENT_PAID_IN_FULL, RECORD_JUDGMENT, TRANSFER_ONLINE_CASE, - asyncStitchingComplete + asyncStitchingComplete, + CLAIMANT_RESPONSE_CUI } ), of( diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtilsTest.java index e11e64e2c49..067bd4020c1 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseNameUtilsTest.java @@ -6,8 +6,11 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.LitigationFriend; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import static uk.gov.hmcts.reform.civil.utils.CaseNameUtils.buildCaseNameInternal; class CaseNameUtilsTest { @@ -214,4 +217,43 @@ void shouldReturnExpectedCaseName_with2v1PartyData_bothAppsLiFriend() { "v 'Respondent One'", actual); } } + + @Nested + class BuildCaseNameInternal { + + @Test + void shouldReturnCaseName_when1v1() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .build(); + + String actual = buildCaseNameInternal(caseData); + + assertThat(actual).isEqualTo("Mr. John Rambo v Mr. Sole Trader"); + } + + @Test + void shouldReturnCaseName_when1v2() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .multiPartyClaimTwoDefendantSolicitors() + .build(); + + String actual = buildCaseNameInternal(caseData); + + assertThat(actual).isEqualTo("Mr. John Rambo v Mr. Sole Trader and Mr. John Rambo"); + } + + @Test + void shouldReturnCaseName_when2v1() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .multiPartyClaimTwoApplicants() + .build(); + + String actual = buildCaseNameInternal(caseData); + + assertThat(actual).isEqualTo("Mr. John Rambo and Mr. Jason Rambo v Mr. Sole Trader"); + } + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtilsTest.java index 25c701014df..55f9c09758b 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/HmcDataUtilsTest.java @@ -2,6 +2,11 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.hmc.model.hearing.Attendees; import uk.gov.hmcts.reform.hmc.model.hearing.CaseDetailsHearing; import uk.gov.hmcts.reform.hmc.model.hearing.HearingDaySchedule; @@ -20,10 +25,13 @@ import java.util.ArrayList; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.utils.HmcDataUtils.includesVideoHearing; import static uk.gov.hmcts.reform.hmc.model.hearing.HearingSubChannel.INTER; import static uk.gov.hmcts.reform.hmc.model.hearing.HearingSubChannel.VIDCVP; @@ -947,4 +955,40 @@ void shouldReturnTrue_IfVideoHearingsExistOneDayWithinMultipleDays() { assertTrue(actual); } } + + @Nested + @ExtendWith(SpringExtension.class) + class GetHearingLocation { + + @MockBean + private LocationRefDataService locationRefDataService; + + @Test + void shouldReturnLocation_whenInvoked() { + List locations = List.of(LocationRefData.builder().epimmsId("venue").build()); + when(locationRefDataService.getCourtLocationsForDefaultJudgments("authToken")) + .thenReturn(locations); + LocationRefData locationRefData = HmcDataUtils.getLocationRefData( + "HER123", + "venue", + "authToken", + locationRefDataService + ); + + assertThat(locationRefData).isEqualTo(LocationRefData.builder().epimmsId("venue").build()); + } + + @Test + void shouldThrowException_whenLocationIsNull() { + when(locationRefDataService.getCourtLocationsForDefaultJudgments("abc")) + .thenReturn(null); + assertThrows( + IllegalArgumentException.class, + () -> HmcDataUtils.getLocationRefData( + "HER123", + "abc", + "authToken", + locationRefDataService)); + } + } } From d840a911f502ac0b83ad888dd97d182f09668cc6 Mon Sep 17 00:00:00 2001 From: Harry H <33700332+HarryH96@users.noreply.github.com> Date: Tue, 21 Nov 2023 09:50:36 +0000 Subject: [PATCH 03/29] CIV-10382 Revert "Revert "CIV-10382 Case flags updates for new experts/witnesses"" (#3592) * Revert "Revert "CIV-10382 Case flags updates for new experts/witnesses (#3296)" (#3591)" This reverts commit 7d4c8332ea45d2082f0305481ae1e19596f753aa. * point to ccd changes --------- Co-authored-by: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Co-authored-by: sankaviv1 --- Jenkinsfile_CNP | 2 +- ...nageContactInformationCallbackHandler.java | 48 ++- .../RespondToClaimSpecCallbackHandler.java | 5 - .../reform/civil/utils/CaseFlagUtils.java | 62 ++- .../utils/ManageContactInformationUtils.java | 71 +++- .../hmcts/reform/civil/utils/PartyUtils.java | 2 +- ...ContactInformationCallbackHandlerTest.java | 45 ++- ...BundleCreationTriggerEventHandlerTest.java | 15 +- .../civil/sampledata/CaseDataBuilder.java | 32 +- .../reform/civil/utils/CaseFlagUtilsTest.java | 359 ++++++++++++++++++ .../utils/CaseFlagsHearingsUtilsTest.java | 10 +- .../civil/utils/CaseFlagsInitialiserTest.java | 50 +-- .../ManageContactInformationUtilsTest.java | 33 +- 13 files changed, 618 insertions(+), 116 deletions(-) diff --git a/Jenkinsfile_CNP b/Jenkinsfile_CNP index b7c16bf6c94..e9515f0aca9 100644 --- a/Jenkinsfile_CNP +++ b/Jenkinsfile_CNP @@ -8,7 +8,7 @@ import uk.gov.hmcts.contino.GithubAPI def type = "java" def product = "civil" def component = "service" -def ccdBranch = "master" +def ccdBranch = "revert-3591-revert-3279-feat/civ-10382" def camundaBranch = "master" def yarnBuilder = new uk.gov.hmcts.contino.YarnBuilder(this) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java index 9c2bc676748..b44285833c5 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java @@ -18,6 +18,7 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.LitigationFriend; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.PartyFlagStructure; import uk.gov.hmcts.reform.civil.model.UpdateDetailsForm; import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; import uk.gov.hmcts.reform.civil.model.common.DynamicList; @@ -49,10 +50,9 @@ import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; -import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addApplicantExpertAndWitnessFlagsStructure; -import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.addRespondentDQPartiesFlagStructure; import static uk.gov.hmcts.reform.civil.utils.CaseNameUtils.buildCaseNameInternal; import static uk.gov.hmcts.reform.civil.utils.CaseNameUtils.buildCaseNamePublic; +import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; @@ -77,6 +77,8 @@ import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQExperts; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQWitnesses; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapWitnessesToUpdatePartyDetailsForm; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.updatePartyDQExperts; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.updatePartyDQWitnesses; import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isApplicantSolicitor; import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isRespondentSolicitorOne; import static uk.gov.hmcts.reform.civil.utils.UserRoleUtils.isRespondentSolicitorTwo; @@ -395,8 +397,11 @@ private void updateExperts(String partyId, CaseData caseData, CaseData.CaseDataB .details(mappedExperts) .build()) .build()); - addApplicantExpertAndWitnessFlagsStructure(builder, caseData); - //TODO: need to add it to top level party object + List> updatedApplicantExperts = updatePartyDQExperts( + unwrapElements(caseData.getApplicantExperts()), + unwrapElements(mappedExperts) + ); + builder.applicantExperts(updatedApplicantExperts); } else if (partyId.equals(DEFENDANT_ONE_EXPERTS_ID)) { mappedExperts = mapUpdatePartyDetailsFormToDQExperts( caseData.getRespondent1DQ().getRespondent1DQExperts().getDetails(), formData); @@ -407,8 +412,11 @@ private void updateExperts(String partyId, CaseData caseData, CaseData.CaseDataB .details(mappedExperts) .build()) .build()); - addRespondentDQPartiesFlagStructure(builder, caseData); - //TODO: need to add it to top level party object + List> updatedRespondent1Experts = updatePartyDQExperts( + unwrapElements(caseData.getRespondent1Experts()), + unwrapElements(mappedExperts) + ); + builder.respondent1Experts(updatedRespondent1Experts); } else if (partyId.equals(DEFENDANT_TWO_EXPERTS_ID)) { mappedExperts = mapUpdatePartyDetailsFormToDQExperts( caseData.getRespondent2DQ().getRespondent2DQExperts().getDetails(), formData); @@ -419,8 +427,11 @@ private void updateExperts(String partyId, CaseData caseData, CaseData.CaseDataB .details(mappedExperts) .build()) .build()); - addRespondentDQPartiesFlagStructure(builder, caseData); - //TODO: need to add it to top level party object + List> updatedRespondent2Experts = updatePartyDQExperts( + unwrapElements(caseData.getRespondent2Experts()), + unwrapElements(mappedExperts) + ); + builder.respondent2Experts(updatedRespondent2Experts); } } @@ -439,8 +450,11 @@ private void updateWitnesses(String partyId, CaseData caseData, CaseData.CaseDat .details(mappedWitnesses) .build()) .build()); - addApplicantExpertAndWitnessFlagsStructure(builder, caseData); - //TODO: need to add it to top level party object + List> updatedApplicantWitnesses = updatePartyDQWitnesses( + unwrapElements(caseData.getApplicantWitnesses()), + unwrapElements(mappedWitnesses) + ); + builder.applicantWitnesses(updatedApplicantWitnesses); } else if (partyId.equals(DEFENDANT_ONE_WITNESSES_ID)) { mappedWitnesses = mapUpdatePartyDetailsFormToDQWitnesses( caseData.getRespondent1DQ().getRespondent1DQWitnesses().getDetails(), formData); @@ -451,8 +465,11 @@ private void updateWitnesses(String partyId, CaseData caseData, CaseData.CaseDat .details(mappedWitnesses) .build()) .build()); - addRespondentDQPartiesFlagStructure(builder, caseData); - //TODO: need to add it to top level party object + List> updatedRespondent1Witnesses = updatePartyDQWitnesses( + unwrapElements(caseData.getRespondent1Witnesses()), + unwrapElements(mappedWitnesses) + ); + builder.respondent1Witnesses(updatedRespondent1Witnesses); } else if (partyId.equals(DEFENDANT_TWO_WITNESSES_ID)) { mappedWitnesses = mapUpdatePartyDetailsFormToDQWitnesses( caseData.getRespondent2DQ().getRespondent2DQWitnesses().getDetails(), formData); @@ -463,8 +480,11 @@ private void updateWitnesses(String partyId, CaseData caseData, CaseData.CaseDat .details(mappedWitnesses) .build()) .build()); - addRespondentDQPartiesFlagStructure(builder, caseData); - //TODO: need to add it to top level party object + List> updatedRespondent2Witnesses = updatePartyDQWitnesses( + unwrapElements(caseData.getRespondent2Witnesses()), + unwrapElements(mappedWitnesses) + ); + builder.respondent2Witnesses(updatedRespondent2Witnesses); } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java index 5640b94350a..5a666f36a17 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/RespondToClaimSpecCallbackHandler.java @@ -138,7 +138,6 @@ import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; import static uk.gov.hmcts.reform.civil.utils.ExpertUtils.addEventAndDateAddedToRespondentExperts; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.populateDQPartyIds; -import static uk.gov.hmcts.reform.civil.utils.PartyUtils.populateWithPartyIds; import static uk.gov.hmcts.reform.civil.utils.WitnessUtils.addEventAndDateAddedToRespondentWitnesses; @Service @@ -1528,10 +1527,6 @@ && ifResponseTypeIsPartOrFullAdmission(caseData)) { } } - if (toggleService.isHmcEnabled()) { - populateWithPartyIds(updatedData); - } - updateCorrespondenceAddress(callbackParams, updatedData, caseData); if (getMultiPartyScenario(caseData) == ONE_V_TWO_TWO_LEGAL_REP diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java index cfc0249f777..34ec802e60a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtils.java @@ -24,21 +24,27 @@ import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_WITNESSES_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_WITNESSES_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_WITNESSES_ID; import static uk.gov.hmcts.reform.civil.utils.PartyUtils.appendWithNewPartyId; import uk.gov.hmcts.reform.civil.model.LitigationFriend; @@ -48,20 +54,20 @@ public class CaseFlagUtils { - public static final String RESPONDENT_SOLICITOR_ONE_WITNESS = "Respondent solicitor 1 witness"; - public static final String RESPONDENT_SOLICITOR_ONE_EXPERT = "Respondent solicitor 1 expert"; - public static final String RESPONDENT_SOLICITOR_TWO_WITNESS = "Respondent solicitor 2 witness"; - public static final String RESPONDENT_SOLICITOR_TWO_EXPERT = "Respondent solicitor 2 expert"; - public static final String APPLICANT_SOLICITOR_WITNESS = "Applicant solicitor witness"; - public static final String APPLICANT_SOLICITOR_EXPERT = "Applicant solicitor expert"; - public static final String APPLICANT_ONE = "Applicant 1"; - public static final String APPLICANT_TWO = "Applicant 2"; - public static final String APPLICANT_ONE_LITIGATION_FRIEND = "Applicant 1 Litigation Friend"; - public static final String APPLICANT_TWO_LITIGATION_FRIEND = "Applicant 2 Litigation Friend"; - public static final String RESPONDENT_ONE = "Respondent 1"; - public static final String RESPONDENT_TWO = "Respondent 2"; - public static final String RESPONDENT_ONE_LITIGATION_FRIEND = "Respondent 1 Litigation Friend"; - public static final String RESPONDENT_TWO_LITIGATION_FRIEND = "Respondent 2 Litigation Friend"; + public static final String RESPONDENT_SOLICITOR_ONE_WITNESS = "Defendant solicitor 1 witness"; + public static final String RESPONDENT_SOLICITOR_ONE_EXPERT = "Defendant solicitor 1 expert"; + public static final String RESPONDENT_SOLICITOR_TWO_WITNESS = "Defendant solicitor 2 witness"; + public static final String RESPONDENT_SOLICITOR_TWO_EXPERT = "Defendant solicitor 2 expert"; + public static final String APPLICANT_SOLICITOR_WITNESS = "Claimant solicitor witness"; + public static final String APPLICANT_SOLICITOR_EXPERT = "Claimant solicitor expert"; + public static final String APPLICANT_ONE = "Claimant 1"; + public static final String APPLICANT_TWO = "Claimant 2"; + public static final String APPLICANT_ONE_LITIGATION_FRIEND = "Claimant 1 Litigation Friend"; + public static final String APPLICANT_TWO_LITIGATION_FRIEND = "Claimant 2 Litigation Friend"; + public static final String RESPONDENT_ONE = "Defendant 1"; + public static final String RESPONDENT_TWO = "Defendant 2"; + public static final String RESPONDENT_ONE_LITIGATION_FRIEND = "Defendant 1 Litigation Friend"; + public static final String RESPONDENT_TWO_LITIGATION_FRIEND = "Defendant 2 Litigation Friend"; private CaseFlagUtils() { //NO-OP @@ -209,6 +215,10 @@ public static void createOrUpdateFlags(CaseData.CaseDataBuilder builder, C updateOrgIndividualsFlags(builder, caseData, partyChosen); // attending for legal rep updateLRIndividualsFlags(builder, caseData, partyChosen, organisationService); + // experts + updateExpertFlags(builder, caseData, partyChosen); + // witnesses + updateWitnessFlags(builder, caseData, partyChosen); } private static void updateLRIndividualsFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen, OrganisationService organisationService) { @@ -265,6 +275,30 @@ private static void updateLitigationFriendFlags(CaseData.CaseDataBuilder b } } + private static void updateExpertFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen) { + if ((CLAIMANT_ONE_EXPERTS_ID).equals(partyChosen)) { + builder.applicantExperts(updatePartyNameForPartyFlagStructures(caseData.getApplicantExperts(), APPLICANT_SOLICITOR_EXPERT)); + } + if ((DEFENDANT_ONE_EXPERTS_ID).equals(partyChosen)) { + builder.respondent1Experts(updatePartyNameForPartyFlagStructures(caseData.getRespondent1Experts(), RESPONDENT_SOLICITOR_ONE_EXPERT)); + } + if ((DEFENDANT_TWO_EXPERTS_ID).equals(partyChosen)) { + builder.respondent2Experts(updatePartyNameForPartyFlagStructures(caseData.getRespondent2Experts(), RESPONDENT_SOLICITOR_TWO_EXPERT)); + } + } + + private static void updateWitnessFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen) { + if ((CLAIMANT_ONE_WITNESSES_ID).equals(partyChosen)) { + builder.applicantWitnesses(updatePartyNameForPartyFlagStructures(caseData.getApplicantWitnesses(), APPLICANT_SOLICITOR_WITNESS)); + } + if ((DEFENDANT_ONE_WITNESSES_ID).equals(partyChosen)) { + builder.respondent1Witnesses(updatePartyNameForPartyFlagStructures(caseData.getRespondent1Witnesses(), RESPONDENT_SOLICITOR_ONE_WITNESS)); + } + if ((DEFENDANT_TWO_WITNESSES_ID).equals(partyChosen)) { + builder.respondent2Witnesses(updatePartyNameForPartyFlagStructures(caseData.getRespondent2Witnesses(), RESPONDENT_SOLICITOR_TWO_WITNESS)); + } + } + private static void updatePartyFlags(CaseData.CaseDataBuilder builder, CaseData caseData, String partyChosen) { if ((CLAIMANT_ONE_ID).equals(partyChosen)) { builder.applicant1(updatePartyNameForFlags(caseData.getApplicant1())); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java index 83ff6136dd6..66b6ddde40e 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtils.java @@ -2,6 +2,7 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.PartyFlagStructure; import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; import uk.gov.hmcts.reform.civil.model.common.Element; @@ -18,6 +19,7 @@ import static uk.gov.hmcts.reform.civil.model.common.DynamicListElement.dynamicElementFromCode; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.PartyUtils.createPartyId; public class ManageContactInformationUtils { @@ -180,18 +182,8 @@ public static List> mapUpdatePartyDetailsFormToDQExperts(List> mapUpdatePartyDetailsFormToDQWitnesses(List .phoneNumber(formWitness.getPhoneNumber()) .dateAdded(LocalDate.now()) .eventAdded("Manage Contact Information Event") - .partyID(null) //CIV-10382 + .partyID(createPartyId()) .build())); - // Replace above to this in CIV-10382 - // newWitnesses.addAll(wrapElements(appendWithNewPartyIds(Witness.builder() - // .firstName(formWitness.getFirstName()) - // .lastName(formWitness.getLastName()) - // .emailAddress(formWitness.getEmailAddress()) - // .phoneNumber(formWitness.getPhoneNumber()) - // .dateAdded(LocalDate.now()) - // .eventAdded("Manage Contact Information Event") - // .build()))); } } } @@ -265,6 +248,52 @@ public static List> mapUpdatePartyDetailsFormToDQWitnesses(List return newWitnesses; } + public static List> updatePartyDQWitnesses(List existingParties, List witnesses) { + List updatedPartyWitnesses = new ArrayList<>(); + if (witnesses == null || witnesses.isEmpty()) { + return null; + } + for (Witness witness : witnesses) { + updatedPartyWitnesses.add(updateTopLevelPartyInfo(witness.getPartyID(), + witness.getFirstName(), witness.getLastName(), + witness.getPhoneNumber(), witness.getEmailAddress(), + existingParties)); + } + return wrapElements(updatedPartyWitnesses); + } + + public static List> updatePartyDQExperts(List existingParties, List experts) { + List updatedPartyExperts = new ArrayList<>(); + if (experts == null || experts.isEmpty()) { + return null; + } + for (Expert expert : experts) { + updatedPartyExperts.add(updateTopLevelPartyInfo(expert.getPartyID(), + expert.getFirstName(), expert.getLastName(), + expert.getPhoneNumber(), expert.getEmailAddress(), + existingParties)); + } + return wrapElements(updatedPartyExperts); + } + + private static PartyFlagStructure updateTopLevelPartyInfo(String partyId, String firstName, String lastName, String phoneNumber, String email, + List existingParties) { + return existingParties.stream().filter(p -> p.getPartyID().equals(partyId)).findFirst() + .map(p -> (p.toBuilder() + .firstName(firstName) + .lastName(lastName) + .phone(phoneNumber) + .email(email) + .build())) + .orElse(PartyFlagStructure.builder() + .partyID(partyId) + .firstName(firstName) + .lastName(lastName) + .phone(phoneNumber) + .email(email) + .build()); + } + private static String formatId(String partyChosen, String isAdmin, Party party) { return String.format("%s_%s_%s", partyChosen, isAdmin, party.getType().toString()); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/utils/PartyUtils.java b/src/main/java/uk/gov/hmcts/reform/civil/utils/PartyUtils.java index 2da2a2861dd..ccc6919e09c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/utils/PartyUtils.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/utils/PartyUtils.java @@ -351,7 +351,7 @@ public static String getAllPartyNames(CaseData caseData) { ? ", " + caseData.getRespondent2().getPartyName() : ""); } - private static String createPartyId() { + public static String createPartyId() { return UUID.randomUUID().toString().substring(0, 16); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java index 8ff9b667be7..5efbacd0c02 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java @@ -1,11 +1,15 @@ package uk.gov.hmcts.reform.civil.handler.callback.user; import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -22,6 +26,7 @@ import uk.gov.hmcts.reform.civil.model.Address; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; +import uk.gov.hmcts.reform.civil.model.PartyFlagStructure; import uk.gov.hmcts.reform.civil.model.UpdateDetailsForm; import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; import uk.gov.hmcts.reform.civil.model.common.DynamicList; @@ -37,6 +42,7 @@ import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.service.CoreCaseUserService; import uk.gov.hmcts.reform.civil.utils.CaseFlagsInitialiser; +import uk.gov.hmcts.reform.civil.utils.PartyUtils; import uk.gov.hmcts.reform.civil.validation.PostcodeValidator; import uk.gov.hmcts.reform.idam.client.models.UserInfo; import java.time.LocalDate; @@ -48,6 +54,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; @@ -79,6 +86,7 @@ CaseDetailsConverter.class, PostcodeValidator.class }) +@SuppressWarnings("unchecked") class ManageContactInformationCallbackHandlerTest extends BaseCallbackHandlerTest { @Autowired @@ -718,6 +726,23 @@ class AboutToSubmit { Expert expectedExpert1; Witness dqWitness; Witness expectedWitness1; + PartyFlagStructure expectedExpertFlags; + PartyFlagStructure expectedWitnessFlags; + + private static final String PARTY_ID = "party-id"; + private static MockedStatic partyIdMock; + + @BeforeAll + static void setupSuite() { + partyIdMock = mockStatic(PartyUtils.class, Mockito.CALLS_REAL_METHODS); + partyIdMock.when(PartyUtils::createPartyId).thenReturn(PARTY_ID); + } + + @AfterAll + static void tearDown() { + partyIdMock.reset(); + partyIdMock.close(); + } @BeforeEach void setup() { @@ -725,12 +750,22 @@ void setup() { dqExpert = Expert.builder().partyID("id").firstName("dq").lastName("dq").build(); expectedExpert1 = dqExpert.builder().firstName("First").lastName("Name") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) - .partyID(null) //change this for CIV-10382 + .partyID(PARTY_ID) + .build(); + expectedExpertFlags = PartyFlagStructure.builder() + .partyID(PARTY_ID) + .firstName("First") + .lastName("Name") .build(); dqWitness = Witness.builder().firstName("dq").lastName("dq").partyID("id").build(); expectedWitness1 = Witness.builder().firstName("First").lastName("Name") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) - .partyID(null).build(); // CIV-10382 + .partyID(PARTY_ID).build(); + expectedWitnessFlags = PartyFlagStructure.builder() + .partyID(PARTY_ID) + .firstName("First") + .lastName("Name") + .build(); } @Test @@ -757,6 +792,7 @@ void shouldUpdateApplicantOneExperts() { CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); assertThat(unwrapElements(updatedData.getApplicant1DQ().getApplicant1DQExperts().getDetails()).get(0)).isEqualTo(expectedExpert1); + assertThat(unwrapElements(updatedData.getApplicantExperts()).get(0)).isEqualTo(expectedExpertFlags); } @Test @@ -783,6 +819,7 @@ void shouldUpdateDefendantOneExperts() { CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); assertThat(unwrapElements(updatedData.getRespondent1DQ().getRespondent1DQExperts().getDetails()).get(0)).isEqualTo(expectedExpert1); + assertThat(unwrapElements(updatedData.getRespondent1Experts()).get(0)).isEqualTo(expectedExpertFlags); } @Test @@ -809,6 +846,7 @@ void shouldUpdateDefendantTwoExperts() { CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); assertThat(unwrapElements(updatedData.getRespondent2DQ().getRespondent2DQExperts().getDetails()).get(0)).isEqualTo(expectedExpert1); + assertThat(unwrapElements(updatedData.getRespondent2Experts()).get(0)).isEqualTo(expectedExpertFlags); } @Test @@ -835,6 +873,7 @@ void shouldUpdateApplicantOneWitnesses() { CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); assertThat(unwrapElements(updatedData.getApplicant1DQ().getApplicant1DQWitnesses().getDetails()).get(0)).isEqualTo(expectedWitness1); + assertThat(unwrapElements(updatedData.getApplicantWitnesses()).get(0)).isEqualTo(expectedWitnessFlags); } @Test @@ -861,6 +900,7 @@ void shouldUpdateDefendantOneWitnesses() { CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); assertThat(unwrapElements(updatedData.getRespondent1DQ().getRespondent1DQWitnesses().getDetails()).get(0)).isEqualTo(expectedWitness1); + assertThat(unwrapElements(updatedData.getRespondent1Witnesses()).get(0)).isEqualTo(expectedWitnessFlags); } @Test @@ -887,6 +927,7 @@ void shouldUpdateDefendantTwoWitnesses() { CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); assertThat(unwrapElements(updatedData.getRespondent2DQ().getRespondent2DQWitnesses().getDetails()).get(0)).isEqualTo(expectedWitness1); + assertThat(unwrapElements(updatedData.getRespondent2Witnesses()).get(0)).isEqualTo(expectedWitnessFlags); } @Test diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/event/BundleCreationTriggerEventHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/event/BundleCreationTriggerEventHandlerTest.java index e16bed27992..e413a24bb18 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/event/BundleCreationTriggerEventHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/event/BundleCreationTriggerEventHandlerTest.java @@ -191,8 +191,9 @@ void testSendBundleCreationTriggerDoesNotThrowExceptionWhenItsAllGood() { // Given: Case details with all type of documents require for bundles BundleCreationTriggerEvent event = new BundleCreationTriggerEvent(1L); when(coreCaseDataService.getCase(1L)).thenReturn(caseDetails); - when(coreCaseDataService.startUpdate(event.getCaseId().toString(), CREATE_BUNDLE)) - .thenReturn(StartEventResponse.builder().caseDetails(CaseDetailsBuilder.builder().data(caseData).build()).eventId("event1").token("test").build()); + StartEventResponse response = StartEventResponse.builder() + .caseDetails(CaseDetailsBuilder.builder().data(caseData).build()).eventId("event1").token("test").build(); + when(coreCaseDataService.startUpdate(event.getCaseId().toString(), CREATE_BUNDLE)).thenReturn(response); when(bundleCreationService.createBundle(event)).thenReturn(bundleCreateResponse); when(caseDetailsConverter.toCaseData(anyMap())).thenReturn(caseData); @@ -279,8 +280,9 @@ void verifyBundleNotificationEventTriggeredWhenBundleCreated() { // Given: Case details with all type of documents require for bundles BundleCreationTriggerEvent event = new BundleCreationTriggerEvent(1L); when(coreCaseDataService.getCase(1L)).thenReturn(caseDetails); - when(coreCaseDataService.startUpdate(event.getCaseId().toString(), CREATE_BUNDLE)) - .thenReturn(StartEventResponse.builder().caseDetails(CaseDetailsBuilder.builder().data(caseData).build()).eventId("event1").token("test").build()); + StartEventResponse response = StartEventResponse.builder() + .caseDetails(CaseDetailsBuilder.builder().data(caseData).build()).eventId("event1").token("test").build(); + when(coreCaseDataService.startUpdate(event.getCaseId().toString(), CREATE_BUNDLE)).thenReturn(response); when(bundleCreationService.createBundle(event)).thenReturn(bundleCreateResponse); when(caseDetailsConverter.toCaseData(anyMap())).thenReturn(caseData); @@ -296,8 +298,9 @@ void verifyNoBundleNotificationEventTriggeredWhenBundleNotCreated() { // createBundle service BundleCreationTriggerEvent event = new BundleCreationTriggerEvent(1L); when(coreCaseDataService.getCase(1L)).thenReturn(caseDetails); - when(coreCaseDataService.startUpdate(event.getCaseId().toString(), CREATE_BUNDLE)) - .thenReturn(StartEventResponse.builder().caseDetails(CaseDetailsBuilder.builder().data(caseData).build()).eventId("event1").token("test").build()); + StartEventResponse response = StartEventResponse.builder() + .caseDetails(CaseDetailsBuilder.builder().data(caseData).build()).eventId("event1").token("test").build(); + when(coreCaseDataService.startUpdate(event.getCaseId().toString(), CREATE_BUNDLE)).thenReturn(response); when(bundleCreationService.createBundle(event)).thenThrow(new RuntimeException("Runtime Exception")); when(caseDetailsConverter.toCaseData(anyMap())).thenReturn(caseData); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java index df35ed83ab4..37ce3e52316 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java @@ -5771,7 +5771,7 @@ public CaseDataBuilder withApplicant1Flags(List> flags) { .partyID("res-1-party-id") .flags(Flags.builder() .partyName(applicant1.getPartyName()) - .roleOnCase("Applicant 1") + .roleOnCase("Claimant 1") .details(flags) .build()) .build(); @@ -5784,7 +5784,7 @@ public CaseDataBuilder withApplicant1WitnessFlags() { .lastName("W last") .flags(Flags.builder() .partyName("W First W Last") - .roleOnCase("Applicant 1 Witness") + .roleOnCase("Claimant 1 Witness") .details(flagDetails()) .build()) .build()); @@ -5797,7 +5797,7 @@ public CaseDataBuilder withApplicant1ExpertFlags() { .lastName("E last") .flags(Flags.builder() .partyName("E First E Last") - .roleOnCase("Applicant 1 Expert") + .roleOnCase("Claimant 1 Expert") .details(flagDetails()) .build()) .build()); @@ -5808,7 +5808,7 @@ public CaseDataBuilder withApplicant1LitigationFriendFlags() { this.applicant1LitigationFriend = applicant1LitigationFriend.toBuilder() .flags(Flags.builder() .partyName(applicant1LitigationFriend.getFullName()) - .roleOnCase("Applicant 1 Litigation Friend") + .roleOnCase("Claimant 1 Litigation Friend") .details(flagDetails()) .build()) .build(); @@ -5819,7 +5819,7 @@ public CaseDataBuilder withApplicant2Flags() { this.applicant2 = applicant2.toBuilder() .flags(Flags.builder() .partyName(applicant2.getPartyName()) - .roleOnCase("Applicant 2") + .roleOnCase("Claimant 2") .details(flagDetails()) .build()) .build(); @@ -5832,7 +5832,7 @@ public CaseDataBuilder withApplicant2WitnessFlags() { .lastName("W last") .flags(Flags.builder() .partyName("W First W Last") - .roleOnCase("Applicant 2 Witness") + .roleOnCase("Claimant 2 Witness") .details(flagDetails()) .build()) .build()); @@ -5845,7 +5845,7 @@ public CaseDataBuilder withApplicant2ExpertFlags() { .lastName("E last") .flags(Flags.builder() .partyName("E First E Last") - .roleOnCase("Applicant 2 Expert") + .roleOnCase("Claimant 2 Expert") .details(flagDetails()) .build()) .build()); @@ -5856,7 +5856,7 @@ public CaseDataBuilder withApplicant2LitigationFriendFlags() { this.applicant2LitigationFriend = applicant2LitigationFriend.toBuilder() .flags(Flags.builder() .partyName(applicant2LitigationFriend.getFullName()) - .roleOnCase("Applicant 2 Litigation Friend") + .roleOnCase("Claimant 2 Litigation Friend") .details(flagDetails()) .build()) .build(); @@ -5872,7 +5872,7 @@ public CaseDataBuilder withRespondent1LitigationFriendFlags(List> flags) { .partyID("res-1-party-id") .flags(Flags.builder() .partyName(respondent1.getPartyName()) - .roleOnCase("Respondent 1") + .roleOnCase("Defendant 1") .details(flags) .build()) .build(); @@ -5903,7 +5903,7 @@ public CaseDataBuilder withRespondent1WitnessFlags() { .lastName("W last") .flags(Flags.builder() .partyName("W First W Last") - .roleOnCase("Respondent 1 Witness") + .roleOnCase("Defendant 1 Witness") .details(flagDetails()) .build()) .build()); @@ -5918,7 +5918,7 @@ public CaseDataBuilder withRespondent1ExpertFlags() { .lastName("E last") .flags(Flags.builder() .partyName("E First E Last") - .roleOnCase("Respondent 1 Expert") + .roleOnCase("Defendant 1 Expert") .details(flagDetails()) .build()) .build()); @@ -5929,7 +5929,7 @@ public CaseDataBuilder withRespondent2Flags() { this.respondent2 = respondent2.toBuilder() .flags(Flags.builder() .partyName(respondent2.getPartyName()) - .roleOnCase("Respondent 2") + .roleOnCase("Defendant 2") .details(flagDetails()) .build()) .build(); @@ -5942,7 +5942,7 @@ public CaseDataBuilder withRespondent2ExpertFlags() { .lastName("E last") .flags(Flags.builder() .partyName("E First E Last") - .roleOnCase("Respondent 2 Expert") + .roleOnCase("Defendant 2 Expert") .details(flagDetails()) .build()) .build()); @@ -5955,7 +5955,7 @@ public CaseDataBuilder withRespondent2WitnessFlags() { .lastName("W last") .flags(Flags.builder() .partyName("W First W Last") - .roleOnCase("Respondent 2 Witness") + .roleOnCase("Defendant 2 Witness") .details(flagDetails()) .build()) .build()); @@ -5966,7 +5966,7 @@ public CaseDataBuilder withRespondent2LitigationFriendFlags() { this.respondent2LitigationFriend = respondent2LitigationFriend.toBuilder() .flags(Flags.builder() .partyName(respondent2LitigationFriend.getFullName()) - .roleOnCase("Respondent 2 Litigation Friend") + .roleOnCase("Defendant 2 Litigation Friend") .details(flagDetails()) .build()) .build(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java index aae666611d3..e326aebcf25 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagUtilsTest.java @@ -35,6 +35,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.APPLICANT_SOLICITOR_EXPERT; @@ -49,21 +50,27 @@ import static uk.gov.hmcts.reform.civil.utils.CaseFlagUtils.getAllCaseFlags; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.unwrapElements; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.wrapElements; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LEGAL_REP_INDIVIDUALS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_ONE_WITNESSES_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.CLAIMANT_TWO_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LEGAL_REP_INDIVIDUALS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_ONE_WITNESSES_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_EXPERTS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LEGAL_REP_INDIVIDUALS_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_LITIGATION_FRIEND_ID; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_ORG_INDIVIDUALS_ID; +import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.DEFENDANT_TWO_WITNESSES_ID; class CaseFlagUtilsTest { @@ -1339,5 +1346,357 @@ void shouldUpdateFlagName_whenRespondent2OrgIndividualNameUpdated() { assertThat(individual.getPartyID()).isEqualTo("res-2-org-ind-party-id"); } } + + @Nested + class Experts { + + @Test + void shouldCreateFlag_whenClaimantExpertsAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_EXPERTS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicantExperts(wrapElements(PartyFlagStructure.builder() + .firstName("Ex").lastName("Pert") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicantExperts()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Ex Pert") + .details(List.of()) + .roleOnCase("Claimant solicitor expert").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenClaimantExpertNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addApplicant1ExpertsAndWitnesses() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_EXPERTS_ID).build()) + .build(); + + PartyFlagStructure newParty = unwrapElements(caseData.getApplicantExperts()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicantExperts(wrapElements(newParty.toBuilder() + .flags(Flags.builder() + .partyName("Exxxx Pert") + .roleOnCase("Claimant solicitor expert") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Ex").lastName("Pert") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicantExperts()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Ex Pert") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Claimant solicitor expert").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("app-1-expert-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent1ExpertsAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_EXPERTS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1Experts(wrapElements(PartyFlagStructure.builder() + .firstName("Ex").lastName("Pert") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1Experts()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Ex Pert") + .details(List.of()) + .roleOnCase("Defendant solicitor 1 expert").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent1ExpertNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addRespondent1ExpertsAndWitnesses() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_EXPERTS_ID).build()) + .build(); + + PartyFlagStructure newParty = unwrapElements(caseData.getRespondent1Experts()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1Experts(wrapElements(newParty.toBuilder() + .flags(Flags.builder() + .partyName("Exxxx Pert") + .roleOnCase("Defendant solicitor 1 expert") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Ex").lastName("Pert") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1Experts()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Ex Pert") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Defendant solicitor 1 expert").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-1-expert-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent2ExpertsAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_EXPERTS_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2Experts(wrapElements(PartyFlagStructure.builder() + .firstName("Ex").lastName("Pert") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2Experts()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Ex Pert") + .details(List.of()) + .roleOnCase("Defendant solicitor 2 expert").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent2ExpertNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .multiPartyClaimTwoDefendantSolicitors() + .atStateApplicantRespondToDefenceAndProceed(ONE_V_TWO_TWO_LEGAL_REP) + .addRespondent2ExpertsAndWitnesses() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_EXPERTS_ID).build()) + .build(); + + PartyFlagStructure newParty = unwrapElements(caseData.getRespondent2Experts()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2Experts(wrapElements(newParty.toBuilder() + .flags(Flags.builder() + .partyName("Exxxx Pert") + .roleOnCase("Defendant solicitor 2 expert") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Ex").lastName("Pert") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2Experts()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Ex Pert") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Defendant solicitor 2 expert").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-2-expert-party-id"); + } + } + + @Nested + class Witnesses { + + @Test + void shouldCreateFlag_whenClaimantWitnessAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_WITNESSES_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicantWitnesses(wrapElements(PartyFlagStructure.builder() + .firstName("Wit").lastName("Ness") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicantWitnesses()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Wit Ness") + .details(List.of()) + .roleOnCase("Claimant solicitor witness").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenClaimantWitnessNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addApplicant1ExpertsAndWitnesses() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(CLAIMANT_ONE_WITNESSES_ID).build()) + .build(); + + PartyFlagStructure newParty = unwrapElements(caseData.getApplicantWitnesses()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .applicantWitnesses(wrapElements(newParty.toBuilder() + .flags(Flags.builder() + .partyName("Wittyness") + .roleOnCase("Claimant solicitor witness") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Wit").lastName("Ness") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getApplicantWitnesses()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Wit Ness") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Claimant solicitor witness").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("app-1-witness-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent1WitnessAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_WITNESSES_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1Witnesses(wrapElements(PartyFlagStructure.builder() + .firstName("Wit").lastName("Ness") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1Witnesses()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Wit Ness") + .details(List.of()) + .roleOnCase("Defendant solicitor 1 witness").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent1WitnessNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .addRespondent1ExpertsAndWitnesses() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_ONE_WITNESSES_ID).build()) + .build(); + + PartyFlagStructure newParty = unwrapElements(caseData.getRespondent1Witnesses()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent1Witnesses(wrapElements(newParty.toBuilder() + .flags(Flags.builder() + .partyName("Wittyness") + .roleOnCase("Defendant solicitor 1 witness") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Wit").lastName("Ness") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent1Witnesses()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Wit Ness") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Defendant solicitor 1 witness").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-1-witness-party-id"); + } + + @Test + void shouldCreateFlag_whenRespondent2WitnessAdded() { + CaseData caseData = CaseDataBuilder.builder() + .atStateApplicantRespondToDefenceAndProceed() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_WITNESSES_ID).build()) + .build(); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2Witnesses(wrapElements(PartyFlagStructure.builder() + .firstName("Wit").lastName("Ness") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2Witnesses()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Wit Ness") + .details(List.of()) + .roleOnCase("Defendant solicitor 2 witness").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isNotNull(); + } + + @Test + void shouldUpdateFlagName_whenRespondent2WitnessNameUpdated() { + CaseData caseData = CaseDataBuilder.builder() + .multiPartyClaimTwoDefendantSolicitors() + .atStateApplicantRespondToDefenceAndProceed(ONE_V_TWO_TWO_LEGAL_REP) + .addRespondent2ExpertsAndWitnesses() + .updateDetailsForm(UpdateDetailsForm.builder().partyChosenId(DEFENDANT_TWO_WITNESSES_ID).build()) + .build(); + + PartyFlagStructure newParty = unwrapElements(caseData.getRespondent2Witnesses()).get(0); + + CaseData.CaseDataBuilder builder = caseData.toBuilder() + .respondent2Witnesses(wrapElements(newParty.toBuilder() + .flags(Flags.builder() + .partyName("Wittyness") + .roleOnCase("Defendant solicitor 2 witness") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))).build()) + .firstName("Wit").lastName("Ness") + .build())); + + CaseFlagUtils.createOrUpdateFlags(builder, builder.build(), organisationService); + + PartyFlagStructure individual = unwrapElements(builder.build().getRespondent2Witnesses()).get(0); + Flags actualFlags = individual.getFlags(); + Flags expectedFlags = Flags.builder().partyName("Wit Ness") + .details(wrapElements(List.of( + FlagDetail.builder().name("flag name").build()))) + .roleOnCase("Defendant solicitor 2 witness").build(); + + assertThat(actualFlags).isEqualTo(expectedFlags); + assertThat(individual.getPartyID()).isEqualTo("res-2-witness-party-id"); + } + } } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsHearingsUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsHearingsUtilsTest.java index cd69f72b6b4..e283a982a6d 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsHearingsUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsHearingsUtilsTest.java @@ -187,25 +187,25 @@ void shouldReturnFalse_whenDetainedIndividualFlagDoesNotExists() { } private PartyFlags getRespondent1Flags(CaseData caseData, List> details) { - return getFlagsForParty(caseData.getRespondent1().getPartyName(), "Respondent 1", details, caseData.getRespondent1().getPartyID()); + return getFlagsForParty(caseData.getRespondent1().getPartyName(), "Defendant 1", details, caseData.getRespondent1().getPartyID()); } private PartyFlags getApplicant1Flags(CaseData caseData, List> details) { - return getFlagsForParty(caseData.getApplicant1().getPartyName(), "Applicant 1", details, caseData.getApplicant1().getPartyID()); + return getFlagsForParty(caseData.getApplicant1().getPartyName(), "Claimant 1", details, caseData.getApplicant1().getPartyID()); } private PartyFlags getRespondent1LitFriendFlags(CaseData caseData, List> details) { return getFlagsForParty(caseData.getRespondent1LitigationFriend().getFullName(), - "Respondent 1 Litigation Friend", details, caseData.getRespondent1LitigationFriend().getPartyID()); + "Defendant 1 Litigation Friend", details, caseData.getRespondent1LitigationFriend().getPartyID()); } private PartyFlags getRespondent1WitnessFlags(CaseData caseData, List> details) { - return getFlagsForParty("W First W Last", "Respondent 1 Witness", details, + return getFlagsForParty("W First W Last", "Defendant 1 Witness", details, "res-1-witness-party-id"); } private PartyFlags getRespondent1ExpertsFlags(CaseData caseData, List> details) { - return getFlagsForParty("E First E Last", "Respondent 1 Expert", details, + return getFlagsForParty("E First E Last", "Defendant 1 Expert", details, "res-1-expert-party-id"); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java index 334bb719764..9259720273c 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/CaseFlagsInitialiserTest.java @@ -76,19 +76,19 @@ void shouldInitialiseCaseFlagsForCreateClaimEvent() { applicant1.toBuilder().flags( Flags.builder() .partyName("Mr. John Rambo") - .roleOnCase("Applicant 1") + .roleOnCase("Claimant 1") .details(List.of()).build()).build()) .applicant2( applicant2.toBuilder().flags( Flags.builder() .partyName("Company ltd") - .roleOnCase("Applicant 2") + .roleOnCase("Claimant 2") .details(List.of()).build()).build()) .applicant1LitigationFriend( applicant1LitFriend.toBuilder().flags( Flags.builder() .partyName("Jason Wilson") - .roleOnCase("Applicant 1 Litigation Friend") + .roleOnCase("Claimant 1 Litigation Friend") .details(List.of()).build()) .build() ) @@ -96,20 +96,20 @@ void shouldInitialiseCaseFlagsForCreateClaimEvent() { applicant2LitFriend.toBuilder().flags( Flags.builder() .partyName("Jenny Carter") - .roleOnCase("Applicant 2 Litigation Friend") + .roleOnCase("Claimant 2 Litigation Friend") .details(List.of()).build()) .build()) .respondent1( respondent1.toBuilder().flags( Flags.builder() .partyName("Mr. Sole Trader") - .roleOnCase("Respondent 1") + .roleOnCase("Defendant 1") .details(List.of()).build()).build()) .respondent2( respondent2.toBuilder().flags( Flags.builder() .partyName("The Organisation") - .roleOnCase("Respondent 2") + .roleOnCase("Defendant 2") .details(List.of()).build()).build()) .build(); @@ -136,7 +136,7 @@ void shouldInitialiseCaseFlagsForAddLitigationFriendEvent() { respondent1LitFriend.toBuilder().flags( Flags.builder() .partyName("Jason Wilson") - .roleOnCase("Respondent 1 Litigation Friend") + .roleOnCase("Defendant 1 Litigation Friend") .details(List.of()).build()) .build() ) @@ -144,7 +144,7 @@ void shouldInitialiseCaseFlagsForAddLitigationFriendEvent() { respondent2LitFriend.toBuilder().flags( Flags.builder() .partyName("Jenny Carter") - .roleOnCase("Respondent 2 Litigation Friend") + .roleOnCase("Defendant 2 Litigation Friend") .details(List.of()).build()) .build()) .build(); @@ -228,19 +228,19 @@ void shouldReinitialiseMissingCaseFlags() { applicant1.toBuilder().flags( Flags.builder() .partyName("Mr. John Rambo") - .roleOnCase("Applicant 1") + .roleOnCase("Claimant 1") .details(List.of()).build()).build()) .applicant2( applicant2.toBuilder().flags( Flags.builder() .partyName("Company ltd") - .roleOnCase("Applicant 2") + .roleOnCase("Claimant 2") .details(List.of()).build()).build()) .applicant1LitigationFriend( applicant1LitFriend.toBuilder().flags( Flags.builder() .partyName("Jason Wilson") - .roleOnCase("Applicant 1 Litigation Friend") + .roleOnCase("Claimant 1 Litigation Friend") .details(List.of()).build()) .build() ) @@ -248,14 +248,14 @@ void shouldReinitialiseMissingCaseFlags() { applicant2LitFriend.toBuilder().flags( Flags.builder() .partyName("Jenny Carter") - .roleOnCase("Applicant 2 Litigation Friend") + .roleOnCase("Claimant 2 Litigation Friend") .details(List.of()).build()) .build()) .respondent1( respondent1.toBuilder().flags( Flags.builder() .partyName("Mr. Sole Trader") - .roleOnCase("Respondent 1") + .roleOnCase("Defendant 1") .details(List.of()).build()).build()) .applicantWitnesses(wrapElements(List.of( PartyFlagStructure.builder() @@ -418,19 +418,19 @@ void shouldNotReinitialiseCaseFlagsForRespondentDQ_whenRespondent1DQFlagsExist() applicant1.toBuilder().flags( Flags.builder() .partyName("Mr. John Rambo") - .roleOnCase("Applicant 1") + .roleOnCase("Claimant 1") .details(List.of()).build()).build()) .applicant2( applicant2.toBuilder().flags( Flags.builder() .partyName("Company ltd") - .roleOnCase("Applicant 2") + .roleOnCase("Claimant 2") .details(List.of()).build()).build()) .applicant1LitigationFriend( applicant1LitFriend.toBuilder().flags( Flags.builder() .partyName("Jason Wilson") - .roleOnCase("Applicant 1 Litigation Friend") + .roleOnCase("Claimant 1 Litigation Friend") .details(List.of()).build()) .build() ) @@ -438,20 +438,20 @@ void shouldNotReinitialiseCaseFlagsForRespondentDQ_whenRespondent1DQFlagsExist() applicant2LitFriend.toBuilder().flags( Flags.builder() .partyName("Jenny Carter") - .roleOnCase("Applicant 2 Litigation Friend") + .roleOnCase("Claimant 2 Litigation Friend") .details(List.of()).build()) .build()) .respondent1( respondent1.toBuilder().flags( Flags.builder() .partyName("Mr. Sole Trader") - .roleOnCase("Respondent 1") + .roleOnCase("Defendant 1") .details(List.of()).build()).build()) .respondent2( respondent2.toBuilder().flags( Flags.builder() .partyName("The Organisation") - .roleOnCase("Respondent 2") + .roleOnCase("Defendant 2") .details(List.of()).build()).build()) .applicantWitnesses(wrapElements(List.of( PartyFlagStructure.builder() @@ -720,19 +720,19 @@ void shouldNotReinitialiseCaseFlagsForApplicantDQ_whenApplicantDQFlagsExist() { applicant1.toBuilder().flags( Flags.builder() .partyName("Mr. John Rambo") - .roleOnCase("Applicant 1") + .roleOnCase("Claimant 1") .details(List.of()).build()).build()) .applicant2( applicant2.toBuilder().flags( Flags.builder() .partyName("Company ltd") - .roleOnCase("Applicant 2") + .roleOnCase("Claimant 2") .details(List.of()).build()).build()) .applicant1LitigationFriend( applicant1LitFriend.toBuilder().flags( Flags.builder() .partyName("Jason Wilson") - .roleOnCase("Applicant 1 Litigation Friend") + .roleOnCase("Claimant 1 Litigation Friend") .details(List.of()).build()) .build() ) @@ -740,20 +740,20 @@ void shouldNotReinitialiseCaseFlagsForApplicantDQ_whenApplicantDQFlagsExist() { applicant2LitFriend.toBuilder().flags( Flags.builder() .partyName("Jenny Carter") - .roleOnCase("Applicant 2 Litigation Friend") + .roleOnCase("Claimant 2 Litigation Friend") .details(List.of()).build()) .build()) .respondent1( respondent1.toBuilder().flags( Flags.builder() .partyName("Mr. Sole Trader") - .roleOnCase("Respondent 1") + .roleOnCase("Defendant 1") .details(List.of()).build()).build()) .respondent2( respondent2.toBuilder().flags( Flags.builder() .partyName("The Organisation") - .roleOnCase("Respondent 2") + .roleOnCase("Defendant 2") .details(List.of()).build()).build()) .applicantWitnesses(wrapElements(List.of( PartyFlagStructure.builder() diff --git a/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java b/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java index ac5effba420..cb5efa6da20 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/utils/ManageContactInformationUtilsTest.java @@ -1,7 +1,11 @@ package uk.gov.hmcts.reform.civil.utils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.model.UpdatePartyDetailsForm; @@ -15,6 +19,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mockStatic; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.RespondentResponseType.FULL_DEFENCE; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; @@ -40,8 +45,24 @@ import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQExperts; import static uk.gov.hmcts.reform.civil.utils.ManageContactInformationUtils.mapUpdatePartyDetailsFormToDQWitnesses; +@SuppressWarnings("unchecked") class ManageContactInformationUtilsTest { + private static final String PARTY_ID = "party-id"; + private static MockedStatic partyIdMock; + + @BeforeAll + static void setupSuite() { + partyIdMock = mockStatic(PartyUtils.class, Mockito.CALLS_REAL_METHODS); + partyIdMock.when(PartyUtils::createPartyId).thenReturn(PARTY_ID); + } + + @AfterAll + static void tearDown() { + partyIdMock.reset(); + partyIdMock.close(); + } + @Test void shouldAddCorrectOptions_forClaimant1AsLegalRep() { CaseData caseDataWithExpertsAndWitnesses = CaseDataBuilder.builder() @@ -312,12 +333,12 @@ void shouldEditExperts() { void shouldAddExperts() { Expert expectedExpert1 = Expert.builder().firstName("Lewis").lastName("John") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) - .partyID(null) //change this for CIV-10382 + .partyID(PARTY_ID) .build(); Expert expectedExpert2 = Expert.builder().firstName("Second").lastName("expert").fieldOfExpertise("field") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") .emailAddress("expertemail") - .partyID(null) //change this for CIV-10382 + .partyID(PARTY_ID) .build(); assertThat(mapUpdatePartyDetailsFormToDQExperts(null, wrapElements(party, party2))) @@ -331,7 +352,7 @@ void shouldAddExpertsWithExistingExperts() { Expert expectedExpert2 = Expert.builder().firstName("Second").lastName("expert").fieldOfExpertise("field") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") .emailAddress("expertemail") - .partyID(null) //change this for CIV-10382 + .partyID(PARTY_ID) .build(); assertThat(mapUpdatePartyDetailsFormToDQExperts(wrapElements(expert1), wrapElements(party, party2))) @@ -370,11 +391,11 @@ void shouldEditWitnesses() { void shouldAddWitnesses() { Witness expectedWitness1 = Witness.builder().firstName("Lewis").lastName("John") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()) - .partyID(null).build(); // CIV-10382 + .partyID(PARTY_ID).build(); Witness expectedWitness2 = Witness.builder().firstName("Second").lastName("witness") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") .emailAddress("witnessemail") - .partyID(null).build(); // CIV-10382 + .partyID(PARTY_ID).build(); assertThat(mapUpdatePartyDetailsFormToDQWitnesses(null, wrapElements(party, party2))) .isEqualTo(wrapElements(expectedWitness1, expectedWitness2)); @@ -393,7 +414,7 @@ void shouldAddWitnessesWithExistingWitnesses() { Witness expectedWitness2 = Witness.builder().firstName("Second").lastName("witness") .eventAdded("Manage Contact Information Event").dateAdded(LocalDate.now()).phoneNumber("1") .emailAddress("witnessemail") - .partyID(null) //change this for CIV-10382 + .partyID(PARTY_ID) .build(); assertThat(mapUpdatePartyDetailsFormToDQWitnesses(wrapElements(witness1), wrapElements(party, party2))) From c5dbc0de4098dd28edf1cc1a99ffbf9ef29dba3c Mon Sep 17 00:00:00 2001 From: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Date: Tue, 21 Nov 2023 11:30:12 +0000 Subject: [PATCH 04/29] CIV-000 CVE-2023-36052 fix (#3605) * suppress CVE-2023-36052 --- config/owasp/suppressions.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/owasp/suppressions.xml b/config/owasp/suppressions.xml index 8effe28d3c5..1ba8ea7ce32 100644 --- a/config/owasp/suppressions.xml +++ b/config/owasp/suppressions.xml @@ -35,5 +35,9 @@ CVE-2023-5072 CVE-2023-44487 + + CVE-2023-36052 + + From 80c425953a98322431e19f10f64b7b59bafa3863 Mon Sep 17 00:00:00 2001 From: Harry H <33700332+HarryH96@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:52:19 +0000 Subject: [PATCH 05/29] point ccdBranch back to master (#3606) --- Jenkinsfile_CNP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile_CNP b/Jenkinsfile_CNP index e9515f0aca9..b7c16bf6c94 100644 --- a/Jenkinsfile_CNP +++ b/Jenkinsfile_CNP @@ -8,7 +8,7 @@ import uk.gov.hmcts.contino.GithubAPI def type = "java" def product = "civil" def component = "service" -def ccdBranch = "revert-3591-revert-3279-feat/civ-10382" +def ccdBranch = "master" def camundaBranch = "master" def yarnBuilder = new uk.gov.hmcts.contino.YarnBuilder(this) From 7b0f0b99db2ce5b21dc23dffef79850212dd95b1 Mon Sep 17 00:00:00 2001 From: drummondjm <93932689+drummondjm@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:28:37 +0000 Subject: [PATCH 06/29] updated court string on document header to use court name/site name (#3603) --- .../templates/CV-UNS-HNO-ENG-01196.docx | Bin 40955 -> 41061 bytes .../templates/CV-UNS-HNO-ENG-01197.docx | Bin 40854 -> 40909 bytes .../templates/CV-UNS-HNO-ENG-01198.docx | Bin 37629 -> 37470 bytes .../model/docmosis/hearing/HearingForm.java | 1 + .../hearing/HearingFormGenerator.java | 12 +++++++++--- .../hearing/HearingFormGeneratorTest.java | 10 ++++++++-- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01196.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01196.docx index be705500ed421c65c24bdc316df3aa84d5eded65..2ff9eb37d325e0131172448ec4b67bd787b36d81 100644 GIT binary patch delta 10853 zcmZ8{V|3m@_ifzRwr$&NoHn*?tH0Qdp4e*aJhAP@jcuzz8{NMDd)IpJz30=Mwf4-M z4|~m;v(J9%g*xnmss}y+V`*|3tGEylHJcC+7!VK;-p+0oY!=Suo{pAI9;`l&4i_Zr z@x@~gA{y_(zok;-GdaGxdbZH*2@1_$Sa5T7D&%S5@ADEM!@C%JHP3&OeSCUU)X>~u zYvJe#>fF>IqAwq8UlJ%g`--#uy6<|Z@#KXs(Btht*j4IGzuxo;wC`_jZUuY{`_OEu zsXO?&FFc66JRXh5JH6i?B>>Myrh-p34-=1Oh`~2Sr&1=HTg?0X87j0%&0uY--+qTW zg=BwXpPLWsXy46tbsi7;(T=gixwr+8B)1!j;k#9Ny8XF26#8`&HVdYu?jbctAXcNB zxd&IiF`KaaL+{c8^U@AbP$Cc%h>!~~uupKqs_a@Q;tp)$@KtcswPYo@d(Ynz#j%oS z(J&n(F<&I?$`>jtcD|YTpBxRKXx>JpU=%vw|h&~(4oBfTl$u<)RU-6_~~ zM&b3~vE-6F?^gB9&Q4px9eg9gcw*x7zoIY^w!pM?>xQ0?KJr2rD_ z*_^?GZlw0wsiXUOzM!uLxxOnc1YG5vSwF&*L(HcQufRMCi& zQhPQts^8ki7o+&FmXwGSq@{)Ktqy5Lvn**M_NP?qaR!=kle5FBx&(K!-fchVWXWdj3K|soF8uBj_)*aM824=o8ut8WidZo@n2DwP|9T?1v_Cs8KUZBXPvF#Vr7!h{)A z#4UKtr;M>Le~J}8%^^<8cgeQJ#)?L?q2Gi^6O|{LmIV`JU88eCC3-5*{4Ua%veC$T zw}j|P{F^l;&rKeKu0QVlIVjaFeV;;~-RIo~z&!y_mDtQ(;=k#Ml@|<&C#4hc%5Y0X z|MKbMz=YgRnkrFi!aG{~o}BIKgFa;=`Ig&lv#x> z^h|rL#1N1bJLGN}e>;e*JOj zWL?eMlc1^kES_WJCXcUWOPSlvi%v5RBtlp%Vs!CFbGdD*c0bBKAtTEqeZ?>;J^5?@ zw6b|mw8WE(b6BIzCFEcmQgP3&VyiHk zV3jOu+Kj(f3{w@L-u_0N4`(ZNtm}uK4<{gHVWZotWd9ftsOO*lh0DBitzS4Ch%A=L zOhqX^+9ikfMIk(+5HxiGSG$xgMHkyh#GGW#ou27kNxEx3GMf*)9S6RdF?nVS&$)o7 z)fc$rQIE*A1&JYnRc-cTr#O5eCa{7Q22sc4fqUofJJG{S-ADFJ#r3RlV3dCca^T(4h@N&+^A9s#Du`2~6pH!gC+9OYXh9iw(^Oa50;^{*NbbVx(3S_!n(mI8y z*y@R^EWD$vEhq+UkxjMEO6v6lwn+TOJYCFC>ZyA}*hFhwjjH4?htjgCv)6}_I_k@dE-`*m7 znqd(Cz=HH5RnXKV1~_0)a+O1gSv!V(3v!B=R9o@G7ML_6i~3J65-3n zH;U+y-y(lF{w$6=)}%jZ3>lvCgc@`;e1!{83IF2H(}bZVpQ#RvvJP48GqqzPL?#{e zB<%fW-o2d>PqEd5nqW#TUeYd)t?W&v(ek00?dY4Y9xIRgi&Xo4ZBTGP(5gdk#{%kF z5a9>+k7yN~@A&9umb5U17xHR3)YPU1#j}6IGI%JCU2R5xVdk@4NWIsj4 z9n4)|7+n0pXSqXNuEJJI#tadab+<~i~t$&|)dWt`! zL#*<1aPXx8h3}S_W#Y;VI&;7CM_pTkIq60-$wukt6%qQlR1Jx=zkid&fD};JK)8J@ zkur3_!b%Gvkc3j2pQ)B7XE>*Y)JwRTGe`2LtTUYd_?h<;v zt>U##&gsd~_%GdJ7F}qG;0Sn+9PEwE=~5a!EzkJ@K1)^(x38u9LQSiUMF`?mp56R8 z?_XCa0p<2qnmuGa#p0-Rew0ri`abcgr^B72vkBCS5xqQP{UdVfomrOC zNP1Exc+_0Vdy#Nw&0M}YqlwC_MXaD-LP_6O7XjC z_T;6bVPo(>B#ct_$k%;-LYcvwuym*#u|O*bRB_bosR?mVC087U7kALI`ZjM(CQuA_ zGCh+iR_ux6>GF`p?we*Uoy$P&jbr6)YIJY?Y0Znp9(K^&XAg$Z8lKQju=%37;Jk}` zY)N5f`Iom%%9n*wb=q0CPdAvHHW5>IejR1fqEn-al}^LPr*I z;JF(*oVeuP)|$@AsEYFpYp-Vt?SXX0VRYqsQZXYTmq^C4O?3gLh%5PssNwAPO2WKI zB?X(NK-oaBFeC_ zh?xqX@t|t|t2UFL5tH9HW;Vv0^^Hi!N3^=6EplE&GWZ+^4!pCFFRL20ivVNuB?^p( z1>ng6ZL!%ms-zKE@J+{ zlZ`y-o(wbZTzMco5azHB3AkT42RLl6d)2dY{ez&|GI|?z zq${^`{2h6L^Txuz&NF~UgC;a7MI_(4ZJyG5#Z4PWsf%WpDkoW_-hr1 zkF>K94X~W851TLPx9U3^rw}-8J%s%E(pSzBR*@tE;dAShcZzuEn+Of{f7WkbomRrA z6aRHsStj)Z1)fzE@|i_tJie^kq37|2c+!`KHM>1cQ9DO9dpli-qGyR+54g{WYpaog>H2I+{HQ;YeSF!MYhruD4`%MKF zVCc+wgt*`{PnKL6dc_=pCSSI9+u~PKz1+krd*b8zWEI#7S=>;58yfO~lo@sxQXgyVL(sSJZ z7BmMNTvum)n&Z5B$I_R+;{cl){&^oX2T>jYZ~ zIfbMU`n~N47(jD1+TSB_x3g-UgTxt2$~_vTh*gL?Hxl0G!(iw3&pl~xXkl5QUQLp% zA765ZTsFCvfz4hMq&CL6lpf~U5yszKCepLRaJ4c{w|U75D_w|D=^=9c&i|CaPk`Y@ zNS?i!zA(ehLN8t}n^QDZFwd)^dEM1^D&UwG&OaIfSYyohkA;;qXr$@hda#VT&UZr7 zjZVEPYF&4Q_m)|bb%WnMI%A89tyfeP6I;DD9k-2ZvpI~?3s?u%+MwC!bDS1?4jO!g zd(Q~#NRFxe{-oJ>65GUag2ccLf>u)kYf7eXOx2C7cNXpmZp0->%ypB^sgFb`V^RAB zd2kj0d@xScEpN4r!y{TFO`zj8U8$~aVwi__W`ITq?QQjxrnlA}0e$R)V=o0v#1`Y_ z*}k?d=qZkmkwnb17He2u`<>uhz)fNWM)-4$NoP}&eKAXu(&a7lq1p<|z2StG8XLCxgh5H{H~-D|sn-QyxJ z*CVmHZdpR6Y@6ghSQ@Q8Zy%h3()f2DOnqp}=bv#%2`$YQ%El^CBOR$5je%f90s&zchin};_>UlB{ieX$&Qgh#q zFTX@`uz+?kcr#B<=gj?$3^SE%%yUMQlFIc|A1|hl5Qn+`*NT-Vf{2)fNhTg(-o#{L z5QaiH9>=-Nr}yJ!J`q8@bKtN4uu(udEiSt&fJ`~2JpY0W7S8sXH5WhfJ(scMK5oqM zG7(j8$RDb+0OVI;8U;BiQof+T!g;_N@dou4^i3Oi>oq%^M z}3-`bs1cx zyQru?5%OEOFv;*cQo834?im$=*O6b{0sV1J6DNpqYg~n`sZgH?_BDT$?5LdG`FDJf z<*ml#od(#BS+v&8I_n1m8c*>=c#GZE)&~Mz6S#G%1xuVh$atQGlH%AkejUF?}(s(oftFM}?`FY6WvWxres98b)7zFn(%;2+eX{94p zqpb5ZI+}1QhX~p3#$9@nq_|n~*lH!$;rN&jh$^-oQOTVnyLlv}$K!06rARx@F5U0L z?{?nlPI)N^*0k-mt}+uUM}T}dGUf8lcABW{a;EBP=Oym&#Syppm1R%wbd`?Zw&+F1 z45fbBANCwnM|ofYW!i&1szH_GNNTop$a?GlVLBx;Ovx1ZC*A70wps&FuYlep5+_tqW?@BpSA%Pl}1 z&I1mIy|uzf6~DXgMAp9W0B!GuNrI@r0PY~QaU-mn_@AA z1n*P(j{3GZ7vS>JuFsY}jfwcn8s%hcAV81K-H0-e9Z;S)zH>%*(=| z`w8oQSr8=Y*7QWBi+M#m7aBx1%|GXxm)~>F;ELmY%hs^jos>prhvQ)y{JaUQvndkvC+vPCXUh)kiL z<38x+$~@r!w$;E{z^N5$hAk}#Db2oQ((H{R#Hn;*w3oZP4JavEg;Q2j*4?} zzG?542&N7-fvFQDN2%Mx$f^$f3DatHL5druFJd*zv_2r>bhoqX$E_+Sx-?4~Cg;8L zy#z4f+abDch|9?Qd?9(nn;j-BNRu1xb#EaxuT*4Ue&&6ynq}qx`86Ec&zO%PeS~!U zsrTCe-ktL4*KB{rGLqmz1*JD%J)e~YvR0^GSH!RdocV=WW|V15gAwyy1N-COkA1Y_ zE<12|=qw}VdT>Z&>Dg;MB<&N~hc#a*+7k~P3rl!Ppy;yhU-Wx z)6-KO8EDoM+%G)RzT;V_bkV2 z6@|M;?0_geJ|q+xbZ?Lzh~BX%fPA*A#y2-h4*+g z$z-;#|0x=CI?!CEj5C4CKlCd2&RoabtMt1YQpgOWW&|DU-KeP{Oaj*nDFJaBP;hw* zMk#@W5$Ow=4MyoT4da1Ms+DA+Bhn#6DOht{$@b&`n4#Lgyn_!vclfp-+!PjL=$h(HtBqZ;6BR?VKYAI z#C9@#z*#^C=5SX$Lg)~6MTj~E2u!K_tu}FKB-Aq6b`B~|YD$<=hm!mfjl(P1PTq(h zcsm)5nPQzp;ty5$#PTYNcI*Pzr15-<&t&*3T{GNW?-dHGd)?$}hE#tpg0^i;88~Ri zRu=i#ZP2^XU5!l32Qeh|Q z>-;K4ghbgk?xX&WW+XN;EQFP2g8LV3*Xfv zcPeH_kGR%e^A_(>MLEz(DbWCJYF<~iyg<~thG+&PI!fL>+PhDsImnDH9Z?2d{t>?S zw=((TVo~8u{`pJ4HhJ59upB=w$Keak^V_347$T21YLp%)r@AlN=BEDr-7!-xY}5e1 zNF;VgaDv7tcnF_BqTE#yf8IOJj0Oy>WC}6kV|S7a!yHKtv;T(fZ3BHaDQezy4t<8S zRolI3AY;*@ZyiD959XJcNHm{>uZ>XJ6*2IT*o8>^&W_wse!Emo;9=w`4w4{0*No&Q zk?la=aKLA{NIn{r-)FVuh+9;k`=#tcfzS#PD#Yh}RKKK$nA*GGYdS?L|?u|-- zmO1(%8MJVt7E18#`pa0{>u`w2O?`Sl? zwE5g3q}fa-7U?P+N`KXrYK=@li_I9zPg| z_hfZcRLC7}wjml+MQ>WeUiG+{lB4*v358(~p9wwm+%t+^M@`rC;#9`3FpKgD3VeDJDo`~cc$M$I;In~(jF zby|&OjYu;=U>Id;jWKxGi^Rzpb+u~HFE7mYb~+*cz#Osnl`wO)xV5Kv*W&xLW2H-N zz1K#l9)L_Gbi9;cEtzCOVb`nC;TOHgW;w(9E0cINYK$P zjr(r#6gWF@OX%(2%k1+}iXZl@hxf zNTKFm_kYOS)I<9&3uM8Dxjeu_KnPL&U$aVgOAilQCu{fr%qqcp`p)aJxZjLTK0*tR zHK*F$!}wvH7fPbmhZ$o7OQk0$2V%uFymE%$pG2r-CRIdn6k-Z&q^9|fIgdp%d)^Pf zXc}!EJ8E-3Oow#e;cEMKJ2n>ebn3pogzEo|1*&RQ&zV`W1$%Xck2d$x`GAl0^GMC~ zClSZ<+9;XLn##**v+bwIr3cT}&122AZaY+8<(*pFDsWl;<)&w93t2+sVM_(7t+7K) z;|W<^`|;^;w6c2>f6K$!keM#dddq2+p;%&d)@JR>QJI)k%%lE+3bkvKh?ehW0%qMh z&_zv>)v=Bj>2##^M$ZTJ#07d06B-KC{P{wf@q{uOXtQ<^y{ErO1dr<2G~F3b{57>H zL?#fIx!3GB^$X6pD2c0u%)t~-*fKc<{?exrl95P!Xxoae5`q?t|CHc9&!+s&gZn%qc-r^6dNZMPZN7Gd{0PWbJ zdTJ7pujBM&o9*<{Wk@#9;u@RP;hgQZmCn=47bxvn_5++j|ESx!RTe3nhwtrd#8>5{ z!>@2wd!_w{PD5xW=HJh>aI7-LEY068#rM08aJ856!m@JyM^oT?>~H)%k8#>nW9FGx zqxmDx$E5_e=PrZX)h_a!n9D!*fC!EgWyL~_@ZTc*ZC+hb{+$)vZBjqzejAHYm7bsw zLOX89q(ia@dA+9u%d0WD^F4Rc#Z~9gTDGWto#c-YIG|MA2rc=eVCCb+XUs6~Q7$GT zpV|SLUmG`ay~r{9(J)sX@s-hArQ>tGWEF} za$&=ah&>-1ifc(hASX@@BsU1i%;U*l5a5|e3n9!5=BQ(?W%&zw;8G4qi-L*LLv+h| z(${3wpliXAHG`?q1i!@HPfZCO1K?_;q8@G(DsB}JFpTTr?RU;I2AOv$(uvP;eWSxM z2B>PVs`aNbhTU==&G458_BSMm;8h9YZDD%Roh9kB#hsBV+WWbI7&_5keLf8{6lNj> zgHxEnNw|IzVUh^d5+zW?LX@US5xA+?uq*4>4!FyVqBUj0Ye|vBhQ$?kPE(F}`&0VM0%DmZ8F9ix0yk*s z3eXP5L%-8h7R?QNsSV#0G z_JNHkyep*%UyjjZS0l3>-`{FXCagBJP-I$))6E@0@=na)W-Y-H+@%9pgqh+BzP*zr zid6{Nu6Se_G-)$hXy#Fc$QtwVPkT{(U*$zk1d16*3V%fac9iiXXF7QahdNgHr3fcv zabbd=P2Mx4b%~uv)DMF<0xDNf{nnpKP)xi2Y&^qF+|qDiPA2JnV)ueazy`t-#~!$DH5n@Y#vKVnJ-2>SM?C?XYy8vB1Qd6(pWrB zP3L?F2Jz=IHu)kxx#Sy~cc!?@nK(WM;;5(i{s=5e$qfNmq5#~t@TI^qMO^=rUN-(D zM@+3X`t4~E^d+v2Ey@vY6uP&bB&C5|s5nE;xvz|}xV!cUsodqt>-@l{hPFB#%8E>9Wcawyjg>L$@6v8g5sr_3WB5dXZ9J19=~ zY=s?R6xZpF&sj-{9&KrMt6+}9SRHI$7&)`ge~gE2?iv_-f_Tz@^1WQ;89ymxznYG^ z@7|^a(4lOA`<%T4Wmf(uA?-e6io)G%(mDo@HuIkJqm%T=iiRT$eseA0t5lLdRwmjd-G*M-lv*}^jlG)UmR&$xpn(&iw!T4?56&iZh11yFX%TFule8z! zi1daPDL4YW;B+c-kGm9xab&Tp?2|~Je2Z}g{G!_yEiolZBaRhp9*;9*?bwFkm-qtE zO3y#XSvL&%A%0w1n4LbN3OQnqlLt5R6%u7698%v6yrxlSmAXaEVzZcZ38+RqYwg%1 zkAC^SKOj)v{AF?0Bu_A($>2|pbIzxk{b~%{k$9w%k?x`4sa<&wYFKR@N!E?f++8$M{<6V@ZtqtSQSRA`j)S~Z$AIx5s-ubbo6ky?Bb&`wor@KLD{Vv zu*FuqP50tF=_S%7bI^La%PwN;09>t17cpNwiV%(Y{Z0LGIeI&K6ray7Y8EgsLU!uK z&wMEwn6v!c_2`hFu{`9f{L}uftMrJ+(`ey7i}crHLSz?9?BD(Ay;FCcZ63>2;e*w6 zuJ@&Ri?G|~d%1iu)y~P^4FZpBkEkp4e{PZoZ~BxEil2akNilT?&0>{Y$va^L;ocv!aIU0j3J!oz2os{EIpm zys`QN*`f`(?Jn)>{)t|(a9Y#>P_~itQJ2p5@u{iLiYvuR`bH&6(WvD{Q z+b{YGf%2D7L=##bko+_Uh>E~X$`@5vrnqSvX@45);`wUFO$7cywNRKt5*1nm(R$Kq z4?3cb2{aAFUM?3*k{GIPPcxY8(oAmM$cR5!ue?CORV^XX(p3y3BhpVdwg42%U^LUH zjlcUy8P^G;)I(EH4{K>?i?%qLin9j#-B)deznlVLJ7x8+LU!qq@IN_?RG0`65N~ho_`bEQD0Hta`q_i zvTF5S5@Gz3T*{F-G7hF(5T10C+**fB_=_glp1%W_ zYQ-6oo)B5GKCTO!L27T-!S!_8z$X;Z?&nqU?I33Bh( zH=&lNU%?58lEK)t4hm$&>uQ7+Xrb^($V74AUucv?r$TnXx|Tv)>zyYA)@dVi9YdE4 zI|{e96D>8?{t^C1I=F%J6lvyRoPx}n2U#T+{?)#tf*_Zqx<&m&52deai3QFIbSd*G zn2jJ8!oQ&h;Z@3a@C0VH7SCub>T-W+nvjd@)5}SYmWK2N^G8uhYky0F5Ah*xbkLk| zxGBP?#5yBj7>kWyTKQ3z;Hz2TUs2JVY`zb!W>pi)cBQ$=KV{L5oc+0*G~C(H5Vx<1p;;ijJFO2-~gw!+iDPmtwTd zp+Y8y=J0vQd%p7Zpp)uXv%E_=q{fo)C~0sBv^U=C5CQd97dv77a0>*cp}moG+UqZ1 z(q2EG)2XBPA~V26vQ&m)`8)u+5nZSNkC6COIAyh;v>v8z0orHTV>ZYA9knFaFHe-I zt`?6b&o%m|=tkHdyxaW$t^0JP{f0*TuSXKpk);ah3qs6hBmN&T2nqrs2?+uM^Ph3@ zzo9|_(#)o&{hxmOA0YN0;6KjF{{}nt|M6K`I$3~BvI#(K*@RH&bfCp-VaO~HMve#+ z12af1M;Njl^!;BV&jFhHmn?!1az&slctPa6cp&3kM#xoAOfEg~|KAk-_Zn0u(9eH6 zIK4qAd7@C--$2TFLQp7ipqM;yD7EMPCHvXyc=>I+a-wHMbq?j)Zg`WSxq};vm%ZIN z$*RM~=pP}G_rUaUa!5+FE7SU$pc4CDTm0q*nH*f~u{rd;1kl*r?hw=~!PwPB+RyT= z$4TjIG1nDL@p{M*sK89z#wk#CyWd%7iGYIc$K9*j5Y49DivuPG@S-Yb86&M&T4Mr=^nBU_VG zQ9Ip%efG%Wgtn&c1OR#u40$@m40A9hH!Mv&Mg@(?o<;yf1&#E)M}mf&!WJrK53<}@AXqZRW z2vleT@7lMGAM`ng&L17YABLuln7Q6dC9bD*gz6NFzgtj^3aF>JEfK4n=S|3nZy<-# zp>`HVTF@CdUKb6{YCs&lFa@{%kW%mING2*}IhzDa$gDyT2l>lTZyt^Vxr8`R1Dgg8@*OX8;`dq30;N{4y0rrDY7)L7;gaZRq0wpA=qa= zuG3<6IL1KC%q`^!&5NnJ;O3g0QBfEV4Fe)$qkZlW_>CmIBMv|NtTImczgANqbZV-2AY6HvbP z4qe+w7zli2Ovi!h@RBxuxh#-AUB3b!6!+)gxX;@YT6q7V4^$>LkaX}~+Ta9Rv5#EW zw;OT+2`tVxzXBi{x?eI3oS$Z$)4oeH3U-B2_2#wSboQ%)1g3(>!4`-GgxchO6l?ci z`fjzv4mejS7l(@D3Ak_S3+hlgUG}KmIUY&K3$NR&GR(SXqe5t_4i#Z`kO&-4vWIWP z(Gla{ndx>?7E{c=+QFZ1cc8rFs`6CB>lGRTaf$+;oP!w7vb8ANQHvlKe#UCBx#KC< zZM>N}D$q;NGNLJ9;_4$^_DW2X7nXHBg9 z=C$ENju8|@MmjgOg8*%-Xj<>n@4aiBNH^piD3UeXLvrj$_#E1UL(ru4LC#2FwP~mT z9XuJ)^D+<_1>7a_%Y3dGy!$QfJ-Wh?zkQD|?}$LZ=+U{<m~CToZ2j6?=aGy$ zNH7acqs6RC&$E{BPde}1yLwRGd3#o z(Br>~%}fQOP1w|->I$$dv@KBF-Fm$UJwFINa|XKGX`99GEr7<9`7~N)7Bc-hgzeoK zEZQVyZgfZFT|pGX`=B4hw6AjP6S&knshz0$faX#eIT zaO-XB0H0}0ybgAZRa_wIs*PLw@hePb5E;Vpm$qpxa^;WY_MEBe=Jm3+PEsPZK%}Td zL2~kD{p8YdYUXHs!hHe)U5Am#CB~SWXP9Be)bI1D^uz-`TV}M%tESR;HuT=#Mjh#Y zI;amGQpYYEvo8 z2vMf|G=p3-or)rr?0l^CdDj+R{Gl0X7yG|ZM2o{dd!?9$KAv8d4Az{}#r5P`xC%lA zO$r$wh()5(%uu}uIY^dh8+0Nh@deX~*oZ`kcsd#rHrg)1WbK3IC}$$}6b90p(eE&J zZ?OHxx>8*lYsvr%l|m^w6MLlfoSLhB>ghUA;nlvz(KOLZtHUGKt@CgiMlj7wINe_49 zhB`CGa}P1Gol>&SP4nxSb!5qgEt+TR%LyE>x<%kFa4IFHdb?Ve-hP7cQ`k;vXY66a zzv5Lnd|E8e>8l@$mT1aA0MuVr5T*9(b}fGE7tN>OhUtoBPCTg9Adv8lC(^iH9@vz2 z(EHamy6FsDDp4jYJ#ZE~IkD$z8x2rCLeql1#_p*Op?966wxc5Y&%QJIbxZeYeb-J; zN(QQ9&AS^7AFqGvbV2kcFni~LMxr~IdRn!kQ4)@EEvQ=W6+f(vNoZ1f4YvO;?Hv;8EsH^#DVwT_6Q&ld_^ zDE6~73b-+3AlV6iWn;ZbxoL7#CJQ+rbX=0M3ymQYWA=fh0nqs`_wLCG3ya3;CALWH zWNcTx#P=M|RTR7w^1M}f##=VgJic@2Fk7S$sxcwo7?u||VR|tPv*TM3m)%};@Bmvb zX4+h@M6NKu)R;-BW}E7cR4*@TA%8nPN}h=P70TZi4gzHaqla?%tY2s^dGPAnl-_y` zc2kn_rbN6giu-#B)&||d(NgUVbAoBXY(EnmAvwdG-Tv>;!G(BQ#pNc zcCHUO!qdFIih@_Qtv=hwxh@96UYjp@rYt_?1=InfF9fz(2|H^-7UKnzW!%e7m!TO0 z8P6(T*5{gaQ*epN1}s_fWa3N$Pw&3KTCCR>{N9w`VO?vnOm4UJI=J-U4hKj>CUFi$i zeBLm`hy9T>kb~wfGAyFy$n3=!dSoTdZE@)9^?KGCxdyshiSC&fyLdR4IHMKdmGa#; zyHuUB7r9e;S{pfxWw~aXY(?Ygx=1I=gA{JgsAJ?`p^=KL?OvaV0efom6&0r{ zow(x1Z4i!@@-MHGxf%|k_e8{S929LUtd9IR0cI#OLy7F;pK8Y(a=;S?ZEE*B57JSf z3|}O;I2W`Qf3>>(h@XS@-1K0*LieuO)gTj6bU#f?H=b1d=MXq7wGP4ZKG#hwQE1lh z#`pvLBP|~v=lUlu>!TR{DG0#NdUY0}$6ft4L{MLo%4)2vhkr*{uZTDZYSidchD_0T ze4?Mw7nx$X9Y}O^fc_Lh8vI4vgvISq&J$R0g+KPk)<-5L-1Q2$+*bTSz3uyOdpOX6 z)^k0=sX(vTJ@98p1e5I3P_db$-e?Ct+fB-t#L3_7iGrwRIpwRf%)*4+K+R;j|V9tBB>?C-)Bs?;{!{Sh17I+amd04 z5{CJ&pW-kET0rLPtU>c2^;U#LtV|(ouFiHQc_T&$vqj(*o`gmyS%Q%tQ2V+7YQ6bM2B3HrXwysf? zR3~}T{dwYBj1CVgN#dVeLJ|V`h1o)KhUU>$;@gVoy^OyqC(5_)%Nto2@#EjS?Qq(3lC0^Y zJ_yhVKa=wd z=#`wlsl?^C<#>Kh(qR}qi+h&Y?9jw+r2T8~eU2Ngov$zGY5M{6jbpvaTv5v*+m$O} z9c?^rs>X$I#=i;6rA6qpUPJXjAyH_7lf1xfHcG}v@HE`1xwxWCY#EB1XRzec<%-I% z10dmhF|EN>l-P7LS+ZmIT0l}u-N)N6MSX0Tj)7f_tw9^N#hzyIKq0)CUtYodvi8-m z(^Tp4H_Z01$nsw7jVhKs)(Z9+k*<+yjnwUo(QPBj)HULVX;=3t6jMF08_d51?lujV76);xt6@GD{tm$tRT`{dFR;%M^@u ziqp**VhT=#`Q~?MXFW6|Ir4WxnQ3Q_JfhcP|LHTrf|SnX*5hz4OOiKnw0Xm?QBU<6 zlo<`7Z&mVxD6XYGrui3D7S3Wd72SJ+U|;2g#n4~GAxr#u4Yn8l3h2MqiyAT^>j09O z&y{OimSY@T1Fq!)6Kg2a@qvARDqorO*~fY~`2%QsnLKK_JS$nO!oxb9&})4zNIw5R#`$gb;|s&Fl&c>p*>ey8If zWM8~iNiU9S`zLN1`PXV~Q54v5WENn%EPvaFMq0>`6SbGMoeFcHegn(fHzBoR(v=@H z8bO88c|Uhi^U+cS>u8S;6%eWPsp&#$Yj~uvRg%zPi;$tE)&3-*QFF&DD({L`kzbc6 zW4S0uMzWJa5ZjU{GsaEs7Xj#B;dWN&*et0Wxjsir{^ILdb`1iiT|G!Pf5cUD_BaI6Vj7AQBdL66y-CmCVav&PF2KAYC|oUU+v zedz+I*~f0jQ?Ncs%fyii2kpk-=o@aUx#$t08U_Z+{8^qtJ5AQcrUuxC6`SF{%hzZZM@t?yNlEN+)L!#P)5XU-WXHgx#sy`^fJn)ht&O@K^@QmITp0Y`FauM; zbHUJ1pG$;T80NC~UDgN;$Ww8ja9GN*dq`dOXFQiz0>e&92N_c}7o2hr)sd`9_1S1- zT=@7Z?)shs#&(lQ+<@Mn4Az=FawGnz{>e&>Pv z{J(FLZBxE`v>8l@X9)i`R@e08cBs2pYoBT09qM!T){kk;v9aM)`#kBk_Y@!-4 z`b-28{X|{oOmZEPmp#`8M9=eK73~Tf+$PhfsmngEZ<9|}efUx#qb;O&j*8P`cgDNi zz%tK!&wYx!#RhcZsOmh+I@1D|C%)Pg9PjXvQ&^(yJ*#Hl8r&QwH@tY{Ry7sduO#Vi z|D_$9b}BtNOX2(7y(a28SAtf#qwX@z=yi8!F?y*9zZSQ}sf#E~gDBIuku={@$CMmJrR>9?sa=cJ&N^!dhLN)S+L;u<-l=G}9_*+xuP$=+~shkSuTEkB8gkArCb2pai&CK&M-ej(Ip3}eUP zQ#*^2IKFGxz%}#DB|NK)=p{gqEt0+)Ao3}R`Z;@HusEIBFk6ho01PFJklRq zawqXi@gs16njqqR6AsOK-Y`lR0EGx2Aexh;;xz#^1rPhPPZwHFr28gPR6M|ZG9&5_ z6gkXZSgL9k1oZWmFQVBEYV3|7mQtxqBH9mRW(A1#NMW=9m@NhDFk*r~?JzUn5MBf$ zUD*01^vO}?1`#vm2Gi+RY#K@V{;V$9fG(_Yh5rDuP=YaXQjDT4*`%oP)sf_w{2ice zy|^(5W%jh{3|O={lZ4r*3FQqp5?i6=eZJ6R)ogS=(%G|N2x;HO_ESkl|5$5)COGz3GYF50n6- zAG!jyy>kWBqCGI76(d=EjLbLl-hm8hsj%Y_2jura5ylQg?Sdx8Enf6275!r1y1K9t!vZpynx;wJ(h;h7lA;f*in+L!00^BFtemV5r_g}YGh#W<#2 zUKuKaL(i;&y<=SaPUeM_E`%$)fezL}arlAI{543}Wo7!YdHL8x4AIP=$;N&IpG^xw za3k9&f+!NH3Gz#^86*RbeU`G+f|RO^`=lm4wK}ATSJ4WG5YzJP0x2lzHNq|h!T_!V z+|7ImGVBkXyBd1mbRxEHX-b|&f4%ZOBA ze%O;?g&l|<|FHOmm_AdC3AAiYyN+mSYR#6;ov=wm=fUK7lrm4I#qwdJn8lw=;uP^b z^3>4T{P*+RBkXyEL?fY?+>_7LFn|fGy}~TWz)9D4567JVi+%^eAqvO+H>{5LGx`a` zqDy^X(VWw%eqDAYQstN0ct7qVP@XAPiKcQ8ZT0A>Nw8|=x_FED_aDkF%$L0iCe$s4 zj3K$Q*!6|xhJ`|&_En7lzGiJ4jJwXki|ue{k(OwSDfRa)m;7rVRNSxLyg+of`Eud`d@mBxr3R5qno+wf9WlY zsbdc7Z0KQEFfXVa#2NOTcB9OK!`x2EM zCo&NAtk0Zit>+zCeJoYr4!jSl|yw?BbMI2^$x4&BZ>h4MyGYte|w#*e1s z?=d|#Ju#hPc8ZAbVGNaZDQn>rX}N{9S|z<6m>q3&_}P+YV*_5$R|q_aS0rbWjup8a zp*4*M<|lApuhA7qm#1dK9Gr7jFDDy_bYg<9N7^@3uC+U&mD5EUYvCQ4L#s)7gJbyK z3T1AulRB=Q9g5;LJWJVG3EbrllUeYvKh&SnlF3!HXm9q+uV0i?c7i@NOi^Y^#V>q_ zB}ec2Q7ZX3Y5-u2G@J%fx_3zcuDbN@1Ret7p7MWT+tu97&Dz28zp>q@vmUq3i|J=* z^pU@N?5^|E3nSJIb}!KUM5=QM=(y#(-Cz&;MfcL*9ePv6JoE&Jc z^(xmwKE7woEx$PxcI+r9bHqJQX=xolvj^kcZ%*xP17sVYwe;NmbS$k`7oVs0*spMV zI-g&+4Zc*icV1cRcuFvwI;h(_;=Xo&sjRN)xDc+Hzf^Y}wT1GO*DVryv%9LUXngY$ zWNMLjmwq)-O_uoZni5iER#Qo)s{afR@c z)clN*xTu-bt$%Bp@_M?w?*z` zm1V!>-uP9WPe5zYa$t{9Lb2H}@nQi}N}YPT^Uqn^@y#ptbq#i@{rkzQ8;Fi%nfh5z zG0`uV^!{fFFI;LFnd?zT5X)J^o2T`zt6mM~)&tr6RJ$W8=b3Pk zIbh|lQoC7V-+poH;V0cfO~mEC&3!1yYU}U#5>YPqO@>Y8yuqVO5zSkW{&K6+L1UB6 zseVy^v*t$ez$^zxNWDueQJtPW*~g{PJ627w(nEe>Sw8op!S6l#FTPfr8Tf)V%+in5 z{FeXqbOi6aLEN;B0lY%d{okgXan8s^Ye3@lvEXitn_y`!e5sDP`-fFZ{GtgsR^n6*ki9Q_vIX#=x51gF1i6MgSy$h{y_*lAdxR6xIiMA2;9>|eJmQZy zGRH)V4t^_=|L<>PKIk&hZToagDr^NoS^=I}qZUq8n3Gr(F>yu=s74N0LLp&-=)yF@ zF_1K=F~;JdtdwwVR3SAWvx0==Ej9;HAH37Rh|qokI!s(s10*SHxC`lW7UAT?oMQU` z_=QL`p#)(HEuu1{-S0nf0VZKCZ9|Ir{vTjTHa)4LIaCgD9cw3+(TLN}8}^Q*Xuu&Z7_PXcg{}5qgt|iG&4&9&_l*Ruc@{(;T zpfiZ@%c4|qfK*GeZXn{?)GHMobBBdFPeI#ca4rzh7KbDjLD(Gmu^%+NhHQzD`UfZ8 z*nx@ERJ{)TrpjIo>QK0u$f1A~~*(g!u#$ zHZh=@gU#U=d|@5;S@@G64R!z0ybirHtZs#GtX~7e&GmbTAke1`JU82tq&1Hc?~i5nmVKrP>ig|4wjpE8rAPHSFT~Uy`pfRxS zH-i_b{`6;)hCo(zbZ~Ue7|B*z@D6TPfyq6H(T;ew3u2g@n@LHFh(w3IQo0UjzV|Is z3}?S*KWdXE!>pBCG>$e#6$=idJ#_C?Pn5?WrAwhS9yn&>k5n>D1 z`G@*FYj|*0o;asOhT0B_(N46b3}RhoFw}ra2HSlFJwI+GywW8H-Z}iLlyRghdcWIs z)|T#MC1~|G6pOQ;YoG_IUOdMdPXfg>VyGfA9!L1|(I{edVTfMq0{_U5L3Ss~Hgukn z0jGoC_v9dVM+41@T`n)L_>Atb@c0Uwq=BRRi)#a4p-FI?J1MYOt)V?fvgga= zpVngS$4{#Jb`7kyrX`IJb}-8sRNAZ84H_6T|7dpYqiHrgKA1 z(P^WfFD%K~dHkzK%mSYvT7`eE=KjF!tDCPC{_)ZM&9ajh;pjqji+MCfgN{$c;g)OAD=pNw7Dct74vfGO1?S9sdg zm(+)QCU@lTZF>61ptsz#>5X9V5j$7R1sR&RF7EwE*3iN+Tet0az4vHCi{;;ne0uo( ziNknd^Bjw`6I0i7!%31_0uwCoS!I4cL3c>n!B*UkynX zxt6kT^q76Lt$%{queZnIi#2V6?#;vQ*H%3hJz#?W1?ntB14-NhAxeaODpZGc_M1D| zjPik?diF1!KB$Yn{Ii?Cl}5CdYyIFQ*h;*e0wWa`ON&76tt?{G5pMFbEEv(yJy~5D zKj{lXqVZ-o6khqHZ%ja+s)Eo^6&rUU21#;utZYMrJKYYl7z$>xXZj?(a6M_I8y!*m zII9X`504WjNfg!F#UMPlJcn&PD#|U^-)3Lm%W6WTrOPNt2Bc{hR$mnJzcL5<`?XZGMQa>&qFFuNuCvzsUk-jquadf#LB>fiF~NYT20qzV{i7l(l)mb5 z+OD%E)YDYAo=QjT<+*}vl~>6tbfXY%xA?2T_<4cYa3}A1doHRMwny?K5eY-h>V>|0 z{5Yq~0&m8MnE}nM;KU8Jw8ZCeGLm(+@(puRVn)Uzq<#3WA1E z`UVZchJb|tlc&LgWF?2D8}O28|J{Zo7CU+u)gLmAZk{a^ie#%j#3E54h}dL%AMUNy zL6hZXJ06>-`xwuxAxMR%yQ6^_M`2_hRzFSRIXL^NO!bB&9IIse#?_itvA5^bOdJZ? zh0$q3y#_2;52~&1z^WEhzeRk+0yg6*RQ7h9tyoi{pY^%@y~*c$%#kxZb)r-kAtBwNq!V_mtK;TosK(*O)ek1 zX+8jMUO^}>S6yvFTgFnWpdp^y_(ft5ui+mv1R?%sj}c6rr3i@wcFSTV{_ok)KeC

klDF5V-D#D5N*|?#CzM|I32@le5|$%$p+wHS7WQ%n^n<^8>f!2%zLg z|No^+PjeGhut*LOm@tL3=(olE^cwFGRKivzWj0QShGBK|KlZ$d&qY(PUmp#LZH kKPw9iZpsyes!j#p=6->q&H$HZ5P=o*&|zsa|10kQ0j9^4a{vGU diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01197.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01197.docx index ac8be099ede4e4963e8e32ab095bb3dd7b04be24..89e02cbd98befa7dc750f110ec097ef7fbe23fe5 100644 GIT binary patch delta 10694 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 private final DocumentManagementService documentManagementService; private final DocumentGeneratorService documentGeneratorService; private final AssignCategoryId assignCategoryId; + private final LocationRefDataService locationRefDataService; + private final CourtLocationUtils courtLocationUtils; public List generate(CaseData caseData, String authorisation) { List caseDocuments = new ArrayList<>(); - HearingForm templateData = getTemplateData(caseData); + HearingForm templateData = getTemplateData(caseData, authorisation); DocmosisTemplates template = getTemplate(caseData); DocmosisDocument document = documentGeneratorService.generateDocmosisDocument(templateData, template); @@ -60,10 +65,11 @@ public List generate(CaseData caseData, String authorisation) { return caseDocuments; } - @Override - public HearingForm getTemplateData(CaseData caseData) { + public HearingForm getTemplateData(CaseData caseData, String authorisation) { + List locations = (locationRefDataService.getCourtLocationsForDefaultJudgments(authorisation)); return HearingForm.builder() + .courtName(courtLocationUtils.findPreferredLocationData(locations, caseData.getHearingLocation()).getSiteName()) .listingOrRelisting(caseData.getListingOrRelisting().toString()) .court(caseData.getHearingLocation().getValue().getLabel()) .caseNumber(caseData.getLegacyCaseReference()) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java index 23b051fd7fa..7bdb3603865 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java @@ -18,11 +18,14 @@ import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; import uk.gov.hmcts.reform.civil.documentmanagement.model.CaseDocument; import uk.gov.hmcts.reform.civil.documentmanagement.model.PDF; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDocumentBuilder; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; import uk.gov.hmcts.reform.civil.documentmanagement.UnsecuredDocumentManagementService; import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; +import uk.gov.hmcts.reform.civil.utils.CourtLocationUtils; import java.math.BigDecimal; import java.util.List; @@ -55,11 +58,14 @@ public class HearingFormGeneratorTest { @MockBean private UnsecuredDocumentManagementService documentManagementService; - @MockBean private DocumentGeneratorService documentGeneratorService; @MockBean private AssignCategoryId assignCategoryId; + @MockBean + private LocationRefDataService locationRefDataService; + @MockBean + private CourtLocationUtils courtLocationUtils; @Autowired private HearingFormGenerator generator; @@ -67,10 +73,10 @@ public class HearingFormGeneratorTest { void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided() { when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_APPLICATION))) .thenReturn(new DocmosisDocument(HEARING_APPLICATION.getDocumentTitle(), bytes)); - when(documentManagementService .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, HEARING_FORM))) .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() .listingOrRelisting(ListingOrRelisting.LISTING) From af17822ad2daa6eb40c37aadc3cada519c65ab0f Mon Sep 17 00:00:00 2001 From: kalachandrasekar1 <114995593+kalachandrasekar1@users.noreply.github.com> Date: Wed, 22 Nov 2023 08:17:07 +0000 Subject: [PATCH 07/29] CIV-8939 - Claimant Intent: Submit Function - Change state to ALL_FINAL_ORDERS_ISSUED (#3421) * Based on full and part admit repayment plan settlement agreement signed * reverted the change * build issue resolved * Adding suppression for CVE-2023-36052 * CIV-8939 reverted CVE suppression change --- .../ClaimantResponseCuiCallbackHandler.java | 2 ++ .../hmcts/reform/civil/model/CaseData.java | 13 ++++++++-- .../model/citizenui/ClaimantLiPResponse.java | 8 +++++++ ...laimantResponseCuiCallbackHandlerTest.java | 24 ++++++++++++++++--- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java index 00186af4da0..77008f21ffd 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandler.java @@ -100,6 +100,8 @@ private boolean isJudicialReferralAllowed(CaseData caseData) { private void updateClaimEndState(AboutToStartOrSubmitCallbackResponse.AboutToStartOrSubmitCallbackResponseBuilder response, CaseData updatedData) { if (updatedData.hasClaimantAgreedToFreeMediation() && updatedData.hasDefendantAgreedToFreeMediation()) { response.state(CaseState.IN_MEDIATION.name()); + } else if (updatedData.hasApplicant1SignedSettlementAgreement() && updatedData.hasApplicantAcceptedRepaymentPlan()) { + response.state(CaseState.All_FINAL_ORDERS_ISSUED.name()); } else if (!updatedData.hasApplicantProceededWithClaim()) { response.state(updatedData.isClaimantConfirmAmountPaidPartAdmit() || updatedData.hasDefendantPayedTheAmountClaimed() ? CaseState.CASE_SETTLED.name() diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index 96dd6656365..b46645b792a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -40,6 +40,7 @@ import uk.gov.hmcts.reform.civil.model.breathing.BreathingSpaceInfo; import uk.gov.hmcts.reform.civil.model.caseprogression.FreeFormOrderValues; import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; +import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantLiPResponse; import uk.gov.hmcts.reform.civil.model.citizenui.HelpWithFees; import uk.gov.hmcts.reform.civil.model.citizenui.RespondentLiPResponse; import uk.gov.hmcts.reform.civil.model.citizenui.ManageDocument; @@ -981,9 +982,10 @@ private String getOrganisationId(Optional policy) { @JsonIgnore public boolean isPartAdmitPayImmediatelyAccepted() { - return SPEC_CLAIM.equals(getCaseAccessCategory()) + return SPEC_CLAIM.equals(getCaseAccessCategory()) && YES.equals(getApplicant1AcceptAdmitAmountPaidSpec()) - && getShowResponseOneVOneFlag().equals(ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_IMMEDIATELY); + && (getShowResponseOneVOneFlag() != null + && getShowResponseOneVOneFlag().equals(ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_IMMEDIATELY)); } @JsonIgnore @@ -1099,4 +1101,11 @@ public String getRespondent1Email() { } return null; } + + @JsonIgnore + public boolean hasApplicant1SignedSettlementAgreement() { + return Optional.ofNullable(getCaseDataLiP()) + .map(CaseDataLiP::getApplicant1LiPResponse) + .filter(ClaimantLiPResponse::hasApplicant1SignedSettlementAgreement).isPresent(); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java index b9cd00096fa..782131ceb90 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java @@ -1,9 +1,11 @@ package uk.gov.hmcts.reform.civil.model.citizenui; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; @Data @Builder @@ -13,4 +15,10 @@ public class ClaimantLiPResponse { private DQExtraDetailsLip applicant1DQExtraDetails; private HearingSupportLip applicant1DQHearingSupportLip; + private YesOrNo applicant1SignedSettlementAgreement; + + @JsonIgnore + public boolean hasApplicant1SignedSettlementAgreement() { + return YesOrNo.YES.equals(applicant1SignedSettlementAgreement); + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java index 238deb1dace..f1b054d05e7 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ClaimantResponseCuiCallbackHandlerTest.java @@ -14,11 +14,13 @@ import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.enums.CaseState; import uk.gov.hmcts.reform.civil.enums.MediationDecision; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.helpers.LocationHelper; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; +import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantLiPResponse; import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantMediationLip; import uk.gov.hmcts.reform.civil.model.defaultjudgment.CaseLocationCivil; import uk.gov.hmcts.reform.civil.model.dq.Applicant1DQ; @@ -296,9 +298,9 @@ void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsCompany_toAllFin .applicant1ProceedWithClaim(YES) .applicant1(Party.builder().type(Party.Type.COMPANY).companyName("CLAIMANT_ORG_NAME").build()) .respondent1(Party.builder() - .type(COMPANY) - .companyName("Test Inc") - .build()) + .type(COMPANY) + .companyName("Test Inc") + .build()) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); @@ -324,6 +326,22 @@ void shouldChangeCaseState_whenApplicantRejectRepaymentPlanAndIsOrganisation_toA assertThat(response.getState()).isEqualTo(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM.name()); } + + @Test + void shouldChangeCaseState_whenApplicantAcceptRepaymentPlanAndChooseSettlementAgreement() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimIssued() + .applicant1AcceptPartAdmitPaymentPlanSpec(YesOrNo.YES) + .caseDataLip(CaseDataLiP.builder().applicant1LiPResponse(ClaimantLiPResponse.builder().applicant1SignedSettlementAgreement( + YesOrNo.YES).build()) + .build()) + .build(); + + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getState()).isEqualTo(CaseState.All_FINAL_ORDERS_ISSUED.name()); + } } @Test From 4b18cc27bae321a0fdf9e54d97a70f237b157560 Mon Sep 17 00:00:00 2001 From: pliao-hmcts <113367232+pliao-hmcts@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:00:57 +0000 Subject: [PATCH 08/29] CIV-11518 Witness Bundle (#3590) * CIV-11511 add witness name to UploadEvidenceDocumentType * CIV-11511 CIV-11515 Naming Updates (CFV) * CIV-11515 deep copy and bundle * CIV-11511 Witness name (#3575) * CIV-11511 add witness name to UploadEvidenceDocumentType * CIV-11511 CIV-11515 Naming Updates (CFV) * CIV-11515 deep copy and bundle * CIV-11518 Witness Evidence (Documents referred to...) - Naming Updates (Bundle) --------- Co-authored-by: Madhan Mahadevan Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../caseprogression/BundleFileNameList.java | 2 +- .../helpers/bundle/BundleRequestMapper.java | 14 +++++--- .../bundle/BundleRequestMapperTest.java | 33 ++++++++++--------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java b/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java index ec628a0643f..5ed04e34a79 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/enums/caseprogression/BundleFileNameList.java @@ -17,7 +17,7 @@ public enum BundleFileNameList { WITNESS_STATEMENT_OTHER_DISPLAY_NAME("Witness Statement %s %s %s"), WITNESS_STATEMENT("Witness Statement"), WITNESS_SUMMARY("Witness Summary %s %s"), - DOC_REFERRED_TO("Documents referred to in statement %s %s"), + DOC_REFERRED_TO("%s referred to in the statement of %s %s"), HEARSAY_NOTICE("Hearsay notice %s %s"), NOTICE_TO_ADMIT_FACTS("Notice to admit facts %s %s"), DF_RESPONSE("DF Response %s"), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java index 8267d327903..537d7300e70 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapper.java @@ -27,6 +27,7 @@ import uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType; import uk.gov.hmcts.reform.civil.utils.ElementUtils; +import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.Collections; import java.util.Collection; @@ -34,6 +35,7 @@ import java.util.HashMap; import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -750,10 +752,7 @@ private String getFileNameBaseOnType(String fileNamePrefix, Element covertExpertEvidenceTypeToBundleRequestDocs(List> evidenceUploadExpert, String fileNamePrefix, String documentType) { List bundlingRequestDocuments = new ArrayList<>(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java b/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java index 1e4665f1f00..eaa0e647a85 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/helpers/bundle/BundleRequestMapperTest.java @@ -36,6 +36,7 @@ class BundleRequestMapperTest { @InjectMocks private BundleRequestMapper bundleRequestMapper; private static final String TEST_URL = "url"; + private static final String TEST_FILE_TYPE = "Email"; private static final String TEST_FILE_NAME = "testFileName.pdf"; @Test @@ -117,7 +118,7 @@ void testBundleRequestMapperWithAllDocs() { bundleCreateRequest.getCaseDetails().getCaseData().getClaimant1WitnessStatements().get(4).getValue().getDocumentFileName()); assertEquals("Witness Summary cl1Fname 12/12/2023", bundleCreateRequest.getCaseDetails().getCaseData().getClaimant1WitnessStatements().get(5).getValue().getDocumentFileName()); - assertEquals("Documents referred to in statement 1 12/12/2022", + assertEquals("Email referred to in the statement of witness 12/12/2022", bundleCreateRequest.getCaseDetails().getCaseData().getClaimant1WitnessStatements().get(10).getValue().getDocumentFileName()); assertEquals("Expert Evidence expert1 Test 12/01/2023", bundleCreateRequest.getCaseDetails().getCaseData().getClaimant1ExpertEvidence().get(0).getValue().getDocumentFileName()); @@ -168,10 +169,10 @@ private CaseData getCaseData() { .documentHearsayNoticeApp2(getWitnessDocs()) .documentHearsayNoticeRes(getWitnessDocs()) .documentHearsayNoticeRes2(getWitnessDocs()) - .documentReferredInStatement(setupOtherEvidenceDocs()) - .documentReferredInStatementApp2(setupOtherEvidenceDocs()) - .documentReferredInStatementRes(setupOtherEvidenceDocs()) - .documentReferredInStatementRes2(setupOtherEvidenceDocs()) + .documentReferredInStatement(setupOtherEvidenceDocs("witness")) + .documentReferredInStatementApp2(setupOtherEvidenceDocs("witness")) + .documentReferredInStatementRes(setupOtherEvidenceDocs("witness")) + .documentReferredInStatementRes2(setupOtherEvidenceDocs("witness")) .documentExpertReport(getExpertDocs("expert1")) .documentExpertReportApp2(getExpertDocs("expert2")) .documentExpertReportRes(getExpertDocs("expert3")) @@ -192,19 +193,19 @@ private CaseData getCaseData() { .documentEvidenceForTrialApp2(getDocumentEvidenceForTrial()) .documentEvidenceForTrialRes(getDocumentEvidenceForTrial()) .documentEvidenceForTrialRes2(getDocumentEvidenceForTrial()) - .documentCaseSummary(setupOtherEvidenceDocs()) - .documentCaseSummaryApp2(setupOtherEvidenceDocs()) - .documentCaseSummaryRes(setupOtherEvidenceDocs()) - .documentCaseSummaryRes2(setupOtherEvidenceDocs()) - .documentForDisclosure(setupOtherEvidenceDocs()) + .documentCaseSummary(setupOtherEvidenceDocs(null)) + .documentCaseSummaryApp2(setupOtherEvidenceDocs(null)) + .documentCaseSummaryRes(setupOtherEvidenceDocs(null)) + .documentCaseSummaryRes2(setupOtherEvidenceDocs(null)) + .documentForDisclosure(setupOtherEvidenceDocs(null)) .defendantResponseDocuments(getDefendantResponseDocs()) .claimantResponseDocuments(getClaimantResponseDocs()) .dismissalOrderDocStaff(getOrderDoc(DocumentType.DISMISSAL_ORDER)) .generalOrderDocStaff(getOrderDoc(DocumentType.GENERAL_ORDER)) - .documentCosts(setupOtherEvidenceDocs()) - .documentCostsApp2(setupOtherEvidenceDocs()) - .documentCostsRes(setupOtherEvidenceDocs()) - .documentCostsRes2(setupOtherEvidenceDocs()) + .documentCosts(setupOtherEvidenceDocs(null)) + .documentCostsApp2(setupOtherEvidenceDocs(null)) + .documentCostsRes(setupOtherEvidenceDocs(null)) + .documentCostsRes2(setupOtherEvidenceDocs(null)) .systemGeneratedCaseDocuments(setupSystemGeneratedCaseDocs()) .applicant1(Party.builder().individualLastName("lastname").individualFirstName("cl1Fname").partyName( "applicant1").type(Party.Type.INDIVIDUAL).build()) @@ -328,10 +329,12 @@ private List> getDocumentEvidenceForTrial() return otherEvidenceDocs; } - private List> setupOtherEvidenceDocs() { + private List> setupOtherEvidenceDocs(String witnessOptionName) { List> otherEvidenceDocs = new ArrayList<>(); otherEvidenceDocs.add(ElementUtils.element(UploadEvidenceDocumentType .builder() + .witnessOptionName(witnessOptionName) + .typeOfDocument(TEST_FILE_TYPE) .documentUpload(Document.builder().documentBinaryUrl(TEST_URL) .documentFileName(TEST_FILE_NAME).build()) .documentIssuedDate(LocalDate.of(2022, 12, 12)) From 67305d1e578bb233b493287e9afca9197450704f Mon Sep 17 00:00:00 2001 From: drummondjm <93932689+drummondjm@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:05:32 +0000 Subject: [PATCH 09/29] CIV-11556 judgecasenotes tab (#3589) * updates to judge case notes for more meta data items * updates to judge case notes for more meta data items * point at CCD * Update Jenkinsfile_CNP to remove CCD pointing --------- Co-authored-by: vasudevganesanhmcts <100689363+vasudevganesanhmcts@users.noreply.github.com> --- .../user/EvidenceUploadJudgeHandler.java | 44 +++++++-------- .../model/documents/DocumentAndNote.java | 2 + .../model/documents/DocumentWithName.java | 1 + .../reform/civil/service/CaseNoteService.java | 33 +++++++++++ .../user/EvidenceUploadJudgeHandlerTest.java | 55 +++++-------------- .../civil/service/CaseNoteServiceTest.java | 31 +++++++++++ 6 files changed, 102 insertions(+), 64 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java index 12ca69bdb86..97086348cb3 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandler.java @@ -18,12 +18,14 @@ import uk.gov.hmcts.reform.civil.model.documents.DocumentWithName; import uk.gov.hmcts.reform.civil.service.CaseNoteService; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.IntStream; import static java.lang.String.format; +import static java.util.Objects.nonNull; import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; @@ -75,10 +77,11 @@ private AboutToStartOrSubmitCallbackResponse removeCaseNoteType(CallbackParams c private AboutToStartOrSubmitCallbackResponse populateSubmittedDateTime(CallbackParams callbackParams) { var caseData = callbackParams.getCaseData(); CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); + String userAuth = callbackParams.getParams().get(BEARER_TOKEN).toString(); if (caseData.getCaseNoteType().equals(CaseNoteType.NOTE_ONLY)) { CaseNote caseNoteTA = caseNoteService.buildCaseNote( - callbackParams.getParams().get(BEARER_TOKEN).toString(), + userAuth, caseData.getCaseNoteTA() ); @@ -92,35 +95,28 @@ private AboutToStartOrSubmitCallbackResponse populateSubmittedDateTime(CallbackP if (caseData.getCaseNoteType().equals(CaseNoteType.DOCUMENT_ONLY)) { List> documentAndNameToAdd = caseData.getDocumentAndNameToAdd(); - List> documentAndNameCurrent = caseData.getDocumentAndName(); - - if (documentAndNameCurrent == null) { - documentAndNameCurrent = documentAndNameToAdd; - } else { - for (Element document : documentAndNameToAdd) { - documentAndNameCurrent.add(document); - } + List> documentAndNameCurrent = new ArrayList<>(); + if (nonNull(caseData.getDocumentAndName())) { + documentAndNameCurrent.addAll(caseData.getDocumentAndName()); } - caseDataBuilder - .documentAndName(documentAndNameCurrent) - .build(); + documentAndNameToAdd.forEach(documentAndName -> { + List> newJudgeCaseNoteDocumentAndName = caseNoteService.buildJudgeCaseNoteDocumentAndName(documentAndName.getValue(), userAuth); + documentAndNameCurrent.addAll(newJudgeCaseNoteDocumentAndName); + }); + caseDataBuilder.documentAndName(documentAndNameCurrent); } if (caseData.getCaseNoteType().equals(CaseNoteType.DOCUMENT_AND_NOTE)) { List> documentAndNoteToAdd = caseData.getDocumentAndNoteToAdd(); - List> documentAndNoteCurrent = caseData.getDocumentAndNote(); - - if (documentAndNoteCurrent == null) { - documentAndNoteCurrent = documentAndNoteToAdd; - } else { - for (Element document : documentAndNoteToAdd) { - documentAndNoteCurrent.add(document); - } + List> documentAndNoteCurrent = new ArrayList<>(); + if (nonNull(caseData.getDocumentAndNote())) { + documentAndNoteCurrent.addAll(caseData.getDocumentAndNote()); } - caseDataBuilder - .documentAndNote(documentAndNoteCurrent) - .build(); - + documentAndNoteToAdd.forEach(documentAndNote -> { + List> newJudgeCaseNoteAndDocument = caseNoteService.buildJudgeCaseNoteAndDocument(documentAndNote.getValue(), userAuth); + documentAndNoteCurrent.addAll(newJudgeCaseNoteAndDocument); + }); + caseDataBuilder.documentAndNote(documentAndNoteCurrent); } return AboutToStartOrSubmitCallbackResponse.builder() diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java index fee4c6e850a..69b3dd9cda9 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentAndNote.java @@ -20,5 +20,7 @@ public class DocumentAndNote { private String documentNote; @Builder.Default private LocalDateTime createdDateTime = LocalDateTime.now(ZoneId.of("Europe/London")); + private String createdBy; + private String documentNoteForTab; } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java index 9aabf622994..f19ba0c57a9 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/documents/DocumentWithName.java @@ -19,4 +19,5 @@ public class DocumentWithName { private String documentName; @Builder.Default private LocalDateTime createdDateTime = LocalDateTime.now(ZoneId.of("Europe/London")); + private String createdBy; } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/CaseNoteService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/CaseNoteService.java index 4c6f63654eb..76240eb63c1 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/CaseNoteService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/CaseNoteService.java @@ -4,6 +4,8 @@ import org.springframework.stereotype.Service; import uk.gov.hmcts.reform.civil.model.CaseNote; import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.documents.DocumentAndNote; +import uk.gov.hmcts.reform.civil.model.documents.DocumentWithName; import uk.gov.hmcts.reform.idam.client.IdamClient; import uk.gov.hmcts.reform.idam.client.models.UserDetails; @@ -43,4 +45,35 @@ public List> addNoteToListEnd(CaseNote caseNote, List> buildJudgeCaseNoteAndDocument(DocumentAndNote documentAndNote, String authorisation) { + UserDetails userDetails = idamClient.getUserDetails(authorisation); + + var updatedJudgeNote = DocumentAndNote.builder() + .documentName(documentAndNote.getDocumentName()) + .document(documentAndNote.getDocument()) + .documentNote(documentAndNote.getDocumentNote()) + .createdBy(userDetails.getFullName()) + .documentNoteForTab(documentAndNote.getDocumentNote()) + .build(); + List> updatedJudgeNoteAndDocument = newArrayList(); + updatedJudgeNoteAndDocument.add(element(updatedJudgeNote)); + + return updatedJudgeNoteAndDocument; + } + + public List> buildJudgeCaseNoteDocumentAndName(DocumentWithName documentAndNote, String authorisation) { + UserDetails userDetails = idamClient.getUserDetails(authorisation); + + var updatedJudgeNote = DocumentWithName.builder() + .document(documentAndNote.getDocument()) + .documentName(documentAndNote.getDocumentName()) + .createdBy(userDetails.getFullName()) + .build(); + List> updatedJudgeNoteDocumentAndName = newArrayList(); + updatedJudgeNoteDocumentAndName.add(element(updatedJudgeNote)); + + return updatedJudgeNoteDocumentAndName; + + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java index d37c56db259..93698b7e222 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/EvidenceUploadJudgeHandlerTest.java @@ -31,6 +31,7 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; @@ -104,109 +105,83 @@ void shouldPopulateNoteDateTime_whenNoteIsAddedToCase() { @Test void shouldCopyDocumentAndNameToAdd_whenDocumentWithNameIsNull() { Document document = Document.builder().documentFileName("fileName").build(); - DocumentWithName testDocument = DocumentWithName.builder() - .documentName("testDocument") - .document(document) - .build(); + DocumentWithName testDocument = DocumentWithName.builder().documentName("testDocument").document(document).createdBy("bill bob").build(); List> documentWithNameToAdd = wrapElements(testDocument); - CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .caseNoteType(CaseNoteType.DOCUMENT_ONLY) .documentAndNameToAdd(documentWithNameToAdd) - .caseNoteTA(null) .build(); + when(caseNoteService.buildJudgeCaseNoteDocumentAndName(any(), any())).thenReturn(documentWithNameToAdd); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertThat(response.getData()).extracting("documentAndName") - .isEqualTo(objectMapper.convertValue(documentWithNameToAdd, new TypeReference<>() {})); + assertThat(response.getData()).extracting("documentAndName").isEqualTo(objectMapper.convertValue(documentWithNameToAdd, new TypeReference<>() {})); assertThat(response.getData()).extracting("caseNotesTA").isNull(); assertThat(response.getData()).extracting("documentAndNote").isNull(); - } @Test void shouldAddDocument_whenDocumentWithNameIsNotNull() { Document document = Document.builder().documentFileName("fileName").build(); - DocumentWithName testDocument = DocumentWithName.builder() - .documentName("testDocument") - .document(document) - .build(); - List> documentWithNameToAdd = wrapElements(testDocument); + DocumentWithName testDocument = DocumentWithName.builder().documentName("testDocument").document(document).createdBy("John Doe").build(); List> documentWithNameStart = wrapElements(testDocument); + List> documentWithNameToAdd = wrapElements(testDocument); List> documentWithNameEnd = wrapElements(testDocument, testDocument); - CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .caseNoteType(CaseNoteType.DOCUMENT_ONLY) .documentAndNameToAdd(documentWithNameToAdd) .documentAndName(documentWithNameStart) - .caseNoteTA(null) .build(); + when(caseNoteService.buildJudgeCaseNoteDocumentAndName(any(), any())).thenReturn(documentWithNameToAdd); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertThat(response.getData()).extracting("documentAndName") - .isEqualTo(objectMapper.convertValue(documentWithNameEnd, new TypeReference<>() {})); + assertThat(response.getData()).extracting("documentAndName").isEqualTo(objectMapper.convertValue(documentWithNameEnd, new TypeReference<>() {})); assertThat(response.getData()).extracting("caseNotesTA").isNull(); assertThat(response.getData()).extracting("documentAndNote").isNull(); - } @Test void shouldAddNote_whenDocumentWithNoteIsNotNull() { Document document = Document.builder().documentFileName("fileName").build(); - DocumentAndNote testDocument = DocumentAndNote.builder() - .documentName("testDocument") - .document(document) - .documentNote("Note") - .build(); + DocumentAndNote testDocument = DocumentAndNote.builder().documentName("testDocument").document(document).documentNote("Note").createdBy("john smith").build(); List> documentAndNoteToAdd = wrapElements(testDocument); List> documentAndNoteStart = wrapElements(testDocument); List> documentAndNoteEnd = wrapElements(testDocument, testDocument); - CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .caseNoteType(CaseNoteType.DOCUMENT_AND_NOTE) .documentAndNoteToAdd(documentAndNoteToAdd) .documentAndNote(documentAndNoteStart) .build(); + when(caseNoteService.buildJudgeCaseNoteAndDocument(any(), any())).thenReturn(documentAndNoteToAdd); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertThat(response.getData()).extracting("documentAndNote") - .isEqualTo(objectMapper.convertValue(documentAndNoteEnd, new TypeReference<>() {})); + assertThat(response.getData()).extracting("documentAndNote").isEqualTo(objectMapper.convertValue(documentAndNoteEnd, new TypeReference<>() {})); assertThat(response.getData()).extracting("caseNotesTA").isNull(); assertThat(response.getData()).extracting("documentAndName").isNull(); - } @Test void shouldCopyDocumentAndNoteToAdd_whenDocumentWithNoteIsNull() { Document document = Document.builder().documentFileName("fileName").build(); - DocumentAndNote testDocument = DocumentAndNote.builder() - .documentName("testDocument") - .document(document) - .documentNote("Note") - .build(); + DocumentAndNote testDocument = DocumentAndNote.builder().documentName("testDocument").document(document).documentNote("Note").createdBy("Jason Bourne").build(); List> documentAndNoteToAdd = wrapElements(testDocument); - CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .caseNoteType(CaseNoteType.DOCUMENT_AND_NOTE) .documentAndNoteToAdd(documentAndNoteToAdd) .build(); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + when(caseNoteService.buildJudgeCaseNoteAndDocument(any(), any())).thenReturn(documentAndNoteToAdd); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - assertThat(response.getData()).extracting("documentAndNote") - .isEqualTo(objectMapper.convertValue(documentAndNoteToAdd, new TypeReference<>() {})); + assertThat(response.getData()).extracting("documentAndNote").isEqualTo(objectMapper.convertValue(documentAndNoteToAdd, new TypeReference<>() {})); assertThat(response.getData()).extracting("caseNotesTA").isNull(); assertThat(response.getData()).extracting("documentAndName").isNull(); - } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/CaseNoteServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/CaseNoteServiceTest.java index 5cb2b9f02ac..715cb1080f1 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/CaseNoteServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/CaseNoteServiceTest.java @@ -6,8 +6,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import uk.gov.hmcts.reform.civil.documentmanagement.model.Document; import uk.gov.hmcts.reform.civil.model.CaseNote; import uk.gov.hmcts.reform.civil.model.common.Element; +import uk.gov.hmcts.reform.civil.model.documents.DocumentAndNote; +import uk.gov.hmcts.reform.civil.model.documents.DocumentWithName; import uk.gov.hmcts.reform.idam.client.IdamClient; import uk.gov.hmcts.reform.idam.client.models.UserDetails; @@ -95,6 +98,34 @@ void shouldAddNoteToListWithNewestAtTop_WhenExistingNotes() { assertThat(unwrapElements(caseNotes)).isEqualTo(List.of(newNote, oldNote)); } + + @Test + void shouldBuildJudgeNote_whenInvokedAndDocumentAndNote() { + Document document = Document.builder().documentFileName("fileName").build(); + DocumentAndNote testDocument = DocumentAndNote.builder().documentName("testDocument").document(document).documentNote("Note").build(); + when(idamClient.getUserDetails(BEARER_TOKEN)).thenReturn(USER_DETAILS); + + var builtDoc = caseNoteService.buildJudgeCaseNoteAndDocument(testDocument, BEARER_TOKEN); + + assertThat(builtDoc.get(0).getValue().getDocumentName()).isEqualTo("testDocument");; + assertThat(builtDoc.get(0).getValue().getDocument()).isEqualTo(document); + assertThat(builtDoc.get(0).getValue().getDocumentNote()).isEqualTo("Note"); + assertThat(builtDoc.get(0).getValue().getCreatedBy()).isEqualTo("John Smith");; + } + + @Test + void shouldBuildJudgeNote_whenInvokedAndDocumentAndName() { + Document document = Document.builder().documentFileName("fileName").build(); + DocumentWithName testDocument = DocumentWithName.builder().documentName("testDocument").document(document).build(); + when(idamClient.getUserDetails(BEARER_TOKEN)).thenReturn(USER_DETAILS); + + var builtDoc = caseNoteService.buildJudgeCaseNoteDocumentAndName(testDocument, BEARER_TOKEN); + + assertThat(builtDoc.get(0).getValue().getDocumentName()).isEqualTo("testDocument");; + assertThat(builtDoc.get(0).getValue().getDocument()).isEqualTo(document); + assertThat(builtDoc.get(0).getValue().getCreatedBy()).isEqualTo("John Smith");; + } + } private CaseNote caseNoteForToday(String note) { From 1c05384b527d779ab5515d6baa9fb572001e3395 Mon Sep 17 00:00:00 2001 From: Deepthi Doppalapudi <107422736+deepthidoppalapudihmcts@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:43:22 +0000 Subject: [PATCH 10/29] CIV-11205 CIV-10754 Initiate GA about to sumit and updated written Rep templates for local (#3566) * CIV-11205 populated full address for after sdo scenarios * CIV-11205 update TriggerGenApp to update address * CIV-11205 Updated address during TriggerLocationUpdate Event * CIV-11205 Unit tests covered for location update * CIV-11205 updated templates with court full address * CIV-11205 Code smell corrected * CIV-11205 Updated written representation templates with location * CIV-11205 updated locationName to courtName * CIV-10754 updated with the changes * CIV-10754 removed duplicate assignment * CIV-10754 check style issue corrected * CIV-10754 checkstyle issues corrected * CIV-10754 Setting up the id only when caseRole is not null * CIV-10754 checkstyle issues corrected * CIV-10754 Added condition to avoid users having multiple roles * CIV-10754 updated tests * CIV-10754 updated unit test data * CIV-10754 Added condition to avoid null pointer * CIV-10754 added condition for adding respondent solicitors * CIV-10754 Log to verify ccd userroles --- .../templates/CV-UNS-GAP-ENG-01070.docx | Bin 23869 -> 23962 bytes .../templates/CV-UNS-GAP-ENG-01071.docx | Bin 23762 -> 23842 bytes ...itiateGeneralApplicationServiceHelper.java | 34 ++++++++++++------ ...teGeneralApplicationServiceHelperTest.java | 8 +++++ .../GeneralApplicationDetailsBuilder.java | 1 + 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01070.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01070.docx index 3e9445b398d0c286ba8d292ef6435082af7ad8cd..df4bdf5e8744cf5c359fc9d7090f6e0eb44fc1c2 100644 GIT binary patch delta 8007 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 OqBBH?>(Tiium1&2g;@9i delta 7971 zcmZ9RWmKKp(xurD+}$;}y99T4cXxN^#T^1{G`Kqi3$7cN;2wg6;0{3peCOQm(S5t? zZ_OI@qn=S?u2o;ULA_m|ug365eHuBhMHo;}C3Rq1cwP!Ft~FB_g9=M$8ugTYY8Q?H zq0x)e88EZF@!7Dv(^M0<7oHdpzRLdrmcyD;&o(N!59zy7Ra2cr&P#NY!uHt6P3?L3 zRonmeJLYsS7H%<{I%=3AEyyh&uCiBNy(}U`6rGlO^vTzqz>2%_*Isw%Xz(Yp7|^ll zqSI0gXNolAjGfp`-tytjKGIOZbmzj)75t!eINX)S6-q zI<^fX+?w9nlD>Dg+yGj`5X4cPnbPVb_rR^<8uKA5HPJ_Ik`v1zrgdNCx;bJoo%-x| zwhagCnzPUPXZL&eF9qy7IQYBli9;5n?AE=}gXT9)QBrkU5g1IRNtlTtO0v`%GCWAa z=gKWsY8j&Tlb-YN)=wwELOR8Kz;g4+v`8mINl(?3&FN7C^M%eZRqM*E-0+5cz%PkT*qZUJ8nZI0{Uxi@;QFq>LZTcY1{179<-|4PySD`)VYY|JZ>$1;Su$nF?Inc8rVITQCaY8WVJw6tA8Y<>l z1~lqv@syPk_Txc-s;)d+?LA431cLD$Brc-99o(Mp+1r0=SNofF>vVIQL4nNr(;Bn` zM{sVj&XnC^a@my!5_k{{KK>j!62xayty}h(`hQEi>^EMw)e{O1!(_sk{Kx^soQ_ax^ z^(VP`^8v?mc0{-1y&V*;6oGf-~7 zQY;W&5|OxBaM%V5>8_(sxzgdU{?$D9#K^e3RYe0Dy>|8cv8qM0u72K=HJ?o{Yf|KCcF@2C`|B?_yaOH+Mcf!iCF;Hv@M`F+rBA7OdHK%L!GF1@FN&l<3#e z`_G^I>F%Bnk!1s(4$0q1Uk8!ZUA?*w)N&jwbdCrKRRGd^je5jFB0;oZ+Df?{@}2&lhrJ@n4CnL zR}&>f{KP~XEcnIE0gAxH*2w$FeK!CCi3WAmA0;!T`=HDfu3+RQEk-+4CGP<_ef@1| z?bbYmCtc1FC&wZB%2_;{H@MyP*17j21=bIPYDf!0+TMA|OYK1P2K*)ztT@7{39wMC zF_Jm@<{c2sH(5*68px=07rq)98X+H z$2$$jk4Vdn4e4}vDrhJKK`9bkxxL;SG&usBS)soMUBd~Iw5%52h#k=|ETz$%KI)nI8(m%Ef#|nNv-8ua1TQjS zM7fpvH#?H1Xd+dEQ9))is5YCuT3>h1E6QJ0U@C!8+u@Z<3NPVXQShE!vuDXcH5=!?P9aitpvU0&ybKTWRu~DTz9-%CTz(r%-~=hZ39N}uh9&-pKA0< zm9lV`q86FiOt6U*g$C~?s4%&_KwMt!~S+;Lm0^Gbg^t+8i{oqCX*>u-^LE%_JndKMi1O(B;l! z!+o7;wO72%BwbQir%BffLl8^Zu}(AldmKQ>Cp4zdA=t~b0dnw= zA9Wddx+i_TC$w`0Y)P$W#rta73erg&{z{edwETGKgyIn+!mPdnJYqBt9g`4j z)$04qCxqG=y|sMvnEJNrh28G+dFxt~8&z8O9JjWkdl#5#EjrYz|4dDG$RPNUHtqFW zJ1qIkf)E6UCb@Lw0xt+f89ucARqpx0-rtaFncM0K0k}bJd%axMD}V_K9D#e|NHHl) z3yNfx6xLX9VL+rPqukny|D>^iMnA!etG%M@ciokKH^3%-y?yqSvRCGkb;Gau^yTzO zMi);sI%q8a_tr$9o#50v?Gt`;TMr91G<^1ee%sI9+#RK+u;Y%&_<^gb@*bCbM^j?g zu3ZpB7wASB{H)kWjP9H7)MMZ5*p14sl(CfGqc3;_qT_Ppxrbv zC;;9fD~&Lb#Y^CDv2*HJPSmDc!(IaDo4#a z3G1jLwn$aH@goSG@tXx+Jq}RWgPRE~e}Dw_l-6d}d*3Yo-P>SWx$pm)d}|`Rf-*2R zCmkP{zax0^1BW`3baAGQRK3+`ImG|m8TiZp2%4dK{+soN{b|v{SR=$=UWsc3*E)pY z{u6m#pt+n{UO8g%5Wdi)M10ijuAjtHBsSOg`@62)MH^AQLs=a6H^t~%SXZ4>KG_d2 z@At-1?>pp5eSO3&hW8V`DKcLid;_#otZut{lKEaGG?D@sY@nRA)>Z|TlB=oiyuh2NZuNzEY)i5 zB%2OHy0y#-?B_o$jRIB{Bv7mJVpaRzn3#p*rco`se@wWFh6x_GAvgQsNsEFU-g}MF zoE72`>WIi5sf(Rk?ho0;J|o*}%`EZEXs~Yi6fUjTbRh}37D5EUEwE`0Oh9O($8spx zYATHmw7I2u*=sX(K9zY(a5$4Ds-7mj<@OlD%S5-Dc;&$<;orX2w;~Us_|#C-sm#x? zBOvDUqk=IdsaCp$Xl{5n)5@>J)=rl#!0D?;9yav1-SIhl#`n%UY__V7=JRvphFPyY zSStkY78zO}LS9cMzWxGAZ2;BGzohAK?vI0N<|f>4_@9=!H7-J`*J86z8*oXb@!k4o_h&xYDeB~1`I!QIY{ zEPpRBNcr4gw*4whfCRJJN9-p1XP(4omM;CHhDbq1(_%w2+FG;D)3&{oKN}&<+|b1fiu+&-elX>P9t}6b*>;iuFE2-6EJ4z&3rWOaDKAQbggoE zOf@8NyeASvc+NF6`k@>Q9Sugpw^Hw5INUdZ>Ce}(Q}Hvy-oD1TLSQO$=;^U<6O!a7 z_(7_q5O29&^X8eefsH)r77l9@ut1IGrlcSL6~o3py+};#T7rJ0@+{T7KndZI!z%by zCxnXgh#b}U`#mK4H^gHvVuLVgrlJnDmQUe0o zvt1%f_`GQ62A)OC0yk2ySKU(7-xzKKC(M2aF=LRH*I0&FzOJ1iK~PSnqr#N|!8(3< zOh_!1qd6UyM2o7soMa}vs0ACPDUtxm&K<&Pb%$7#43Ph6UmW8wTiBmw^usr+6@i1s z?vj)2H0T?LtBv?Cwc@JtkMrve(()@tOl-uB=UXnEyxpQ7KSD&#*z0At<*ht^w_yKPDr+2Z49*P2Tl{&Hni{}%8A#}%nmF#m!rUBDPBTm0{z}=xkU-(`4iBaj z!2!qWqqT$+xIx3VT!Zb3!4E{_z@|qoJ4W=S;G(aY*ChfwKN_|mcvzXvH@_knN_spR z@lzr-@ymJl5Xp}n8}^)MiD=xH<5dUW-Fuf=WY@9QiE_Q7ok>|TY^{pUHRicXQ&q6Q zO(G2yO%#q(7}|7E_wQArhH14aP39oHoY6wYfxhiv~XxppDzZxv^?r zuVGcdx+DG5NHO{2a>ha$r={7TES1l25s~Zz#IBl_hF{Pu(q5+3`Xw3D2qo?swctT~ z7Xjmp9p$;|c%+KZrzW7t4hKQ&kK8r?Le9+0XzGy2aR7<^2Hnh9YQXXE3nD8nHhX90 z7i{GAfCzzkS3@4qS1Mirm`V6S7J58OgfcO*i6FhRjP=Ofo9&j=sie=LOdM}iRF5Zr zE^7apf46^R`rbxXNAQiA**9YSC*CM;Ux3_M@&%K8dmf^pG^(SH7)d$1e#6Gaz}SKr zrz1u8XXvlLq;HL?!^6t&8&|%4B9nwCq3RbAG$F|Vlu-VHDvvShfiVn3pmCjkH)U{Z zs8qre>xY@ytv!@EI(wXfpxa}Pz$!G3xW8Y@u8B9aOQe)LuuQY5>*KppaLQrlf2039BTkrJjG!Wx zR>$E3ZB`MuC_pXDGrgnJmR;uh_2liCK_&y &3g@wCu0%C+b25c(+uM|Sb3n5Ta2 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 YdSg*&9$j#QE-^UL7z55i?_bsb0PXiANB{r; diff --git a/docker/docmosis/templates/CV-UNS-GAP-ENG-01071.docx b/docker/docmosis/templates/CV-UNS-GAP-ENG-01071.docx index 57e6930dbe339b25dee82139e86d06fcf15e8163..3b9258c333f29a5fe68f361840cd43a641ba8c9e 100644 GIT binary patch delta 8181 zcmYkBWmMJew#D~GLQ1+@y1N_cPU!~eZV>*IbZs`>-6b8;AP7izhk$e|xQXj~&%NiI z_30Vo`LxFPjk)HUYqkSi)Cq1dMgpD=^$(9QK_K-S5C{td0{OVOTd`ZYSb8~GJA1PE zIys&io;a@w;6L~F^@MF3dwvKhTYTEh^el+Y#UJ$ydbWs*JmH`_>0xx)!>`D3Bv zg*OU@a*bmdakNrJ#kDWf&}DP$VU_=@Piq%dC_8;Fj#3q z4bY{kWDKeGo>HU*W{QYEk^Vm5A<@1|%=%+=E2-bx$;<27sNXc5GY5<;u`ucxr#lyQ zHTtV##ZDXK@50~8H(KByq6?Qe&1~=2Aa;C|2dCR<8kqV#-Ubb>DgJgz^R^Bt%*Di_G#}Z~07P)yQM780J*>2+>#UxxG zIltNoPxkAPj`evL&{Z=39NnT9^@&$2>vTkobHgQB$pT-?`mx(Mn9OO|fNKLC8 zN?&9Aozpz780EGxor zm!2_9nhDQ$LhI%tDB}3)QG2ZW$|&kjh?8#*V+023xC5|I-$0C8L><3dE!n?cgL1&X z%Ez+N{5UG3!rnk*&xZAa93!hRlxAh`{#Nnyq;+dl<`(b}cXJZ(P z$x)|!iWrfZXz(11L`2Hz*sj4yXBsj0yF+zj7h4o7U)_i87Eh5Fe>>5AdzX&Axw2Kx zBAk(h69|Y}c*LM8v%6i~^-hKDbZ9??E2X54o!7x492wsYU&&7OxaGT?8cyIrdx9Vh z6!%;7ul+9NrR%m{xT$q}jqYd1d!HX&Xr9o-?ZCZ%pIg1pzMP+~FMT2l5lBQNs6ub~ z$}ksxMamWk@^46!b=FzN!INAps668=en8oo1CZwIi391<0x`!=+A@be=v{vku|y3D zlf~@Xu_TL&?VjFq(lp|R@N$Xj`(4vjMep`ZMwyo!$C$h+E?-Ygf-UKqr}!`o3v)C^ z@t3L)>60Vm5fkcUtUL?_zLtGvA+15bgVcF#EAd<5Y!M_jLKC;Eg|f>nm5~y!Qs~E9 zfxw^6JR-Q>;=&>!`B>yNzkI4H9zuydZz>Ya44`ZdcjP3sNh6 z6;2Tw?bWhW>+EL{(Q)s7^_Y{cn9}QEAnaX5eL%!&f93BcMjb~t&-%IQ zH4T%6!Y3_r*+~W}D9Mbm_PPB#E{Y+2Y#Y6p-B4rF8+5e1>#TV@=mN-f{G$vS_R?_WZ?S+;mw1#?-^qxeI5O3hXc_Kj0cnNCq%wg)+|TyRj1=J) zY-$W+Hf{n%ln6^K#LBwvstWgoKt*D5vp}@^`HRg^exYN`##eL?h=BJ9;uC6BjoCe4dv2AfM!qqHayd- zm+cnw$M2};UJS_B?cO0O7zx^|Y;EgGOE}?-5yqykwYNS+JvHJOErx1L3=pZQ766Ca z<<_|epVYrLzC2c9eu+X{!pXW8j-oP-{oGSQ%$iE6HwYn{tJ5o1PDh_l^)P6_QPzy6 zm&m6KnWpcA*B>wPf+%J*0)CKiaSe;%9o_u#nfJ3Llrs^cf`yw|Y(DWMUMsq0=es*& z@7*k)R#dmlRG;n~%ZX$~S(j*Aqc|R5skwLA^r-jxaV0Bd1gR7&Wu_Jz6ajXfBo(Wd z66OO0*qz=k1m9b&27eg>Exr2tXlAd5`^AO3GNgPZ;cC=< zc5}jWTcw38t__*`V$C<=P^gL(hQx1TgB zC11B~skv&CRJE~s0mwD|1EV)@zivr7Xha=_Bo zFz=-8nSIFS&&5}j&{ff2BQM9U0x4d?0`M;mSyhaaKOwY}hZiZYFmcLyeOk9IkL!4E z@2@(HH@06uAOQ68a%$w{ku8Av%$y_MoPS2SuZ+jLvAP@yrAS#pnN>LCe(5`aU&fNq|hPZiq)lDNjVCc+e{C+li4 zEZ;k>qc?D|Y{t55eMj~!&udEbw5lDu@A(4h-ZuWwdFs<`(Y|hbJP4@~d#bbA?WcG9 zExnF9ys?`kZgpBj5OjA^R))uI4Yv?sfObK zufZ2a+Dr*RD2(pOoct37w|M3+)ECzw-nl!+HNZ%~u0d9@u?D-lnU(+F8erOD2f z?lu?xZJRAz`#A_Q4uNn5BfFlMvI?`gQYsHZF)*0}Bn!k3g3NkBQ~v2=>{Foeginm$ z1QPPW_9W7b%*X-4y4WZ9Em19B^>PR(0ALnxj`tN-*zD8Vu%)RDjdXiU-};Qup7$oY zHt%spU5<&|*~V#@tu~IokSFb`O_84}r$Zasy~h;=2L2C+a0%N^bhLZHye)H)-imbL z7GL=#QY8cji{mFf5y#FqjXU7SG#uR$#*@a!oBof$cP=N?o!0AO`X++0CI)F|AS@oq zW($BIdodkn(SC@Ws_7Wggq)BGwjH-_Z}1;0tB}1ouMC%<9@4%d zSUco5dR20q5sSnoYjZu?$L(~C!y=;83$0Zx$?LON-khJ;+?7;mJ4%rOR4dF`N>=w8 zS=;iQXdc7T>0u{VI#=EW$!)7GTEo@sIcm+KS2#JQd~5s=lqAQvQ^WwJDd|oy~TzMO-mDjpf-nn{H59{_dxr#G{i{h{FT%HXZAa zJ7aBz{dtX{{!xrf_nQJ`^y73l0W0^r1EJlkYuX&L(Wcf5XsR3VP$!caNvHBb0Cz82 zV@MEHoTeOM;F|u=$9?X798m)7DLWJxnn%Cu4Qk|Aebdh6p!%pLOGk1k0>-SXOO+7& zPZ!j9c6y4`tohc{VoJ?8Cp?n(dx4+NZmp5R*uFrIv+)yGZsMz_F#zX?y5KsMvE3N8i%plAXPV4M`u~ZZu4MRT3uyUirw-R~~}ezA1I*HvS^- zn;%fY+y9fm7?d`wL23Ho2C9xFol>eWI&?G&sDIVZ`BT__T`)gZlJZ$fL)uO=#is!# zuZ=O*uJ~P6F^i>Q*;yw*CY(d(UePG>!JL$K;_6{SN1*@a9M2ON|>l-o0* z>9xkYM52v@Rg@QHx6`l1Q6@3L2_gH$(;<1U(Nz|BmzUl3@ZFsqr`u9?daLaW=40?U_AF?`uxTf3y_zE2?ltNr)!@UYSxiOGx1udAwmZ8W z?>Ez*_U!1)-;eJfb9r4pH5(j12az|ebyWL==447pBDu@Svu>Yy3LNa)DZtSRj}jT< z^wen4;z!zD3MERdv=%&6M76lF+4L~ zaH8ltA+&J%nB?^OOW+6Ad50C9~yan{}-zlputl=t#V@knUqyGD>t`3BV%;b;nsBOgYI zW@blg$*{jc)}4t88PbI$H82r}Q)iRaEzSB}^hg`7lt=}=i)o1uw@-sDr8R3EXEZ{sMF4PhdSF=>2jde;Q{1+y{xp zOfg3H0j#^TfI3Y0=xU|+v0Bu2(MezL96VF}J+AhnSNd}9#!~XBAYN+}@hnf6fTFo( z+3|TFY}SmcmNL>101I5!__OJnk7&Yl9Srjm3&GwH(>$`N$uSq4!Gb|MA?dRjnSm{b z_lg2mu1&7>(?;<8r^_FiBb6 z`e^tRE{ddej376|_~py<(dSXOVj56lpIrh@&8{iD0UuW2cU9r%sTq^3w2ZELsIZ>3 zq%nTSLr%sLF7wZnoFR5$D&C-R39OVzB%*UX`fXWx+~2xJvzF#QHfJ5=d+h9D)n7zf z=@DMP!&_WdJPZ3q`;(G|Tzgw2VPhSYFzoxWU(agI;{Xaf>q$-1^`X%Y3Ht*w2I7n_ zS9ZMpT$b~dxLDI!CdDKVYO!Af6aKt&#X`Y8HIpMpl|@a8=>`I1fa^26(8I|H8GEZ#K^TajAKOh4S&3P($e;F43%kaM=KWk^J|3Y}fd6ffqL$%RY;Cfw{ z!-DX|M zi{=gREFEpf1UP*}iVcW6T70zKS=!d(xQyg;x2G{4uT||7GC3PIsj-kO)ISxE1T{-T z;d01aL+uostw++Z*3mL|14J%D2f&oe=7gRaf2RqSca>1VH%iQkA9u7xGY8DPEaQDWeXzQ0fyqS#SudMw{QSe-%J=(XSHIU5q z0_MFyM<&Oh5giK!J+BPgj7e@)zN~8M(g*FaCpY*JZ&!2>)F9XfLr0mQK0*s6QX)H{91;>pb$!KTYTRKL}en znT6$vUUp}o1}iuwZ%QMdv|Ai1u_#2_VQ*lqI2DzlpAWHHlz8Vehf^4w13F6MVsZiY zh884m>RKw2BI}+=<1{!smbRBFU(elUudx<^_{bX{?uiu^yQ{pIr42 zMXX(|XR41nQvmmK$nbpDq~_>&Bt_WwK>0}jIXeK(lIINte}5Y^CP2Iy4|Mdh5zIT=&TlWkrSlQ$2)-YvKMPSb=l;yT zc7FqVy4P*R3E%lh=2Z03om)L1wrmjK^8Q~^EJ!&@h#YA8r?&XWR7q+wQ;?hZ zP2?U1MgF+OWq1c=oGR<#SSw=22Nrry;g;th`3MLvCiV;|Ufgb_SKq)N-zS(0#jnqO znxR>QAOt+OOqJT)6de)bXh$GYiKb5P6Js#RS0x(r@wQ^@tC3FP4>dJOG>nW@27VeB?{0*e49xXTL9h;fqrkqj`?aKkt*k8<`f=wI5zx`8kU} z_c(kIdT3;CJBgP4W~p{jr41e@Mp1rGAIa!5>FSDDouJ>7AM-097oFY~x_A;L>2pXk zf^mGmc&)w-pWH#Wb&396d`Sx1Y(DUk;O)HzD1&Lrv|yY34W24TGB4?xu;5%O1h>Qh zYm%t9Sa5!$OOQGn{a`zoGFn%CGQ6pK@`hDbP^9YOM;rblPKALw&1v%Vc@n0z- zp+8NeG?4Jg|4nt%mlwC@-ywnDvv+%7wzGQUw&uW&wRHu+oSuI-6L>8B^6%wA&UM|) zKCwCq|5jAn+WK`&4_%`Q;A38>K(w~xl(QZ~Ca#&!;MF8%1ah$KFL4JABh(;Xxx}sl zjv$SqBKhqxLW%N%IFGkg2%A5>K1+REyJ{u=qKi_$d`O+{zr*n|q;JgoGq1SHPC|D0 z>S-}q-A@frq$cp{{6vV~Jo_K;3rcQapVL!s0@-3i&E-XLsdD;rchLi`13LSSUE$?&0pQv{Ye6B!dpjJ;f zd6(%O_FV_ZR}!A*3FQOjxAy+$>5RP*!SVC?(fu}=7PLXvbN;6p&Lbfxe)L1|F&4C@4x7VF{)+w3P{AAs0Q;y`2R8_k!V@PlI+GDa6)+e1JH~jY{ zVe)my6gH{1rJmqt_(Q6Khzwe2eCaK7eP z_kh)s6#q2(DCY({@QB{Ih=8Yc!=jiG$`JM|qs~ox3Om|adZ^2@o}GB!OSc{@a_-sc zy%{Te-#r_4i?is1=)3fEQ{l%+sbxf#COY|=NlA%mB$b>QWB9wjhte^vA)Ci9?m&{s zvCz~w(L2k@KWb7Q8QTGt5Rbf@8+4dXp6NuqTz`Az!@JrSFc=!Fii-f^MRi+lGSr|2 z1O3ix9B2_2uYSFWIFC=RQHqt&;4C5ZUtR>ct#Q-OMRVw5)9~8ceblV&=@?o>ADk&>_94^6?c zrXoC^xmE2OyI`VyBH0i!nW2!K@lQ$!5#YVvQv2TbWZol^@9M#`bNfDdns3?Y{xc;B z6C1`65X+}(-E*%;A-Vu9`Z`G>&j9>TroR7)*`j1-zfowE6u>it=uNn9bSW7{Pmsl6 zlV28!p;_}AQ-an$?@MRNj{$tsFZ>3QMXh5O1_%Vk*;TN-ma&J>bgIz%wu-zkRX|RG zKc(!xj1@eM5JuSu>H-C+2@tt754{iR=j}FXHG7NlyhL@5d9BS~z`aGqicyh_sx#kf zSLgBmDLksfl-WDDpr4K}99_0PK9Og#l|_Z7j5INNzJg*=W7j(Fkl$Tv}^4PalNRB555*KYu9^MU`x03 zH#2`Aptn#makMSiQA#)In|~SZ zzkB2Vm4YC2-#`?OMhr@0C=7-{%?u^M0nj2tT9SV&!(XHRk4gVeEkkz=X-NJT(!a{F k^a=#}d%pj#N`q1viGoX@rbZHQ#JbQzBW6T7y?_4y2P%oR9smFU delta 8051 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 U>hy)d$2CE>`t;CGTL0evAL2uSGynhq diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java index d6d35fe839d..57bb35d38bd 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/InitiateGeneralApplicationServiceHelper.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -39,6 +40,7 @@ public class InitiateGeneralApplicationServiceHelper { private final AuthTokenGenerator authTokenGenerator; private final UserService userService; private final CrossAccessUserConfiguration crossAccessUserConfiguration; + public CaseAssignedUserRolesResource userRoles; public boolean isGAApplicantSameAsPCClaimant(CaseData caseData, String organisationIdentifier) { @@ -56,14 +58,12 @@ public GeneralApplication setRespondentDetailsIfPresent(CaseData.CaseDataBuilder || (YES.equals(caseData.getAddRespondent2()) && caseData.getRespondent2OrganisationPolicy() == null)) { throw new IllegalArgumentException("Solicitor Org details are not set correctly."); } - GeneralApplication.GeneralApplicationBuilder applicationBuilder = generalApplication.toBuilder(); String parentCaseId = caseData.getCcdCaseReference().toString(); - String applicant1OrgCaseRole = caseData.getApplicant1OrganisationPolicy().getOrgPolicyCaseAssignedRole(); String respondent1OrgCaseRole = caseData.getRespondent1OrganisationPolicy().getOrgPolicyCaseAssignedRole(); - CaseAssignedUserRolesResource userRoles = getUserRoles(parentCaseId); + userRoles = getUserRoles(parentCaseId); /*Filter the case users to collect solicitors whose ID doesn't match with GA Applicant Solicitor's ID*/ List respondentSolicitors = userRoles.getCaseAssignedUserRoles().stream() @@ -119,7 +119,7 @@ public GeneralApplication setRespondentDetailsIfPresent(CaseData.CaseDataBuilder } } } - + GeneralApplication.GeneralApplicationBuilder applicationBuilder = generalApplication.toBuilder(); applicationBuilder .generalAppApplnSolicitor(applicantBuilder.build()); String applicantPartyName = null; @@ -133,13 +133,13 @@ public GeneralApplication setRespondentDetailsIfPresent(CaseData.CaseDataBuilder GASolicitorDetailsGAspec.GASolicitorDetailsGAspecBuilder specBuilder = GASolicitorDetailsGAspec .builder(); - specBuilder.id(respSol.getUserId()); - if (respSol.getCaseRole() != null) { + log.info(respSol.getCaseRole(), "**", respSol.getUserId()); /*Populate the GA respondent solicitor details in accordance with civil case Applicant Solicitor 1 details if case role of collected user matches with case role of Applicant 1*/ if (respSol.getCaseRole().equals(applicant1OrgCaseRole)) { if (caseData.getApplicantSolicitor1UserDetails() != null) { + specBuilder.id(respSol.getUserId()); specBuilder.email(caseData.getApplicantSolicitor1UserDetails().getEmail()); specBuilder.organisationIdentifier(caseData.getApplicant1OrganisationPolicy() .getOrganisation().getOrganisationID()); @@ -147,14 +147,19 @@ public GeneralApplication setRespondentDetailsIfPresent(CaseData.CaseDataBuilder /*Populate the GA respondent solicitor details in accordance with civil case Respondent Solicitor 1 details if caserole of collected user matches with caserole Respondent Solicitor 1*/ } else if (respSol.getCaseRole().equals(respondent1OrgCaseRole)) { + specBuilder.id(respSol.getUserId()); specBuilder.email(caseData.getRespondentSolicitor1EmailAddress()); specBuilder.organisationIdentifier(getRespondent1SolicitorOrgId(caseData)); /*Populate the GA respondent solicitor details in accordance with civil case Respondent Solicitor 2 details if it's 1 V 2 Different Solicitor scenario*/ } else { - specBuilder.email(caseData.getRespondentSolicitor2EmailAddress()); - specBuilder.organisationIdentifier(getRespondent2SolicitorOrgId(caseData)); + if (Objects.nonNull(caseData.getAddRespondent2()) + && caseData.getAddRespondent2().equals(YES)) { + specBuilder.id(respSol.getUserId()); + specBuilder.email(caseData.getRespondentSolicitor2EmailAddress()); + specBuilder.organisationIdentifier(getRespondent2SolicitorOrgId(caseData)); + } } /*Set the GA Respondent solicitor details to Empty if above checks are failed*/ } else { @@ -167,7 +172,10 @@ public GeneralApplication setRespondentDetailsIfPresent(CaseData.CaseDataBuilder } GASolicitorDetailsGAspec gaSolicitorDetailsGAspec = specBuilder.build(); - respondentSols.add(element(gaSolicitorDetailsGAspec)); + if (Objects.nonNull(gaSolicitorDetailsGAspec.getId())) { + respondentSols.add(element(gaSolicitorDetailsGAspec)); + } + }); applicantPartyName = getApplicantPartyName(userRoles, userDetails, caseData); applicationBuilder.applicantPartyName(applicantPartyName); @@ -252,8 +260,12 @@ public boolean isGAApplicantSameAsParentCaseClaimant(CaseData caseData, String a } public CaseAssignedUserRolesResource getUserRoles(String parentCaseId) { - return caseAccessDataStoreApi.getUserRoles( - getCaaAccessToken(), authTokenGenerator.generate(), List.of(parentCaseId)); + if (Objects.isNull(userRoles)) { + userRoles = caseAccessDataStoreApi.getUserRoles( + getCaaAccessToken(), authTokenGenerator.generate(), List.of(parentCaseId)); + } + log.info("UserRoles from API :" + userRoles); + return userRoles; } public String getCaaAccessToken() { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/InitiateGeneralApplicationServiceHelperTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/InitiateGeneralApplicationServiceHelperTest.java index 9f2c10dcfc0..a7d8476c88f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/InitiateGeneralApplicationServiceHelperTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/InitiateGeneralApplicationServiceHelperTest.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.reform.civil.handler.callback.user; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -95,6 +96,11 @@ void setup() { .caseAssignedUserRoles(getCaseAssignedApplicantUserRoles()).build()); } + @AfterEach + void setUserRolesAsNull() { + helper.userRoles = null; + } + public List getCaseAssignedApplicantUserRoles() { return List.of( CaseAssignedUserRole.builder().caseDataId("1").userId(STRING_NUM_CONSTANT) @@ -268,6 +274,7 @@ void shouldSetApplicantSolicitorOrgIDTo200() { .respondentSolicitor1EmailAddress(RESPONDENT_EMAIL_ID_CONSTANT) .applicant1(Party.builder().type(COMPANY).companyName("Applicant1").build()) .respondent2(Party.builder().type(COMPANY).companyName("Respondent1").build()) + .addRespondent2(YesOrNo.YES) .applicant1OrganisationPolicy(OrganisationPolicy.builder() .organisation(Organisation.builder().organisationID("200").build()) .orgPolicyCaseAssignedRole(APPLICANTSOLICITORONE.getFormattedName()) @@ -309,6 +316,7 @@ void shouldSetApplicantSolicitorOrgIDTo100() { .applicant2(Party.builder().type(COMPANY).companyName("Applicant2").build()) .respondent1(Party.builder().type(COMPANY).companyName("Respondent1").build()) .respondent2(Party.builder().type(COMPANY).companyName("Respondent2").build()) + .addRespondent2(YesOrNo.YES) .applicant1OrganisationPolicy(OrganisationPolicy.builder() .organisation(Organisation.builder().organisationID("200").build()) .orgPolicyCaseAssignedRole(APPLICANTSOLICITORONE.getFormattedName()) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/GeneralApplicationDetailsBuilder.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/GeneralApplicationDetailsBuilder.java index cdd3e35fc73..0caef94ebf2 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/GeneralApplicationDetailsBuilder.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/GeneralApplicationDetailsBuilder.java @@ -1588,6 +1588,7 @@ public CaseData getVaryJudgmentWithN245TestData() { .ccdCaseReference(1L) .applicant1(Party.builder().type(Party.Type.COMPANY).companyName("Applicant1").build()) .respondent1(Party.builder().type(Party.Type.COMPANY).companyName("Respondent1").build()) + .addRespondent2(NO) .courtLocation(CourtLocation.builder() .caseLocation(CaseLocationCivil.builder() .region("2") From 44d869f2678b37acb0c03640aaf9aec1e79cdc13 Mon Sep 17 00:00:00 2001 From: hmcts-version1-domini <107860057+hmcts-version1-domini@users.noreply.github.com> Date: Wed, 22 Nov 2023 17:46:54 +0100 Subject: [PATCH 11/29] CIV-11073 Notify claimant HWF yes (#3545) * Modify claim submission handler to add notification for HWF * Add frontend_url in the properties for the template * Add template id to the application.yaml * fiz unit tests and add one more * add R2 flag * change civil commons release version for testing * change civil commons release version for testing * fix unit tests after r2 flag added * create function to add template * Change civil commons version back to latest * Change civil commons version to latest --------- Co-authored-by: Raja Mani --- build.gradle | 2 +- .../NotifyClaimantClaimSubmitted.java | 18 +++- src/main/resources/application.yaml | 1 + .../NotifyClaimantClaimSubmittedTest.java | 83 +++++++++++++++---- 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index e840aa8b239..2e0219c4e14 100644 --- a/build.gradle +++ b/build.gradle @@ -369,7 +369,7 @@ configurations.all { } dependencies { - implementation 'com.github.hmcts:civil-commons:1.0.34' + implementation 'com.github.hmcts:civil-commons:1.0.35' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop' diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmitted.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmitted.java index 5904bcff271..db83dd1d822 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmitted.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmitted.java @@ -8,9 +8,11 @@ import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.config.PinInPostConfiguration; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.notify.NotificationService; import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import java.util.List; import java.util.Map; @@ -27,6 +29,8 @@ public class NotifyClaimantClaimSubmitted extends CallbackHandler implements Not public static final String TASK_ID_Applicant1 = "NotifyApplicant1ClaimSubmitted"; private static final String REFERENCE_TEMPLATE = "claim-submitted-notification-%s"; private final NotificationService notificationService; + private final FeatureToggleService toggleService; + private final PinInPostConfiguration pipInPostConfiguration; private final NotificationsProperties notificationsProperties; private final Map callBackMap = Map.of( callbackKey(ABOUT_TO_SUBMIT), this::notifyApplicantForClaimSubmitted @@ -45,7 +49,7 @@ public String camundaActivityId(CallbackParams callbackParams) { private CallbackResponse notifyApplicantForClaimSubmitted(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - if (Objects.isNull(caseData.getHelpWithFeesReferenceNumber())) { + if (caseData.isLipvLipOneVOne() && toggleService.isLipVLipEnabled()) { generateEmail(caseData); } @@ -61,15 +65,23 @@ public List handledEvents() { @Override public Map addProperties(CaseData caseData) { return Map.of( - CLAIMANT_NAME, getPartyNameBasedOnType(caseData.getApplicant1()) + CLAIMANT_NAME, getPartyNameBasedOnType(caseData.getApplicant1()), + DEFENDANT_NAME, getPartyNameBasedOnType(caseData.getRespondent1()), + FRONTEND_URL, pipInPostConfiguration.getCuiFrontEndUrl() ); } + private String addTemplate(CaseData caseData) { + return Objects.isNull(caseData.getHelpWithFeesReferenceNumber()) + ? notificationsProperties.getNotifyLiPClaimantClaimSubmittedAndPayClaimFeeTemplate() + : notificationsProperties.getNotifyLiPClaimantClaimSubmittedAndHelpWithFeeTemplate(); + } + private void generateEmail(CaseData caseData) { if (Objects.nonNull(caseData.getApplicant1Email())) { notificationService.sendMail( caseData.getApplicant1Email(), - notificationsProperties.getNotifyLiPClaimantClaimSubmittedAndPayClaimFeeTemplate(), + addTemplate(caseData), addProperties(caseData), String.format(REFERENCE_TEMPLATE, caseData.getLegacyCaseReference()) ); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index e0f7be8b390..29ac16b639e 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -310,6 +310,7 @@ notifications: hearingNotificationLipDefendantTemplate: "9239a55e-fd08-4f03-9ba5-7d90ac35af41" notifyLiPClaimantClaimSubmittedAndPayClaimFeeTemplate: "3d302844-ecdc-47e6-8aed-971c3f42a059" + notifyLiPClaimantClaimSubmittedAndHelpWithFeeTemplate: "a9c1ccba-eb72-414d-8dc7-d75f33c79b28" notifyLiPClaimantDefendantResponded: "4b1325dd-51ed-4dc2-bcc6-d9afb01a3f29" notifyLiPClaimantDefendantChangedContactDetails: "72a14146-c897-4fc6-be4f-474266da7398" diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmittedTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmittedTest.java index e7eacfc0f36..5d836ab236f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmittedTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/NotifyClaimantClaimSubmittedTest.java @@ -8,6 +8,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.config.PinInPostConfiguration; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; @@ -17,6 +19,7 @@ import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import java.util.Map; @@ -25,6 +28,8 @@ import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIMANT_NAME; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.FRONTEND_URL; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.DEFENDANT_NAME; @SpringBootTest(classes = { NotifyClaimantClaimSubmitted.class, @@ -36,21 +41,33 @@ public class NotifyClaimantClaimSubmittedTest extends BaseCallbackHandlerTest { private NotificationService notificationService; @MockBean private NotificationsProperties notificationsProperties; + @MockBean + private FeatureToggleService toggleService; + @MockBean + private PinInPostConfiguration pinInPostConfiguration; @Autowired private NotifyClaimantClaimSubmitted handler; @Nested class AboutToSubmitCallback { - private static final String EMAIL_TEMPLATE = "test-notification-id"; + private static final String EMAIL_TEMPLATE_HWF = "test-notification-id"; + private static final String EMAIL_TEMPLATE_NO_HWF = "test-notification-no-hwf-id"; private static final String CLAIMANT_EMAIL_ID = "testorg@email.com"; + private static final String CLAIMANT_EMAIL_ID_INDIVIDUAL = "rambo@email.com"; private static final String REFERENCE_NUMBER = "claim-submitted-notification-000DC001"; private static final String CLAIMANT = "Mr. John Rambo"; + private static final String RESPONDENT_NAME = "Mr. Sole Trader"; + public static final String FRONTEND_CUI_URL = "dummy_cui_front_end_url"; @BeforeEach void setup() { when(notificationsProperties.getNotifyLiPClaimantClaimSubmittedAndPayClaimFeeTemplate()).thenReturn( - EMAIL_TEMPLATE); + EMAIL_TEMPLATE_NO_HWF); + when(notificationsProperties.getNotifyLiPClaimantClaimSubmittedAndHelpWithFeeTemplate()).thenReturn( + EMAIL_TEMPLATE_HWF); + when(pinInPostConfiguration.getCuiFrontEndUrl()).thenReturn("dummy_cui_front_end_url"); + when(toggleService.isLipVLipEnabled()).thenReturn(true); } @Test @@ -62,6 +79,9 @@ void shouldNotifyApplicant1_ClaimIsSubmittedButNotIssued() { .build()) .respondent1(PartyBuilder.builder().soleTrader().build().toBuilder() .build()) + .respondent1Represented(YesOrNo.NO) + .specRespondent1Represented(YesOrNo.NO) + .applicant1Represented(YesOrNo.NO) .build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); @@ -72,20 +92,23 @@ void shouldNotifyApplicant1_ClaimIsSubmittedButNotIssued() { // Then verify(notificationService, times(1)).sendMail( CLAIMANT_EMAIL_ID, - EMAIL_TEMPLATE, - getNotificationDataMap(caseData), + EMAIL_TEMPLATE_NO_HWF, + getNotificationDataMap(), REFERENCE_NUMBER ); } @Test - void shouldNotSendEmail_whenEventIsCalledAndDefendantHasNoEmail() { + void shouldNotSendEmail_whenEventIsCalledAndApplicantHasNoEmail() { //Given CaseData caseData = CaseDataBuilder.builder().atStateClaimSubmitted().build().toBuilder() .applicant1(PartyBuilder.builder().individual().build().toBuilder() .build()) .respondent1(PartyBuilder.builder().soleTrader().build().toBuilder() .build()) + .respondent1Represented(YesOrNo.NO) + .specRespondent1Represented(YesOrNo.NO) + .applicant1Represented(YesOrNo.NO) .build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); @@ -96,14 +119,14 @@ void shouldNotSendEmail_whenEventIsCalledAndDefendantHasNoEmail() { // Then verify(notificationService, times(0)).sendMail( CLAIMANT_EMAIL_ID, - EMAIL_TEMPLATE, - getNotificationDataMap(caseData), + EMAIL_TEMPLATE_NO_HWF, + getNotificationDataMap(), REFERENCE_NUMBER ); } @Test - void shouldNotSendEmail_whenHFWReferanceNumberPresent() { + void shouldSendEmail_whenHFWReferenceNumberPresent() { //Given CaseData caseData = CaseDataBuilder.builder().atStateClaimSubmitted().build().toBuilder() .applicant1(PartyBuilder.builder().individual().build().toBuilder() @@ -111,6 +134,9 @@ void shouldNotSendEmail_whenHFWReferanceNumberPresent() { .respondent1(PartyBuilder.builder().soleTrader().build().toBuilder() .build()) .caseDataLiP(CaseDataLiP.builder().helpWithFees(HelpWithFees.builder().helpWithFeesReferenceNumber("1111").build()).build()) + .respondent1Represented(YesOrNo.NO) + .specRespondent1Represented(YesOrNo.NO) + .applicant1Represented(YesOrNo.NO) .build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); @@ -119,17 +145,46 @@ void shouldNotSendEmail_whenHFWReferanceNumberPresent() { handler.handle(params); // Then - verify(notificationService, times(0)).sendMail( - CLAIMANT_EMAIL_ID, - EMAIL_TEMPLATE, - getNotificationDataMap(caseData), + verify(notificationService, times(1)).sendMail( + CLAIMANT_EMAIL_ID_INDIVIDUAL, + EMAIL_TEMPLATE_HWF, + getNotificationDataMap(), + REFERENCE_NUMBER + ); + } + + @Test + void shouldSendEmail_whenHFWReferanceNumberNotPresent() { + //Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimSubmitted().build().toBuilder() + .applicant1(PartyBuilder.builder().individual().build().toBuilder() + .build()) + .respondent1(PartyBuilder.builder().soleTrader().build().toBuilder() + .build()) + .respondent1Represented(YesOrNo.NO) + .specRespondent1Represented(YesOrNo.NO) + .applicant1Represented(YesOrNo.NO) + .build(); + + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); + + // When + handler.handle(params); + + // Then + verify(notificationService, times(1)).sendMail( + CLAIMANT_EMAIL_ID_INDIVIDUAL, + EMAIL_TEMPLATE_NO_HWF, + getNotificationDataMap(), REFERENCE_NUMBER ); } - private Map getNotificationDataMap(CaseData caseData) { + private Map getNotificationDataMap() { return Map.of( - CLAIMANT_NAME, CLAIMANT + CLAIMANT_NAME, CLAIMANT, + DEFENDANT_NAME, RESPONDENT_NAME, + FRONTEND_URL, FRONTEND_CUI_URL ); } From 8c8f7ef2f2c00595c98fa13c3ed0fa8c5fa7e0e0 Mon Sep 17 00:00:00 2001 From: drummondjm <93932689+drummondjm@users.noreply.github.com> Date: Wed, 22 Nov 2023 16:47:28 +0000 Subject: [PATCH 12/29] updated classification on hearing notice (#3613) --- .../templates/CV-UNS-HNO-ENG-01196.docx | Bin 41061 -> 35508 bytes .../templates/CV-UNS-HNO-ENG-01197.docx | Bin 40909 -> 35352 bytes .../templates/CV-UNS-HNO-ENG-01198.docx | Bin 37470 -> 35092 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01196.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01196.docx index 2ff9eb37d325e0131172448ec4b67bd787b36d81..a8323e9b537119c43fb70896ee39e77a672aae16 100644 GIT binary patch delta 11648 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 delta 16752 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 Ky+r)S?tcNh62>?H delta 16650 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 diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01198.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01198.docx index a4240ad5a61e0ebf05117e36ffa12df4b8b1ffcb..74a8cfd7c0d93eb6563d89a4d916ba029f2ad2ad 100644 GIT binary patch delta 10902 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 delta 13330 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 aB4RLJ;(Is@A{q!9$RGp=NN~&_RsRpjKi0_r From 8c9f680d2241434bf6e7d79273c4e07594b03f3f Mon Sep 17 00:00:00 2001 From: Miguel Molina <93722947+miguelMolina3691@users.noreply.github.com> Date: Wed, 22 Nov 2023 18:56:22 +0100 Subject: [PATCH 13/29] CIV-10370 Add SDO claimant lip Notification (#3349) * CIV-10370 Add SDO claimant lip Notification * CIV-10370 update test --------- Co-authored-by: pats-john <13101669+pats-john@users.noreply.github.com> Co-authored-by: Raja Mani Co-authored-by: meulendijksm Co-authored-by: marianadpereira <71711509+marianadpereira@users.noreply.github.com> Co-authored-by: dharmendra kumar --- ...reateSDOApplicantsNotificationHandler.java | 50 ++++++++++--- .../hmcts/reform/civil/model/CaseData.java | 5 ++ ...eSDOApplicantsNotificationHandlerTest.java | 74 ++++++++++++++++++- 3 files changed, 115 insertions(+), 14 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandler.java index 7c69a19f9fe..c7ea157702d 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandler.java @@ -57,18 +57,10 @@ public List handledEvents() { private CallbackResponse notifyApplicantsSolicitorSDOTriggered(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - String unspecTemplate = featureToggleService.isEarlyAdoptersEnabled() - ? notificationsProperties.getSdoOrderedEA() : notificationsProperties.getSdoOrdered(); - - String specTemplate = featureToggleService.isEarlyAdoptersEnabled() - ? notificationsProperties.getSdoOrderedSpecEA() : notificationsProperties.getSdoOrderedSpec(); - notificationService.sendMail( - caseData.getApplicantSolicitor1UserDetails().getEmail(), - caseData.getCaseAccessCategory() == CaseCategory.SPEC_CLAIM - ? specTemplate - : unspecTemplate, - addProperties(caseData), + getRecipientEmail(caseData), + getNotificationTemplate(caseData), + getEmailProperties(caseData), String.format(REFERENCE_TEMPLATE, caseData.getLegacyCaseReference()) ); @@ -84,9 +76,45 @@ CLAIM_LEGAL_ORG_NAME_SPEC, getApplicantsLegalOrganizationName(caseData.getApplic ); } + public Map addPropertiesLip(CaseData caseData) { + return Map.of( + CLAIM_REFERENCE_NUMBER, caseData.getLegacyCaseReference(), + CLAIMANT_NAME, caseData.getApplicant1().getPartyName() + ); + } + public String getApplicantsLegalOrganizationName(String id, CaseData caseData) { Optional organisation = organisationService.findOrganisationById(id); return organisation.isPresent() ? organisation.get().getName() : caseData.getApplicantSolicitor1ClaimStatementOfTruth().getName(); } + + private String getNotificationTemplate(CaseData caseData) { + + String unspecTemplate = featureToggleService.isEarlyAdoptersEnabled() + ? notificationsProperties.getSdoOrderedEA() : notificationsProperties.getSdoOrdered(); + + String specTemplate = featureToggleService.isEarlyAdoptersEnabled() + ? notificationsProperties.getSdoOrderedSpecEA() : notificationsProperties.getSdoOrderedSpec(); + + if (caseData.isApplicantLiP()) { + return notificationsProperties.getClaimantLipClaimUpdatedTemplate(); + } else { + if (caseData.getCaseAccessCategory() == CaseCategory.SPEC_CLAIM) { + return specTemplate; + } else { + return unspecTemplate; + } + } + } + + private String getRecipientEmail(CaseData caseData) { + return caseData.isApplicantLiP() ? caseData.getClaimantUserDetails().getEmail() + : caseData.getApplicantSolicitor1UserDetails().getEmail(); + } + + private Map getEmailProperties(CaseData caseData) { + return caseData.isApplicantLiP() ? addPropertiesLip(caseData) + : addProperties(caseData); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index b46645b792a..f81f81988c1 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -671,6 +671,11 @@ public boolean isRespondent1LiP() { return YesOrNo.NO == getRespondent1Represented(); } + @JsonIgnore + public boolean isApplicantLiP() { + return YesOrNo.NO == getApplicant1Represented(); + } + public YesOrNo getRespondent2Represented() { return Stream.of( respondent2Represented, diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandlerTest.java index c5bb04f3f96..c67eaaf0d3f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/CreateSDOApplicantsNotificationHandlerTest.java @@ -9,7 +9,12 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; +import uk.gov.hmcts.reform.ccd.model.OrganisationPolicy; import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.CaseCategory; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.model.IdamUserDetails; +import uk.gov.hmcts.reform.civil.model.StatementOfTruth; import uk.gov.hmcts.reform.civil.notify.NotificationsProperties; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -29,6 +34,7 @@ import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.CreateSDOApplicantsNotificationHandler.TASK_ID; +import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIMANT_NAME; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIM_LEGAL_ORG_NAME_SPEC; import static uk.gov.hmcts.reform.civil.handler.callback.camunda.notification.NotificationData.CLAIM_REFERENCE_NUMBER; import static uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder.LEGACY_CASE_REFERENCE; @@ -57,32 +63,94 @@ class AboutToSubmitCallback { @BeforeEach void setup() { when(notificationsProperties.getSdoOrdered()).thenReturn("template-id"); + when(notificationsProperties.getSdoOrderedSpec()).thenReturn("template-id-spec"); + when(notificationsProperties.getClaimantLipClaimUpdatedTemplate()).thenReturn("template-id-lip"); when(organisationService.findOrganisationById(anyString())) .thenReturn(Optional.of(Organisation.builder().name("Signer Name").build())); } @Test void shouldNotifyApplicantSolicitor_whenInvoked() { + // Given CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); + // When + handler.handle(params); + // Then + verify(notificationService).sendMail( + "applicantsolicitor@example.com", + "template-id", + getNotificationDataMap(), + "create-sdo-applicants-notification-000DC001" + ); + } + @Test + void shouldNotifyApplicantLip_whenInvoked() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build() + .toBuilder().claimantUserDetails(IdamUserDetails.builder().email("applicantLip@example.com").build()) + .applicant1Represented(YesOrNo.NO) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); + // When handler.handle(params); + // Then + verify(notificationService).sendMail( + "applicantLip@example.com", + "template-id-lip", + getNotificationDataMapLip(), + "create-sdo-applicants-notification-000DC001" + ); + } + @Test + void shouldNotifyApplicantSolicitorStatement_whenInvoked() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build() + .toBuilder() + .applicant1Represented(YesOrNo.YES) + .applicant1OrganisationPolicy(OrganisationPolicy.builder().organisation( + uk.gov.hmcts.reform.ccd.model.Organisation.builder().organisationID("abc1").build()).build()) + .caseAccessCategory(CaseCategory.SPEC_CLAIM) + .applicantSolicitor1ClaimStatementOfTruth(StatementOfTruth.builder().name("test name").build()) + .build(); + CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); + // When + when(organisationService.findOrganisationById(anyString())).thenReturn(Optional.empty()); + handler.handle(params); + // Then verify(notificationService).sendMail( "applicantsolicitor@example.com", - "template-id", - getNotificationDataMap(caseData), + "template-id-spec", + getNotificationDataMapStatement(), "create-sdo-applicants-notification-000DC001" ); } @NotNull - private Map getNotificationDataMap(CaseData caseData) { + private Map getNotificationDataMap() { return Map.of( CLAIM_REFERENCE_NUMBER, LEGACY_CASE_REFERENCE, CLAIM_LEGAL_ORG_NAME_SPEC, "Signer Name" ); } + + @NotNull + private Map getNotificationDataMapLip() { + return Map.of( + CLAIM_REFERENCE_NUMBER, LEGACY_CASE_REFERENCE, + CLAIMANT_NAME, "Mr. John Rambo" + ); + } + + @NotNull + private Map getNotificationDataMapStatement() { + return Map.of( + CLAIM_REFERENCE_NUMBER, LEGACY_CASE_REFERENCE, + CLAIM_LEGAL_ORG_NAME_SPEC, "test name" + ); + } } @Nested From 69f77de57a19f625346de036bf9555ad1d5013c4 Mon Sep 17 00:00:00 2001 From: asthamalviya <104994907+asthamalviya@users.noreply.github.com> Date: Thu, 23 Nov 2023 08:30:10 +0000 Subject: [PATCH 14/29] CIV-11582 pointing to already created DB15 (#3607) * Adding v15 secret value in terraform --- infrastructure/tf-kv-secrets-cmc.tf | 64 ++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/infrastructure/tf-kv-secrets-cmc.tf b/infrastructure/tf-kv-secrets-cmc.tf index 0155092338f..886e7261230 100644 --- a/infrastructure/tf-kv-secrets-cmc.tf +++ b/infrastructure/tf-kv-secrets-cmc.tf @@ -21,4 +21,66 @@ resource "azurerm_key_vault_secret" "civil_db_password__v11_secret" { depends_on = [ module.key-vault ] -} \ No newline at end of file +} + +data "azurerm_key_vault_secret" "db_password_v15_secret" { + key_vault_id = data.azurerm_key_vault.cmc_vault.id + name = "cmc-db-password-v15" +} + +resource "azurerm_key_vault_secret" "civil_db_password__v15_secret" { + name = "cmc-db-username-v15" + value = data.azurerm_key_vault_secret.db_password_v15_secret.value + key_vault_id = module.key-vault.key_vault_id + + content_type = "secret" + tags = merge(var.common_tags, { + "source" : "Vault ${data.azurerm_key_vault.cmc_vault.name}" + }) + + depends_on = [ + module.key-vault + ] +} + +data "azurerm_key_vault_secret" "db_username_v15_secret" { + key_vault_id = data.azurerm_key_vault.cmc_vault.id + name = "cmc-db-username-v15" +} + +resource "azurerm_key_vault_secret" "civil_db_username__v15_secret" { + name = "cmc-db-username-v15" + value = data.azurerm_key_vault_secret.db_username_v15_secret.value + key_vault_id = module.key-vault.key_vault_id + + content_type = "secret" + tags = merge(var.common_tags, { + "source" : "Vault ${data.azurerm_key_vault.cmc_vault.name}" + }) + + depends_on = [ + module.key-vault + ] +} + +data "azurerm_key_vault_secret" "db_host_v15_secret" { + key_vault_id = data.azurerm_key_vault.cmc_vault.id + name = "cmc-db-host-v15" +} + +resource "azurerm_key_vault_secret" "civil_db_host__v15_secret" { + name = "cmc-db-host-v15" + value = data.azurerm_key_vault_secret.db_host_v15_secret.value + key_vault_id = module.key-vault.key_vault_id + + content_type = "secret" + tags = merge(var.common_tags, { + "source" : "Vault ${data.azurerm_key_vault.cmc_vault.name}" + }) + + depends_on = [ + module.key-vault + ] +} + + From 6ad91235c58ae27a11239c3e02b3f90008066cf2 Mon Sep 17 00:00:00 2001 From: asthamalviya <104994907+asthamalviya@users.noreply.github.com> Date: Thu, 23 Nov 2023 11:10:49 +0000 Subject: [PATCH 15/29] CIV-10543 civil service password creation (#3620) * v15 creating password secret on all the enviornments --- infrastructure/tf-kv-secrets-cmc.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/tf-kv-secrets-cmc.tf b/infrastructure/tf-kv-secrets-cmc.tf index 886e7261230..afe11a0afa5 100644 --- a/infrastructure/tf-kv-secrets-cmc.tf +++ b/infrastructure/tf-kv-secrets-cmc.tf @@ -29,7 +29,7 @@ data "azurerm_key_vault_secret" "db_password_v15_secret" { } resource "azurerm_key_vault_secret" "civil_db_password__v15_secret" { - name = "cmc-db-username-v15" + name = "cmc-db-password-v15" value = data.azurerm_key_vault_secret.db_password_v15_secret.value key_vault_id = module.key-vault.key_vault_id From 1765fef42247d9ee68ce6f3f13e6a127f834fb1a Mon Sep 17 00:00:00 2001 From: marianadpereira <71711509+marianadpereira@users.noreply.github.com> Date: Thu, 23 Nov 2023 13:51:52 +0000 Subject: [PATCH 16/29] CIV-9065 PR to whitelist only the download document endpoint (#3515) * Trigger build with empty commit * Trigger build with empty commit * removing endpoint to whitelisted services --------- Co-authored-by: dharmendra kumar --- .../uk/gov/hmcts/reform/civil/config/SecurityConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/config/SecurityConfiguration.java b/src/main/java/uk/gov/hmcts/reform/civil/config/SecurityConfiguration.java index b768e973f22..553ce8d97dc 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/config/SecurityConfiguration.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/config/SecurityConfiguration.java @@ -51,7 +51,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { "/assignment/**", "/service-request-update", "/service-request-update-claim-issued", - "/case/document/**" + "/case/document/downloadDocument/**" }; @Value("${spring.security.oauth2.client.provider.oidc.issuer-uri}") From a33ca4edee844e6e4246560a3c28dc2872b0bb32 Mon Sep 17 00:00:00 2001 From: Harry H <33700332+HarryH96@users.noreply.github.com> Date: Thu, 23 Nov 2023 14:40:12 +0000 Subject: [PATCH 17/29] CIV-10810 NoC/CoS toggle cleanup - again (#3614) * CIV-10810 NoC/CoS toggle cleanup --------- Co-authored-by: sankaviv1 Co-authored-by: sankaviv1 <95748224+sankaviv1@users.noreply.github.com> Co-authored-by: AhsanZX97 --- .../RpaCaseHandedOfflineConsumerTest.java | 8 - .../hmcts/reform/civil/RpaConsumerTest.java | 28 - .../TestingSupportController.java | 16 - .../UnrepresentedOrUnregisteredScenario.java | 17 +- .../GenerateClaimFormCallbackHandler.java | 2 +- ...nerateClaimFormForSpecCallbackHandler.java | 2 +- ...ingOnlineApplicantNotificationHandler.java | 5 +- .../user/CreateClaimCallbackHandler.java | 40 +- .../user/CreateClaimSpecCallbackHandler.java | 4 +- .../user/NotifyClaimCallbackHandler.java | 9 +- .../NotifyClaimDetailsCallbackHandler.java | 118 ++- .../handler/tasks/CaseEventTaskHandler.java | 7 +- .../civil/service/FeatureToggleService.java | 8 - .../civil/service/flowstate/FlowFlag.java | 2 - .../service/flowstate/FlowPredicate.java | 6 + .../service/flowstate/StateFlowEngine.java | 54 +- .../robotics/mapper/EventHistoryMapper.java | 16 +- .../robotics/mapper/RoboticsDataMapper.java | 5 +- .../mapper/RoboticsDataMapperForSpec.java | 5 +- ...representedOrUnregisteredScenarioTest.java | 89 +-- .../GenerateClaimFormCallbackHandlerTest.java | 36 - .../GenerateClaimFormForSpecHandlerTest.java | 22 - ...nlineApplicantNotificationHandlerTest.java | 36 +- .../user/CreateClaimCallbackHandlerTest.java | 172 ----- .../CreateClaimSpecCallbackHandlerTest.java | 2 - .../user/NotifyClaimCallbackHandlerTest.java | 102 --- ...NotifyClaimDetailsCallbackHandlerTest.java | 49 -- .../tasks/CaseEventTaskHandlerTest.java | 93 +-- .../handler/tasks/PaymentTaskHandlerTest.java | 4 +- .../civil/sampledata/CaseDataBuilder.java | 5 +- .../civil/sampledata/CaseDataBuilderSpec.java | 6 +- .../sampledata/CaseDataBuilderUnspec.java | 6 +- .../service/FeatureToggleServiceTest.java | 18 - .../docmosis/RepresentativeServiceTest.java | 57 -- ...DefaultJudgmentOrderFormGeneratorTest.java | 1 - .../service/flowstate/FlowPredicateTest.java | 16 + .../flowstate/StateFlowEngineSpecTest.java | 21 +- .../flowstate/StateFlowEngineTest.java | 670 ++++-------------- .../flowstate/StateFlowEngineUnspecTest.java | 18 +- .../mapper/EventHistoryMapperTest.java | 354 --------- .../mapper/RoboticsDataMapperForSpecTest.java | 6 - .../mapper/RoboticsDataMapperTest.java | 6 - 42 files changed, 275 insertions(+), 1866 deletions(-) diff --git a/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaCaseHandedOfflineConsumerTest.java b/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaCaseHandedOfflineConsumerTest.java index b9af898ee07..44e087ddd18 100644 --- a/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaCaseHandedOfflineConsumerTest.java +++ b/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaCaseHandedOfflineConsumerTest.java @@ -89,8 +89,6 @@ void setUp() { @Test @SneakyThrows void shouldGeneratePact_whenCaseTakenOffline() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - CaseData caseData = CaseDataBuilder.builder() .atState(FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED) .legacyCaseReference("100DC001") @@ -110,8 +108,6 @@ void shouldGeneratePact_whenCaseTakenOffline() { @Test @SneakyThrows void shouldGeneratePact_whenCaseDismissed() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - CaseData caseData = CaseDataBuilder.builder() .atState(FlowState.Main.CLAIM_DISMISSED_PAST_CLAIM_NOTIFICATION_DEADLINE) .legacyCaseReference("100DC001") @@ -131,8 +127,6 @@ void shouldGeneratePact_whenCaseDismissed() { @Test @SneakyThrows void shouldGeneratePact_whenNoticeOfChangeAndCaseTakenOffline() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - CaseData caseData = CaseDataBuilder.builder() .atState(FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED) .legacyCaseReference("100DC001") @@ -163,8 +157,6 @@ void shouldGeneratePact_whenNoticeOfChangeAndCaseTakenOffline() { @Test @SneakyThrows void shouldGeneratePact_whenNoticeOfChangeAndCaseDismissed() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - CaseData caseData = CaseDataBuilder.builder() .atState(FlowState.Main.CLAIM_DISMISSED_PAST_CLAIM_NOTIFICATION_DEADLINE) .legacyCaseReference("100DC001") diff --git a/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaConsumerTest.java b/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaConsumerTest.java index 731b59c66f5..a496f481388 100644 --- a/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaConsumerTest.java +++ b/src/contractTest/java/uk/gov/hmcts/reform/civil/RpaConsumerTest.java @@ -214,10 +214,6 @@ void shouldGeneratePact_whenClaimAgainstUnrepresentedDefendantWithMinimalData_wi @Nested class UnrepresentedAndUnregisteredDefendant { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - } @Test @SneakyThrows @@ -235,30 +231,6 @@ void shouldGeneratePact_whenClaimAgainstUnrepresentedAndUnregisteredDefendant() assertEquals(PactVerificationResult.Ok.INSTANCE, result); } - - @Nested - class ToBeRemovedAfterNoc { - @Test - @SneakyThrows - void shouldGeneratePact_whenClaimAgainstUnrepresentedAndUnregisteredDefendant() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(false); - - CaseData caseData = CaseDataBuilder.builder() - .atState(FlowState.Main.TAKEN_OFFLINE_UNREPRESENTED_UNREGISTERED_DEFENDANT) - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .legacyCaseReference("000DC047") - .build(); - String payload = roboticsDataMapper.toRoboticsCaseData(caseData, BEARER_TOKEN).toJsonString(); - - assertThat(payload, validateJson()); - - String description = "Robotics case data for claim against unrepresented and unregistered defendant"; - PactVerificationResult result = getPactVerificationResult(payload, description); - - assertEquals(PactVerificationResult.Ok.INSTANCE, result); - } - } } @Nested diff --git a/src/main/java/uk/gov/hmcts/reform/civil/controllers/testingsupport/TestingSupportController.java b/src/main/java/uk/gov/hmcts/reform/civil/controllers/testingsupport/TestingSupportController.java index 8e779ede86d..350018b0076 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/controllers/testingsupport/TestingSupportController.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/controllers/testingsupport/TestingSupportController.java @@ -89,22 +89,6 @@ public ResponseEntity checkFeatureToggle( return new ResponseEntity<>(featureToggleInfo, HttpStatus.OK); } - @GetMapping("/testing-support/feature-toggle/noc") - @Operation(summary = "Check if noc feature toggle is enabled") - public ResponseEntity checkNoCToggleEnabled() { - boolean featureEnabled = featureToggleService.isNoticeOfChangeEnabled(); - FeatureToggleInfo featureToggleInfo = new FeatureToggleInfo(featureEnabled); - return new ResponseEntity<>(featureToggleInfo, HttpStatus.OK); - } - - @GetMapping("/testing-support/feature-toggle/isCertificateOfServiceEnabled") - @Operation(summary = "Check if access profiles feature toggle is enabled") - public ResponseEntity checkCertificateOfServiceEnabled() { - boolean featureEnabled = featureToggleService.isCertificateOfServiceEnabled(); - FeatureToggleInfo featureToggleInfo = new FeatureToggleInfo(featureEnabled); - return new ResponseEntity<>(featureToggleInfo, HttpStatus.OK); - } - @Data private static class BusinessProcessInfo { private BusinessProcess businessProcess; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenario.java b/src/main/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenario.java index 0251e6e0807..e479191be1d 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenario.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenario.java @@ -9,8 +9,7 @@ public enum UnrepresentedOrUnregisteredScenario { UNREPRESENTED, - UNREGISTERED, - UNREGISTERED_NOTICE_OF_CHANGE; + UNREGISTERED; public static List getDefendantNames(UnrepresentedOrUnregisteredScenario scenario, CaseData caseData) { List defendantNames = new ArrayList<>(); @@ -24,20 +23,6 @@ public static List getDefendantNames(UnrepresentedOrUnregisteredScenario } break; case UNREGISTERED: - if (caseData.getRespondent1OrgRegistered() != YES - && caseData.getRespondent1OrganisationPolicy() == null - && caseData.getRespondent1Represented() == YES) { - defendantNames.add(caseData.getRespondent1().getPartyName()); - } - if (caseData.getRespondent2OrgRegistered() != YES - && caseData.getRespondent2Represented() == YES - && caseData.getRespondent2OrganisationPolicy() == null - && caseData.getRespondent2() != null) { - defendantNames.add(caseData.getRespondent2().getPartyName()); - } - break; - //this should be removed during removal of notice of change flag - case UNREGISTERED_NOTICE_OF_CHANGE: if (caseData.getRespondent1OrgRegistered() != YES && caseData.getRespondent1OrganisationPolicy() != null && caseData.getRespondent1OrganisationPolicy().getOrganisation() == null diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandler.java index 5b8cb3ec373..7b4c098951c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandler.java @@ -80,7 +80,7 @@ private CallbackResponse generateClaimForm(CallbackParams callbackParams) { ); assignCategoryId.assignCategoryIdToCaseDocument(sealedClaim, "detailsOfClaim"); - if (featureToggleService.isNoticeOfChangeEnabled() && stitchEnabled + if (stitchEnabled && (YesOrNo.NO.equals(caseData.getRespondent1Represented()) || YesOrNo.NO.equals(caseData.getRespondent2Represented()))) { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecCallbackHandler.java index ad19e6b8e9f..f5566efef7e 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecCallbackHandler.java @@ -154,7 +154,7 @@ private List fetchDocumentsFromCaseData(CaseData caseData, Cas LocalDate.now().toString())); //LiP Claim form guidance needs be sent as the 2nd doc to go on the back of the claim form - if (toggleService.isNoticeOfChangeEnabled() && stitchEnabled) { + if (stitchEnabled) { if (YesOrNo.NO.equals(caseData.getSpecRespondent1Represented()) || YesOrNo.NO.equals(caseData.getSpecRespondent2Represented())) { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandler.java index 238cb42db57..342a4b278bc 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandler.java @@ -54,10 +54,7 @@ public List handledEvents() { private CallbackResponse notifyApplicantSolicitorForClaimContinuingOnline(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - boolean isCosEnabled = featureToggleService.isCertificateOfServiceEnabled(); - String emailTemplateID = isCosEnabled != true - ? notificationsProperties.getClaimantSolicitorClaimContinuingOnline() - : notificationsProperties.getClaimantSolicitorClaimContinuingOnlineCos(); + String emailTemplateID = notificationsProperties.getClaimantSolicitorClaimContinuingOnlineCos(); notificationService.sendMail( caseData.getApplicantSolicitor1UserDetails().getEmail(), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java index 9b273d650af..5e9b9441fa4 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandler.java @@ -482,10 +482,8 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { handleCourtLocationData(caseData, dataBuilder, callbackParams); - if (toggleService.isNoticeOfChangeEnabled()) { - // LiP are not represented or registered - OrgPolicyUtils.addMissingOrgPolicies(dataBuilder); - } + // LiP are not represented or registered + OrgPolicyUtils.addMissingOrgPolicies(dataBuilder); // temporarily default to yes for CIV-2659 if (YES.equals(caseData.getRespondent1Represented()) && caseData.getRespondent1OrgRegistered() == null) { @@ -510,20 +508,17 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { log.info("Case management equals: " + caseData.getCaseManagementCategory()); log.info("CaseName equals: " + caseData.getCaseNameHmctsInternal()); - //Adding variables for feature Certificate of Service - if (toggleService.isCertificateOfServiceEnabled()) { - if (caseData.getRespondent1Represented().equals(NO)) { - dataBuilder.defendant1LIPAtClaimIssued(YES); - } else { - dataBuilder.defendant1LIPAtClaimIssued(NO); - } + if (caseData.getRespondent1Represented().equals(NO)) { + dataBuilder.defendant1LIPAtClaimIssued(YES); + } else { + dataBuilder.defendant1LIPAtClaimIssued(NO); + } - if (YES.equals(caseData.getAddRespondent2())) { - if (caseData.getRespondent2Represented() == NO) { - dataBuilder.defendant2LIPAtClaimIssued(YES); - } else { - dataBuilder.defendant2LIPAtClaimIssued(NO); - } + if (YES.equals(caseData.getAddRespondent2())) { + if (caseData.getRespondent2Represented() == NO) { + dataBuilder.defendant2LIPAtClaimIssued(YES); + } else { + dataBuilder.defendant2LIPAtClaimIssued(NO); } } //assign category ids to documents uploaded as part of particulars of claim @@ -606,18 +601,11 @@ private boolean isSecondRespondentLitigantInPerson(CaseData caseData) { private String getBody(CaseData caseData) { return areRespondentsRepresentedAndRegistered(caseData) ? getConfirmationSummary(caseData) - : toggleService.isCertificateOfServiceEnabled() - ? format(CONFIRMATION_BODY_LIP_COS, + : format(CONFIRMATION_BODY_LIP_COS, format("/cases/case-details/%s#Service%%20Request", caseData.getCcdCaseReference()), format(caseDocLocation, caseData.getCcdCaseReference()), claimUrlsConfiguration.getResponsePackLink()) - + exitSurveyContentService.applicantSurvey() - : format(CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", caseData.getCcdCaseReference()), - format(caseDocLocation, caseData.getCcdCaseReference()), - claimUrlsConfiguration.getResponsePackLink()) - + exitSurveyContentService.applicantSurvey(); - + + exitSurveyContentService.applicantSurvey(); } private String getConfirmationSummary(CaseData caseData) { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java index 5ecd44f42bb..7b1929169e4 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java @@ -472,9 +472,7 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { log.info("Case management equals: " + caseData.getCaseManagementCategory()); log.info("CaseName equals: " + caseData.getCaseNameHmctsInternal()); - if (featureToggleService.isNoticeOfChangeEnabled()) { - OrgPolicyUtils.addMissingOrgPolicies(dataBuilder); - } + OrgPolicyUtils.addMissingOrgPolicies(dataBuilder); caseFlagInitialiser.initialiseCaseFlags(CREATE_CLAIM_SPEC, dataBuilder); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandler.java index 8ac6181347f..29bb2f10da9 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandler.java @@ -103,11 +103,6 @@ public List handledEvents() { private CallbackResponse prepareDefendantSolicitorOptions(CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - if (!featureToggleService.isCertificateOfServiceEnabled() && areAnyRespondentsLitigantInPerson(caseData)) { - return AboutToStartOrSubmitCallbackResponse.builder() - .errors(List.of(ERROR_PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT)) - .build(); - } List dynamicListOptions = new ArrayList<>(); dynamicListOptions.add("Both"); dynamicListOptions.add("Defendant One: " + caseData.getRespondent1().getPartyName()); @@ -190,7 +185,7 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { // workaround for hiding cases in CAA list before case notify setOrganisationPolicy(caseData, caseDataBuilder); LocalDateTime claimDetailsNotificationDeadline; - if (featureToggleService.isCertificateOfServiceEnabled() && areAnyRespondentsLitigantInPerson(caseData)) { + if (areAnyRespondentsLitigantInPerson(caseData)) { claimDetailsNotificationDeadline = getDeadline(getServiceDate(caseData)); if (Objects.nonNull(caseData.getCosNotifyClaimDefendant1())) { caseDataBuilder @@ -254,7 +249,7 @@ private SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParam String header = ""; String body = ""; - if (featureToggleService.isCertificateOfServiceEnabled() && isConfirmationForLip(caseData)) { + if (isConfirmationForLip(caseData)) { String formattedDeadline = formatLocalDate(caseData.getClaimDetailsNotificationDeadline().toLocalDate(), DATE); header = String.format(CONFIRMATION_COS_HEADER, caseData.getLegacyCaseReference()); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandler.java index 9dd8d9fe63b..c407f75720a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandler.java @@ -124,13 +124,11 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { LocalDate notificationDate = notificationDateTime.toLocalDate(); MultiPartyScenario multiPartyScenario = getMultiPartyScenario(caseData); - if (featureToggleService.isCertificateOfServiceEnabled()) { - caseData = saveCoSDetailsDoc(caseData, 1); - caseData = saveCoSDetailsDoc(caseData, 2); + caseData = saveCoSDetailsDoc(caseData, 1); + caseData = saveCoSDetailsDoc(caseData, 2); - if (multiPartyScenario == ONE_V_TWO_TWO_LEGAL_REP && isConfirmationForLip(caseData)) { - multiPartyScenario = null; - } + if (multiPartyScenario == ONE_V_TWO_TWO_LEGAL_REP && isConfirmationForLip(caseData)) { + multiPartyScenario = null; } CaseData updatedCaseData; @@ -171,7 +169,7 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { builder.respondent2ResponseDeadline( deadlinesCalculator.plus14DaysAt4pmDeadline(notificationDateTime)); } - if (featureToggleService.isCertificateOfServiceEnabled() && areAnyRespondentsLitigantInPerson(caseData)) { + if (areAnyRespondentsLitigantInPerson(caseData)) { if (Objects.nonNull(caseData.getCosNotifyClaimDetails1())) { builder .cosNotifyClaimDetails1(updateStatementOfTruthForLip(caseData.getCosNotifyClaimDetails1())) @@ -196,22 +194,20 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { private LocalDateTime getEarliestDateOfService(CaseData caseData) { LocalDateTime date = time.now(); - if (featureToggleService.isCertificateOfServiceEnabled()) { - if (Objects.nonNull(caseData.getCosNotifyClaimDetails1()) - && Objects.nonNull(caseData.getCosNotifyClaimDetails1().getCosDateOfServiceForDefendant())) { - LocalDateTime cosDate1 = caseData.getCosNotifyClaimDetails1() - .getCosDateOfServiceForDefendant().atTime(time.now().toLocalTime()); - if (cosDate1.isBefore(date)) { - date = cosDate1; - } + if (Objects.nonNull(caseData.getCosNotifyClaimDetails1()) + && Objects.nonNull(caseData.getCosNotifyClaimDetails1().getCosDateOfServiceForDefendant())) { + LocalDateTime cosDate1 = caseData.getCosNotifyClaimDetails1() + .getCosDateOfServiceForDefendant().atTime(time.now().toLocalTime()); + if (cosDate1.isBefore(date)) { + date = cosDate1; } - if (Objects.nonNull(caseData.getCosNotifyClaimDetails2()) - && Objects.nonNull(caseData.getCosNotifyClaimDetails2().getCosDateOfServiceForDefendant())) { - LocalDateTime cosDate2 = caseData.getCosNotifyClaimDetails2() - .getCosDateOfServiceForDefendant().atTime(time.now().toLocalTime()); - if (cosDate2.isBefore(date)) { - date = cosDate2; - } + } + if (Objects.nonNull(caseData.getCosNotifyClaimDetails2()) + && Objects.nonNull(caseData.getCosNotifyClaimDetails2().getCosDateOfServiceForDefendant())) { + LocalDateTime cosDate2 = caseData.getCosNotifyClaimDetails2() + .getCosDateOfServiceForDefendant().atTime(time.now().toLocalTime()); + if (cosDate2.isBefore(date)) { + date = cosDate2; } } return date; @@ -273,23 +269,15 @@ private String getConfirmationBody(CaseData caseData) { || caseData.getDefendantSolicitorNotifyClaimDetailsOptions() == null ? CONFIRMATION_SUMMARY : NOTIFICATION_ONE_PARTY_SUMMARY; - if (featureToggleService.isCertificateOfServiceEnabled()) { - return isConfirmationForLip(caseData) - ? CONFIRMATION_COS_SUMMARY - : confirmationTextLR; - } else { - return confirmationTextLR; - } + return isConfirmationForLip(caseData) + ? CONFIRMATION_COS_SUMMARY + : confirmationTextLR; } private String getConfirmationHeader(CaseData caseData) { - if (featureToggleService.isCertificateOfServiceEnabled()) { - return isConfirmationForLip(caseData) - ? CONFIRMATION_COS_HEADER - : CONFIRMATION_HEADER; - } else { - return CONFIRMATION_HEADER; - } + return isConfirmationForLip(caseData) + ? CONFIRMATION_COS_HEADER + : CONFIRMATION_HEADER; } private boolean isConfirmationForLip(CaseData caseData) { @@ -362,23 +350,21 @@ private CallbackResponse validateCoSDetailsDefendant1(final CallbackParams callb CaseData caseData = callbackParams.getCaseData(); ArrayList errors = new ArrayList<>(); - CertificateOfService certificateOfService = caseData.getCosNotifyClaimDetails1(); - if (featureToggleService.isCertificateOfServiceEnabled()) { - if (Objects.nonNull(caseData.getCosNotifyClaimDetails1())) { - caseData.getCosNotifyClaimDetails1().setCosDocSaved(NO); - } + if (Objects.nonNull(caseData.getCosNotifyClaimDetails1())) { + caseData.getCosNotifyClaimDetails1().setCosDocSaved(NO); + } - final String dateValidationErrorMessage = getServiceOfDateValidationMessage( - caseData.getCosNotifyClaimDetails1()); + final String dateValidationErrorMessage = getServiceOfDateValidationMessage( + caseData.getCosNotifyClaimDetails1()); - if (!dateValidationErrorMessage.isEmpty()) { - errors.add(dateValidationErrorMessage); - } - if (Objects.nonNull(caseData.getCosNotifyClaimDetails1()) - && isMandatoryDocMissing(caseData.getCosNotifyClaimDetails1())) { - errors.add(DOC_SERVED_MANDATORY); - } + if (!dateValidationErrorMessage.isEmpty()) { + errors.add(dateValidationErrorMessage); + } + if (Objects.nonNull(caseData.getCosNotifyClaimDetails1()) + && isMandatoryDocMissing(caseData.getCosNotifyClaimDetails1())) { + errors.add(DOC_SERVED_MANDATORY); } + CertificateOfService certificateOfService = caseData.getCosNotifyClaimDetails1(); CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); caseDataBuilder.cosNotifyClaimDetails1(certificateOfService.toBuilder() .build()); @@ -391,28 +377,26 @@ && isMandatoryDocMissing(caseData.getCosNotifyClaimDetails1())) { private CallbackResponse validateCoSDetailsDefendant2(final CallbackParams callbackParams) { CaseData caseData = callbackParams.getCaseData(); - CertificateOfService certificateOfServiceDef2 = caseData.getCosNotifyClaimDetails2(); ArrayList errors = new ArrayList<>(); - if (featureToggleService.isCertificateOfServiceEnabled()) { - if (Objects.nonNull(caseData.getCosNotifyClaimDetails2())) { - caseData.getCosNotifyClaimDetails2().setCosDocSaved(NO); - } - final String dateValidationErrorMessage = getServiceOfDateValidationMessage( - caseData.getCosNotifyClaimDetails2()); + if (Objects.nonNull(caseData.getCosNotifyClaimDetails2())) { + caseData.getCosNotifyClaimDetails2().setCosDocSaved(NO); + } + final String dateValidationErrorMessage = getServiceOfDateValidationMessage( + caseData.getCosNotifyClaimDetails2()); - if (!dateValidationErrorMessage.isEmpty()) { - errors.add(dateValidationErrorMessage); - } + if (!dateValidationErrorMessage.isEmpty()) { + errors.add(dateValidationErrorMessage); + } - if (isBothDefendantLip(caseData) && !isBothDefendantWithSameDateOfService(caseData)) { - errors.add(BOTH_CERTIFICATE_SERVED_SAME_DATE); - } + if (isBothDefendantLip(caseData) && !isBothDefendantWithSameDateOfService(caseData)) { + errors.add(BOTH_CERTIFICATE_SERVED_SAME_DATE); + } - if (Objects.nonNull(caseData.getCosNotifyClaimDetails2()) - && isMandatoryDocMissing(caseData.getCosNotifyClaimDetails2())) { - errors.add(DOC_SERVED_MANDATORY); - } + if (Objects.nonNull(caseData.getCosNotifyClaimDetails2()) + && isMandatoryDocMissing(caseData.getCosNotifyClaimDetails2())) { + errors.add(DOC_SERVED_MANDATORY); } + CertificateOfService certificateOfServiceDef2 = caseData.getCosNotifyClaimDetails2(); CaseData.CaseDataBuilder caseDataBuilder = caseData.toBuilder(); caseDataBuilder.cosNotifyClaimDetails2(certificateOfServiceDef2.toBuilder() .build()); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandler.java index 00377207bab..d10600c3301 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandler.java @@ -35,7 +35,6 @@ import static uk.gov.hmcts.reform.civil.enums.ReasonForProceedingOnPaper.JUDGEMENT_REQUEST; import static uk.gov.hmcts.reform.civil.enums.ReasonForProceedingOnPaper.OTHER; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREGISTERED; -import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREGISTERED_NOTICE_OF_CHANGE; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREPRESENTED; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.getDefendantNames; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; @@ -181,8 +180,7 @@ private String getDescription(String eventId, Map data, String state, CaseData c case PENDING_CLAIM_ISSUED_UNREGISTERED_DEFENDANT: return format("Unregistered defendant solicitor firm: %s", StringUtils.join( - getDefendantNames(featureToggleService.isNoticeOfChangeEnabled() - ? UNREGISTERED_NOTICE_OF_CHANGE : UNREGISTERED, + getDefendantNames(UNREGISTERED, caseData), " and " )); case PENDING_CLAIM_ISSUED_UNREPRESENTED_UNREGISTERED_DEFENDANT: @@ -191,8 +189,7 @@ private String getDescription(String eventId, Map data, String state, CaseData c + "Unregistered defendant solicitor firm: %s.", StringUtils.join(getDefendantNames(UNREPRESENTED, caseData), " and "), StringUtils.join( - getDefendantNames(featureToggleService.isNoticeOfChangeEnabled() - ? UNREGISTERED_NOTICE_OF_CHANGE : UNREGISTERED, + getDefendantNames(UNREGISTERED, caseData), " and " )); case FULL_DEFENCE_PROCEED: diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/FeatureToggleService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/FeatureToggleService.java index 8b11403a6fc..1480a91bb46 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/FeatureToggleService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/FeatureToggleService.java @@ -24,10 +24,6 @@ public boolean isBulkClaimEnabled() { return this.featureToggleApi.isFeatureEnabled("bulk_claim_enabled"); } - public boolean isNoticeOfChangeEnabled() { - return this.featureToggleApi.isFeatureEnabled("notice-of-change"); - } - public boolean isCaseFlagsEnabled() { return this.featureToggleApi.isFeatureEnabled("case-flags"); } @@ -40,10 +36,6 @@ public boolean isPbaV3Enabled() { return this.featureToggleApi.isFeatureEnabled("pba-version-3-ways-to-pay"); } - public boolean isCertificateOfServiceEnabled() { - return this.featureToggleApi.isFeatureEnabled("isCertificateOfServiceEnabled"); - } - public boolean isRPAEmailEnabled() { return this.featureToggleApi.isFeatureEnabled("enable-rpa-emails"); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowFlag.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowFlag.java index 210de4df026..58964b34eed 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowFlag.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowFlag.java @@ -6,14 +6,12 @@ public enum FlowFlag { UNREPRESENTED_DEFENDANT_ONE, UNREPRESENTED_DEFENDANT_TWO, PIP_ENABLED, - NOTICE_OF_CHANGE, AGREED_TO_MEDIATION, IS_MULTI_TRACK, SDO_ENABLED, CONTACT_DETAILS_CHANGE, GENERAL_APPLICATION_ENABLED, BULK_CLAIM_ENABLED, - CERTIFICATE_OF_SERVICE, RESPONDENT_RESPONSE_LANGUAGE_IS_BILINGUAL, LR_V_LIP_ENABLED, LIP_CASE; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicate.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicate.java index f0bfc9f7825..c8c2b45c00e 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicate.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicate.java @@ -71,6 +71,12 @@ private FlowPredicate() { && ((caseData.getRespondent1OrgRegistered() == YES && caseData.getRespondent2OrgRegistered() == NO) || (caseData.getRespondent2OrgRegistered() == YES && caseData.getRespondent1OrgRegistered() == NO)); + public static final Predicate claimSubmitted1v1RespondentOneUnregistered = caseData -> + caseData.getSubmittedDate() != null + && caseData.getAddRespondent2() == NO + && caseData.getRespondent1Represented() == YES + && caseData.getRespondent1OrgRegistered() == NO; + // have to use this for now because cannot use featureToggleService.isNoticeOfChangeEnabled() as predicate public static final Predicate noticeOfChangeEnabled = caseData -> (caseData.getDefendant1LIPAtClaimIssued() != null diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java index 39f82bb7088..2ddc4c56dd5 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java @@ -46,13 +46,12 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimDismissedByCamunda; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimIssued; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimNotified; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedBothRespondentUnrepresented; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedBothUnregisteredSolicitors; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedOneRespondentRepresentative; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedOneUnrepresentedDefendantOnly; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedOnlyOneRespondentRepresented; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedRespondent1Unrepresented; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedRespondent2Unrepresented; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmitted1v1RespondentOneUnregistered; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedTwoRegisteredRespondentRepresentatives; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedTwoRespondentRepresentativesOneUnregistered; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.contactDetailsChange; @@ -75,7 +74,6 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.isPayImmediately; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.isRespondentResponseLangIsBilingual; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.multipartyCase; -import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.noticeOfChangeEnabled; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.notificationAcknowledged; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.oneVsOneCase; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.partAdmission; @@ -190,98 +188,68 @@ public StateFlow build(FlowState.Main initialState) { return StateFlowBuilder.flow(FLOW_NAME) .initial(initialState) .transitionTo(CLAIM_SUBMITTED) - .onlyIf(claimSubmittedOneRespondentRepresentative) + .onlyIf(claimSubmittedOneRespondentRepresentative.or(claimSubmitted1v1RespondentOneUnregistered)) .set(flags -> flags.putAll( // Do not set UNREPRESENTED_DEFENDANT_ONE or UNREPRESENTED_DEFENDANT_TWO to false here unless // camunda diagram for TAKE_CASE_OFFLINE is changed Map.of( FlowFlag.ONE_RESPONDENT_REPRESENTATIVE.name(), true, - FlowFlag.NOTICE_OF_CHANGE.name(), featureToggleService.isNoticeOfChangeEnabled(), - FlowFlag.CERTIFICATE_OF_SERVICE.name(), featureToggleService.isCertificateOfServiceEnabled(), GENERAL_APPLICATION_ENABLED.name(), featureToggleService.isGeneralApplicationsEnabled(), BULK_CLAIM_ENABLED.name(), featureToggleService.isBulkClaimEnabled() ))) .transitionTo(CLAIM_SUBMITTED) .onlyIf(claimSubmittedTwoRegisteredRespondentRepresentatives - .or(claimSubmittedTwoRespondentRepresentativesOneUnregistered)) + .or(claimSubmittedTwoRespondentRepresentativesOneUnregistered) + .or(claimSubmittedBothUnregisteredSolicitors)) .set(flags -> flags.putAll( // Do not set UNREPRESENTED_DEFENDANT_ONE or UNREPRESENTED_DEFENDANT_TWO to false here unless // camunda diagram for TAKE_CASE_OFFLINE is changed Map.of( FlowFlag.ONE_RESPONDENT_REPRESENTATIVE.name(), false, FlowFlag.TWO_RESPONDENT_REPRESENTATIVES.name(), true, - FlowFlag.NOTICE_OF_CHANGE.name(), featureToggleService.isNoticeOfChangeEnabled(), - FlowFlag.CERTIFICATE_OF_SERVICE.name(), featureToggleService.isCertificateOfServiceEnabled(), - GENERAL_APPLICATION_ENABLED.name(), featureToggleService.isGeneralApplicationsEnabled(), - BULK_CLAIM_ENABLED.name(), featureToggleService.isBulkClaimEnabled() - ))) - // To be removed when NOC is released. Needed for cases with unregistered and unrepresented defendants - .transitionTo(CLAIM_SUBMITTED) - .onlyIf(noticeOfChangeEnabled.negate() - .and((claimSubmittedBothRespondentUnrepresented - .or(claimSubmittedOnlyOneRespondentRepresented) - .or(claimSubmittedBothUnregisteredSolicitors) - // this line MUST be removed when NOC toggle(noticeOfChangeEnabledAndLiP) is removed - .or(claimSubmittedOneUnrepresentedDefendantOnly)))) - .set(flags -> flags.putAll( - // Do not set UNREPRESENTED_DEFENDANT_ONE or UNREPRESENTED_DEFENDANT_TWO to false here unless - // camunda diagram for TAKE_CASE_OFFLINE is changed - Map.of( - FlowFlag.NOTICE_OF_CHANGE.name(), featureToggleService.isNoticeOfChangeEnabled(), - FlowFlag.CERTIFICATE_OF_SERVICE.name(), featureToggleService.isCertificateOfServiceEnabled(), GENERAL_APPLICATION_ENABLED.name(), featureToggleService.isGeneralApplicationsEnabled(), BULK_CLAIM_ENABLED.name(), featureToggleService.isBulkClaimEnabled() ))) // Only one unrepresented defendant .transitionTo(CLAIM_SUBMITTED) - .onlyIf(noticeOfChangeEnabled.and(claimSubmittedOneUnrepresentedDefendantOnly)) + .onlyIf(claimSubmittedOneUnrepresentedDefendantOnly) .set(flags -> flags.putAll( Map.of( FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true, - FlowFlag.NOTICE_OF_CHANGE.name(), featureToggleService.isNoticeOfChangeEnabled(), - FlowFlag.CERTIFICATE_OF_SERVICE.name(), featureToggleService.isCertificateOfServiceEnabled(), GENERAL_APPLICATION_ENABLED.name(), featureToggleService.isGeneralApplicationsEnabled(), BULK_CLAIM_ENABLED.name(), featureToggleService.isBulkClaimEnabled() ))) // Unrepresented defendant 1 .transitionTo(CLAIM_SUBMITTED) - .onlyIf(noticeOfChangeEnabled - .and(claimSubmittedRespondent1Unrepresented) + .onlyIf(claimSubmittedRespondent1Unrepresented .and(claimSubmittedOneUnrepresentedDefendantOnly.negate()) .and(claimSubmittedRespondent2Unrepresented.negate())) .set(flags -> flags.putAll( Map.of( FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true, FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), false, - FlowFlag.NOTICE_OF_CHANGE.name(), featureToggleService.isNoticeOfChangeEnabled(), - FlowFlag.CERTIFICATE_OF_SERVICE.name(), featureToggleService.isCertificateOfServiceEnabled(), GENERAL_APPLICATION_ENABLED.name(), featureToggleService.isGeneralApplicationsEnabled(), BULK_CLAIM_ENABLED.name(), featureToggleService.isBulkClaimEnabled() ))) // Unrepresented defendant 2 .transitionTo(CLAIM_SUBMITTED) - .onlyIf(noticeOfChangeEnabled - .and(claimSubmittedRespondent2Unrepresented - .and(claimSubmittedRespondent1Unrepresented.negate()))) + .onlyIf(claimSubmittedRespondent2Unrepresented + .and(claimSubmittedRespondent1Unrepresented.negate())) .set(flags -> flags.putAll( Map.of( FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), false, FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), true, - FlowFlag.NOTICE_OF_CHANGE.name(), featureToggleService.isNoticeOfChangeEnabled(), - FlowFlag.CERTIFICATE_OF_SERVICE.name(), featureToggleService.isCertificateOfServiceEnabled(), GENERAL_APPLICATION_ENABLED.name(), featureToggleService.isGeneralApplicationsEnabled(), BULK_CLAIM_ENABLED.name(), featureToggleService.isBulkClaimEnabled() ))) // Unrepresented defendants .transitionTo(CLAIM_SUBMITTED) - .onlyIf(noticeOfChangeEnabled.and(claimSubmittedRespondent1Unrepresented.and( - claimSubmittedRespondent2Unrepresented))) + .onlyIf(claimSubmittedRespondent1Unrepresented.and( + claimSubmittedRespondent2Unrepresented)) .set(flags -> flags.putAll( Map.of( FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true, FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), true, - FlowFlag.NOTICE_OF_CHANGE.name(), featureToggleService.isNoticeOfChangeEnabled(), - FlowFlag.CERTIFICATE_OF_SERVICE.name(), featureToggleService.isCertificateOfServiceEnabled(), GENERAL_APPLICATION_ENABLED.name(), featureToggleService.isGeneralApplicationsEnabled(), BULK_CLAIM_ENABLED.name(), featureToggleService.isBulkClaimEnabled() ))) @@ -355,7 +323,7 @@ public StateFlow build(FlowState.Main initialState) { .and(not(specClaim)) .and(certificateOfServiceEnabled)) .transitionTo(TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT).onlyIf(takenOfflineBySystem - .and(noticeOfChangeEnabled.negate())) + .and(specClaim)) .state(PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT_ONE_V_ONE_SPEC) .transitionTo(CLAIM_ISSUED) .onlyIf(claimIssued.and(pinInPostEnabledAndLiP)) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java index 75ecdc725a7..6c9d71c1bcf 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapper.java @@ -68,7 +68,6 @@ import static uk.gov.hmcts.reform.civil.enums.PartyRole.RESPONDENT_ONE; import static uk.gov.hmcts.reform.civil.enums.RespondentResponseType.FULL_DEFENCE; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREGISTERED; -import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREGISTERED_NOTICE_OF_CHANGE; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREPRESENTED; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.getDefendantNames; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; @@ -1636,12 +1635,7 @@ private void buildOfflineAfterClaimsDetailsNotified(EventHistory.EventHistoryBui private void buildUnregisteredDefendant(EventHistory.EventHistoryBuilder builder, CaseData caseData) { List unregisteredDefendantsNames; - // NOC: Revert after NOC is live - if (featureToggleService.isNoticeOfChangeEnabled()) { - unregisteredDefendantsNames = getDefendantNames(UNREGISTERED_NOTICE_OF_CHANGE, caseData); - } else { - unregisteredDefendantsNames = getDefendantNames(UNREGISTERED, caseData); - } + unregisteredDefendantsNames = getDefendantNames(UNREGISTERED, caseData); List events = IntStream.range(0, unregisteredDefendantsNames.size()) .mapToObj(index -> { @@ -1675,13 +1669,7 @@ private void buildUnregisteredAndUnrepresentedDefendant(EventHistory.EventHistor CaseData caseData) { String localDateTime = time.now().toLocalDate().toString(); - // NOC: Revert after NOC is live - List unregisteredDefendantsNames; - if (featureToggleService.isNoticeOfChangeEnabled()) { - unregisteredDefendantsNames = getDefendantNames(UNREGISTERED_NOTICE_OF_CHANGE, caseData); - } else { - unregisteredDefendantsNames = getDefendantNames(UNREGISTERED, caseData); - } + List unregisteredDefendantsNames = getDefendantNames(UNREGISTERED, caseData); String unrepresentedEventText = format( "RPA Reason: [1 of 2 - %s] Unrepresented defendant and unregistered " diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapper.java b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapper.java index 40e0726dfc4..c98b7054f5c 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapper.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapper.java @@ -71,9 +71,8 @@ public RoboticsCaseData toRoboticsCaseData(CaseData caseData, String authToken) .claimDetails(buildClaimDetails(caseData)) .events(eventHistoryMapper.buildEvents(caseData)); - if (featureToggleService.isNoticeOfChangeEnabled() - && (caseData.getCcdState() == PROCEEDS_IN_HERITAGE_SYSTEM - || caseData.getCcdState() == CASE_DISMISSED)) { + if (caseData.getCcdState() == PROCEEDS_IN_HERITAGE_SYSTEM + || caseData.getCcdState() == CASE_DISMISSED) { roboticsBuilder.noticeOfChange(RoboticsDataUtil.buildNoticeOfChange(caseData)); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpec.java b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpec.java index f3354fc706a..c6fcdf4f165 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpec.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpec.java @@ -69,9 +69,8 @@ public RoboticsCaseDataSpec toRoboticsCaseData(CaseData caseData) { .claimDetails(buildClaimDetails(caseData)) .events(eventHistoryMapper.buildEvents(caseData)); - if (featureToggleService.isNoticeOfChangeEnabled() - && (caseData.getCcdState() == PROCEEDS_IN_HERITAGE_SYSTEM - || caseData.getCcdState() == CASE_DISMISSED)) { + if (caseData.getCcdState() == PROCEEDS_IN_HERITAGE_SYSTEM + || caseData.getCcdState() == CASE_DISMISSED) { builder.noticeOfChange(RoboticsDataUtil.buildNoticeOfChange(caseData)); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenarioTest.java b/src/test/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenarioTest.java index d15008b02c4..8f4fd7698e1 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenarioTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/enums/UnrepresentedOrUnregisteredScenarioTest.java @@ -9,7 +9,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREGISTERED; -import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREGISTERED_NOTICE_OF_CHANGE; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.UNREPRESENTED; import static uk.gov.hmcts.reform.civil.enums.UnrepresentedOrUnregisteredScenario.getDefendantNames; @@ -84,7 +83,7 @@ void shouldReturnUnregisteredDefendantNames_WhenBothDefendantsUnregisteredScenar // To be changed to UNREGISTERED when NOC is merged // assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - assertThat(getDefendantNames(UNREGISTERED_NOTICE_OF_CHANGE, caseData)).isEqualTo( + assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( List.of( caseData.getRespondent1().getPartyName(), caseData.getRespondent2().getPartyName() @@ -98,7 +97,7 @@ void shouldReturnUnregisteredDefendantNames_WhenUnregisteredDefendant1Scenario() // To be changed to UNREGISTERED when NOC is merged // assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - assertThat(getDefendantNames(UNREGISTERED_NOTICE_OF_CHANGE, caseData)).isEqualTo( + assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( List.of( caseData.getRespondent1().getPartyName() ) @@ -111,7 +110,7 @@ void shouldReturnUnregisteredDefendantNames_WhenUnregisteredDefendant2Scenario() // To be changed to UNREGISTERED when NOC is merged // assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - assertThat(getDefendantNames(UNREGISTERED_NOTICE_OF_CHANGE, caseData)).isEqualTo( + assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( List.of( caseData.getRespondent2().getPartyName() ) @@ -125,7 +124,7 @@ void shouldReturnUnregisteredDefendantNames_WhenUnrepresentedDefendant1Unregiste // To be changed to UNREGISTERED when NOC is merged // assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - assertThat(getDefendantNames(UNREGISTERED_NOTICE_OF_CHANGE, caseData)).isEqualTo( + assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( List.of( caseData.getRespondent2().getPartyName() ) @@ -139,85 +138,6 @@ void shouldReturnUnregisteredDefendantNames_WhenUnregisteredDefendant1Unrepresen // To be changed to UNREGISTERED when NOC is merged // assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - assertThat(getDefendantNames(UNREGISTERED_NOTICE_OF_CHANGE, caseData)).isEqualTo( - List.of( - caseData.getRespondent1().getPartyName() - ) - ); - } - } - - @Nested - class ToBeRemovedAfterNocUnregistered { - @Test - void shouldReturnUnregisteredDefendantNames_WhenBothDefendantsUnregisteredScenario() { - CaseData caseData = CaseDataBuilder.builder() - .atStateProceedsOfflineUnregisteredDefendants() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - - assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - List.of( - caseData.getRespondent1().getPartyName(), - caseData.getRespondent2().getPartyName() - ) - ); - } - - @Test - void shouldReturnUnregisteredDefendantNames_WhenUnregisteredDefendant1Scenario() { - CaseData caseData = CaseDataBuilder.builder() - .atStateProceedsOfflineUnregisteredDefendant1() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - - assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - List.of( - caseData.getRespondent1().getPartyName() - ) - ); - } - - @Test - void shouldReturnUnregisteredDefendantNames_WhenUnregisteredDefendant2Scenario() { - CaseData caseData = CaseDataBuilder.builder() - .atStateProceedsOfflineUnregisteredDefendant2() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - - assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - List.of( - caseData.getRespondent2().getPartyName() - ) - ); - } - - @Test - void shouldReturnUnregisteredDefendantNames_WhenUnrepresentedDefendant1UnregisteredDefendant2Scenario() { - CaseData caseData = CaseDataBuilder.builder() - .atStateProceedsOfflineUnrepresentedDefendant1UnregisteredDefendant2() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - - assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( - List.of( - caseData.getRespondent2().getPartyName() - ) - ); - } - - @Test - void shouldReturnUnregisteredDefendantNames_WhenUnregisteredDefendant1UnrepresentedDefendant2Scenario() { - CaseData caseData = CaseDataBuilder.builder() - .atStateProceedsOfflineUnregisteredDefendant1UnrepresentedDefendant2() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - assertThat(getDefendantNames(UNREGISTERED, caseData)).isEqualTo( List.of( caseData.getRespondent1().getPartyName() @@ -225,5 +145,4 @@ void shouldReturnUnregisteredDefendantNames_WhenUnregisteredDefendant1Unrepresen ); } } - } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandlerTest.java index 68b11d63c29..6333b075840 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormCallbackHandlerTest.java @@ -136,7 +136,6 @@ class GenerateClaimFormCallbackHandlerTest extends BaseCallbackHandlerTest { @BeforeEach void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); when(sealedClaimFormGenerator.generate(any(CaseData.class), anyString())).thenReturn(CLAIM_FORM); when(litigantInPersonFormGenerator.generate(any(CaseData.class), anyString())).thenReturn(LIP_FORM); when(civilDocumentStitchingService.bundle(ArgumentMatchers.anyList(), anyString(), anyString(), anyString(), @@ -329,39 +328,4 @@ void testSingleSealedClaimGeneratedWhenStitchingDisabled() { } } - - @Nested - @ExtendWith(SpringExtension.class) - @SpringBootTest(classes = { - GenerateClaimFormCallbackHandler.class, - JacksonAutoConfiguration.class, - CaseDetailsConverter.class, - AssignCategoryId.class - }) - class GenerateSealedClaimNoNoC { - - @Autowired - private GenerateClaimFormCallbackHandler handler; - @Autowired - private AssignCategoryId assignCategoryId; - - @BeforeEach - void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(false); - when(sealedClaimFormGenerator.generate(any(CaseData.class), anyString())).thenReturn(CLAIM_FORM); - when(time.now()).thenReturn(issueDate.atStartOfDay()); - } - - @Test - void testSingleSealedClaimGeneratedWhenNoCDisabled() { - CaseData caseData = CaseDataBuilder.builder().atStatePendingClaimIssuedUnrepresentedDefendant().build(); - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); - - assertThat(updatedData.getSystemGeneratedCaseDocuments().get(0).getValue()).isEqualTo(CLAIM_FORM); - verify(sealedClaimFormGenerator).generate(any(CaseData.class), eq(BEARER_TOKEN)); - } - } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecHandlerTest.java index 36217026471..4946909fab0 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/docmosis/GenerateClaimFormForSpecHandlerTest.java @@ -229,23 +229,6 @@ void shouldGenerateClaimFormWithClaimTimeLineDocs_whenUploadedByRespondent() { verify(civilDocumentStitchingService).bundle(eq(specClaimTimelineDocuments), anyString(), anyString(), anyString(), eq(caseData)); } - - @Test - void shouldNotStitchClaimFormWithLipForm_whenOneVsOne_withLitigantInPersonSpecClaim_whenToggleIsOff() { - when(toggleService.isNoticeOfChangeEnabled()).thenReturn(false); - - CaseData caseData = CaseDataBuilder.builder() - .atStatePendingClaimIssuedUnrepresentedDefendant().build().toBuilder() - .specRespondent1Represented(NO) - .build(); - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); - - var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - CaseData updatedData = mapper.convertValue(response.getData(), CaseData.class); - - assertThat(updatedData.getSystemGeneratedCaseDocuments().get(0).getValue()).isEqualTo(CLAIM_FORM); - } - } @Test @@ -358,11 +341,6 @@ void shouldNullDocuments_whenInvokedAndCaseFileEnabled() { @Nested class GenerateAndStitchLitigantInPersonFormSpec { - @BeforeEach - void setup() { - when(toggleService.isNoticeOfChangeEnabled()).thenReturn(true); - } - @Test void shouldStitchClaimFormWithLipForm_whenOneVsOne_withLitigantInPersonSpecClaim() { CaseData caseData = CaseDataBuilder.builder() diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandlerTest.java index 1e92ae2974d..32c12ff81cb 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/notification/ClaimContinuingOnlineApplicantNotificationHandlerTest.java @@ -52,25 +52,9 @@ class AboutToSubmitCallback { @BeforeEach void setup() { - when(notificationsProperties.getClaimantSolicitorClaimContinuingOnline()).thenReturn("template-id"); when(notificationsProperties.getClaimantSolicitorClaimContinuingOnlineCos()).thenReturn("template-id-cos"); } - @Test - void shouldNotifyApplicantSolicitor_whenInvoked() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); - CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); - - handler.handle(params); - - verify(notificationService).sendMail( - "applicantsolicitor@example.com", - "template-id", - getNotificationDataMap(caseData), - "claim-continuing-online-notification-000DC001" - ); - } - @NotNull private Map getNotificationDataMap(CaseData caseData) { return Map.of( @@ -82,11 +66,10 @@ PARTY_REFERENCES, buildClaimantReference(caseData) } @Test - void shouldNotifyApplicantSolicitor_whenCosEnabled() { + void shouldNotifyApplicantSolicitor_whenInvoked() { CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); handler.handle(params); verify(notificationService).sendMail( @@ -96,22 +79,5 @@ void shouldNotifyApplicantSolicitor_whenCosEnabled() { "claim-continuing-online-notification-000DC001" ); } - - @Test - void shouldNotifyApplicantSolicitorWithOldTemplate_whenCosDisabled() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); - CallbackParams params = CallbackParamsBuilder.builder().of(ABOUT_TO_SUBMIT, caseData).build(); - - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - handler.handle(params); - - verify(notificationService).sendMail( - "applicantsolicitor@example.com", - "template-id", - getNotificationDataMap(caseData), - "claim-continuing-online-notification-000DC001" - ); - } - } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandlerTest.java index 71b10419903..9580191589f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimCallbackHandlerTest.java @@ -7,7 +7,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; @@ -91,7 +90,6 @@ import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; import static uk.gov.hmcts.reform.civil.handler.callback.user.CreateClaimCallbackHandler.CONFIRMATION_SUMMARY; -import static uk.gov.hmcts.reform.civil.handler.callback.user.CreateClaimCallbackHandler.CONFIRMATION_BODY_COS; import static uk.gov.hmcts.reform.civil.handler.callback.user.CreateClaimCallbackHandler.CONFIRMATION_BODY_LIP_COS; import static uk.gov.hmcts.reform.civil.model.common.DynamicList.fromList; import static uk.gov.hmcts.reform.civil.utils.ElementUtils.element; @@ -1293,7 +1291,6 @@ void shouldSetCaseCategoryToUnspec_whenInvoked() { class DefendantLipAtClaimIssued { @Test void shouldSetDefend1LipAtClaimIssued_when_defendant1LitigantParty() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); caseData = CaseDataBuilder.builder().atStateClaimSubmitted1v1AndNoRespondentRepresented().build(); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle( callbackParamsOf(caseData, ABOUT_TO_SUBMIT)); @@ -1305,7 +1302,6 @@ void shouldSetDefend1LipAtClaimIssued_when_defendant1LitigantParty() { @Test void shouldSetDefend1LipAtClaimIssued_1v2_defendant2LitigantParty_whenInvoked() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); caseData = CaseDataBuilder.builder() .atStateClaimSubmitted1v2AndOnlyFirstRespondentIsRepresented() .build(); @@ -1321,7 +1317,6 @@ void shouldSetDefend1LipAtClaimIssued_1v2_defendant2LitigantParty_whenInvoked() @Test void shouldSetDefend1LipAtClaimIssued_1v2_defendant1LitigantParty_whenInvoked() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); caseData = CaseDataBuilder.builder() .atStateClaimSubmitted1v2AndOnlySecondRespondentIsRepresented() .build(); @@ -1337,7 +1332,6 @@ void shouldSetDefend1LipAtClaimIssued_1v2_defendant1LitigantParty_whenInvoked() @Test void shouldSetDefendantLIPAtClaim_1v2_BothDefendantLitigantParty_whenInvoked() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); caseData = CaseDataBuilder.builder().atStateClaimSubmittedNoRespondentRepresented().build(); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle( @@ -1630,10 +1624,6 @@ void shouldReturnExpectedErrorMessagesInResponse_whenInvokedWithNullApplicantPre @Nested class PopulateBlankOrgPolicies { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - } @Test void oneVOne() { @@ -1788,33 +1778,10 @@ class SubmittedCallback { @Nested class RespondentsDoNotHaveLegalRepresentation { - @Test - void shouldReturnExpectedSubmittedCallbackResponse_whenRespondentsDoesNotHaveRepresentation() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimIssuedUnrepresentedDefendants().build(); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - - LocalDateTime serviceDeadline = now().plusDays(112).atTime(23, 59); - - String body = format( - CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", CASE_ID), - format("/cases/case-details/%s#CaseDocuments", CASE_ID), - responsePackLink - ) + exitSurveyContentService.applicantSurvey(); - - assertThat(response).usingRecursiveComparison().isEqualTo( - SubmittedCallbackResponse.builder() - .confirmationHeader(format("# Please now pay your claim fee%n# using the link below")) - .confirmationBody(body) - .build()); - } - @Test void certificateOfService_shouldReturnExpectedResponse_whenRespondentsDoesNotHaveRepresentation() { CaseData caseData = CaseDataBuilder.builder().atStateClaimIssuedUnrepresentedDefendants().build(); CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); @@ -1880,7 +1847,6 @@ void shouldReturnExpectedSubmittedCallbackResponse_whenRespondent1HasRepresentat @Test void shouldReturnExpectedSubmittedCallbackResponse_whenRespondent1HasRepresentationAndPBAv3AndCOSIsOn() { - Mockito.when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); CaseData caseData = CaseDataBuilder.builder() .atStateClaimDetailsNotified() .multiPartyClaimOneDefendantSolicitor().build(); @@ -1903,35 +1869,11 @@ void shouldReturnExpectedSubmittedCallbackResponse_whenRespondent1HasRepresentat @Nested class Respondent1DoesNotHaveLegalRepresentation { - @Test - void shouldReturnExpectedSubmittedCallbackResponse_whenRespondentsDoesNotHaveRepresentation() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimIssuedUnrepresentedDefendant1().build(); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - - LocalDateTime serviceDeadline = now().plusDays(112).atTime(23, 59); - - String body = format( - CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", CASE_ID), - format("/cases/case-details/%s#CaseDocuments", CASE_ID), - responsePackLink - ) + exitSurveyContentService.applicantSurvey(); - - assertThat(response).usingRecursiveComparison().isEqualTo( - SubmittedCallbackResponse.builder() - .confirmationHeader(format("# Please now pay your claim fee%n# using the link below")) - .confirmationBody(body) - .build()); - } - @Test void certificateOfService_shouldReturnExpectedResponse_whenRespondentsDoesNotHaveRepresentation() { CaseData caseData = CaseDataBuilder.builder().atStateClaimIssuedUnrepresentedDefendant1().build(); CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); String body = format( @@ -1952,35 +1894,12 @@ void certificateOfService_shouldReturnExpectedResponse_whenRespondentsDoesNotHav @Nested class Respondent1SolicitorOrgNotRegisteredInMyHmcts { - @Test - void shouldReturnExpectedSubmittedCallbackResponse_whenRespondent1SolicitorNotRegisteredInMyHmcts() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() - .respondent1Represented(YES) - .respondent1OrgRegistered(NO) - .build(); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - - assertThat(response).usingRecursiveComparison().isEqualTo( - SubmittedCallbackResponse.builder() - .confirmationHeader(format("# Please now pay your claim fee%n# using the link below")) - .confirmationBody(format( - CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", CASE_ID), - format("/cases/case-details/%s#CaseDocuments", CASE_ID), - responsePackLink - ) + exitSurveyContentService.applicantSurvey()) - .build()); - } - @Test void certificateOfService_shouldReturnExpectedResponse_whenRespondent1SolicitorNotRegisteredInMyHmcts() { CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() .respondent1Represented(YES) .respondent1OrgRegistered(NO) .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); @@ -2000,31 +1919,10 @@ void certificateOfService_shouldReturnExpectedResponse_whenRespondent1SolicitorN @Nested class Respondent2DoesNotHaveLegalRepresentation { - @Test - void shouldReturnExpectedSubmittedCallbackResponse_whenRespondent2DoesNotHaveRepresentation() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimIssuedUnrepresentedDefendants().build(); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - - String body = format( - CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", CASE_ID), - format("/cases/case-details/%s#CaseDocuments", CASE_ID), - responsePackLink - ) + exitSurveyContentService.applicantSurvey(); - - assertThat(response).usingRecursiveComparison().isEqualTo( - SubmittedCallbackResponse.builder() - .confirmationHeader(format("# Please now pay your claim fee%n# using the link below")) - .confirmationBody(body) - .build()); - } - @Test void certificateOfService_shouldReturnExpectedResponse_whenRespondent2DoesNotHaveRepresentation() { CaseData caseData = CaseDataBuilder.builder().atStateClaimIssuedUnrepresentedDefendants().build(); CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); String body = format( @@ -2042,76 +1940,6 @@ void certificateOfService_shouldReturnExpectedResponse_whenRespondent2DoesNotHav } } - @Nested - class Respondent2SolicitorOrgNotRegisteredInMyHmcts { - - @Test - void shouldReturnExpectedSubmittedCallbackResponse_whenRespondent2SolicitorNotRegisteredInMyHmcts() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() - .respondent2Represented(YES) - .respondent2OrgRegistered(NO) - .build(); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - - assertThat(response).usingRecursiveComparison().isEqualTo( - SubmittedCallbackResponse.builder() - .confirmationHeader(format("# Please now pay your claim fee%n# using the link below")) - .confirmationBody(format( - CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", CASE_ID), - format("/cases/case-details/%s#CaseDocuments", CASE_ID), - responsePackLink - ) + exitSurveyContentService.applicantSurvey()) - .build()); - } - - @Test - void shouldReturnExpectedSubmittedCallbackResponse_whenRespondent2SolicitorNotRegisteredInMyHmcts_PBAV3() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() - .respondent2Represented(YES) - .respondent2OrgRegistered(NO) - .build(); - - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - - assertThat(response).usingRecursiveComparison().isEqualTo( - SubmittedCallbackResponse.builder() - .confirmationHeader(format("# Please now pay your claim fee%n# using the link below")) - .confirmationBody(format( - CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", CASE_ID), - format("/cases/case-details/%s#CaseDocuments", CASE_ID), - responsePackLink - ) + exitSurveyContentService.applicantSurvey()) - .build()); - } - - @Test - void certificateOfService_shouldReturnExpectedResponse_whenRespondent2SolicitorNotRegisteredInMyHmcts() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified() - .respondent2Represented(YES) - .respondent2OrgRegistered(NO) - .build(); - CallbackParams params = callbackParamsOf(caseData, SUBMITTED); - - SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); - - assertThat(response).usingRecursiveComparison().isEqualTo( - SubmittedCallbackResponse.builder() - .confirmationHeader(format("# Please now pay your claim fee%n# using the link below")) - .confirmationBody(format( - CONFIRMATION_BODY_COS, - format("/cases/case-details/%s#Service%%20Request", CASE_ID), - format("/cases/case-details/%s#CaseDocuments", CASE_ID), - responsePackLink - ) + exitSurveyContentService.applicantSurvey()) - .build()); - } - - } - @Nested class RespondentHasLegalRepresentation1v1 { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java index 72f96b705a7..40c83a10559 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java @@ -1965,7 +1965,6 @@ void shouldAddMissingRespondent1OrgPolicyWithCaseRole_whenInvoked() { .respondent1OrganisationPolicy(null) .build()) .build(); - when(toggleService.isNoticeOfChangeEnabled()).thenReturn(true); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(callbackParams); @@ -1982,7 +1981,6 @@ void shouldAddMissingRespondent2OrgPolicyWithCaseRole_whenInvoked() { var callbackParams = params.toBuilder() .caseData(params.getCaseData().toBuilder().build()) .build(); - when(toggleService.isNoticeOfChangeEnabled()).thenReturn(true); // When var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(callbackParams); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandlerTest.java index ff03f28aeb7..90222fc7112 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimCallbackHandlerTest.java @@ -36,7 +36,6 @@ import static java.time.format.DateTimeFormatter.ISO_DATE; import static java.time.format.DateTimeFormatter.ISO_DATE_TIME; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @@ -98,75 +97,12 @@ void shouldPrepopulateDynamicListWithOptions_whenInvoked() { CaseData caseData = CaseDataBuilder.builder() .atStateClaimNotified_1v2_andNotifyBothSolicitors() .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); AboutToStartOrSubmitCallbackResponse response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); assertTrue(response.getData().containsKey("defendantSolicitorNotifyClaimOptions")); } - - @Test - void aboutToStart_ShouldReturnErrorMessageCallbackResponse_1v1_WhenDefendant1LiP_CosDisabled() { - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued1v1LiP() - .build(); - - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); - AboutToStartOrSubmitCallbackResponse response = - (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertThat(response.getErrors()).contains(ERROR_PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT); - } - - @Test - void aboutToStart_ShouldReturnErrorMessageCallbackResponse_1v2WhenDefendant2LiP_CosDisabled() { - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued1v2Respondent2LiP() - .addRespondent2(YesOrNo.YES) - .build(); - - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); - AboutToStartOrSubmitCallbackResponse response = - (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertThat(response.getErrors()).contains(ERROR_PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT); - } - - @Test - void aboutToStart_Should_Not_ReturnErrorMessageCallbackResponse_1v1_WhenDefendant1Represented_CosDisabled() { - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued() - .addRespondent2(YesOrNo.NO) - .build(); - - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); - AboutToStartOrSubmitCallbackResponse response = - (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertNull(response.getErrors()); - } - - @Test - void aboutToStart_ShouldNotReturnErrorMessageCallbackResponse_1v2_BothDefendant1Represented_CosDisabled() { - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimSubmittedTwoRespondentRepresentatives() - .build(); - - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); - AboutToStartOrSubmitCallbackResponse response = - (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertNull(response.getErrors()); - } } @Nested @@ -296,7 +232,6 @@ void should_ThrowError_whenCosServiceDate_is14thDay_afterBusinessDayEndTime() { .build(); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 15, 16, 05)); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosNotifyDate.atTime(16, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -341,8 +276,6 @@ void shouldNot_ThrowError_whenCosServiceDate_notOlderThan14Days() { when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); - when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosNotifyDate.atTime(15, 05))) .thenReturn(cosNotifyDate.plusDays(14).atTime(END_OF_BUSINESS_DAY)); @@ -366,7 +299,6 @@ void shouldNot_ThrowError_whenCosServiceDate_is14thDay_beforeBusinessDayEndTime( .build(); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 15, 15, 05)); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosNotifyDate.atTime(15, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -506,7 +438,6 @@ void shouldSetDetailsNotificationDeadline_Cos_1v2_whenLipDefendant1() { LocalDate cosNotifyDate = LocalDate.of(2021, 4, 2); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 3, 15, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosNotifyDate.atTime(15, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -538,7 +469,6 @@ void shouldSetDetailsNotificationDeadline_Cos_1v2_whenLipDefendant1() { void shouldSetDetailsNotificationDeadline_Cos_1v2_whenLipDefendant2() { LocalDate cosNotifyDate = LocalDate.of(2021, 4, 2); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 3, 15, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosNotifyDate.atTime(15, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -573,7 +503,6 @@ void shouldSetDetailsNotificationDeadline_Cos_1v2_bothDefendantsLip_def1Notified LocalDate cosDef2NotifyDate = LocalDate.of(2021, 5, 2); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 3, 15, 05)); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosDef1NotifyDate.atTime(15, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -606,7 +535,6 @@ void shouldSetDetailsNotificationDeadline_Cos_1v2_bothDefendantsLip_def2Notified LocalDate cosDef2NotifyDate = LocalDate.of(2021, 4, 28); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 3, 15, 05)); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosDef2NotifyDate.atTime(15, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -639,7 +567,6 @@ void shouldSetDetailsNotificationDeadline_Cos_1v2_bothDefendantsLip_sameDates() LocalDate cosDef2NotifyDate = LocalDate.of(2021, 4, 2); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 3, 15, 05)); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosDef1NotifyDate.atTime(15, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -670,7 +597,6 @@ void shouldSetDetailsNotificationDeadline_Cos_1v1_whenLipDefendant() { LocalDate cosNotifyDate = LocalDate.of(2021, 4, 26); when(time.now()).thenReturn(LocalDateTime.of(2021, 5, 3, 15, 05)); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosNotifyDate.atTime(15, 05))) .thenReturn(claimDetailsNotificationDeadline); @@ -690,32 +616,6 @@ void shouldSetDetailsNotificationDeadline_Cos_1v1_whenLipDefendant() { assertThat(response.getData()) .containsEntry("claimDetailsNotificationDeadline", expectedDeadline.format(ISO_DATE_TIME)); } - - @Test - void shouldSetDetailsNotificationDeadline_Cos_disabled_1v1_whenLipDefendant() { - - LocalDate cosNotifyDate = LocalDate.of(2021, 4, 2); - - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - - when(deadlinesCalculator.plus14DaysAt4pmDeadline(notifyClaimDateTime)) - .thenReturn(claimDetailsNotificationDeadline); - - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimNotified1v1LiP(CertificateOfService.builder() - .cosDateOfServiceForDefendant(cosNotifyDate) - .build()) - .claimNotificationDeadline(claimNotificationDeadline) - .build(); - CallbackParams params = CallbackParamsBuilder.builder().of( - CallbackType.ABOUT_TO_SUBMIT, - caseData - ).build(); - var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - - assertThat(response.getData()) - .containsEntry("claimDetailsNotificationDeadline", expectedDeadline.format(ISO_DATE_TIME)); - } } @Nested @@ -899,7 +799,6 @@ void shouldReturnExpectedSubmittedCallbackResponse_Defendant1Lip_whenInvoked() { .builder().cosDateOfServiceForDefendant(LocalDate.now()) .build()) .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); CallbackParams params = callbackParamsOf(caseData, SUBMITTED); SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); @@ -922,7 +821,6 @@ void shouldReturnExpectedSubmittedCallbackResponse_Defendant2Lip_whenInvoked() { .cosDateOfServiceForDefendant(LocalDate.now()) .build()) .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); CallbackParams params = callbackParamsOf(caseData, SUBMITTED); SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandlerTest.java index b9ac78d66d1..56cefd08ece 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/NotifyClaimDetailsCallbackHandlerTest.java @@ -254,7 +254,6 @@ void shouldUpdateBusinessProcess_whenInvoked1v2DifferentSolicitor() { @Test void shouldUpdateCertificateOfService_and_documents_cos1_whenSubmitted() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); LocalDate cosDate = localDateTime.minusDays(2).toLocalDate(); when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosDate.atTime(15, 05))) @@ -278,7 +277,6 @@ void shouldUpdateCertificateOfService_and_documents_cos1_whenSubmitted() { @Test void shouldUpdateCertificateOfService_and_documents_cos2_whenSubmitted() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); LocalDate cosDate = localDateTime.minusDays(2).toLocalDate(); when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(cosDate.atTime(15, 05))) @@ -302,7 +300,6 @@ void shouldUpdateCertificateOfService_and_documents_cos2_whenSubmitted() { @Test void shouldUpdate_to_earliest_day_cos2_is_earliest_whenSubmitted() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); LocalDate cos1Date = localDateTime.minusDays(2).toLocalDate(); LocalDate cos2Date = localDateTime.minusDays(3).toLocalDate(); when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); @@ -328,7 +325,6 @@ void shouldUpdate_to_earliest_day_cos2_is_earliest_whenSubmitted() { @Test void shouldUpdate_to_earliest_day_cos1_is_earliest_whenSubmitted() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); LocalDate cos1Date = localDateTime.minusDays(3).toLocalDate(); LocalDate cos2Date = localDateTime.minusDays(2).toLocalDate(); when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); @@ -436,7 +432,6 @@ void shouldReturnExpectedSubmittedCallbackResponse_whenInvoked() { @Test void shouldReturnExpectedSubmittedCallbackResponse_with_cos_whenInvoked() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); CaseData caseData = CaseDataBuilder.builder().atStateClaimDetailsNotified().build(); CallbackParams params = callbackParamsOf(caseData, SUBMITTED); SubmittedCallbackResponse response = (SubmittedCallbackResponse) handler.handle(params); @@ -499,7 +494,6 @@ void shouldReturnExpectedSubmittedCallbackResponse_whenNotifyingOneParty_whenInv @Test void shouldReturnCoSConfirmation_whenCosNotifyDetailsSuccess() { LocalDate past = LocalDate.now().minusDays(1); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.now()); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -515,7 +509,6 @@ void shouldReturnCoSConfirmation_whenCosNotifyDetailsSuccess() { @Test void shouldReturnCoSConfirmation_1Lip1Lr_whenCosNotifyDetailsSuccess() { LocalDate past = LocalDate.now().minusDays(1); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.now()); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -535,7 +528,6 @@ class MidEventValidateCos { void shouldPassValidateCertificateOfService_whenDateIsPast() { LocalDate past = LocalDate.now().minusDays(1); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -556,7 +548,6 @@ void shouldPassValidateCertificateOfService_whenDateIsPast() { void shouldPassValidateCertificateOfService_1Lip1Lr_whenDateIsPast() { LocalDate past = LocalDate.now().minusDays(1); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDate.now().atTime(16, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -577,7 +568,6 @@ void shouldPassValidateCertificateOfService_1Lip1Lr_whenDateIsPast() { void shouldPassValidateCertificateOfService_1Lr1Lip_whenServiceDateIsPast_notOlderThan14Days() { LocalDate past = LocalDate.now().minusDays(1); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(past.atTime(15, 05))) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -597,7 +587,6 @@ void shouldPassValidateCertificateOfService_1Lr1Lip_whenServiceDateIsPast_notOld void shouldNotPassValidateCertificateOfService_1Lr1Lip_whenServiceDateIsPast_OlderThan14Days() { LocalDate past = LocalDate.now().minusDays(15); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDate.now().atTime(15, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(past.atTime(15, 05))) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -617,7 +606,6 @@ void shouldNotPassValidateCertificateOfService_1Lr1Lip_whenServiceDateIsPast_Old void shouldNotPassValidateCertificateOfService_1Lr1Lip_whenServiceDateIsPast_deadlineTodayDate_After16hrs() { LocalDate past = LocalDate.now().minusDays(14); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDate.now().atTime(16, 05)); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -633,45 +621,11 @@ void shouldNotPassValidateCertificateOfService_1Lr1Lip_whenServiceDateIsPast_dea assertThat(params.getCaseData().getCosNotifyClaimDetails1().getCosDocSaved()).isEqualTo(NO); } - @Test - void shouldIgnoreValidateCertificateOfService_whenDisabled() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - when(time.now()).thenReturn(LocalDateTime.now()); - LocalDate past = LocalDate.now().minusDays(1); - LocalDate future = LocalDate.now().plusDays(1); - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimDetailsNotified_1v2_andNotifyBothCoS() - .setCoSClaimDetailsWithDate(true, true, past, future, true, true) - .build(); - CallbackParams params = callbackParamsOf(caseData, MID, "validateCosNotifyClaimDetails2"); - AboutToStartOrSubmitCallbackResponse successResponse = - (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - assertThat(successResponse.getErrors().size()).isEqualTo(0); - } - - @Test - void shouldFailValidateCertificateOfService_whenDateIsFuture() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); - when(time.now()).thenReturn(LocalDateTime.now()); - - LocalDate past = LocalDate.now().minusDays(1); - LocalDate future = LocalDate.now().plusDays(1); - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimDetailsNotified_1v2_andNotifyBothCoS() - .setCoSClaimDetailsWithDate(true, true, past, future, true, true) - .build(); - CallbackParams params = callbackParamsOf(caseData, MID, "validateCosNotifyClaimDetails2"); - AboutToStartOrSubmitCallbackResponse successResponse = - (AboutToStartOrSubmitCallbackResponse) handler.handle(params); - assertThat(successResponse.getErrors().size()).isEqualTo(2); - } - @Test void shouldFailValidateCertificateOfService_When1v2LIP_BothDefendant_DifferentDateOfService() { LocalDate def1pastDate = LocalDate.now().minusDays(1); LocalDate def2pastDate = LocalDate.now().minusDays(2); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.now()); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(def2pastDate.plusDays(14).atTime(16, 0)); @@ -688,7 +642,6 @@ void shouldFailValidateCertificateOfService_When1v2LIP_BothDefendant_DifferentDa @Test void shouldNotFailValidateCertificateOfService_When1v2LIP_BothDefendant_SameDateOfService() { - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.now()); LocalDate def1pastDate = LocalDate.now().minusDays(1); @@ -710,7 +663,6 @@ void shouldNotFailValidateCertificateOfService_When1v2LIP_BothDefendant_SameDate @Test void shouldPassValidateCertificateOfService_whenHasFile() { LocalDate past = LocalDate.now().minusDays(1); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.now()); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(past.plusDays(14).atTime(16, 0)); @@ -728,7 +680,6 @@ void shouldPassValidateCertificateOfService_whenHasFile() { @Test void shouldFailValidateCertificateOfService_whenHasNoFile() { LocalDate past = LocalDate.now().minusDays(1); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); when(time.now()).thenReturn(LocalDateTime.now()); when(deadlinesCalculator.plus14DaysAt4pmDeadline(any())) .thenReturn(past.plusDays(14).atTime(16, 0)); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandlerTest.java index 9be08ccdca7..5fddf8c0714 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/CaseEventTaskHandlerTest.java @@ -248,8 +248,6 @@ void init() { ); when(mockTask.getAllVariables()).thenReturn(variables); - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); } @ParameterizedTest @@ -428,86 +426,6 @@ void shouldHaveCorrectDescription_whenInUnrepresentedDefendantAndUnregisteredSol + "Unregistered defendant solicitor firm: Mr. Sole Trader."); } - @Nested - class ToBeRemovedAfterNOC { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(false); - } - - @Test - void prod_shouldHaveCorrectDescription_whenInUnregisteredSolicitorState() { - FlowState.Main state = PENDING_CLAIM_ISSUED_UNREGISTERED_DEFENDANT; - VariableMap variables = Variables.createVariables(); - variables.putValue(FLOW_STATE, state.fullName()); - variables.putValue( - FLOW_FLAGS, - getFlowFlags(state) - ); - - when(mockTask.getVariable(FLOW_STATE)).thenReturn(state.fullName()); - - CaseData caseData = CaseDataBuilder.builder() - .atStatePendingClaimIssuedUnregisteredDefendant() - .businessProcess(BusinessProcess.builder().status(BusinessProcessStatus.READY).build()) - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - - CaseDetails caseDetails = CaseDetailsBuilder.builder().data(caseData).build(); - - when(coreCaseDataService.startUpdate(CASE_ID, PROCEEDS_IN_HERITAGE_SYSTEM)) - .thenReturn(StartEventResponse.builder().caseDetails(caseDetails) - .eventId(PROCEEDS_IN_HERITAGE_SYSTEM.name()).build()); - - when(coreCaseDataService.submitUpdate(eq(CASE_ID), caseDataContentArgumentCaptor.capture())) - .thenReturn(caseData); - - caseEventTaskHandler.execute(mockTask, externalTaskService); - - CaseDataContent caseDataContent = caseDataContentArgumentCaptor.getValue(); - Event event = caseDataContent.getEvent(); - assertThat(event.getDescription()).isEqualTo("Unregistered defendant solicitor firm: Mr. Sole Trader"); - } - - @Test - void prod_shouldHaveCorrectDescription_whenInUnrepresentedDefendantAndUnregisteredSolicitorState() { - FlowState.Main state = PENDING_CLAIM_ISSUED_UNREPRESENTED_UNREGISTERED_DEFENDANT; - VariableMap variables = Variables.createVariables(); - variables.putValue(FLOW_STATE, state.fullName()); - variables.putValue( - FLOW_FLAGS, - getFlowFlags(state) - ); - - when(mockTask.getVariable(FLOW_STATE)).thenReturn(state.fullName()); - - CaseData caseData = CaseDataBuilder.builder() - .atStatePendingClaimIssuedUnrepresentedUnregisteredDefendant() - .businessProcess(BusinessProcess.builder().status(BusinessProcessStatus.READY).build()) - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - CaseDetails caseDetails = CaseDetailsBuilder.builder().data(caseData).build(); - - when(coreCaseDataService.startUpdate(CASE_ID, PROCEEDS_IN_HERITAGE_SYSTEM)) - .thenReturn(StartEventResponse.builder().caseDetails(caseDetails) - .eventId(PROCEEDS_IN_HERITAGE_SYSTEM.name()).build()); - - when(coreCaseDataService.submitUpdate(eq(CASE_ID), caseDataContentArgumentCaptor.capture())) - .thenReturn(caseData); - - caseEventTaskHandler.execute(mockTask, externalTaskService); - - CaseDataContent caseDataContent = caseDataContentArgumentCaptor.getValue(); - Event event = caseDataContent.getEvent(); - assertThat(event.getDescription()) - .isEqualTo("Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unrepresented defendant: Mr. John Rambo. " - + "Unregistered defendant solicitor firm: Mr. Sole Trader."); - } - } - @Nested class FullDefenceProceed { FlowState.Main state = FULL_DEFENCE_PROCEED; @@ -713,12 +631,11 @@ void shouldHaveExpectedDescription_WhenOnlySecondClaimantProceeds() { @NotNull private Map getFlowFlags(FlowState.Main state) { if (state.equals(TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED) - || state.equals(TAKEN_OFFLINE_AFTER_CLAIM_DETAILS_NOTIFIED)) { + || state.equals(TAKEN_OFFLINE_AFTER_CLAIM_DETAILS_NOTIFIED) + || state.equals(PENDING_CLAIM_ISSUED_UNREGISTERED_DEFENDANT)) { return Map.of("TWO_RESPONDENT_REPRESENTATIVES", true, "ONE_RESPONDENT_REPRESENTATIVE", false, - FlowFlag.NOTICE_OF_CHANGE.name(), true, FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false, - FlowFlag.CERTIFICATE_OF_SERVICE.name(), true, FlowFlag.BULK_CLAIM_ENABLED.name(), false ); } else if (state.equals(TAKEN_OFFLINE_BY_STAFF) @@ -731,15 +648,11 @@ private Map getFlowFlags(FlowState.Main state) { || state.equals(CLAIM_DETAILS_NOTIFIED) || state.equals(NOTIFICATION_ACKNOWLEDGED_TIME_EXTENSION)) { return Map.of("ONE_RESPONDENT_REPRESENTATIVE", true, - FlowFlag.NOTICE_OF_CHANGE.name(), true, FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false, - FlowFlag.CERTIFICATE_OF_SERVICE.name(), true, FlowFlag.BULK_CLAIM_ENABLED.name(), false ); } - return Map.of(FlowFlag.NOTICE_OF_CHANGE.name(), true, - FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false, - FlowFlag.CERTIFICATE_OF_SERVICE.name(), true, + return Map.of(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false, FlowFlag.BULK_CLAIM_ENABLED.name(), false ); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/PaymentTaskHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/PaymentTaskHandlerTest.java index c04cc3b01ac..f9adb659089 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/PaymentTaskHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/tasks/PaymentTaskHandlerTest.java @@ -87,9 +87,7 @@ void shouldTriggerMakePbaPaymentCCDEvent_whenHandlerIsExecuted() { variables.putValue(FLOW_STATE, "MAIN.CLAIM_SUBMITTED"); variables.putValue(FLOW_FLAGS, Map.of("ONE_RESPONDENT_REPRESENTATIVE", true, FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false, - FlowFlag.NOTICE_OF_CHANGE.name(), false, - FlowFlag.BULK_CLAIM_ENABLED.name(), false, - FlowFlag.CERTIFICATE_OF_SERVICE.name(), false)); + FlowFlag.BULK_CLAIM_ENABLED.name(), false)); CaseDetails caseDetails = CaseDetailsBuilder.builder().data(caseData).build(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java index 37ce3e52316..bc230fb1382 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java @@ -1863,6 +1863,7 @@ public CaseDataBuilder atStateProceedsOffline1v1UnregisteredDefendant() { addRespondent2 = NO; respondent2 = null; respondent2Represented = null; + respondent2OrgRegistered = null; return this; } @@ -2293,8 +2294,8 @@ public CaseDataBuilder atStateClaimSubmittedNoRespondentRepresented() { atStateClaimSubmitted(); addRespondent2 = YES; respondent2SameLegalRepresentative = NO; - respondent1OrgRegistered = NO; - respondent2OrgRegistered = NO; + respondent1OrgRegistered = null; + respondent2OrgRegistered = null; respondent1Represented = NO; respondent2Represented = NO; respondent2 = PartyBuilder.builder().individual().build().toBuilder().partyID("res-2-party-id").build(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderSpec.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderSpec.java index bb94bb5256d..747d17d86f9 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderSpec.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderSpec.java @@ -354,8 +354,8 @@ public CaseDataBuilderSpec atStateSpec1v2BothDefendantUnrepresentedClaimSubmitte respondent2 = PartyBuilder.builder().individual().build(); respondent1Represented = NO; respondent2Represented = NO; - respondent1OrgRegistered = NO; - respondent2OrgRegistered = NO; + respondent1OrgRegistered = null; + respondent2OrgRegistered = null; return this; } @@ -392,7 +392,7 @@ public CaseDataBuilderSpec atStateSpec1v2OneDefendantRepresentedUnregisteredOthe addRespondent2 = YES; respondent2 = PartyBuilder.builder().individual().build(); respondent1Represented = NO; - respondent1OrgRegistered = NO; + respondent1OrgRegistered = null; respondent2Represented = YES; respondent2OrgRegistered = NO; return this; diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderUnspec.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderUnspec.java index c8157be2880..2fb122ed673 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderUnspec.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilderUnspec.java @@ -310,8 +310,8 @@ public CaseDataBuilderUnspec atState1v2BothDefendantUnrepresentedClaimSubmitted( respondent2 = PartyBuilder.builder().individual().build(); respondent1Represented = NO; respondent2Represented = NO; - respondent1OrgRegistered = NO; - respondent2OrgRegistered = NO; + respondent1OrgRegistered = null; + respondent2OrgRegistered = null; return this; } @@ -348,7 +348,7 @@ public CaseDataBuilderUnspec atState1v2OneDefendantRepresentedUnregisteredOtherU addRespondent2 = YES; respondent2 = PartyBuilder.builder().individual().build(); respondent1Represented = NO; - respondent1OrgRegistered = NO; + respondent1OrgRegistered = null; respondent2Represented = YES; respondent2OrgRegistered = YES; return this; diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/FeatureToggleServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/FeatureToggleServiceTest.java index 764bd837d0b..3563aef0920 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/FeatureToggleServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/FeatureToggleServiceTest.java @@ -33,15 +33,6 @@ void shouldReturnCorrectValue_whenMyFeatureIsEnabledOrDisabled(Boolean toggleSta assertThat(featureToggleService.isFeatureEnabled("myFeature")).isEqualTo(toggleState); } - @ParameterizedTest - @ValueSource(booleans = {true, false}) - void shouldReturnCorrectValue_whenIsNoticeOfChangeEnabledInvoked(Boolean toggleState) { - var noticeOfChangeKey = "notice-of-change"; - givenToggle(noticeOfChangeKey, toggleState); - - assertThat(featureToggleService.isNoticeOfChangeEnabled()).isEqualTo(toggleState); - } - @ParameterizedTest @ValueSource(booleans = {true, false}) void shouldReturnCorrectValue_whenAutomatedHearingNoticeEnabledInvoked(Boolean toggleStat) { @@ -78,15 +69,6 @@ void shouldReturnCorrectValue_whenIsPinInPostEnabledInvoked(Boolean toggleStat) assertThat(featureToggleService.isPinInPostEnabled()).isEqualTo(toggleStat); } - @ParameterizedTest - @ValueSource(booleans = {true, false}) - void shouldReturnCorrectValue_whenIsCertificateOfServiceEnabledInvoked(Boolean toggleStat) { - var certificateOfServiceKey = "isCertificateOfServiceEnabled"; - givenToggle(certificateOfServiceKey, toggleStat); - - assertThat(featureToggleService.isCertificateOfServiceEnabled()).isEqualTo(toggleStat); - } - @ParameterizedTest @ValueSource(booleans = {true, false}) void shouldReturnCorrectValue_whenIsPbaV3EnabledInvoked(Boolean toggleStat) { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/RepresentativeServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/RepresentativeServiceTest.java index 6f0b54ba275..c2cba69a173 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/RepresentativeServiceTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/RepresentativeServiceTest.java @@ -29,7 +29,6 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; @SpringBootTest(classes = { @@ -122,10 +121,6 @@ void setup() { @Nested class GetRespondent1Representative { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - } @Test void shouldReturnValidOrganisationDetails_whenDefendantIsRepresented() { @@ -331,10 +326,6 @@ void prod_shouldReturnEmptyRepresentative_whenDefendantSolicitorIsNotRegistered( @Nested class GetRespondent2Representative { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - } @Test void shouldReturnValidOrganisationDetails_whenDefendantIsRepresented() { @@ -468,54 +459,6 @@ void shouldReturnValidOrganisationDetails_whenOrganisationIDIsEmpty() { respondent2ContactInformation.getPostCode() ); } - - @Nested - class ToBeRemovedAfterNOC { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(false); - } - - @Test - void prod_shouldReturnValidOrganisationDetails_whenDefendantIsNotRepresented() { - CaseData caseData = CaseDataBuilder.builder() - .atStatePendingClaimIssuedUnrepresentedDefendant() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .multiPartyClaimTwoDefendantSolicitors().build(); - - Representative representative = representativeService.getRespondent2Representative(caseData); - - verifyNoInteractions(organisationService); - assertThat(representative).extracting( - "organisationName", "phoneNumber", "dxAddress", "emailAddress").containsExactly( - null, - null, - null, - null - ); - assertThat(representative).extracting("serviceAddress").isNull(); - - } - - @Test - void prod_shouldReturnEmptyRepresentative_whenDefendantSolicitorIsNotRegistered() { - CaseData caseData = CaseDataBuilder.builder() - .atStatePendingClaimIssuedUnregisteredDefendant() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .multiPartyClaimTwoDefendantSolicitors().build(); - - Representative representative = representativeService.getRespondent2Representative(caseData); - - verifyNoInteractions(organisationService); - assertThat(representative).extracting( - "organisationName", "phoneNumber", "dxAddress", "emailAddress").containsExactly( - null, null, null, null - ); - assertThat(representative).extracting("serviceAddress").isNull(); - } - } } @Nested diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/dj/DefaultJudgmentOrderFormGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/dj/DefaultJudgmentOrderFormGeneratorTest.java index 9555538850e..14d23a6819a 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/dj/DefaultJudgmentOrderFormGeneratorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/dj/DefaultJudgmentOrderFormGeneratorTest.java @@ -200,7 +200,6 @@ void shouldDefaultJudgementDisposalFormGenerator_HnlFieldsWhenToggled() { @Test void shouldDefaultJudgmentTrialOrderFormGenerator_whenNoticeOfChangeEnabled() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(DJ_SDO_TRIAL))) .thenReturn(new DocmosisDocument(DJ_SDO_TRIAL.getDocumentTitle(), bytes)); when(documentManagementService diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicateTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicateTest.java index 89a8e8f507a..7d910330a96 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicateTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowPredicateTest.java @@ -56,6 +56,7 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimDismissedByCamunda; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimIssued; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimNotified; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmitted1v1RespondentOneUnregistered; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedBothRespondentUnrepresented; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedBothUnregisteredSolicitors; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.claimSubmittedOneRespondentRepresentative; @@ -172,6 +173,21 @@ void shouldReturnTrue_whenCaseTakenOfflineBeforeIssue() { .build(); assertTrue(takenOfflineByStaffBeforeClaimIssued.test(caseData)); } + + @Test + void shouldReturnTrue_whenRespondentSolicitorUnregistered() { + CaseData caseData = CaseDataBuilder.builder() + .atStateClaimSubmittedRespondent1Unregistered() + .addRespondent2(NO) + .build(); + assertTrue(claimSubmitted1v1RespondentOneUnregistered.test(caseData)); + } + + @Test + void shouldReturnFalse_whenRespondentSolicitorRegistered() { + CaseData caseData = CaseDataBuilder.builder().atStateClaimSubmitted().build(); + assertFalse(claimSubmitted1v1RespondentOneUnregistered.test(caseData)); + } } @Nested diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineSpecTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineSpecTest.java index 92c2cbfd854..e186a771137 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineSpecTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineSpecTest.java @@ -55,8 +55,6 @@ class StateFlowEngineSpecTest { @BeforeEach void setup() { given(featureToggleService.isGeneralApplicationsEnabled()).willReturn(false); - given(featureToggleService.isCertificateOfServiceEnabled()).willReturn(false); - given(featureToggleService.isNoticeOfChangeEnabled()).willReturn(false); } static Stream caseDataStream() { @@ -198,12 +196,9 @@ void shouldContainCommonFlags_whenCaseDataAtStateClaimSubmitted(CaseData caseDat //When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); - // Then Claim will have NOTICE_OF_CHANGE, GENERAL_APPLICATION_ENABLED, CERTIFICATE_OF_SERVICE and RPA_CONTINUOUS_FEED + // Then Claim will have GENERAL_APPLICATION_ENABLED and RPA_CONTINUOUS_FEED assertThat(stateFlow.getFlags()).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @ParameterizedTest(name = "{index}: The state flow flag ONE_RESPONDENT_REPRESENTATIVE is set to true (for appropriate cases)") @@ -216,7 +211,7 @@ void shouldHaveOneRespondentRepresentativeFlagsSet_whenCaseDataAtStateClaimSubmi assertThat(stateFlow.getFlags()).contains( entry(FlowFlag.ONE_RESPONDENT_REPRESENTATIVE.name(), true) ); - assertThat(stateFlow.getFlags()).hasSize(5); // bonus: if this fails, a flag was added/removed but tests were not updated + assertThat(stateFlow.getFlags()).hasSize(3); // bonus: if this fails, a flag was added/removed but tests were not updated } @ParameterizedTest(name = "{index}: The state flow flags ONE_RESPONDENT_REPRESENTATIVE and " + @@ -231,7 +226,7 @@ void shouldReturnFlags_whenAtStateClaimSubmitted1v2DiffSol_OrSolicitor1UnrepAndS entry(FlowFlag.ONE_RESPONDENT_REPRESENTATIVE.name(), false), entry(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES.name(), true) ); - assertThat(stateFlow.getFlags()).hasSize(6); // bonus: if this fails, a flag was added/removed but tests were not updated + assertThat(stateFlow.getFlags()).hasSize(4); // bonus: if this fails, a flag was added/removed but tests were not updated } public interface StubbingFn extends Function> { @@ -239,12 +234,8 @@ public interface StubbingFn extends Function commonFlagNames() { return Stream.of( - arguments(FlowFlag.NOTICE_OF_CHANGE.name(), (StubbingFn)(featureToggleService) - -> when(featureToggleService.isNoticeOfChangeEnabled())), arguments(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), (StubbingFn)(featureToggleService) - -> when(featureToggleService.isGeneralApplicationsEnabled())), - arguments(FlowFlag.CERTIFICATE_OF_SERVICE.name(), (StubbingFn)(featureToggleService) - -> when(featureToggleService.isCertificateOfServiceEnabled())) + -> when(featureToggleService.isGeneralApplicationsEnabled())) ); } @@ -432,7 +423,7 @@ void shouldGoClaimIssued_1v1_whenRepresented() { // Specified 1V2 both unrepresented with state transition from PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT -> // TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT @Test() - void shouldGoOffline_1v2_whenBothUnrepresented() { + void shouldNotGoOffline_1v2_whenBothUnrepresented() { //Given CaseData caseData = CaseDataBuilderSpec.builder().atStateTakenOfflineUnrepresentedDefendantSameSolicitor() .build(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java index e281096e8cd..95b6eeb883e 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java @@ -129,10 +129,8 @@ void shouldReturnClaimSubmitted_whenCaseDataAtStateClaimSubmittedWithOneResponde .containsExactly( DRAFT.fullName(), CLAIM_SUBMITTED.fullName()); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true) ); @@ -159,10 +157,8 @@ void shouldReturnTakenOffline_whenCaseTakenOfflineBeforeIssue() { .containsExactly( DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), TAKEN_OFFLINE_BY_STAFF.fullName()); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true) ); @@ -194,13 +190,11 @@ void shouldReturnClaimSubmitted_whenCaseDataAtStateClaimSubmittedTwoRespondentRe .containsExactly( DRAFT.fullName(), CLAIM_SUBMITTED.fullName()); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -229,13 +223,10 @@ void shouldReturnClaimSubmitted_whenCaseDataAtStateClaimSubmittedTwoRepresentati .containsExactly( DRAFT.fullName(), CLAIM_SUBMITTED.fullName()); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -380,144 +371,6 @@ void shouldReturnClaimSubmitted_whenCaseDataAtStateClaimSubmitted2v1RespondentIs DRAFT.fullName(), CLAIM_SUBMITTED.fullName()); } - // remove this when NoC is implemented - @Nested - class UnrepresentedTakenOfflineBeforeNoC { - // 1v1 Unrepresented - @Test - void shouldReturnProceedsWithOfflineJourney_1v1_whenCaseDataAtStateClaimDraftIssuedAndResUnrepresented() { - // Given - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued1v1UnrepresentedDefendant() - .defendant1LIPAtClaimIssued(null) - .defendant2LIPAtClaimIssued(null) - .build(); - - // When - StateFlow stateFlow = stateFlowEngine.evaluate(caseData); - - // Then - assertThat(stateFlow.getState()) - .extracting(State::getName) - .isNotNull() - .isEqualTo(TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName()); - assertThat(stateFlow.getStateHistory()) - .hasSize(5) - .extracting(State::getName) - .containsExactly( - DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName(), - PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName(), - TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName() - ); - assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) - ); - } - - // 1v2 - // Unrepresented - // 1. Both def1 and def2 unrepresented - @Test - void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedRespondentsNotRepresented() { - // Given - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssuedUnrepresentedDefendants() - .defendant1LIPAtClaimIssued(null) - .defendant2LIPAtClaimIssued(null) - .build(); - - // When - StateFlow stateFlow = stateFlowEngine.evaluate(caseData); - - // Then - assertThat(stateFlow.getState()) - .extracting(State::getName) - .isNotNull() - .isEqualTo(TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName()); - assertThat(stateFlow.getStateHistory()) - .hasSize(5) - .extracting(State::getName) - .containsExactly( - DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName(), - PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName(), - TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName() - ); - assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) - ); - } - - // Unrepresented - // 2. Def1 unrepresented, Def2 registered - @Test - void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedRespondent1NotRepresented() { - // Given - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssuedUnrepresentedDefendant1() - .defendant1LIPAtClaimIssued(null) - .build(); - - // When - StateFlow stateFlow = stateFlowEngine.evaluate(caseData); - - // Then - assertThat(stateFlow.getState()) - .extracting(State::getName) - .isNotNull() - .isEqualTo(TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName()); - assertThat(stateFlow.getStateHistory()) - .hasSize(5) - .extracting(State::getName) - .containsExactly( - DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName(), - PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName(), - TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName() - ); - assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) - ); - } - - // Unrepresented - // 3. Def1 registered, Def 2 unrepresented - @Test - void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedRespondent2NotRepresented() { - // Given - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssuedUnrepresentedDefendant2() - .defendant2LIPAtClaimIssued(null) - .build(); - - // When - StateFlow stateFlow = stateFlowEngine.evaluate(caseData); - - // Then - assertThat(stateFlow.getState()) - .extracting(State::getName) - .isNotNull() - .isEqualTo(TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName()); - assertThat(stateFlow.getStateHistory()) - .hasSize(5) - .extracting(State::getName) - .containsExactly( - DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName(), - PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName(), - TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName() - ); - assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) - ); - } - } - @Nested class UnrepresentedDefendant { @Test @@ -547,52 +400,13 @@ void shouldGoOffline_whenDeadlinePassed() { PAST_CLAIM_NOTIFICATION_DEADLINE_AWAITING_CAMUNDA.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true), entry(FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } - // 1v1 - // Unrepresented cos service not activated - @Test - void shouldContinueOnline_1v1_whenDefendantIsUnrepresented() { - // Given - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued1v1UnrepresentedDefendant() - .defendant1LIPAtClaimIssued(YES) - .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); - - // When - StateFlow stateFlow = stateFlowEngine.evaluate(caseData); - - // Then - assertThat(stateFlow.getState()) - .extracting(State::getName) - .isNotNull() - .isEqualTo(PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName()); - assertThat(stateFlow.getStateHistory()) - .hasSize(4) - .extracting(State::getName) - .containsExactly( - DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName(), - PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() - ); - - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); - } - - // Unrepresented cos service activated @Test void shouldContinueOnline_1v1_cos_whenDefendantIsUnrepresented() { // Given @@ -600,7 +414,6 @@ void shouldContinueOnline_1v1_cos_whenDefendantIsUnrepresented() { .atStateClaimIssued1v1UnrepresentedDefendant() .defendant2LIPAtClaimIssued(YES) .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); // When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); @@ -618,11 +431,9 @@ void shouldContinueOnline_1v1_cos_whenDefendantIsUnrepresented() { PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), true) + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -654,10 +465,8 @@ void shouldContinueOnline_1v1Spec_whenDefendantIsUnrepresented() { PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT_ONE_V_ONE_SPEC.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -673,7 +482,6 @@ void shouldContinueOnline_WhenBothDefendantsAreUnrepresented() { .defendant1LIPAtClaimIssued(YES) .defendant2LIPAtClaimIssued(YES) .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); // When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); @@ -691,11 +499,9 @@ void shouldContinueOnline_WhenBothDefendantsAreUnrepresented() { PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true), entry(FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -708,7 +514,6 @@ void shouldContinueOnline_WhenCaseDataAtStateClaimDraftIssuedAndRespondent1NotRe CaseData caseData = CaseDataBuilder.builder() .atStateClaimIssuedUnrepresentedDefendant1() .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); // When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); @@ -726,11 +531,9 @@ void shouldContinueOnline_WhenCaseDataAtStateClaimDraftIssuedAndRespondent1NotRe PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true), entry(FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -743,7 +546,6 @@ void shouldContinueOnline_Cos_WhenCaseDataAtStateClaimDraftIssuedAndRespondent1N CaseData caseData = CaseDataBuilder.builder() .atStateClaimIssuedUnrepresentedDefendant1() .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); // When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); @@ -761,11 +563,9 @@ void shouldContinueOnline_Cos_WhenCaseDataAtStateClaimDraftIssuedAndRespondent1N PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), true), entry(FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), true), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -779,7 +579,6 @@ void shouldContinueOnline_WhenCaseDataAtStateClaimDraftIssuedAndRespondent2NotRe .atStateClaimIssuedUnrepresentedDefendant2() .defendant2LIPAtClaimIssued(YES) .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(false); // When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); @@ -797,11 +596,9 @@ void shouldContinueOnline_WhenCaseDataAtStateClaimDraftIssuedAndRespondent2NotRe PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), false), entry(FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -816,8 +613,6 @@ void shouldContinueOnline_Cos_WhenCaseDataAtStateClaimDraftIssuedAndRespondent2N .defendant2LIPAtClaimIssued(YES) .build(); - when(featureToggleService.isCertificateOfServiceEnabled()).thenReturn(true); - // When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); @@ -834,13 +629,10 @@ void shouldContinueOnline_Cos_WhenCaseDataAtStateClaimDraftIssuedAndRespondent2N PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_ONE.name(), false), entry(FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), true) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } // 1v2 spec @@ -862,19 +654,18 @@ void shouldContinueOnline_WhenCaseDataAtStateClaimDraftIssuedAndRespondent2NotRe assertThat(stateFlow.getState()) .extracting(State::getName) .isNotNull() - .isEqualTo(PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName()); + .isEqualTo(TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName()); assertThat(stateFlow.getStateHistory()) - .hasSize(4) + .hasSize(5) .extracting(State::getName) .containsExactly( SPEC_DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName(), - PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName() + PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName(), + TAKEN_OFFLINE_UNREPRESENTED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.UNREPRESENTED_DEFENDANT_TWO.name(), true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -905,10 +696,8 @@ void shouldReturnProceedsWithOfflineJourney_1v1_whenCaseDataAtStateClaimDraftIss TAKEN_OFFLINE_UNREGISTERED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -938,8 +727,6 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedR TAKEN_OFFLINE_UNREGISTERED_DEFENDANT.fullName() ); assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -970,8 +757,6 @@ void shouldReturnProceedsWithOfflineJourney_whenRespondentsNotRegisteredSpec() { TAKEN_OFFLINE_UNREGISTERED_DEFENDANT.fullName() ); assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -1000,10 +785,8 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedR TAKEN_OFFLINE_UNREGISTERED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -1038,10 +821,8 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedR TAKEN_OFFLINE_UNREGISTERED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -1069,10 +850,8 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedS TAKEN_OFFLINE_UNREGISTERED_DEFENDANT.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -1104,8 +883,6 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedA TAKEN_OFFLINE_UNREPRESENTED_UNREGISTERED_DEFENDANT.fullName() ); assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -1136,8 +913,6 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimDraftIssuedA ); assertThat(stateFlow.getFlags()).hasSize(4).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -1169,11 +944,9 @@ void shouldReturnPaymentSuccessful_whenCaseDataAtStatePaymentSuccessful() { .containsExactly( DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName()); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -1198,13 +971,10 @@ void shouldReturnPaymentSuccessful_whenCaseDataAtStatePaymentSuccessful1v2SameRe .containsExactly( DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_SUCCESSFUL.fullName()); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1226,13 +996,10 @@ void shouldReturnPaymentFailed_whenCaseDataAtStatePaymentFailed() { .containsExactly( DRAFT.fullName(), CLAIM_SUBMITTED.fullName(), CLAIM_ISSUED_PAYMENT_FAILED.fullName()); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1262,13 +1029,10 @@ void shouldReturnAwaitingCaseNotification_whenCaseDataAtStateAwaitingCaseNotific PENDING_CLAIM_ISSUED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1302,14 +1066,11 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataAtStateClaimIssued_andOn CLAIM_ISSUED.fullName(), TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1343,14 +1104,11 @@ void shouldReturnClaimNotified_whenCaseDataAtStateClaimNotified_andBothSolicitor CLAIM_ISSUED.fullName(), CLAIM_NOTIFIED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1380,13 +1138,10 @@ void shouldReturnAwaitingCaseNotification_whenCaseDataAtStateAwaitingCaseDetails PENDING_CLAIM_ISSUED.fullName(), CLAIM_ISSUED.fullName(), CLAIM_NOTIFIED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false)); } @Test @@ -1411,12 +1166,9 @@ void shouldReturnClaimDetailsNotified_whenCaseDataAtStateClaimDetailsNotified() CLAIM_DETAILS_NOTIFIED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("ONE_RESPONDENT_REPRESENTATIVE", true)); } @Test @@ -1449,13 +1201,10 @@ void shouldReturnClaimDetailsNotified_whenCaseDataAtStateClaimDetailsNotifiedBot CLAIM_DETAILS_NOTIFIED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1512,12 +1261,9 @@ void shouldReturnClaimDetailsNotifiedTimeExtension_whenCaseDataAtStateClaimDetai CLAIM_DETAILS_NOTIFIED.fullName(), CLAIM_DETAILS_NOTIFIED_TIME_EXTENSION.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1548,12 +1294,9 @@ void shouldReturnClaimAcknowledge_whenCaseDataAtStateClaimAcknowledge() { CLAIM_DETAILS_NOTIFIED.fullName(), NOTIFICATION_ACKNOWLEDGED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1586,12 +1329,9 @@ void shouldReturnNotificationAcknowledgedTimeExtension_whenCaseDataAtStateClaimA NOTIFICATION_ACKNOWLEDGED_TIME_EXTENSION.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1622,13 +1362,10 @@ void shouldReturnClaimDismissed_whenCaseDataAtStateClaimAcknowledgeAndCcdStateIs CLAIM_DISMISSED_PAST_CLAIM_DISMISSED_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1653,12 +1390,9 @@ void shouldReturnExtensionRequested_whenCaseDataAtStateClaimDetailsNotifiedTimeE CLAIM_DETAILS_NOTIFIED.fullName(), CLAIM_DETAILS_NOTIFIED_TIME_EXTENSION.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Nested @@ -1689,12 +1423,9 @@ void shouldReturnFullDefence_whenCaseDataAtStateRespondentFullDefence() { ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("ONE_RESPONDENT_REPRESENTATIVE", true)); } @Test @@ -1734,12 +1465,9 @@ void shouldReturnFullAdmission_whenCaseDataAtStateRespondentFullAdmission() { FULL_ADMISSION.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("ONE_RESPONDENT_REPRESENTATIVE", true)); } @Test @@ -1773,12 +1501,9 @@ void shouldReturnPartAdmission_whenCaseDataAtStateRespondentPartAdmission() { PART_ADMISSION.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -1816,12 +1541,9 @@ void shouldReturnCounterClaim_whenCaseDataAtStateRespondentCounterClaim() { COUNTER_CLAIM.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } } @@ -1861,13 +1583,10 @@ void shouldGenerateDQ_1v2DiffSol_whenFirstResponseIsFullDefence() { AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } //1v2 Different solicitor scenario-first response FullDefence received @@ -1903,13 +1622,10 @@ void shouldGenerateDQ_1v2DiffSol_whenFirstResponseIsNotFullDefence() { AWAITING_RESPONSES_NOT_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } //1v2 Different solicitor scenario-first response FullDefence received @@ -1945,13 +1661,10 @@ void shouldGenerateDQ_in1v2Scenario_whenFirstPartySubmitFullDefenceResponse() { AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } //1v2 Different solicitor scenario-first party acknowledges, not responds @@ -1988,13 +1701,10 @@ void shouldGenerateDQ_in1v2Scenario_whenSecondPartySubmitFullDefenceResponse() { AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("TWO_RESPONDENT_REPRESENTATIVES", true)); } //Respondent 1 submits FULL DEFENCE, Respondent 2 submits FULL DEFENCE @@ -2030,13 +1740,10 @@ void shouldReturnFullDefence_in1v2Scenario_whenBothPartiesSubmitFullDefenceRespo ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("TWO_RESPONDENT_REPRESENTATIVES", true)); } //Respondent 1 and 2 acknowledges claim, then submits FULL DEFENCE @@ -2073,13 +1780,10 @@ void shouldReturnFullDefence_in1v2Scenario_whenBothPartiesAcknowledgedAndSubmitF ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("TWO_RESPONDENT_REPRESENTATIVES", true)); } //Respondent 1 acknowledges claim, then Respondent 1 & 2 submits FULL DEFENCE @@ -2117,13 +1821,10 @@ void shouldReturnFullDefence_in1v2Scenario_whenRep1AcknowledgedAndBothSubmitFull ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("TWO_RESPONDENT_REPRESENTATIVES", true)); } // Respondent 2 acknowledges claim, Respondent 1 & 2 submits FULL DEFENCE @@ -2161,10 +1862,8 @@ void shouldReturnFullDefence_in1v2Scenario_whenRep2AcknowledgedAndBothSubmitFull ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true) ); @@ -2203,10 +1902,8 @@ void shouldReturnDivergentResponseAndGoOffline_1v2Scenario_whenFirstRespondentSu ALL_RESPONSES_RECEIVED.fullName(), DIVERGENT_RESPOND_GO_OFFLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true) ); @@ -2246,10 +1943,8 @@ void shouldReturnDivergentResponse_in1v2SameSolicitorScenario_whenOneRespondentS ALL_RESPONSES_RECEIVED.fullName(), DIVERGENT_RESPOND_GENERATE_DQ_GO_OFFLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -2287,11 +1982,9 @@ void shouldReturnDivergentResponse_in1v2Scenario_whenNeitherRespondentSubmitsFul ALL_RESPONSES_RECEIVED.fullName(), DIVERGENT_RESPOND_GO_OFFLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -2329,10 +2022,8 @@ void shouldReturnAdmitsPartResponse_in1v2Scenario_whenBothRespondentsSubmitAdmit ALL_RESPONSES_RECEIVED.fullName(), FULL_ADMISSION.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true) ); @@ -2363,10 +2054,8 @@ void shouldReturnClaimDismissed_whenCaseDataAtStateClaimDismissed() { CLAIM_DISMISSED_PAST_CLAIM_DISMISSED_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -2417,17 +2106,13 @@ void shouldReturnFullDefenceProceed_whenCaseDataAtStateApplicantRespondToDefence } if (flowState == FlowState.Main.FULL_DEFENCE_NOT_PROCEED) { - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true) ); } else if (flowState == TAKEN_OFFLINE_AFTER_SDO) { - assertThat(stateFlow.getFlags()).hasSize(6).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true), @@ -2504,12 +2189,10 @@ void shouldAwaitResponse_1v2DiffSol_whenFirstResponseIsFullDefenceAndTimeExtensi AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -2556,13 +2239,11 @@ void shouldAwaitResponse_1v2DiffSol_whenBothRespondFullDefenceAndTimeExtension() FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) + entry("TWO_RESPONDENT_REPRESENTATIVES", true) ); } @@ -2602,11 +2283,9 @@ void shouldAwaitResponse_1v2DiffSol_whenFirstResponseIsFullDefenceAfterAcknowled AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -2632,9 +2311,7 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseDataIsCaseProceedsInCaseman( PENDING_CLAIM_ISSUED.fullName(), CLAIM_ISSUED.fullName(), TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true) ); @@ -2690,9 +2367,7 @@ void shouldReturnTakenOffline_whenApplicantIsOutOfTimeAndCamundaHasProcessedCase TAKEN_OFFLINE_PAST_APPLICANT_RESPONSE_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true) ); @@ -2752,9 +2427,7 @@ void shouldReturnClaimDismissedState_whenPastClaimNotificationDeadlineAndProcess CLAIM_DISMISSED_HEARING_FEE_DUE_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true), @@ -2846,10 +2519,8 @@ void shouldReturnCaseDismissedState_whenCaseDataIsPastClaimDetailsNotificationAn CLAIM_DISMISSED_PAST_CLAIM_DETAILS_NOTIFICATION_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true) ); @@ -2879,9 +2550,7 @@ void shouldReturnClaimDismissedState_whenPastHearingFeeDueDeadlineAndProcessedBy CLAIM_DISMISSED_HEARING_FEE_DUE_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.SDO_ENABLED.name(), false) ); @@ -2929,11 +2598,9 @@ void shouldReturnClaimantResponse_FullDefence_in1v2Scenario_whenRep2Acknowledged FULL_DEFENCE_PROCEED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(8).contains( + assertThat(stateFlow.getFlags()).hasSize(6).contains( entry("BULK_CLAIM_ENABLED", false), entry("ONE_RESPONDENT_REPRESENTATIVE", false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.IS_MULTI_TRACK.name(), true), @@ -2967,11 +2634,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterClaimIssue( PENDING_CLAIM_ISSUED.fullName(), CLAIM_ISSUED.fullName(), TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -2998,11 +2663,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterClaimIssueS PENDING_CLAIM_ISSUED.fullName(), CLAIM_ISSUED.fullName(), TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3029,11 +2692,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterClaimNotifi TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3060,11 +2721,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterClaimDetail CLAIM_DETAILS_NOTIFIED.fullName(), TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3093,11 +2752,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterClaimDetail TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3126,11 +2783,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterNotificatio TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3160,11 +2815,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterNotificatio NOTIFICATION_ACKNOWLEDGED_TIME_EXTENSION.fullName(), TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3202,12 +2855,10 @@ void shouldAwaitResponse_1v2DiffSol_whenFirstResponseIsFullDefenceAfterAcknowled TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3236,11 +2887,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflineAfterDefendantRe ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName(), TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3271,11 +2920,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflinePastClaimNotific TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3306,11 +2953,9 @@ void shouldReturnProceedsWithOfflineJourney_whenCaseTakenOfflinePastClaimDetails TAKEN_OFFLINE_BY_STAFF.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3432,11 +3077,9 @@ void shouldReturnAwaitingCamundaState_whenDeadlinePassedAfterStateClaimDetailsNo PAST_CLAIM_DISMISSED_DEADLINE_AWAITING_CAMUNDA.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3475,12 +3118,10 @@ void shouldReturnDismissedState_whenDeadlinePassedAfterClaimDetailsNotifiedExten ); assertThat(stateFlow.getFlags()) - .hasSize(5) + .hasSize(3) .contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3517,11 +3158,9 @@ void shouldReturnClaimDismissedPastDeadline_whenDeadlinePassedAfterStateNotifica PAST_CLAIM_DISMISSED_DEADLINE_AWAITING_CAMUNDA.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3554,11 +3193,9 @@ void shouldReturnDismissedState_whenDeadlinePassedAfterNotificationAcknowledgedA CLAIM_DISMISSED_PAST_CLAIM_DISMISSED_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3656,11 +3293,9 @@ void shouldReturnClaimDismissed_whenCaseDataAtStateClaimDismissed() { CLAIM_DISMISSED_PAST_CLAIM_DISMISSED_DEADLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3729,12 +3364,10 @@ void shouldGenerateDQ_1v2DiffSol_whenFirstResponseIsFullDefence() { AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3772,12 +3405,10 @@ void shouldGenerateDQ_1v2DiffSol_whenFirstResponseIsNotFullDefence() { AWAITING_RESPONSES_NOT_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3815,12 +3446,10 @@ void shouldGenerateDQ_in1v2Scenario_whenFirstPartySubmitFullDefenceResponse() { AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3859,12 +3488,10 @@ void shouldGenerateDQ_in1v2Scenario_whenSecondPartySubmitFullDefenceResponse() { AWAITING_RESPONSES_FULL_DEFENCE_RECEIVED.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3901,12 +3528,10 @@ void shouldReturnFullDefence_in1v2Scenario_whenBothPartiesSubmitFullDefenceRespo ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3944,12 +3569,10 @@ void shouldReturnFullDefence_in1v2Scenario_whenBothPartiesAcknowledgedAndSubmitF ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -3989,12 +3612,10 @@ void shouldReturnFullDefence_in1v2Scenario_whenRep1AcknowledgedAndBothSubmitFull ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -4034,13 +3655,11 @@ void shouldReturnFullDefence_in1v2Scenario_whenRep2AcknowledgedAndBothSubmitFull ALL_RESPONSES_RECEIVED.fullName(), FULL_DEFENCE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -4077,12 +3696,10 @@ void shouldReturnDivergentResponseAndGoOffline_1v2Scenario_whenFirstRespondentSu ALL_RESPONSES_RECEIVED.fullName(), DIVERGENT_RESPOND_GO_OFFLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -4121,10 +3738,8 @@ void shouldReturnDivergentResponse_in1v2SameSolicitorScenario_whenOneRespondentS ALL_RESPONSES_RECEIVED.fullName(), DIVERGENT_RESPOND_GENERATE_DQ_GO_OFFLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); @@ -4163,12 +3778,10 @@ void shouldReturnDivergentResponse_in1v2Scenario_whenNeitherRespondentSubmitsFul ALL_RESPONSES_RECEIVED.fullName(), DIVERGENT_RESPOND_GO_OFFLINE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -4206,12 +3819,10 @@ void shouldReturnAdmitsPartResponse_in1v2Scenario_whenBothRespondentsSubmitAdmit ALL_RESPONSES_RECEIVED.fullName(), FULL_ADMISSION.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", false), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry("TWO_RESPONDENT_REPRESENTATIVES", true), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -4501,12 +4112,10 @@ void shouldReturnContactDetailsChange_whenCaseDataAtStateRespondentContactDetail PENDING_CLAIM_ISSUED.fullName(), CLAIM_ISSUED.fullName(), CONTACT_DETAILS_CHANGE.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(6).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(4).contains( entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry(FlowFlag.CONTACT_DETAILS_CHANGE.name(), true), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false), entry("ONE_RESPONDENT_REPRESENTATIVE", true) ); } @@ -4686,13 +4295,10 @@ void shouldReturnInHearingReadiness_whenTransitionedFromCaseDetailsNotified() { CLAIM_DETAILS_NOTIFIED.fullName(), IN_HEARING_READINESS.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("ONE_RESPONDENT_REPRESENTATIVE", true)); } @Test @@ -4827,13 +4433,10 @@ void shouldReaturnTakenOfflineSdoNotDrawn_whenCaseDataAtStateClaimDetailsNotifie CLAIM_DETAILS_NOTIFIED.fullName(), TAKEN_OFFLINE_SDO_NOT_DRAWN.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry("ONE_RESPONDENT_REPRESENTATIVE", true), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry("ONE_RESPONDENT_REPRESENTATIVE", true)); } @Test @@ -4860,13 +4463,10 @@ void shouldReaturnTakenOfflineSdoNotDrawn_whenCaseDataAtStateClaimDetailsNotifie TAKEN_OFFLINE_SDO_NOT_DRAWN.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -4900,13 +4500,10 @@ void shouldReaturnTakenOfflineSdoNotDrawn_whenCaseDataAtStateClaimAcknowledge() TAKEN_OFFLINE_SDO_NOT_DRAWN.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test @@ -4940,13 +4537,10 @@ void shouldReaturnTakenOfflineSdoNotDrawn_whenCaseDataAtStateClaimAcknowledgeTim NOTIFICATION_ACKNOWLEDGED_TIME_EXTENSION.fullName(), TAKEN_OFFLINE_SDO_NOT_DRAWN.fullName() ); - assertThat(stateFlow.getFlags()).hasSize(5).contains( + assertThat(stateFlow.getFlags()).hasSize(3).contains( entry("ONE_RESPONDENT_REPRESENTATIVE", true), entry(FlowFlag.BULK_CLAIM_ENABLED.name(), false), - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) - ); + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false)); } @Test diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineUnspecTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineUnspecTest.java index c1491419ecb..c63730aa2ac 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineUnspecTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineUnspecTest.java @@ -43,8 +43,6 @@ public class StateFlowEngineUnspecTest { @BeforeEach void setup() { given(featureToggleService.isGeneralApplicationsEnabled()).willReturn(false); - given(featureToggleService.isCertificateOfServiceEnabled()).willReturn(false); - given(featureToggleService.isNoticeOfChangeEnabled()).willReturn(false); } static Stream caseDataStream() { @@ -119,11 +117,9 @@ void shouldContainCommonFlags_whenCaseDataAtStateClaimSubmitted(CaseData caseDat //When StateFlow stateFlow = stateFlowEngine.evaluate(caseData); - // Then Claim will have NOTICE_OF_CHANGE, GENERAL_APPLICATION_ENABLED, CERTIFICATE_OF_SERVICE and RPA_CONTINUOUS_FEED + // Then Claim will have GENERAL_APPLICATION_ENABLED and RPA_CONTINUOUS_FEED assertThat(stateFlow.getFlags()).contains( - entry(FlowFlag.NOTICE_OF_CHANGE.name(), false), - entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false), - entry(FlowFlag.CERTIFICATE_OF_SERVICE.name(), false) + entry(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), false) ); } @@ -137,7 +133,7 @@ void shouldHaveOneRespondentRepresentativeFlagsSet_whenCaseDataAtStateClaimSubmi assertThat(stateFlow.getFlags()).contains( entry(FlowFlag.ONE_RESPONDENT_REPRESENTATIVE.name(), true) ); - assertThat(stateFlow.getFlags()).hasSize(5); // bonus: if this fails, a flag was added/removed but tests were not updated + assertThat(stateFlow.getFlags()).hasSize(3); // bonus: if this fails, a flag was added/removed but tests were not updated } @ParameterizedTest(name = "{index}: The state flow flags ONE_RESPONDENT_REPRESENTATIVE " + @@ -152,7 +148,7 @@ void shouldReturnClaimSubmitted_whenCaseDataAtStateClaimSubmitted1v2DiffSoliBoth entry(FlowFlag.ONE_RESPONDENT_REPRESENTATIVE.name(), false), entry(FlowFlag.TWO_RESPONDENT_REPRESENTATIVES.name(), true) ); - assertThat(stateFlow.getFlags()).hasSize(6); // bonus: if this fails, a flag was added/removed but tests were not updated + assertThat(stateFlow.getFlags()).hasSize(4); // bonus: if this fails, a flag was added/removed but tests were not updated } public interface StubbingFn extends Function> { @@ -160,10 +156,8 @@ public interface StubbingFn extends Function commonFlagNames() { return Stream.of( - arguments(FlowFlag.NOTICE_OF_CHANGE.name(), (StubbingFn)(featureToggleService) -> when(featureToggleService.isNoticeOfChangeEnabled())), - arguments(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), (StubbingFn)(featureToggleService) -> when(featureToggleService.isGeneralApplicationsEnabled())), - arguments(FlowFlag.CERTIFICATE_OF_SERVICE.name(), (StubbingFn)(featureToggleService) -> when(featureToggleService.isCertificateOfServiceEnabled())) - ); + arguments(FlowFlag.GENERAL_APPLICATION_ENABLED.name(), + (StubbingFn)(featureToggleService) -> when(featureToggleService.isGeneralApplicationsEnabled()))); } @ParameterizedTest(name = "{index}: The feature flags are carried to the appropriate state flow flags") diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapperTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapperTest.java index b7632f0aad4..2e8789ce5ce 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapperTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/EventHistoryMapperTest.java @@ -132,94 +132,8 @@ void setup() { when(locationRefDataUtil.getPreferredCourtData(any(), any(), eq(true))).thenReturn("121"); } - @Nested - class UnrepresentedDefendant { - - @Test - void shouldPrepareMiscellaneousEvent_whenClaimWith1v1UnrepresentedDefendant() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimIssued1v1UnrepresentedDefendant().build(); - Event expectedEvent = Event.builder() - .eventSequence(1) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: Unrepresented defendant: Mr. Sole Trader") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: Unrepresented defendant: Mr. Sole Trader") - .build()) - .build(); - - var eventHistory = mapper.buildEvents(caseData); - - assertThat(eventHistory).isNotNull(); - assertThat(eventHistory) - .extracting("miscellaneous") - .asList() - .containsExactly(expectedEvent); - assertEmptyEvents( - eventHistory, - "acknowledgementOfServiceReceived", - "consentExtensionFilingDefence", - "defenceFiled", - "defenceAndCounterClaim", - "receiptOfPartAdmission", - "receiptOfAdmission", - "replyToDefence", - "directionsQuestionnaireFiled" - ); - } - - @Test - void shouldPrepareMiscellaneousEvent_whenClaimWith2UnrepresentedDefendants() { - CaseData caseData = CaseDataBuilder.builder().atStateClaimIssuedUnrepresentedDefendants().build(); - - Event expectedEvent1 = Event.builder() - .eventSequence(1) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [1 of 2 - 2020-08-01] Unrepresented defendant: Mr. Sole Trader") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [1 of 2 - 2020-08-01] " - + "Unrepresented defendant: Mr. Sole Trader") - .build()) - .build(); - - Event expectedEvent2 = Event.builder() - .eventSequence(2) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [2 of 2 - 2020-08-01] Unrepresented defendant: Mr. John Rambo") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [2 of 2 - 2020-08-01] Unrepresented defendant: Mr. John Rambo") - .build()) - .build(); - - var eventHistory = mapper.buildEvents(caseData); - - assertThat(eventHistory).isNotNull(); - assertThat(eventHistory) - .extracting("miscellaneous") - .asList() - .containsExactly(expectedEvent1, expectedEvent2); - assertEmptyEvents( - eventHistory, - "acknowledgementOfServiceReceived", - "consentExtensionFilingDefence", - "defenceFiled", - "defenceAndCounterClaim", - "receiptOfPartAdmission", - "receiptOfAdmission", - "replyToDefence", - "directionsQuestionnaireFiled" - ); - } - } - @Nested class UnregisteredDefendant { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - } @Test void shouldPrepareMiscellaneousEvent_whenClaimWith1v1UnregisteredDefendant() { @@ -306,228 +220,10 @@ void shouldPrepareMiscellaneousEvent_whenClaimWith2UnregisteredDefendants() { "directionsQuestionnaireFiled" ); } - - @Nested - class ToBeRemovedAfterNOC { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(false); - } - - @Test - void prod_shouldPrepareMiscellaneousEvent_whenClaimWith1v1UnregisteredDefendant() { - CaseData caseData = CaseDataBuilder.builder().atStateProceedsOffline1v1UnregisteredDefendant() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - Event expectedEvent = Event.builder() - .eventSequence(1) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: Unregistered defendant solicitor firm: Mr. Sole Trader") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: Unregistered defendant solicitor firm: Mr. Sole Trader") - .build()) - .build(); - - var eventHistory = mapper.buildEvents(caseData); - - assertThat(eventHistory).isNotNull(); - assertThat(eventHistory) - .extracting("miscellaneous") - .asList() - .containsExactly(expectedEvent); - assertEmptyEvents( - eventHistory, - "acknowledgementOfServiceReceived", - "consentExtensionFilingDefence", - "defenceFiled", - "defenceAndCounterClaim", - "receiptOfPartAdmission", - "receiptOfAdmission", - "replyToDefence", - "directionsQuestionnaireFiled" - ); - } - - @Test - void prod_shouldPrepareMiscellaneousEvent_whenClaimWith2UnregisteredDefendants() { - CaseData caseData = CaseDataBuilder.builder().atStateProceedsOfflineUnregisteredDefendants() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - Event expectedEvent1 = Event.builder() - .eventSequence(1) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [1 of 2 - 2020-08-01] " - + "Unregistered defendant solicitor firm: Mr. Sole Trader") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [1 of 2 - 2020-08-01] " - + "Unregistered defendant solicitor firm: Mr. Sole Trader") - .build()) - .build(); - - Event expectedEvent2 = Event.builder() - .eventSequence(2) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [2 of 2 - 2020-08-01] " - + "Unregistered defendant solicitor firm: Mr. John Rambo") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [2 of 2 - 2020-08-01] " - + "Unregistered defendant solicitor firm: Mr. John Rambo") - .build()) - .build(); - - var eventHistory = mapper.buildEvents(caseData); - - assertThat(eventHistory).isNotNull(); - assertThat(eventHistory) - .extracting("miscellaneous") - .asList() - .containsExactly(expectedEvent1, expectedEvent2); - assertEmptyEvents( - eventHistory, - "acknowledgementOfServiceReceived", - "consentExtensionFilingDefence", - "defenceFiled", - "defenceAndCounterClaim", - "receiptOfPartAdmission", - "receiptOfAdmission", - "replyToDefence", - "directionsQuestionnaireFiled" - ); - } - } } @Nested class UnrepresentedAndUnregisteredDefendant { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - } - - // Remove after NOC - @Nested - class ToBeRemovedAfterNOC { - @BeforeEach - public void setup() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(false); - } - - @Test - void prod_shouldPrepareMiscellaneousEvent_whenClaimWithUnrepresentedDefendant1UnregisteredDefendant2() { - CaseData caseData = CaseDataBuilder.builder() - .atStateProceedsOfflineUnrepresentedDefendant1UnregisteredDefendant2() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - Event expectedEvent1 = Event.builder() - .eventSequence(1) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [1 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unrepresented defendant: Mr. Sole Trader") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [1 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unrepresented defendant: Mr. Sole Trader") - .build()) - .build(); - - Event expectedEvent2 = Event.builder() - .eventSequence(2) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [2 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unregistered defendant solicitor firm: Mr. John Rambo") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [2 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unregistered defendant solicitor firm: Mr. John Rambo") - .build()) - .build(); - - var eventHistory = mapper.buildEvents(caseData); - - assertThat(eventHistory).isNotNull(); - assertThat(eventHistory) - .extracting("miscellaneous") - .asList() - .containsExactly(expectedEvent1, expectedEvent2); - assertEmptyEvents( - eventHistory, - "acknowledgementOfServiceReceived", - "consentExtensionFilingDefence", - "defenceFiled", - "defenceAndCounterClaim", - "receiptOfPartAdmission", - "receiptOfAdmission", - "replyToDefence", - "directionsQuestionnaireFiled" - ); - } - - @Test - void prod_shouldPrepareMiscellaneousEvent_whenClaimWithUnregisteredDefendant1UnrepresentedDefendant2() { - CaseData caseData = CaseDataBuilder.builder() - .atStateProceedsOfflineUnregisteredDefendant1UnrepresentedDefendant2() - .respondent1OrganisationPolicy(null) - .respondent2OrganisationPolicy(null) - .build(); - Event expectedEvent1 = Event.builder() - .eventSequence(1) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [1 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unrepresented defendant: Mr. John Rambo") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [1 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unrepresented defendant: Mr. John Rambo") - .build()) - .build(); - - Event expectedEvent2 = Event.builder() - .eventSequence(2) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [2 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unregistered defendant solicitor firm: Mr. Sole Trader") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [2 of 2 - 2020-08-01] " - + "Unrepresented defendant and unregistered defendant solicitor firm. " - + "Unregistered defendant solicitor firm: Mr. Sole Trader") - .build()) - .build(); - - var eventHistory = mapper.buildEvents(caseData); - - assertThat(eventHistory).isNotNull(); - assertThat(eventHistory) - .extracting("miscellaneous") - .asList() - .containsExactly(expectedEvent1, expectedEvent2); - assertEmptyEvents( - eventHistory, - "acknowledgementOfServiceReceived", - "consentExtensionFilingDefence", - "defenceFiled", - "defenceAndCounterClaim", - "receiptOfPartAdmission", - "receiptOfAdmission", - "replyToDefence", - "directionsQuestionnaireFiled" - ); - } - - } @Test void shouldPrepareMiscellaneousEvent_whenClaimWithUnrepresentedDefendant1UnregisteredDefendant2() { @@ -7418,56 +7114,6 @@ private void assertEmptyEvents(EventHistory eventHistory, String... eventNames) eventName -> assertThat(eventHistory).extracting(eventName).asList().containsOnly(EMPTY_EVENT)); } - @Test - public void specCaseEvents() { - CaseData caseData = CaseDataBuilder.builder() - .atStateClaimIssued1v2UnrepresentedDefendant() - .defendant1LIPAtClaimIssued(NO) - .defendant2LIPAtClaimIssued(null) - .build().toBuilder() - .caseAccessCategory(SPEC_CLAIM) - .build(); - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(false); - Event expectedEvent = Event.builder() - .eventSequence(1) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [1 of 2 - 2020-08-01] Unrepresented defendant: Mr. Sole Trader") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [1 of 2 - 2020-08-01] Unrepresented defendant: Mr. Sole Trader") - .build()) - .build(); - - Event expectedEvent2 = Event.builder() - .eventSequence(2) - .eventCode("999") - .dateReceived(caseData.getSubmittedDate()) - .eventDetailsText("RPA Reason: [2 of 2 - 2020-08-01] Unrepresented defendant: Mr. John Rambo") - .eventDetails(EventDetails.builder() - .miscText("RPA Reason: [2 of 2 - 2020-08-01] Unrepresented defendant: Mr. John Rambo") - .build()) - .build(); - - var eventHistory = mapper.buildEvents(caseData); - - assertThat(eventHistory).isNotNull(); - assertThat(eventHistory) - .extracting("miscellaneous") - .asList() - .containsExactly(expectedEvent, expectedEvent2); - assertEmptyEvents( - eventHistory, - "acknowledgementOfServiceReceived", - "consentExtensionFilingDefence", - "defenceFiled", - "defenceAndCounterClaim", - "receiptOfPartAdmission", - "receiptOfAdmission", - "replyToDefence", - "directionsQuestionnaireFiled" - ); - } - @Test void specShouldPrepareMiscellaneousEvent_whenCaseNoteAdded() { LocalDateTime noteCreatedOn = LocalDateTime.now().plusDays(3); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpecTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpecTest.java index 19c4436f400..4bf9de10713 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpecTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperForSpecTest.java @@ -5,7 +5,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Mockito; import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.ccd.model.OrganisationPolicy; import uk.gov.hmcts.reform.ccd.model.PreviousOrganisation; @@ -82,7 +81,6 @@ public void whenSpecEnabled_includeBS() { @Test public void shouldMapExpectedNoticeOfChangeData_whenCaseGoesOffline() { - Mockito.when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); var app1NocDate = LocalDateTime.parse("2022-01-01T12:00:00.000550439"); var res1NocDate = LocalDateTime.parse("2022-02-01T12:00:00.000550439"); @@ -142,8 +140,6 @@ public void shouldMapExpectedNoticeOfChangeData_whenCaseGoesOffline() { @Test public void shouldMapExpectedNoticeOfChangeData_whenCaseDismissed() { - Mockito.when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - var app1NocDate = LocalDateTime.parse("2022-01-01T12:00:00.000550439"); var res1NocDate = LocalDateTime.parse("2022-02-01T12:00:00.000550439"); var res2NocDate = LocalDateTime.parse("2022-03-01T12:00:00.000550439"); @@ -202,8 +198,6 @@ public void shouldMapExpectedNoticeOfChangeData_whenCaseDismissed() { @Test public void shouldNotPopulateNoticeOfChangeSection_whenCaseIsStillOnline() { - Mockito.when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - CaseData caseData = CaseData.builder() .legacyCaseReference("reference") .submittedDate(LocalDateTime.now().minusDays(14)) diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperTest.java index 230d1ff387c..3c5e2cd108d 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/robotics/mapper/RoboticsDataMapperTest.java @@ -399,8 +399,6 @@ void shouldReturnEmptyStringWhenPreferredCourtCodeisUnavailableFromLocationRefDa @Test void shouldMapExpectedNoticeOfChangeData_whenCaseGoesOffline() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - CaseData caseData = CaseDataBuilder.builder() .atStatePaymentSuccessful() .build().toBuilder() @@ -437,8 +435,6 @@ void shouldMapExpectedNoticeOfChangeData_whenCaseGoesOffline() { @Test void shouldMapExpectedNoticeOfChangeData_whenCaseDismissed() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - CaseData caseData = CaseDataBuilder.builder() .atStatePaymentSuccessful() .build().toBuilder() @@ -475,8 +471,6 @@ void shouldMapExpectedNoticeOfChangeData_whenCaseDismissed() { @Test void shouldNotPopulateNoticeOfChangeSection_whenCaseIsStillOnline() { - when(featureToggleService.isNoticeOfChangeEnabled()).thenReturn(true); - var app1NocDate = LocalDateTime.parse("2022-01-01T12:00:00.000550439"); var res1NocDate = LocalDateTime.parse("2022-02-01T12:00:00.000550439"); var res2NocDate = LocalDateTime.parse("2022-03-01T12:00:00.000550439"); From 23ad2eb34f9b1df87b4a172120430daa2cb0866a Mon Sep 17 00:00:00 2001 From: bhagyashreesharma90 <114094319+bhagyashreesharma90@users.noreply.github.com> Date: Thu, 23 Nov 2023 16:36:14 +0000 Subject: [PATCH 18/29] CIV-10568 Transfer WA task for GA (#3470) * CIV-10568 initial commit * CIV-10568 temp commit * CIV-10568 delete unwanted changes * CIV-10568 fix sonar * CIV-10568 fix sonar * CIV-10568 added camunda event * Update TransferOnlineCaseCallbackHandler.java * Update FlowStateAllowedEventService.java * Update FlowStateAllowedEventServiceTest.java * Update TriggerGenAppLocationUpdateCallbackHandlerTest.java * CIV-10568 add jenkins file to point ccd and camunda PR * Update Jenkinsfile_CNP * Update CaseEvent.java --------- Co-authored-by: Azam <106387766+Azam-Hmcts@users.noreply.github.com> Co-authored-by: ShwetaTandel-hmcts <130586258+ShwetaTandel-hmcts@users.noreply.github.com> --- .../reform/civil/callback/CaseEvent.java | 4 ++- ...erGenAppLocationUpdateCallbackHandler.java | 11 ++++-- .../TransferOnlineCaseCallbackHandler.java | 5 ++- ...nAppLocationUpdateCallbackHandlerTest.java | 35 +++++++++++++++++-- ...TransferOnlineCaseCallbackHandlerTest.java | 2 +- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java index a54355cea51..85bf880ebe6 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java @@ -94,6 +94,7 @@ public enum CaseEvent { GENERATE_TRIAL_READY_DOCUMENT_RESPONDENT1(USER), GENERATE_TRIAL_READY_DOCUMENT_RESPONDENT2(USER), LIP_CLAIM_SETTLED(USER), + TRIGGER_TASK_RECONFIG(USER), NOTIFY_FORMER_SOLICITOR(CAMUNDA), NOTIFY_OTHER_SOLICITOR_1(CAMUNDA), NOTIFY_OTHER_SOLICITOR_2(CAMUNDA), @@ -300,7 +301,8 @@ public enum CaseEvent { NOTIFY_LIP_RESPONDENT_CLAIMANT_CONFIRM_TO_PROCEED(CAMUNDA), NOTIFY_LIP_APPLICANT_CLAIMANT_CONFIRM_TO_PROCEED(CAMUNDA), NOTIFY_APPLICANT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT(CAMUNDA), - NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT(CAMUNDA); + NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT(CAMUNDA), + TRIGGER_TASK_RECONFIG_GA(CAMUNDA); private final UserType userType; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java index 6a7c730596d..4664afc38b7 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandler.java @@ -20,13 +20,16 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_LOCATION_UPDATE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_UPDATE_GA_LOCATION; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_TASK_RECONFIG; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_TASK_RECONFIG_GA; @Slf4j @Service @RequiredArgsConstructor public class TriggerGenAppLocationUpdateCallbackHandler extends CallbackHandler { - private static final List EVENTS = List.of(TRIGGER_UPDATE_GA_LOCATION); + private static final List EVENTS = List.of(TRIGGER_UPDATE_GA_LOCATION, + TRIGGER_TASK_RECONFIG_GA); private final GenAppStateHelperService helperService; private final ObjectMapper objectMapper; @@ -49,7 +52,11 @@ private CallbackResponse triggerGaEvent(CallbackParams callbackParams) { try { if (caseData.getGeneralApplications() != null && !caseData.getGeneralApplications().isEmpty()) { caseData = helperService.updateApplicationLocationDetailsInClaim(caseData, authToken); - helperService.triggerEvent(caseData, TRIGGER_LOCATION_UPDATE); + if (callbackParams.getRequest().getEventId().equals(TRIGGER_UPDATE_GA_LOCATION.name())) { + helperService.triggerEvent(caseData, TRIGGER_LOCATION_UPDATE); + } else if (callbackParams.getRequest().getEventId().equals(TRIGGER_TASK_RECONFIG_GA.name())) { + helperService.triggerEvent(caseData, TRIGGER_TASK_RECONFIG); + } } } catch (Exception e) { String errorMessage = "Could not trigger event to update location on application under case: " diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandler.java index 85837b957ac..9aa24b4646f 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandler.java @@ -12,6 +12,7 @@ import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.helpers.LocationHelper; +import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.common.DynamicList; import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; @@ -22,7 +23,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; - import static java.util.Objects.nonNull; import static uk.gov.hmcts.reform.civil.callback.CallbackParams.Params.BEARER_TOKEN; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; @@ -30,6 +30,7 @@ import static uk.gov.hmcts.reform.civil.callback.CallbackType.MID; import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRANSFER_ONLINE_CASE; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_TASK_RECONFIG_GA; import static uk.gov.hmcts.reform.civil.model.common.DynamicList.fromList; @Service @@ -110,10 +111,12 @@ private CallbackResponse saveTransferOnlineCase(CallbackParams callbackParams) { callbackParams.getCaseData().getTransferCourtLocationList()); if (nonNull(newCourtLocation)) { caseDataBuilder.caseManagementLocation(LocationHelper.buildCaseLocation(newCourtLocation)); + caseDataBuilder.locationName(newCourtLocation.getSiteName()); } DynamicList tempLocationList = caseData.getTransferCourtLocationList(); tempLocationList.setListItems(null); caseDataBuilder.transferCourtLocationList(tempLocationList); + caseDataBuilder.businessProcess(BusinessProcess.ready(TRIGGER_TASK_RECONFIG_GA)); return AboutToStartOrSubmitCallbackResponse.builder() .data(caseDataBuilder.build().toMap(objectMapper)) .build(); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java index 53cd99df257..b2a913e47bc 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/camunda/caseevents/TriggerGenAppLocationUpdateCallbackHandlerTest.java @@ -8,9 +8,11 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit.jupiter.SpringExtension; import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.ccd.client.model.CallbackRequest; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.sampledata.CallbackParamsBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.GeneralApplicationDetailsBuilder; import uk.gov.hmcts.reform.civil.service.GenAppStateHelperService; @@ -28,8 +30,10 @@ import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_LOCATION_UPDATE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_UPDATE_GA_LOCATION; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_TASK_RECONFIG_GA; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_LOCATION_UPDATE; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.TRIGGER_TASK_RECONFIG; @ExtendWith(SpringExtension.class) @SpringBootTest(classes = { @@ -51,6 +55,7 @@ class TriggerGenAppLocationUpdateCallbackHandlerTest extends BaseCallbackHandler @Test void handleEventsReturnsTheExpectedCallbackEvent() { assertThat(handler.handledEvents()).contains(TRIGGER_UPDATE_GA_LOCATION); + assertThat(handler.handledEvents()).contains(TRIGGER_TASK_RECONFIG_GA); } @Test @@ -63,7 +68,12 @@ void shouldTriggerGeneralApplicationEvent_whenCaseHasGeneralApplication() { getOriginalStatusOfGeneralApplication() ); when(helperService.updateApplicationLocationDetailsInClaim(any(), any())).thenReturn(caseData); - CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + CallbackParams params = CallbackParamsBuilder.builder() + .of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder() + .eventId(TRIGGER_UPDATE_GA_LOCATION.name()) + .build()) + .build(); var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); assertThat(response.getErrors()).isNull(); @@ -106,6 +116,27 @@ void triggerGeneralApplicationEventThrowsException_HandleFailure() { assertThat(response.getErrors()).contains(expectedErrorMessage); } + @Test + void shouldTriggerReconfigureWhenCallbackEventIsReconfigGA() { + CaseData caseData = GeneralApplicationDetailsBuilder.builder() + .getTestCaseDataWithDetails(CaseData.builder().build(), + true, + true, + true, true, + getOriginalStatusOfGeneralApplication() + ); + when(helperService.updateApplicationLocationDetailsInClaim(any(), any())).thenReturn(caseData); + CallbackParams callbackParams = CallbackParamsBuilder.builder() + .of(ABOUT_TO_SUBMIT, caseData) + .request(CallbackRequest.builder() + .eventId(TRIGGER_TASK_RECONFIG_GA.name()) + .build()) + .build(); + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(callbackParams); + assertThat(response.getErrors()).isNull(); + verify(helperService, times(1)).triggerEvent(caseData, TRIGGER_TASK_RECONFIG); + } + private Map getOriginalStatusOfGeneralApplication() { Map latestStatus = new HashMap<>(); latestStatus.put("1234", "Application Submitted - Awaiting Judicial Decision"); diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandlerTest.java index b68d54ff9e8..19f87d67765 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/TransferOnlineCaseCallbackHandlerTest.java @@ -228,4 +228,4 @@ void shouldReturnExpectedSubmittedCallbackResponse() { void handleEventsReturnsTheExpectedCallbackEvent() { assertThat(handler.handledEvents()).contains(CaseEvent.TRANSFER_ONLINE_CASE); } -} +} \ No newline at end of file From 2fa6327b6de1256a6a5fcc922bb293bb0bfe518b Mon Sep 17 00:00:00 2001 From: Manish Garg Date: Thu, 23 Nov 2023 17:56:21 +0000 Subject: [PATCH 19/29] CIV-8147 Sign settlement agreement: Submit Function Back end (#3501) * CIV-8147 Added functionality to save respondent sign settlement agreement * CIV-8147 Added functionality to save respondent sign settlement agreement details * CIV-8147 Revereted local env changes * CIV-8147 Changes from CIV-8291 for ResponseOneVOneShowTag * CIV-8147 Rebase with master * CIV-8147 Reverted formatting changes --------- Co-authored-by: jarekPierchala <118526007+jarekPierchala@users.noreply.github.com> --- .../reform/civil/callback/CaseEvent.java | 1 + ...ignSettlementAgreementCallbackHandler.java | 56 +++++++++++++ .../hmcts/reform/civil/model/CaseData.java | 5 ++ .../civil/model/citizenui/CaseDataLiP.java | 4 + .../service/flowstate/FlowLipPredicate.java | 3 + .../civil/service/flowstate/FlowState.java | 3 +- .../FlowStateAllowedEventService.java | 27 +++++-- .../service/flowstate/StateFlowEngine.java | 5 ++ ...ettlementAgreementCallbackHandlerTest.java | 80 +++++++++++++++++++ .../reform/civil/model/CaseDataTest.java | 30 +++++++ .../flowstate/StateFlowEngineTest.java | 76 ++++++++++++++++++ 11 files changed, 283 insertions(+), 7 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandler.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java index 85bf880ebe6..d6d83c5ee22 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java @@ -94,6 +94,7 @@ public enum CaseEvent { GENERATE_TRIAL_READY_DOCUMENT_RESPONDENT1(USER), GENERATE_TRIAL_READY_DOCUMENT_RESPONDENT2(USER), LIP_CLAIM_SETTLED(USER), + DEFENDANT_SIGN_SETTLEMENT_AGREEMENT(USER), TRIGGER_TASK_RECONFIG(USER), NOTIFY_FORMER_SOLICITOR(CAMUNDA), NOTIFY_OTHER_SOLICITOR_1(CAMUNDA), diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandler.java new file mode 100644 index 00000000000..4a721827ddb --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandler.java @@ -0,0 +1,56 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.ccd.client.model.CallbackResponse; +import uk.gov.hmcts.reform.civil.callback.Callback; +import uk.gov.hmcts.reform.civil.callback.CallbackHandler; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.model.BusinessProcess; +import uk.gov.hmcts.reform.civil.model.CaseData; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.SUBMITTED; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_SIGN_SETTLEMENT_AGREEMENT; + +@Service +@RequiredArgsConstructor +public class DefendantSignSettlementAgreementCallbackHandler extends CallbackHandler { + + private final ObjectMapper objectMapper; + + private final Map callbackMap = Map.of( + callbackKey(ABOUT_TO_START), this::emptyCallbackResponse, + callbackKey(ABOUT_TO_SUBMIT), this::aboutToSubmit, + callbackKey(SUBMITTED), this::emptySubmittedCallbackResponse); + + @Override + protected Map callbacks() { + return callbackMap; + } + + @Override + public List handledEvents() { + return Collections.singletonList( + DEFENDANT_SIGN_SETTLEMENT_AGREEMENT + ); + } + + private CallbackResponse aboutToSubmit(CallbackParams callbackParams) { + CaseData caseDataUpdated = callbackParams.getCaseData().toBuilder() + .businessProcess(BusinessProcess.ready(DEFENDANT_SIGN_SETTLEMENT_AGREEMENT)) + .build(); + + return AboutToStartOrSubmitCallbackResponse.builder() + .data(caseDataUpdated.toMap(objectMapper)) + .build(); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index f81f81988c1..7eaee138a62 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -1113,4 +1113,9 @@ public boolean hasApplicant1SignedSettlementAgreement() { .map(CaseDataLiP::getApplicant1LiPResponse) .filter(ClaimantLiPResponse::hasApplicant1SignedSettlementAgreement).isPresent(); } + + @JsonIgnore + public boolean isRespondentSignSettlementAgreement() { + return getCaseDataLiP() != null && getCaseDataLiP().getRespondentSignSettlementAgreement() != null; + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CaseDataLiP.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CaseDataLiP.java index b66b6b1ffbc..f16fd0b272b 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CaseDataLiP.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CaseDataLiP.java @@ -6,6 +6,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.common.Element; import java.util.List; @@ -33,6 +34,9 @@ public class CaseDataLiP { @JsonProperty("applicant1AdditionalLipPartyDetails") private AdditionalLipPartyDetails applicant1AdditionalLipPartyDetails; + @JsonProperty("respondentSignSettlementAgreement") + private YesOrNo respondentSignSettlementAgreement; + @JsonIgnore public boolean hasClaimantAgreedToFreeMediation() { return applicant1ClaimMediationSpecRequiredLip != null diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java index a78a97571a0..f1d9c2bcd31 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowLipPredicate.java @@ -24,4 +24,7 @@ private FlowLipPredicate() { public static final Predicate ccjRequestJudgmentByAdmission = CaseData::isCcjRequestJudgmentByAdmission; + public static final Predicate isRespondentSignSettlementAgreement = + CaseData::isRespondentSignSettlementAgreement; + } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowState.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowState.java index dd643f7bc6e..e0d1d9c4f54 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowState.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowState.java @@ -84,7 +84,8 @@ enum Main implements FlowState { IN_HEARING_READINESS, MEDIATION_UNSUCCESSFUL_PROCEED, All_FINAL_ORDERS_ISSUED, - PREPARE_FOR_HEARING_CONDUCT_HEARING; + PREPARE_FOR_HEARING_CONDUCT_HEARING, + SIGN_SETTLEMENT_AGREEMENT; public static final String FLOW_NAME = "MAIN"; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java index 9e6f7feac1c..6b3bca35ff1 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/FlowStateAllowedEventService.java @@ -41,6 +41,7 @@ import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE_CUI; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_RESPONSE_SPEC; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_SIGN_SETTLEMENT_AGREEMENT; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DISCONTINUE_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DISMISS_CLAIM; import static uk.gov.hmcts.reform.civil.callback.CaseEvent.ENTER_BREATHING_SPACE_LIP; @@ -106,6 +107,7 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.DIVERGENT_RESPOND_GO_OFFLINE; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.DRAFT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMISSION; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_ADMIT_AGREE_REPAYMENT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_DEFENCE; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_DEFENCE_NOT_PROCEED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.FULL_DEFENCE_PROCEED; @@ -115,6 +117,7 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.NOTIFICATION_ACKNOWLEDGED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.NOTIFICATION_ACKNOWLEDGED_TIME_EXTENSION; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMISSION; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_AGREE_REPAYMENT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PART_ADMIT_NOT_SETTLED_NO_MEDIATION; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PAST_APPLICANT_RESPONSE_DEADLINE_AWAITING_CAMUNDA; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PAST_CLAIM_DETAILS_NOTIFICATION_DEADLINE_AWAITING_CAMUNDA; @@ -601,11 +604,11 @@ public class FlowStateAllowedEventService { PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT.fullName(), List.of( NOC_REQUEST, - APPLY_NOC_DECISION, - TAKE_CASE_OFFLINE, - NOTIFY_DEFENDANT_OF_CLAIM, - APPLICATION_OFFLINE_UPDATE_CLAIM, - migrateCase + APPLY_NOC_DECISION, + TAKE_CASE_OFFLINE, + NOTIFY_DEFENDANT_OF_CLAIM, + APPLICATION_OFFLINE_UPDATE_CLAIM, + migrateCase ) ), entry( @@ -1257,7 +1260,7 @@ public class FlowStateAllowedEventService { asyncStitchingComplete ) ), - entry( + entry( PART_ADMIT_NOT_SETTLED_NO_MEDIATION.fullName(), List.of( ADD_DEFENDANT_LITIGATION_FRIEND, @@ -1413,6 +1416,18 @@ public class FlowStateAllowedEventService { ADD_CASE_NOTE, AMEND_PARTY_DETAILS ) + ), + entry( + PART_ADMIT_AGREE_REPAYMENT.fullName(), + List.of( + DEFENDANT_SIGN_SETTLEMENT_AGREEMENT + ) + ), + entry( + FULL_ADMIT_AGREE_REPAYMENT.fullName(), + List.of( + DEFENDANT_SIGN_SETTLEMENT_AGREEMENT + ) ) ); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java index 2ddc4c56dd5..7c3887dda80 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngine.java @@ -21,6 +21,7 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.ccjRequestJudgmentByAdmission; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.declinedMediation; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.isLipCase; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.isRespondentSignSettlementAgreement; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.isTranslatedDocumentUploaded; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowLipPredicate.partAdmitPayImmediately; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowPredicate.acceptRepaymentPlan; @@ -166,6 +167,7 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT_ONE_V_ONE_SPEC; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PENDING_CLAIM_ISSUED_UNREPRESENTED_UNREGISTERED_DEFENDANT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.RESPONDENT_RESPONSE_LANGUAGE_IS_BILINGUAL; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.SIGN_SETTLEMENT_AGREEMENT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.SPEC_DRAFT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_DETAILS_NOTIFIED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED; @@ -561,6 +563,7 @@ public StateFlow build(FlowState.Main initialState) { .state(TAKEN_OFFLINE_AFTER_SDO) .state(PART_ADMIT_AGREE_SETTLE) .state(PART_ADMIT_AGREE_REPAYMENT) + .transitionTo(SIGN_SETTLEMENT_AGREEMENT).onlyIf(isRespondentSignSettlementAgreement) .state(PART_ADMIT_REJECT_REPAYMENT) .state(PART_ADMIT_PROCEED) .state(PART_ADMIT_NOT_PROCEED) @@ -571,6 +574,7 @@ public StateFlow build(FlowState.Main initialState) { .transitionTo(TAKEN_OFFLINE_AFTER_SDO).onlyIf(takenOfflineAfterSDO) .transitionTo(TAKEN_OFFLINE_SDO_NOT_DRAWN).onlyIf(takenOfflineSDONotDrawn) .state(FULL_ADMIT_AGREE_REPAYMENT) + .transitionTo(SIGN_SETTLEMENT_AGREEMENT).onlyIf(isRespondentSignSettlementAgreement) .state(FULL_ADMIT_REJECT_REPAYMENT) .state(FULL_ADMIT_PROCEED) .state(FULL_ADMIT_NOT_PROCEED) @@ -588,6 +592,7 @@ public StateFlow build(FlowState.Main initialState) { .transitionTo(TAKEN_OFFLINE_SDO_NOT_DRAWN).onlyIf(takenOfflineSDONotDrawn) .state(IN_HEARING_READINESS) .state(FULL_ADMIT_JUDGMENT_ADMISSION) + .state(SIGN_SETTLEMENT_AGREEMENT) .build(); } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java new file mode 100644 index 00000000000..9b17a6b87d6 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/DefendantSignSettlementAgreementCallbackHandlerTest.java @@ -0,0 +1,80 @@ +package uk.gov.hmcts.reform.civil.handler.callback.user; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.reform.ccd.client.model.AboutToStartOrSubmitCallbackResponse; +import uk.gov.hmcts.reform.civil.callback.CallbackParams; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; +import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; + +import static org.assertj.core.api.Assertions.assertThat; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_START; +import static uk.gov.hmcts.reform.civil.callback.CallbackType.ABOUT_TO_SUBMIT; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.DEFENDANT_SIGN_SETTLEMENT_AGREEMENT; + +@ExtendWith(MockitoExtension.class) +public class DefendantSignSettlementAgreementCallbackHandlerTest extends BaseCallbackHandlerTest { + + private DefendantSignSettlementAgreementCallbackHandler handler; + + @BeforeEach + void setUp() { + handler = new DefendantSignSettlementAgreementCallbackHandler(new ObjectMapper()); + } + + @Test + void handleEventsReturnsTheExpectedCallbackEvent() { + assertThat(handler.handledEvents()).contains(DEFENDANT_SIGN_SETTLEMENT_AGREEMENT); + } + + @Nested + class AboutToStartCallback { + + @Test + void shouldReturnNoError_WhenAboutToStartIsInvoked() { + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder() + .respondentSignSettlementAgreement(YesOrNo.NO) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_START); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getErrors()).isNull(); + } + } + + @Nested + class AboutToSubmitCallback { + + @Test + void shouldUpdateBusinessProcess() { + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder() + .respondentSignSettlementAgreement(YesOrNo.NO) + .build()) + .build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + assertThat(response.getData()) + .extracting("businessProcess") + .extracting("camundaEvent") + .isEqualTo(DEFENDANT_SIGN_SETTLEMENT_AGREEMENT.name()); + assertThat(response.getData()) + .extracting("businessProcess") + .extracting("status") + .isEqualTo("READY"); + } + } + +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java index 6652420c25f..1a3f90ae40f 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java @@ -668,6 +668,36 @@ void shouldReturnEmptyArrayListOfManageDocumentsIfNull() { assertThat(caseData.getManageDocumentsList()).isEmpty(); } + + @Test + void shouldReturnTrueWhenRespondentSignSettlementAgreementIsNotNull() { + + //Given + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder().respondentSignSettlementAgreement(YesOrNo.NO).build()) + .build(); + + //When + boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + + //Then + assertTrue(isRespondentSignSettlementAgreement); + } + + @Test + void shouldReturnFalseWhenRespondentSignSettlementAgreementIsNull() { + + //Given + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder().build()) + .build(); + + //When + boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + + //Then + assertFalse(isRespondentSignSettlementAgreement); + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java index 95b6eeb883e..fade4561d58 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/flowstate/StateFlowEngineTest.java @@ -31,8 +31,10 @@ import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.stateflow.StateFlow; import uk.gov.hmcts.reform.civil.stateflow.model.State; + import java.time.LocalDate; import java.time.LocalDateTime; + import static java.util.Map.entry; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -83,6 +85,7 @@ import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PENDING_CLAIM_ISSUED_UNREPRESENTED_DEFENDANT_ONE_V_ONE_SPEC; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.PENDING_CLAIM_ISSUED_UNREPRESENTED_UNREGISTERED_DEFENDANT; +import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.SIGN_SETTLEMENT_AGREEMENT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.SPEC_DRAFT; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_DETAILS_NOTIFIED; import static uk.gov.hmcts.reform.civil.service.flowstate.FlowState.Main.TAKEN_OFFLINE_AFTER_CLAIM_NOTIFIED; @@ -4604,4 +4607,77 @@ void shouldContinueOnline_1v1Spec_whenDefendantIsUnrepresented() { } } + @Nested + class FromPartAdmitRepaymentAgreed { + @Test + void partAdmitRepaymentAgreedSpec() { + CaseData caseData = CaseData.builder() + // spec claim + .caseAccessCategory(SPEC_CLAIM) + // claim submitted + .submittedDate(LocalDateTime.now()) + .respondent1Represented(YES) + // payment successful + .paymentSuccessfulDate(LocalDateTime.now()) + // pending claim issued + .issueDate(LocalDate.now()) + .respondent1OrgRegistered(YES) + // claim issued + .claimNotificationDeadline(LocalDateTime.now()) + // part admit + .respondent1ResponseDate(LocalDateTime.now()) + .caseDataLiP(CaseDataLiP.builder().respondentSignSettlementAgreement(YES) + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder().hasAgreedFreeMediation(MediationDecision.No).build()) + .build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .claimNotificationDate(LocalDateTime.now()) + .responseClaimTrack(AllocatedTrack.SMALL_CLAIM.name()) + .applicant1PartAdmitConfirmAmountPaidSpec(YES) + .ccdState(CaseState.All_FINAL_ORDERS_ISSUED) + .applicant1AcceptFullAdmitPaymentPlanSpec(YES) + .build(); + + // When + StateFlow fullState = stateFlowEngine.evaluate(caseData); + + // Then + assertEquals(SIGN_SETTLEMENT_AGREEMENT.fullName(), fullState.getState().getName()); + } + } + + @Nested + class FromFullAdmitRepaymentAgreed { + @Test + void fullAdmitRepaymentAgreedSpec() { + CaseData caseData = CaseData.builder() + // spec claim + .caseAccessCategory(SPEC_CLAIM) + .submittedDate(LocalDateTime.now()) + .respondent1Represented(YES) + // payment successful + .paymentSuccessfulDate(LocalDateTime.now()) + // pending claim issued + .issueDate(LocalDate.now()) + .respondent1OrgRegistered(YES) + // claim issued + .claimNotificationDeadline(LocalDateTime.now()) + // part admit + .respondent1ResponseDate(LocalDateTime.now()) + .caseDataLiP(CaseDataLiP.builder().respondentSignSettlementAgreement(YES) + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder().hasAgreedFreeMediation(MediationDecision.No).build()) + .build()) + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_ADMISSION) + .claimNotificationDate(LocalDateTime.now()) + .responseClaimTrack(AllocatedTrack.SMALL_CLAIM.name()) + .ccdState(CaseState.All_FINAL_ORDERS_ISSUED) + .applicant1AcceptFullAdmitPaymentPlanSpec(YES) + .build(); + + // When + StateFlow fullState = stateFlowEngine.evaluate(caseData); + + // Then + assertEquals(SIGN_SETTLEMENT_AGREEMENT.fullName(), fullState.getState().getName()); + } + } } From 35c78cfe4a30262b9bde1bf90690051a08c76b60 Mon Sep 17 00:00:00 2001 From: Omaira-Melo-Hmcts <148855113+Omaira-Melo-Hmcts@users.noreply.github.com> Date: Thu, 23 Nov 2023 18:35:06 +0000 Subject: [PATCH 20/29] CIV-8324 Adding the new option to PersonalInjuryType. Occurs a error when trying to calculate de fee if not exists. (#3594) Co-authored-by: krishnanuthalapati <32389208+krishnanuthalapati@users.noreply.github.com> Co-authored-by: Azam <106387766+Azam-Hmcts@users.noreply.github.com> --- .../java/uk/gov/hmcts/reform/civil/enums/PersonalInjuryType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/enums/PersonalInjuryType.java b/src/main/java/uk/gov/hmcts/reform/civil/enums/PersonalInjuryType.java index 14e611b322d..0ac4ac0b110 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/enums/PersonalInjuryType.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/enums/PersonalInjuryType.java @@ -6,5 +6,6 @@ public enum PersonalInjuryType { PUBLIC_LIABILITY, HOLIDAY_ILLNESS, DISEASE_CLAIM, + NOISE_INDUCED_HEARING_LOSS, PERSONAL_INJURY_OTHER } From c7dd08fae0b7452ec57a3031995814d0e2595aa0 Mon Sep 17 00:00:00 2001 From: sherlynkhaw Date: Fri, 24 Nov 2023 09:11:49 +0000 Subject: [PATCH 21/29] Make manage contact information event available for caseworkers in awaiting defendant acknowledgmement state (#3618) --- .../user/ManageContactInformationCallbackHandler.java | 7 ++++--- .../user/ManageContactInformationCallbackHandlerTest.java | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java index b44285833c5..3100b3e1253 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandler.java @@ -46,6 +46,7 @@ import static uk.gov.hmcts.reform.civil.callback.CaseEvent.MANAGE_CONTACT_INFORMATION; import static uk.gov.hmcts.reform.civil.enums.CaseCategory.SPEC_CLAIM; import static uk.gov.hmcts.reform.civil.enums.CaseState.AWAITING_APPLICANT_INTENTION; +import static uk.gov.hmcts.reform.civil.enums.CaseState.AWAITING_RESPONDENT_ACKNOWLEDGEMENT; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.ONE_V_TWO_TWO_LEGAL_REP; import static uk.gov.hmcts.reform.civil.enums.MultiPartyScenario.getMultiPartyScenario; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.NO; @@ -129,7 +130,7 @@ private CallbackResponse prepareEvent(CallbackParams callbackParams) { UserInfo userInfo = userService.getUserInfo(authToken); boolean isAdmin = isAdmin(authToken); - List errors = isAwaitingClaimantIntention(caseData) + List errors = isBeforeAwaitingApplicantIntention(caseData) && !isAdmin ? List.of(INVALID_CASE_STATE_ERROR) : null; if (errors != null) { @@ -495,8 +496,8 @@ private SubmittedCallbackResponse buildConfirmation(CallbackParams callbackParam .build(); } - private boolean isAwaitingClaimantIntention(CaseData caseData) { - return caseData.getCcdState().equals(AWAITING_APPLICANT_INTENTION); + private boolean isBeforeAwaitingApplicantIntention(CaseData caseData) { + return caseData.getCcdState().equals(AWAITING_APPLICANT_INTENTION) || caseData.getCcdState().equals(AWAITING_RESPONDENT_ACKNOWLEDGEMENT); } private boolean isAdmin(String userAuthToken) { diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java index 5efbacd0c02..0cdec436412 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/ManageContactInformationCallbackHandlerTest.java @@ -7,6 +7,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -147,10 +148,11 @@ void shouldNotReturnReturnErrors_WhenAboutToStartIsInvokedByAdminUserWhileCaseIn assertNull(response.getErrors()); } - @Test - void shouldReturnErrors_WhenAboutToStartIsInvokedByNonAdminUserWhileCaseInAwaitingApplicantIntentionState() { + @ParameterizedTest + @EnumSource(value = CaseState.class, names = {"AWAITING_RESPONDENT_ACKNOWLEDGEMENT", "AWAITING_APPLICANT_INTENTION"}) + void shouldReturnErrors_WhenAboutToStartIsInvokedByNonAdminUserWhileCaseInAwaitingRespondentAcknowledgementState(CaseState states) { when(userService.getUserInfo(anyString())).thenReturn(LEGAL_REP_USER); - CaseData caseData = CaseData.builder().ccdState(CaseState.AWAITING_APPLICANT_INTENTION) + CaseData caseData = CaseData.builder().ccdState(states) .ccdCaseReference(123L) .build(); CallbackParams params = callbackParamsOf(caseData, CallbackType.ABOUT_TO_START); From 21c9d4ec8cdde22a5ed85f23a912cfe82e995efe Mon Sep 17 00:00:00 2001 From: MMNycz <94067802+MMNycz@users.noreply.github.com> Date: Fri, 24 Nov 2023 10:12:45 +0000 Subject: [PATCH 22/29] CIV-11363 add option to retrigger cases (#3608) * CIV-11363 add option to retrigger cases * add tests * Update tests * update tests * CIV-11363 exclude unit tests tested in local using camunda * add cpd exclusions * CIV-11363 remove unused Handler * update with test case * Update caseIdForRetrigger.txt * CIV-11363 change event name * CIV-11363 revert event name to RETRIGGER_CASES * CIV-11363 update caseIfForRetrigger with one test case * CIV-11363 --------- Co-authored-by: Azam <106387766+Azam-Hmcts@users.noreply.github.com> --- build.gradle | 2 +- .../reform/civil/callback/CaseEvent.java | 3 +- ...r.java => RetriggerCasesEventHandler.java} | 29 ++++++++----------- ...r.java => RetriggerCasesTaskListener.java} | 10 +++---- src/main/resources/caseIdForRetrigger.txt | 1 + 5 files changed, 21 insertions(+), 24 deletions(-) rename src/main/java/uk/gov/hmcts/reform/civil/handler/{ResendNotifyRPAEventsHandler.java => RetriggerCasesEventHandler.java} (75%) rename src/main/java/uk/gov/hmcts/reform/civil/service/tasklisteners/{ResendNotifyRPAEventsTaskListener.java => RetriggerCasesTaskListener.java} (50%) create mode 100644 src/main/resources/caseIdForRetrigger.txt diff --git a/build.gradle b/build.gradle index 2e0219c4e14..4cf7766b450 100644 --- a/build.gradle +++ b/build.gradle @@ -314,7 +314,7 @@ sonarqube { property "sonar.projectName", "CIVIL :: service" property "sonar.projectKey", "civil-service" property "sonar.coverage.jacoco.xmlReportPaths", "${jacocoTestReport.reports.xml.destination.path}" - property "sonar.coverage.exclusions", "**/model/**, **/config/**/*Configuration.java, **/testingsupport/**, **/*ExternalTaskListener.java, **/*BaseExternalTaskHandler.java, **/stereotypes/**, **/*Exception.java, **/EventHistoryMapper*.java, **/model/hearingvalues/**, **/enums/hearing/**, **/fees/client/**, **/enums/sdo/**, **/service/PaymentsService.java" + property "sonar.coverage.exclusions", "**/model/**, **/config/**/*Configuration.java, **/testingsupport/**, **/*ExternalTaskListener.java, **/*BaseExternalTaskHandler.java, **/stereotypes/**, **/*Exception.java, **/EventHistoryMapper*.java, **/model/hearingvalues/**, **/enums/hearing/**, **/fees/client/**, **/enums/sdo/**, **/service/PaymentsService.java, **/RetriggerCases*.java" property "sonar.cpd.exclusions", "**/*DocumentManagementService.java, **/*Spec*.java" property "sonar.exclusions", "**/hmc/model/**, **/model/hearingvalues/**" property "sonar.host.url", "https://sonar.reform.hmcts.net/" diff --git a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java index d6d83c5ee22..f1ee5498ce0 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/callback/CaseEvent.java @@ -303,8 +303,9 @@ public enum CaseEvent { NOTIFY_LIP_APPLICANT_CLAIMANT_CONFIRM_TO_PROCEED(CAMUNDA), NOTIFY_APPLICANT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT(CAMUNDA), NOTIFY_RESPONDENT1_FOR_REQUEST_JUDGEMENT_BY_ADMISSION_LIP_CLAIMANT(CAMUNDA), - TRIGGER_TASK_RECONFIG_GA(CAMUNDA); + TRIGGER_TASK_RECONFIG_GA(CAMUNDA), + RETRIGGER_CASES(CAMUNDA); private final UserType userType; public boolean isCamundaEvent() { diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/ResendNotifyRPAEventsHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandler.java similarity index 75% rename from src/main/java/uk/gov/hmcts/reform/civil/handler/ResendNotifyRPAEventsHandler.java rename to src/main/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandler.java index 7479189bf39..08e6562df3a 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/ResendNotifyRPAEventsHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandler.java @@ -23,49 +23,44 @@ import java.util.function.Predicate; import java.util.stream.Collectors; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_RPA_ON_CONTINUOUS_FEED; -import static uk.gov.hmcts.reform.civil.callback.CaseEvent.NOTIFY_RPA_ON_CASE_HANDED_OFFLINE; +import static uk.gov.hmcts.reform.civil.callback.CaseEvent.RETRIGGER_CASES; @Slf4j @RequiredArgsConstructor @Component -public class ResendNotifyRPAEventsHandler implements BaseExternalTaskHandler { +public class RetriggerCasesEventHandler implements BaseExternalTaskHandler { private final CoreCaseDataService coreCaseDataService; @Override public void handleTask(ExternalTask externalTask) { log.info("User authentication successful."); - var caseIdForNotifyRpaOnCaseHandedOffline = readCaseIds("/caseIdForNotifyRpaOnCaseHandedOffline.txt"); - updateCaseByEvent(caseIdForNotifyRpaOnCaseHandedOffline, NOTIFY_RPA_ON_CASE_HANDED_OFFLINE); - - var caseIdForNotifyRpaOnContinuousFeed = readCaseIds("/caseIdForNotifyRpaOnContinuousFeed.txt"); - updateCaseByEvent(caseIdForNotifyRpaOnContinuousFeed, NOTIFY_RPA_ON_CONTINUOUS_FEED); - + var caseIdForNotifyRpaOnCaseHandedOffline = readCaseIds("/caseIdForRetrigger.txt"); + updateCaseByEvent(caseIdForNotifyRpaOnCaseHandedOffline, RETRIGGER_CASES); } private void updateCaseByEvent(List caseIdList, CaseEvent caseEvent) { if (caseIdList != null && !caseIdList.isEmpty()) { - log.info("Resend notify RPA started for event: {}", caseEvent); + log.info("Retrigger cases started for event: {}", caseEvent); caseIdList.forEach(caseId -> { try { - log.info("Resend CaseId: {} started", caseId); + log.info("Retrigger CaseId: {} started", caseId); var startEventResponse = coreCaseDataService.startUpdate(caseId, caseEvent); Map caseDataMap = coreCaseDataService.getCase(Long.valueOf(caseId)).getData(); coreCaseDataService.submitUpdate(caseId, caseDataContent(startEventResponse, caseDataMap)); - log.info("Resend CaseId: {} finished", caseId); + log.info("Retrigger CaseId: {} finished", caseId); } catch (FeignException e) { - log.error("ERROR Resend CaseId: {}", caseId); + log.error("ERROR Retrigger CaseId: {}", caseId); log.error(String.format("Updating case data failed: %s", e.contentUTF8())); throw e; } catch (Exception e) { - log.error("ERROR Resend CaseId: {}", caseId); + log.error("ERROR Retrigger CaseId: {}", caseId); log.error(String.format("Updating case data failed: %s", e.getMessage())); } - log.info("Resend notify RPA Finished for event: {}", caseEvent); + log.info("Retrigger cases Finished for event: {}", caseEvent); }); } else { log.info("List id empty for: {}", caseEvent); @@ -84,7 +79,7 @@ private CaseDataContent caseDataContent(StartEventResponse startEventResponse, M .build(); } - private List readCaseIds(String file) { + public List readCaseIds(String file) { String data = readString(file); return Arrays.stream(data.split("[\r\n]+")) @@ -99,7 +94,7 @@ private String readString(String resourcePath) { } private byte[] readBytes(String resourcePath) { - try (InputStream inputStream = ResendNotifyRPAEventsHandler.class.getResourceAsStream(resourcePath)) { + try (InputStream inputStream = RetriggerCasesEventHandler.class.getResourceAsStream(resourcePath)) { return IOUtils.toByteArray(inputStream); } catch (IOException e) { throw new IllegalStateException(e); diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/tasklisteners/ResendNotifyRPAEventsTaskListener.java b/src/main/java/uk/gov/hmcts/reform/civil/service/tasklisteners/RetriggerCasesTaskListener.java similarity index 50% rename from src/main/java/uk/gov/hmcts/reform/civil/service/tasklisteners/ResendNotifyRPAEventsTaskListener.java rename to src/main/java/uk/gov/hmcts/reform/civil/service/tasklisteners/RetriggerCasesTaskListener.java index 8fe17b89291..3b62da4de96 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/tasklisteners/ResendNotifyRPAEventsTaskListener.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/tasklisteners/RetriggerCasesTaskListener.java @@ -4,16 +4,16 @@ import org.camunda.bpm.client.topic.TopicSubscriptionBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import uk.gov.hmcts.reform.civil.handler.ResendNotifyRPAEventsHandler; +import uk.gov.hmcts.reform.civil.handler.RetriggerCasesEventHandler; @Component -public class ResendNotifyRPAEventsTaskListener { +public class RetriggerCasesTaskListener { - private static final String TOPIC = "RESEND_NOTIFY_RPA_EVENTS"; + private static final String TOPIC = "RETRIGGER_CASES_EVENTS"; @Autowired - private ResendNotifyRPAEventsTaskListener(ResendNotifyRPAEventsHandler resendNotifyRPAEventsHandler, ExternalTaskClient client) { + private RetriggerCasesTaskListener(RetriggerCasesEventHandler retriggerCasesEventHandler, ExternalTaskClient client) { TopicSubscriptionBuilder subscriptionBuilder = client.subscribe(TOPIC); - subscriptionBuilder.handler(resendNotifyRPAEventsHandler).open(); + subscriptionBuilder.handler(retriggerCasesEventHandler).open(); } } diff --git a/src/main/resources/caseIdForRetrigger.txt b/src/main/resources/caseIdForRetrigger.txt new file mode 100644 index 00000000000..301cfca6940 --- /dev/null +++ b/src/main/resources/caseIdForRetrigger.txt @@ -0,0 +1 @@ +1693404277952499 From dbbbd1f5b9f2dc1e80d352fcd24f46065e381b9f Mon Sep 17 00:00:00 2001 From: LTurkingtonHMCTS <95024266+LTurkingtonHMCTS@users.noreply.github.com> Date: Fri, 24 Nov 2023 11:18:26 +0000 Subject: [PATCH 23/29] CIV-11159 Update Hearing Notices (#3538) * CIV-11159 Update Hearing Notices --------- Co-authored-by: Hemanth Potipati Co-authored-by: Douglas Rice Co-authored-by: mounikahmcts <43175082+mounikahmcts@users.noreply.github.com> --- .../templates/CV-UNS-HNO-ENG-01200.docx | Bin 48232 -> 42130 bytes .../templates/CV-UNS-HNO-ENG-01201.docx | Bin 0 -> 41682 bytes .../templates/CV-UNS-HNO-ENG-01202.docx | Bin 0 -> 41391 bytes .../templates/CV-UNS-HNO-ENG-01203.docx | Bin 0 -> 37914 bytes .../templates/CV-UNS-HNO-ENG-01204.docx | Bin 0 -> 37304 bytes .../service/docmosis/DocmosisTemplates.java | 4 + .../hearing/HearingFormGenerator.java | 38 ++- .../hearing/HearingFormGeneratorTest.java | 230 +++++++++++++++++- 8 files changed, 262 insertions(+), 10 deletions(-) create mode 100644 docker/docmosis/templates/CV-UNS-HNO-ENG-01201.docx create mode 100644 docker/docmosis/templates/CV-UNS-HNO-ENG-01202.docx create mode 100644 docker/docmosis/templates/CV-UNS-HNO-ENG-01203.docx create mode 100644 docker/docmosis/templates/CV-UNS-HNO-ENG-01204.docx diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01200.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01200.docx index 56e1165f73de818f00e7fa5d335e2ed592b8d6d8..864bb9ebb62dadc12833c88f6ff0b71192026784 100644 GIT binary patch delta 15976 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 I{`2<#1Lx6;BLDyZ delta 22220 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%0D%Z#dvce}vM!C%9FfVTG-JI7` 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 diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01201.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01201.docx new file mode 100644 index 0000000000000000000000000000000000000000..78cc5d54741bde1c712375a5a4c5cbc28e301572 GIT binary patch literal 41682 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 literal 0 HcmV?d00001 diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01202.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01202.docx new file mode 100644 index 0000000000000000000000000000000000000000..0409b5c1e6f8382dd2121f5473384b2517e9a687 GIT binary patch literal 41391 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%0D4k3f^vg0v7KUf~?GDaI_cBsGlqOw4?O!CnqrSX0 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 literal 0 HcmV?d00001 diff --git a/docker/docmosis/templates/CV-UNS-HNO-ENG-01203.docx b/docker/docmosis/templates/CV-UNS-HNO-ENG-01203.docx new file mode 100644 index 0000000000000000000000000000000000000000..45d3ad6dff5a737e382e2f2a7e60e265800031d4 GIT binary patch literal 37914 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 private final DocumentManagementService documentManagementService; private final DocumentGeneratorService documentGeneratorService; private final AssignCategoryId assignCategoryId; + private final FeatureToggleService featureToggleService; private final LocationRefDataService locationRefDataService; private final CourtLocationUtils courtLocationUtils; @@ -121,15 +128,28 @@ private boolean checkReference(CaseData caseData) { } private DocmosisTemplates getTemplate(CaseData caseData) { - switch (caseData.getHearingNoticeList()) { - case SMALL_CLAIMS: - return HEARING_SMALL_CLAIMS; - case FAST_TRACK_TRIAL: - return HEARING_FAST_TRACK; - case HEARING_OF_APPLICATION: - return HEARING_APPLICATION; - default: - return HEARING_OTHER; + if (!featureToggleService.isAutomatedHearingNoticeEnabled()) { + switch (caseData.getHearingNoticeList()) { + case SMALL_CLAIMS: + return HEARING_SMALL_CLAIMS; + case FAST_TRACK_TRIAL: + return HEARING_FAST_TRACK; + case HEARING_OF_APPLICATION: + return HEARING_APPLICATION; + default: + return HEARING_OTHER; + } + } else { + switch (caseData.getHearingNoticeList()) { + case SMALL_CLAIMS: + return HEARING_SMALL_CLAIMS_AHN; + case FAST_TRACK_TRIAL: + return HEARING_FAST_TRACK_AHN; + case HEARING_OF_APPLICATION: + return HEARING_APPLICATION_AHN; + default: + return HEARING_OTHER_AHN; + } } } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java index 7bdb3603865..d817d478715 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/hearing/HearingFormGeneratorTest.java @@ -22,6 +22,7 @@ import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDocumentBuilder; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; import uk.gov.hmcts.reform.civil.documentmanagement.UnsecuredDocumentManagementService; import uk.gov.hmcts.reform.civil.utils.AssignCategoryId; @@ -38,6 +39,13 @@ import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.DEFAULT_JUDGMENT; import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.HEARING_FORM; import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_APPLICATION; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_APPLICATION_AHN; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_FAST_TRACK; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_FAST_TRACK_AHN; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_OTHER; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_OTHER_AHN; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_SMALL_CLAIMS; +import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.HEARING_SMALL_CLAIMS_AHN; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { @@ -51,6 +59,13 @@ public class HearingFormGeneratorTest { private static final byte[] bytes = {1, 2, 3, 4, 5, 6}; private static final String fileName_application = String.format( HEARING_APPLICATION.getDocumentTitle(), REFERENCE_NUMBER); + private static final String fileName_small_claim = String.format( + HEARING_SMALL_CLAIMS.getDocumentTitle(), REFERENCE_NUMBER); + private static final String fileName_fast_track = String.format( + HEARING_FAST_TRACK.getDocumentTitle(), REFERENCE_NUMBER); + private static final String fileName_other_claim = String.format( + HEARING_OTHER.getDocumentTitle(), REFERENCE_NUMBER); + private static final CaseDocument CASE_DOCUMENT = CaseDocumentBuilder.builder() .documentName(fileName_application) .documentType(DEFAULT_JUDGMENT) @@ -63,14 +78,17 @@ public class HearingFormGeneratorTest { @MockBean private AssignCategoryId assignCategoryId; @MockBean + FeatureToggleService featureToggleService; + @MockBean private LocationRefDataService locationRefDataService; @MockBean private CourtLocationUtils courtLocationUtils; + @Autowired private HearingFormGenerator generator; @Test - void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided() { + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_application() { when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_APPLICATION))) .thenReturn(new DocmosisDocument(HEARING_APPLICATION.getDocumentTitle(), bytes)); when(documentManagementService @@ -78,6 +96,126 @@ void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided() { .thenReturn(CASE_DOCUMENT); when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(false); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .listingOrRelisting(ListingOrRelisting.LISTING) + .totalClaimAmount(new BigDecimal(2000)) + .build().toBuilder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder().label("County Court").build()) + .build()) + .hearingTimeHourMinute("0800") + .channel(HearingChannel.IN_PERSON) + .hearingDuration(HearingDuration.DAY_1) + .hearingNoticeList(HearingNoticeList.HEARING_OF_APPLICATION).build(); + List caseDocuments = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocuments.size()).isEqualTo(1); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, HEARING_FORM)); + } + + @Test + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_small_claims() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_SMALL_CLAIMS))) + .thenReturn(new DocmosisDocument(HEARING_SMALL_CLAIMS.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_small_claim, bytes, HEARING_FORM))) + .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(false); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .listingOrRelisting(ListingOrRelisting.LISTING) + .totalClaimAmount(new BigDecimal(2000)) + .build().toBuilder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder().label("County Court").build()) + .build()) + .hearingTimeHourMinute("0800") + .channel(HearingChannel.IN_PERSON) + .hearingDuration(HearingDuration.DAY_1) + .hearingNoticeList(HearingNoticeList.SMALL_CLAIMS).build(); + List caseDocuments = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocuments.size()).isEqualTo(1); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_small_claim, bytes, HEARING_FORM)); + } + + @Test + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_fast_track() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_FAST_TRACK))) + .thenReturn(new DocmosisDocument(HEARING_FAST_TRACK.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_fast_track, bytes, HEARING_FORM))) + .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(false); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .listingOrRelisting(ListingOrRelisting.LISTING) + .totalClaimAmount(new BigDecimal(2000)) + .build().toBuilder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder().label("County Court").build()) + .build()) + .hearingTimeHourMinute("0800") + .channel(HearingChannel.IN_PERSON) + .hearingDuration(HearingDuration.DAY_1) + .hearingNoticeList(HearingNoticeList.FAST_TRACK_TRIAL).build(); + List caseDocuments = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocuments.size()).isEqualTo(1); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_fast_track, bytes, HEARING_FORM)); + } + + @Test + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_oher() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_OTHER))) + .thenReturn(new DocmosisDocument(HEARING_OTHER.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_other_claim, bytes, HEARING_FORM))) + .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(false); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .listingOrRelisting(ListingOrRelisting.LISTING) + .totalClaimAmount(new BigDecimal(2000)) + .build().toBuilder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder().label("County Court").build()) + .build()) + .hearingTimeHourMinute("0800") + .channel(HearingChannel.IN_PERSON) + .hearingDuration(HearingDuration.DAY_1) + .hearingNoticeList(HearingNoticeList.OTHER).build(); + List caseDocuments = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocuments.size()).isEqualTo(1); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_other_claim, bytes, HEARING_FORM)); + } + + @Test + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_application_ahn() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_APPLICATION_AHN))) + .thenReturn(new DocmosisDocument(HEARING_APPLICATION_AHN.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, HEARING_FORM))) + .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(true); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() .listingOrRelisting(ListingOrRelisting.LISTING) .totalClaimAmount(new BigDecimal(2000)) @@ -95,4 +233,94 @@ void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided() { verify(documentManagementService) .uploadDocument(BEARER_TOKEN, new PDF(fileName_application, bytes, HEARING_FORM)); } + + @Test + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_small_claims_ahn() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_SMALL_CLAIMS_AHN))) + .thenReturn(new DocmosisDocument(HEARING_SMALL_CLAIMS_AHN.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_small_claim, bytes, HEARING_FORM))) + .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(true); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .listingOrRelisting(ListingOrRelisting.LISTING) + .totalClaimAmount(new BigDecimal(2000)) + .build().toBuilder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder().label("County Court").build()) + .build()) + .hearingTimeHourMinute("0800") + .channel(HearingChannel.IN_PERSON) + .hearingDuration(HearingDuration.DAY_1) + .hearingNoticeList(HearingNoticeList.SMALL_CLAIMS).build(); + List caseDocuments = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocuments.size()).isEqualTo(1); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_small_claim, bytes, HEARING_FORM)); + } + + @Test + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_fast_track_ahn() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_FAST_TRACK_AHN))) + .thenReturn(new DocmosisDocument(HEARING_FAST_TRACK_AHN.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_fast_track, bytes, HEARING_FORM))) + .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(true); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .listingOrRelisting(ListingOrRelisting.LISTING) + .totalClaimAmount(new BigDecimal(2000)) + .build().toBuilder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder().label("County Court").build()) + .build()) + .hearingTimeHourMinute("0800") + .channel(HearingChannel.IN_PERSON) + .hearingDuration(HearingDuration.DAY_1) + .hearingNoticeList(HearingNoticeList.FAST_TRACK_TRIAL).build(); + List caseDocuments = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocuments.size()).isEqualTo(1); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_fast_track, bytes, HEARING_FORM)); + } + + @Test + void shouldHearingFormGeneratorOneForm_whenValidDataIsProvided_hearing_other_ahn() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(HEARING_OTHER_AHN))) + .thenReturn(new DocmosisDocument(HEARING_OTHER_AHN.getDocumentTitle(), bytes)); + + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileName_other_claim, bytes, HEARING_FORM))) + .thenReturn(CASE_DOCUMENT); + when(courtLocationUtils.findPreferredLocationData(any(), any())).thenReturn(LocationRefData.builder().build()); + + when(featureToggleService.isAutomatedHearingNoticeEnabled()).thenReturn(true); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged() + .listingOrRelisting(ListingOrRelisting.LISTING) + .totalClaimAmount(new BigDecimal(2000)) + .build().toBuilder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.builder().label("County Court").build()) + .build()) + .hearingTimeHourMinute("0800") + .channel(HearingChannel.IN_PERSON) + .hearingDuration(HearingDuration.DAY_1) + .hearingNoticeList(HearingNoticeList.OTHER).build(); + List caseDocuments = generator.generate(caseData, BEARER_TOKEN); + + assertThat(caseDocuments.size()).isEqualTo(1); + + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileName_other_claim, bytes, HEARING_FORM)); + } } From e991d219912dbe1a26f97cb8dc64d8ef4caaaaa1 Mon Sep 17 00:00:00 2001 From: hmcts-version1-ignacio <107860328+hmcts-version1-ignacio@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:17:45 +0000 Subject: [PATCH 24/29] CIV-8155 Enter flight details screen (#3520) * CIV-11150 Add new handler * CIV-11150 Add new handler * CIV-11150 Fix sonar issues * CIV-11150 Add new test and new changes * CIV-11150 Add new test and new changes * CIV-11150 Fix sonar issue * CIV-11150 Add claimType modifyer * CIV-8155 enter flight delay details list and validations * CIV-8155 Add tests * CIV-8155 Add flightDelay object * CIV-8155 Fix imports * CIV-8155 Fix imports * CIV-8155 Fix tests * CIV-8155 Add airlines * CIV-8155 Add airlines and locations * CIV-8155 Fix airline locations and add tests * CIV-8155 Fix sonar issues * CIV-8155 Fix sonar issues * CIV-8155 Fix tests * CIV-8155 Add csv file read * CIV-8155 update dropdown and locations functionality * CIV-8155 change type for flightCourtLocation variable * CIV-8155 changes in the variables stored in caseData * CIV-8155 update tests * CIV-8155 update tests * CIV-8155 update tests * CIV-8155 update tests * CIV-8155 update tests * Fixing PR build issues Fixing PR build issues * CIV-8155 update tests * CIV-8155 update tests * CIV-8155 update tests * CIV-8155 fix sonar issues * CIV-8155 refactoring * CIV-8155 refactoring test * CIV-8155 add temporary suppression * CIV-8155 remove suppression --------- Co-authored-by: Azam <106387766+Azam-Hmcts@users.noreply.github.com> Co-authored-by: ShwetaTandel-hmcts --- build.gradle | 4 + .../user/CreateClaimSpecCallbackHandler.java | 82 ++++++++++- .../reform/civil/model/AirlineEpimsId.java | 14 ++ .../hmcts/reform/civil/model/CaseData.java | 1 + .../civil/model/FlightDelayDetails.java | 23 ++++ .../civil/service/AirlineEpimsDataLoader.java | 44 ++++++ .../civil/service/AirlineEpimsService.java | 22 +++ .../airline_ePimsID_csv/airline_ePimsID.csv | 100 ++++++++++++++ .../CreateClaimSpecCallbackHandlerTest.java | 130 +++++++++++++++++- .../civil/sampledata/CaseDataBuilder.java | 9 ++ .../service/AirlineEpimsDataLoaderTest.java | 27 ++++ .../service/AirlineEpimsServiceTest.java | 64 +++++++++ 12 files changed, 518 insertions(+), 2 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/model/AirlineEpimsId.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/model/FlightDelayDetails.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoader.java create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsService.java create mode 100644 src/main/resources/airline_ePimsID_csv/airline_ePimsID.csv create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoaderTest.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsServiceTest.java diff --git a/build.gradle b/build.gradle index 4cf7766b450..c8f9c7a8400 100644 --- a/build.gradle +++ b/build.gradle @@ -496,6 +496,10 @@ dependencies { integrationTestImplementation sourceSets.main.runtimeClasspath integrationTestImplementation sourceSets.test.runtimeClasspath + // https://mvnrepository.com/artifact/com.opencsv/opencsv + implementation group: 'com.opencsv', name: 'opencsv', version: '5.8', { + exclude group: 'commons-collections', module: 'commons-collections' + } } mainClassName = 'uk.gov.hmcts.reform.civil.Application' diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java index 7b1929169e4..43e1f27e4f0 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandler.java @@ -11,6 +11,7 @@ import uk.gov.hmcts.reform.ccd.client.model.SubmittedCallbackResponse; import uk.gov.hmcts.reform.ccd.model.OrganisationPolicy; import uk.gov.hmcts.reform.civil.callback.Callback; +import uk.gov.hmcts.reform.civil.callback.CallbackException; import uk.gov.hmcts.reform.civil.callback.CallbackHandler; import uk.gov.hmcts.reform.civil.callback.CallbackParams; import uk.gov.hmcts.reform.civil.callback.CaseEvent; @@ -20,12 +21,15 @@ import uk.gov.hmcts.reform.civil.enums.ClaimType; import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.model.Address; +import uk.gov.hmcts.reform.civil.service.AirlineEpimsDataLoader; +import uk.gov.hmcts.reform.civil.model.AirlineEpimsId; import uk.gov.hmcts.reform.civil.model.BusinessProcess; import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.CaseManagementCategory; import uk.gov.hmcts.reform.civil.model.CaseManagementCategoryElement; import uk.gov.hmcts.reform.civil.model.ClaimAmountBreakup; import uk.gov.hmcts.reform.civil.model.CorrectEmail; +import uk.gov.hmcts.reform.civil.model.FlightDelayDetails; import uk.gov.hmcts.reform.civil.model.IdamUserDetails; import uk.gov.hmcts.reform.civil.model.Party; import uk.gov.hmcts.reform.civil.model.PaymentDetails; @@ -37,8 +41,11 @@ import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.model.defaultjudgment.CaseLocationCivil; import uk.gov.hmcts.reform.civil.prd.model.Organisation; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.repositories.ReferenceNumberRepository; import uk.gov.hmcts.reform.civil.repositories.SpecReferenceNumberRepository; +import uk.gov.hmcts.reform.civil.service.AirlineEpimsService; import uk.gov.hmcts.reform.civil.service.ExitSurveyContentService; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.FeesService; @@ -156,6 +163,10 @@ public class CreateClaimSpecCallbackHandler extends CallbackHandler implements P + "to : OCMCNton@justice.gov.uk. The Certificate of Service form can be found here:" + "%n%n

"; + private static final String ERROR_MESSAGE_SCHEDULED_DATE_OF_FLIGHT_MUST_BE_TODAY_OR_IN_THE_PAST = "Scheduled date of flight must be today or in the past"; + + private static final String LOCATION_NOT_FOUND_MESSAGE = "Location not found for ePIMS_ID: %s"; + private final ClaimUrlsConfiguration claimUrlsConfiguration; private final ExitSurveyContentService exitSurveyContentService; private final ReferenceNumberRepository referenceNumberRepository; @@ -176,7 +187,10 @@ public class CreateClaimSpecCallbackHandler extends CallbackHandler implements P private final StateFlowEngine stateFlowEngine; private final CaseFlagsInitialiser caseFlagInitialiser; private final ToggleConfiguration toggleConfiguration; + private final LocationRefDataService locationRefDataService; private final String caseDocLocation = "/cases/case-details/%s#CaseDocuments"; + private final AirlineEpimsDataLoader airlineEpimsDataLoader; + private final AirlineEpimsService airlineEpimsService; @Value("${court-location.specified-claim.region-id}") private String regionId; @@ -232,6 +246,8 @@ protected Map callbacks() { .put(callbackKey(MID, "validate-spec-defendant-legal-rep-email"), this::validateSpecRespondentRepEmail) .put(callbackKey(MID, "validate-spec-defendant2-legal-rep-email"), this::validateSpecRespondent2RepEmail) .put(callbackKey(MID, "is-flight-delay-claim"), this::isFlightDelayClaim) + .put(callbackKey(MID, "get-airline-list"), this::getAirlineList) + .put(callbackKey(MID, "validate-date-of-flight"), this::validateDateOfFlight) .build(); } @@ -523,7 +539,6 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { populateWithPartyIds(dataBuilder); } - List errors = new ArrayList<>(); if (caseData.getSdtRequestIdFromSdt() != null) { // assign StdRequestId, to ensure duplicate requests from SDT/bulk claims are not processed List> stdRequestIdList = new ArrayList<>(); @@ -540,6 +555,7 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { .build()).build()); } + List errors = new ArrayList<>(); if (getMultiPartyScenario(caseData) == ONE_V_TWO_ONE_LEGAL_REP && caseData.getSpecRespondentCorrespondenceAddressdetails() != null) { // to keep with heading tab @@ -550,6 +566,19 @@ private CallbackResponse submitClaim(CallbackParams callbackParams) { caseData.getSpecRespondentCorrespondenceAddressdetails()); } + if ((toggleService.isSdoR2Enabled() && callbackParams.getCaseData().getFlightDelayDetails() != null)) { + FlightDelayDetails flightDelayDetails = callbackParams.getCaseData().getFlightDelayDetails(); + String selectedAirlineCode = flightDelayDetails.getAirlineList().getValue().getCode(); + + dataBuilder.flightDelayDetails(FlightDelayDetails.builder() + .airlineList(DynamicList.builder().value(flightDelayDetails.getAirlineList().getValue()).build()) + .nameOfAirline(flightDelayDetails.getNameOfAirline()) + .flightNumber(flightDelayDetails.getFlightNumber()) + .scheduledDate(flightDelayDetails.getScheduledDate()) + .flightCourtLocation(getAirlineCaseLocation(selectedAirlineCode, callbackParams)) + .build()); + } + return AboutToStartOrSubmitCallbackResponse.builder() .errors(errors) .data(dataBuilder.build().toMap(objectMapper)) @@ -917,6 +946,36 @@ private CallbackResponse isFlightDelayClaim(CallbackParams callbackParams) { .build(); } + private CallbackResponse getAirlineList(CallbackParams callbackParams) { + CaseData.CaseDataBuilder caseDataBuilder = callbackParams.getCaseData().toBuilder(); + List airlineEpimsIDList = new ArrayList<>(airlineEpimsDataLoader.getAirlineEpimsIDList()); + DynamicList airlineList = DynamicList + .fromList(airlineEpimsIDList.stream() + .map(AirlineEpimsId::getAirline).toList(), Object::toString, Object::toString, null, false); + DynamicList dropdownAirlineList = DynamicList.builder() + .listItems(airlineList.getListItems()).build(); + + FlightDelayDetails flightDelayDetails = FlightDelayDetails.builder().airlineList(dropdownAirlineList).build(); + caseDataBuilder.flightDelayDetails(flightDelayDetails); + return AboutToStartOrSubmitCallbackResponse.builder() + .data(caseDataBuilder.build().toMap(objectMapper)) + .build(); + } + + private CallbackResponse validateDateOfFlight(CallbackParams callbackParams) { + CaseData.CaseDataBuilder caseDataBuilder = callbackParams.getCaseData().toBuilder(); + List errors = new ArrayList<>(); + LocalDate today = LocalDate.now(); + LocalDate scheduledDate = callbackParams.getCaseData().getFlightDelayDetails().getScheduledDate(); + if (scheduledDate.isAfter(today)) { + errors.add(ERROR_MESSAGE_SCHEDULED_DATE_OF_FLIGHT_MUST_BE_TODAY_OR_IN_THE_PAST); + } + return AboutToStartOrSubmitCallbackResponse.builder() + .data(caseDataBuilder.build().toMap(objectMapper)) + .errors(errors) + .build(); + } + private CallbackResponse setRespondent2SameLegalRepToNo(CallbackParams callbackParams) { CaseData.CaseDataBuilder caseDataBuilder = callbackParams.getCaseData().toBuilder(); @@ -943,4 +1002,25 @@ private boolean areRespondentsRepresentedAndRegistered(CaseData caseData) { || caseData.getRespondent2Represented() == NO || caseData.getRespondent2OrgRegistered() == NO); } + + private CaseLocationCivil getAirlineCaseLocation(String airline, CallbackParams callbackParams) { + if (airline.equals("OTHER")) { + return null; + } + String locationEpimmsId = airlineEpimsService.getEpimsIdForAirline(airline); + List locations = fetchLocationData(callbackParams); + var matchedLocations = locations.stream().filter(loc -> loc.getEpimmsId().equals(locationEpimmsId)).toList(); + if (matchedLocations.isEmpty()) { + throw new CallbackException(String.format(LOCATION_NOT_FOUND_MESSAGE, locationEpimmsId)); + } else { + return CaseLocationCivil.builder() + .region(matchedLocations.get(0).getRegionId()) + .baseLocation(matchedLocations.get(0).getEpimmsId()).build(); + } + } + + private List fetchLocationData(CallbackParams callbackParams) { + String authToken = callbackParams.getParams().get(BEARER_TOKEN).toString(); + return locationRefDataService.getCourtLocationsForDefaultJudgments(authToken); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/AirlineEpimsId.java b/src/main/java/uk/gov/hmcts/reform/civil/model/AirlineEpimsId.java new file mode 100644 index 00000000000..d03bb5bdc02 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/AirlineEpimsId.java @@ -0,0 +1,14 @@ +package uk.gov.hmcts.reform.civil.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Value; + +@Value +@Builder +@AllArgsConstructor +public class AirlineEpimsId { + + String airline; + String epimsID; +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java index 7eaee138a62..caa3f46a47b 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseData.java @@ -638,6 +638,7 @@ public boolean hasNoOngoingBusinessProcess() { //SDO-R2 private YesOrNo isFlightDelayClaim; + private FlightDelayDetails flightDelayDetails; /** * There are several fields that can hold the I2P of applicant1 depending diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/FlightDelayDetails.java b/src/main/java/uk/gov/hmcts/reform/civil/model/FlightDelayDetails.java new file mode 100644 index 00000000000..514f0f0ab52 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/FlightDelayDetails.java @@ -0,0 +1,23 @@ +package uk.gov.hmcts.reform.civil.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import uk.gov.hmcts.reform.civil.model.common.DynamicList; +import uk.gov.hmcts.reform.civil.model.defaultjudgment.CaseLocationCivil; + +import java.time.LocalDate; + +@Data +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +public class FlightDelayDetails { + + private DynamicList airlineList; + private String nameOfAirline; + private String flightNumber; + private LocalDate scheduledDate; + private CaseLocationCivil flightCourtLocation; +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoader.java b/src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoader.java new file mode 100644 index 00000000000..718c4755838 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoader.java @@ -0,0 +1,44 @@ +package uk.gov.hmcts.reform.civil.service; + +import com.google.common.collect.ImmutableList; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import com.opencsv.CSVReader; +import com.opencsv.exceptions.CsvException; +import uk.gov.hmcts.reform.civil.model.AirlineEpimsId; + +@Service +@Slf4j +public class AirlineEpimsDataLoader { + + private static final String CSV_FILE_PATH = "airline_ePimsID_csv/airline_ePimsID.csv"; + private final List airlineEpimsIDList = new ArrayList<>(); + + @PostConstruct + protected void init() { + InputStream inputStream = getClass().getClassLoader().getResourceAsStream(CSV_FILE_PATH); + try (CSVReader reader = new CSVReader(new InputStreamReader(inputStream))) { + + List linesList = reader.readAll(); + linesList.forEach(line -> { + AirlineEpimsId airlineEpimsID = AirlineEpimsId.builder() + .airline(line[0]) + .epimsID(line[1]) + .build(); + airlineEpimsIDList.add(airlineEpimsID); + }); + } catch (IOException | CsvException e) { + log.error("Error occurred while loading the airline_ePimsID.csv file: " + CSV_FILE_PATH + e); + } + } + + public List getAirlineEpimsIDList() { + return ImmutableList.copyOf(airlineEpimsIDList); + } +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsService.java new file mode 100644 index 00000000000..00e47a34789 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsService.java @@ -0,0 +1,22 @@ +package uk.gov.hmcts.reform.civil.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.civil.model.AirlineEpimsId; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class AirlineEpimsService { + + private final AirlineEpimsDataLoader airlineEpimsDataLoader; + + public String getEpimsIdForAirline(String airline) { + AirlineEpimsId airlineEpimsID = airlineEpimsDataLoader.getAirlineEpimsIDList() + .stream().filter(item -> item.getAirline().equals(airline)).findFirst().orElse(null); + + return Optional.ofNullable(airlineEpimsID) + .map(AirlineEpimsId::getEpimsID) + .orElseThrow(() -> new IllegalStateException("Unable to find epims ID for airline: " + airline)); + } +} diff --git a/src/main/resources/airline_ePimsID_csv/airline_ePimsID.csv b/src/main/resources/airline_ePimsID_csv/airline_ePimsID.csv new file mode 100644 index 00000000000..49d7c177ec2 --- /dev/null +++ b/src/main/resources/airline_ePimsID_csv/airline_ePimsID.csv @@ -0,0 +1,100 @@ +Aegean,298828 +Aer Lingus,621184 +Aeroflot,298828 +Aeromexico,621184 +Air Algerie,268374 +Air Baltic,317442 +Air Canada,298828 +Air China,36791 +Air Europa,20262 +Air France,298828 +Air India,36791 +Air Malta,298828 +Air Moldova,365554 +Air New Zealand,268374 +Air Portugal,701411 +Air Transat,20262 +All Nippon Airways,268374 +American Airlines,621184 +Aurigny,317442 +Austrian Airways,621184 +Avianca,365554 +Azerbaijan Airlines,268374 +BA/Cityflyer,621184 +Biman Bangladesh,345663 +Blue Air,345663 +Brussels,621184 +Bulgaria Air,298828 +Cathay Pacific,268374 +China Airlines,20262 +China Eastern,20262 +China Southern,621184 +Condor,701411 +Croatia Airlines,298828 +Delta,268374 +Eastern,317442 +Easyjet,365554 +Egyptair,268374 +El Al,20262 +Emirates,701411 +Etihad,345663 +Eurowings,621184 +Eva Air,20262 +Finnair,345663 +Garuda,621184 +Gulf Air,36791 +Iberia/Express,621184 +Icelandair,20262 +Iran Air,268374 +ITA,298828 +Japan Airlines,20262 +Jet2.com,701411 +JetBlue,317442 +Kenya Airways,298828 +KLM,298828 +Korean,20262 +Kuwait Airways,621184 +LATAM/JJ,298828 +Loganair,701411 +LOT,20262 +Lufthansa,621184 +Luxair,20262 +Malaysian,268374 +Middle East,20262 +Norse,317442 +Norweigan,317442 +Oman,701411 +Pakistan,36791 +Pegasus,365554 +Phillipine Airlines,317442 +Play,345663 +Qatar,345663 +Quantas,268374 +Royal Air Maroc,20262 +Royal Brunei,268374 +Royal Jordanian,36791 +Ryanair,345663 +SAS,298828 +SAS,621184 +Saudi Arabian Airlines,20262 +Saudia,20262 +Singapore Airlines,36791 +Sky Express,298828 +Smartwings,365554 +South African Airways,268374 +Sri Lankan,36791 +Swiss International,621184 +Thai Airways,20262 +TUI / Thomson ,365554 +Tunisair,268374 +Turkish,36791 +Ukraine International,36791 +United,621184 +Vietnam Airlines,20262 +Virgin,317442 +Vistara,268374 +Vueling,345663 +WestJet,317442 +Wideroe,298828 +WizzAir,345663 +OTHER, diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java index 40c83a10559..a8f216dcd76 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/callback/user/CreateClaimSpecCallbackHandlerTest.java @@ -29,6 +29,13 @@ import uk.gov.hmcts.reform.civil.enums.YesOrNo; import uk.gov.hmcts.reform.civil.handler.callback.BaseCallbackHandlerTest; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; +import uk.gov.hmcts.reform.civil.model.AirlineEpimsId; +import uk.gov.hmcts.reform.civil.service.AirlineEpimsDataLoader; +import uk.gov.hmcts.reform.civil.model.FlightDelayDetails; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; +import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; +import uk.gov.hmcts.reform.civil.sampledata.LocationRefSampleDataBuilder; +import uk.gov.hmcts.reform.civil.service.AirlineEpimsService; import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.model.Address; import uk.gov.hmcts.reform.civil.model.CaseData; @@ -207,6 +214,15 @@ class CreateClaimSpecCallbackHandlerTest extends BaseCallbackHandlerTest { @MockBean private ToggleConfiguration toggleConfiguration; + @MockBean + protected LocationRefDataService locationRefDataService; + + @MockBean + private AirlineEpimsDataLoader airlineEpimsDataLoader; + + @MockBean + private AirlineEpimsService airlineEpimsService; + @Nested class AboutToStartCallback { @@ -1623,7 +1639,7 @@ void shouldReturnErrors_whenRequiredAddressIsYesAndNotValid() { } @Nested - class IsFlightDelayClaimMidCallback { + class FlightDelayDetailsMidCallbacks { @ParameterizedTest @ValueSource(booleans = {true, false}) void shouldSetIsFlightDelayClaim_whenPopulatedAndSdoR2Enabled(Boolean toggleStat) { @@ -1661,6 +1677,61 @@ void shouldSetIsFlightDelayClaim_whenPopulatedAndSdoR2Disabled() { assertThat(response.getData()).doesNotHaveToString("isFlightDelayClaim"); assertThat(response.getData()).doesNotHaveToString("claimType"); } + + @Test + void shouldGetAirlineList_whenRequired() { + // Given + List airlineEpimsIDList = new ArrayList<>(); + airlineEpimsIDList.add(AirlineEpimsId.builder().airline("BA/Cityflyer").epimsID("111000").build()); + airlineEpimsIDList.add(AirlineEpimsId.builder().airline("OTHER").epimsID("111111").build()); + + given(airlineEpimsDataLoader.getAirlineEpimsIDList()) + .willReturn(airlineEpimsIDList); + + CaseData caseData = CaseData.builder().build(); + CallbackParams params = callbackParamsOf(caseData, MID, "get-airline-list"); + + // When + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + // Then + assertThat(response.getData()).extracting("flightDelayDetails").extracting("airlineList") + .extracting("list_items").asList().extracting("label") + .contains("BA/Cityflyer"); + + assertThat(response.getData()).extracting("flightDelayDetails").extracting("airlineList") + .extracting("list_items").asList().extracting("label") + .contains("OTHER"); + } + + @Test + void shouldReturnErrorWhenDateOfFlightIsInTheFuture() { + // Given + CaseData caseData = CaseData.builder() + .flightDelayDetails(FlightDelayDetails.builder().scheduledDate(now().plusDays(1)).build()).build(); + + CallbackParams params = callbackParamsOf(caseData, MID, "validate-date-of-flight"); + // When + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + // Then + assertThat(response.getErrors()).contains("Scheduled date of flight must be today or in the past"); + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void shouldNotReturnErrorWhenDateOfFlightIsTodayOrInThePast(Integer days) { + // Given + CaseData caseData = CaseData.builder() + .flightDelayDetails(FlightDelayDetails.builder().scheduledDate(now().minusDays(days)).build()).build(); + + CallbackParams params = callbackParamsOf(caseData, MID, "validate-date-of-flight"); + // When + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + // Then + assertThat(response.getErrors()).isEmpty(); + } } @Nested @@ -2099,6 +2170,63 @@ void shouldMoveStatementOfTruthToCorrectFieldAndResetUIField_whenInvoked() { .doesNotHaveToString("role"); } } + + @Nested + class GetAirlineCourtLocation extends LocationRefSampleDataBuilder { + + @BeforeEach + void mockAirlineEpimsData() { + given(airlineEpimsService.getEpimsIdForAirline("GULF_AIR")) + .willReturn("36791"); + + List locations = new ArrayList<>(); + locations.add(LocationRefData.builder().regionId("Site Name").epimmsId("36791") + .build()); + given(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) + .willReturn(locations); + + when(toggleService.isSdoR2Enabled()).thenReturn(true); + } + + @Test + void shouldReturnExpectedCourtLocation_whenAirlineExists() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft() + .flightDelay(FlightDelayDetails.builder() + .airlineList( + DynamicList.builder() + .value(DynamicListElement.builder().code("GULF_AIR").label("Gulf Air") + .build()).build()).build()).build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + // When + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + // Then + assertThat(response.getData()).extracting("flightDelayDetails").extracting("flightCourtLocation").extracting("region").isEqualTo("Site Name"); + } + + @Test + void shouldReturnExpectedCourtLocation_whenOtherAirlineSelected() { + // Given + CaseData caseData = CaseDataBuilder.builder().atStateClaimDraft() + .flightDelay(FlightDelayDetails.builder() + .airlineList( + DynamicList.builder() + .value(DynamicListElement.builder().code("OTHER").label("OTHER") + .build()).build()).build()).build(); + CallbackParams params = callbackParamsOf(caseData, ABOUT_TO_SUBMIT); + + given(locationRefDataService.getCourtLocationsForDefaultJudgments(any())) + .willReturn(getSampleCourLocationsRefObject()); + + // When + var response = (AboutToStartOrSubmitCallbackResponse) handler.handle(params); + + // Then + assertThat(response.getData()).extracting("flightDelayDetails").extracting("flightCourtLocation").isNull(); + } + } } @Nested diff --git a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java index bc230fb1382..5e445820d77 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/sampledata/CaseDataBuilder.java @@ -37,6 +37,7 @@ import uk.gov.hmcts.reform.civil.enums.sdo.TrialHearingTimeEstimateDJ; import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.ResponseOneVOneShowTag; import uk.gov.hmcts.reform.civil.enums.sdo.DateToShowToggle; +import uk.gov.hmcts.reform.civil.model.FlightDelayDetails; import uk.gov.hmcts.reform.civil.model.UpdateDetailsForm; import uk.gov.hmcts.reform.civil.model.Address; import uk.gov.hmcts.reform.civil.model.Bundle; @@ -504,6 +505,7 @@ public class CaseDataBuilder { private DynamicList transferCourtLocationList; private String reasonForTransfer; + private FlightDelayDetails flightDelayDetails; public CaseDataBuilder sameRateInterestSelection(SameRateInterestSelection sameRateInterestSelection) { this.sameRateInterestSelection = sameRateInterestSelection; @@ -5190,6 +5192,11 @@ public CaseDataBuilder reasonForTransfer(String reasonForTransfer) { return this; } + public CaseDataBuilder flightDelay(FlightDelayDetails flightDelayDetails) { + this.flightDelayDetails = flightDelayDetails; + return this; + } + public CaseData buildMakePaymentsCaseData() { Organisation orgId = Organisation.builder() .organisationID("OrgId").build(); @@ -6545,6 +6552,7 @@ public CaseData build() { .drawDirectionsOrderRequired(drawDirectionsOrderRequired) .transferCourtLocationList(transferCourtLocationList) .reasonForTransfer(reasonForTransfer) + .applicant1LRIndividuals(applicant1LRIndividuals) .respondent1LRIndividuals(respondent1LRIndividuals) .respondent2LRIndividuals(respondent2LRIndividuals) @@ -6552,6 +6560,7 @@ public CaseData build() { .applicant2OrgIndividuals(applicant2OrgIndividuals) .respondent1OrgIndividuals(respondent1OrgIndividuals) .respondent2OrgIndividuals(respondent2OrgIndividuals) + .flightDelayDetails(flightDelayDetails) .build(); } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoaderTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoaderTest.java new file mode 100644 index 00000000000..7b8b2e07427 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsDataLoaderTest.java @@ -0,0 +1,27 @@ +package uk.gov.hmcts.reform.civil.service; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest(classes = {AirlineEpimsDataLoader.class}) +class AirlineEpimsDataLoaderTest { + + private AirlineEpimsDataLoader airlineEpimsDataLoader; + + @BeforeEach + public void setUp() { + airlineEpimsDataLoader = new AirlineEpimsDataLoader(); + airlineEpimsDataLoader.init(); + } + + @Test + void shouldGetAnAirlineEpimsList() { + String airline = airlineEpimsDataLoader.getAirlineEpimsIDList().get(0).getAirline(); + String epimsID = airlineEpimsDataLoader.getAirlineEpimsIDList().get(0).getEpimsID(); + assertEquals("Aegean", airline); + assertEquals("298828", epimsID); + } +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsServiceTest.java new file mode 100644 index 00000000000..ccbfcd2b902 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/AirlineEpimsServiceTest.java @@ -0,0 +1,64 @@ +package uk.gov.hmcts.reform.civil.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import uk.gov.hmcts.reform.civil.model.AirlineEpimsId; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.BDDMockito.given; + +@SpringBootTest(classes = {AirlineEpimsService.class}) +class AirlineEpimsServiceTest { + + @MockBean + private AirlineEpimsDataLoader airlineEpimsDataLoader; + + private AirlineEpimsService airlineEpimsService; + + @BeforeEach + void setup() { + List airlineEpimsIDList = new ArrayList<>(); + airlineEpimsIDList.add(AirlineEpimsId.builder().airline("Gulf Air").epimsID("36791").build()); + airlineEpimsIDList.add(AirlineEpimsId.builder().airline("NoLocationAirline").build()); + + given(airlineEpimsDataLoader.getAirlineEpimsIDList()) + .willReturn(airlineEpimsIDList); + } + + @Test + void getEpimsIdForAirline_shouldReturnCorrespondingEpimsIdForAirline() { + // Given + airlineEpimsService = new AirlineEpimsService(airlineEpimsDataLoader); + + // When + String result = airlineEpimsService.getEpimsIdForAirline("Gulf Air"); + + // Then + assertThat(result).isEqualTo("36791"); + } + + @Test + void getEpimsIdForAirline_givenInvalidAirline_shouldThrowException() { + // Given + airlineEpimsService = new AirlineEpimsService(airlineEpimsDataLoader); + + // Then + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> airlineEpimsService.getEpimsIdForAirline("INVALID_AIRLINE")); + } + + @Test + void getEpimsIdForAirline_givenNoLocationAirline_shouldThrowException() { + // Given + airlineEpimsService = new AirlineEpimsService(airlineEpimsDataLoader); + + // Then + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> airlineEpimsService.getEpimsIdForAirline("NoLocationAirline")); + } +} From 4cfb11d83addd987fc282226cb5874959d731a7e Mon Sep 17 00:00:00 2001 From: sampankumar Date: Fri, 24 Nov 2023 15:36:14 +0000 Subject: [PATCH 25/29] CIV-0000 add service auth (#3495) * Adding S2S token for service request update url * Adding S2S token for service request update url * Adding S2S token for service request update url * Adding S2S token for service request update url * Adding S2S token for service request update url * Adding S2S token for service request update url * Adding S2S token for service request update url * Adding S2S token for service request update url * Bumping chart version/ fixing aliases * Update Jenkinsfile_CNP * Pointing to a branch * CIV-0000 - Add service Auth for payment * Bumping chart version/ fixing aliases * Bumping chart version/ fixing aliases * Fixing unit tests * Fixing unit tests * Fixing unit tests * Fixing unit tests * Fixing unit tests * Fixing unit tests * Bumping chart version/ fixing aliases * Adding service-request-update-claim-issued * Update Jenkinsfile_CNP * converting to List * Checkstyle error * converting to List * converting to List * Fixing Sonar failures * Fixing Sonar failures --------- Co-authored-by: hmcts-jenkins-a-to-c <62422075+hmcts-jenkins-a-to-c[bot]@users.noreply.github.com> Co-authored-by: sankhajuria Co-authored-by: mfallonhmcts <114912573+mfallonhmcts@users.noreply.github.com> --- build.gradle | 2 +- charts/civil-service/Chart.yaml | 2 +- charts/civil-service/values.yaml | 1 + .../controllers/BaseIntegrationTest.java | 9 ++ ...ceRequestUpdateCallbackControllerTest.java | 32 ++++++ ...dateClaimIssuedCallbackControllerTest.java | 32 +++++- ...erviceRequestUpdateCallbackController.java | 14 ++- ...stUpdateClaimIssuedCallbackController.java | 13 ++- .../civil/service/AuthorisationService.java | 65 ++++++++++++ src/main/resources/application.yaml | 2 + .../service/AuthorisationServiceTest.java | 99 +++++++++++++++++++ 11 files changed, 264 insertions(+), 7 deletions(-) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/service/AuthorisationService.java create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/service/AuthorisationServiceTest.java diff --git a/build.gradle b/build.gradle index c8f9c7a8400..2d2f22d5414 100644 --- a/build.gradle +++ b/build.gradle @@ -396,7 +396,7 @@ dependencies { implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign' implementation group: 'org.springframework.cloud', name: 'spring-cloud-openfeign-core' implementation group: 'uk.gov.hmcts.reform', name: 'properties-volume-spring-boot-starter', version: '0.1.0' - implementation group: 'uk.gov.hmcts.reform', name: 'service-auth-provider-client', version: '4.0.0' + implementation group: 'uk.gov.hmcts.reform', name: 'service-auth-provider-client', version: '4.0.3' implementation group: 'io.github.openfeign', name: 'feign-httpclient', version: '12.4' implementation group: 'org.springframework.retry', name: 'spring-retry' diff --git a/charts/civil-service/Chart.yaml b/charts/civil-service/Chart.yaml index dbf0c702042..bc3f1ae9b6c 100644 --- a/charts/civil-service/Chart.yaml +++ b/charts/civil-service/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 description: A Helm chart for civil-service App name: civil-service home: https://github.com/hmcts/civil-service -version: 0.0.52 +version: 0.0.53 maintainers: - name: HMCTS Civil team diff --git a/charts/civil-service/values.yaml b/charts/civil-service/values.yaml index 54a997ceadd..fc9b9e0d99f 100644 --- a/charts/civil-service/values.yaml +++ b/charts/civil-service/values.yaml @@ -74,6 +74,7 @@ java: ASYNC_HANDLER_CORE_POOL_SIZE: 7 ASYNC_HANDLER_MAX_POOL_SIZE: 42 ASYNC_HANDLER_QUEUE_CAPACITY: 10 + CIVIL_S2S_AUTHORISED_SERVICES: payment_app,ccd_data,civil_service,civil-citizen-ui keyVaults: civil: diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/BaseIntegrationTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/BaseIntegrationTest.java index 139b311e778..a844c3a91fc 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/BaseIntegrationTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/BaseIntegrationTest.java @@ -22,8 +22,10 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import uk.gov.hmcts.reform.authorisation.ServiceAuthorisationApi; import uk.gov.hmcts.reform.civil.Application; import uk.gov.hmcts.reform.civil.TestIdamConfiguration; +import uk.gov.hmcts.reform.civil.service.AuthorisationService; import uk.gov.hmcts.reform.civil.service.UserService; import uk.gov.hmcts.reform.idam.client.models.UserInfo; @@ -61,6 +63,9 @@ public abstract class BaseIntegrationTest { .roles(of("caseworker-civil-solicitor")) .build(); + private static final String s2sToken = "s2s AuthToken"; + @MockBean + private ServiceAuthorisationApi serviceAuthorisationApi; @MockBean protected UserService userService; @MockBean @@ -69,6 +74,8 @@ public abstract class BaseIntegrationTest { protected SecurityContext securityContext; @MockBean protected JwtDecoder jwtDecoder; + @MockBean + public AuthorisationService authorisationService; @Autowired protected ObjectMapper objectMapper; @@ -78,11 +85,13 @@ public abstract class BaseIntegrationTest { @BeforeEach public void setUpBase() { + when(authorisationService.isServiceAuthorized(any())).thenReturn(true); when(userService.getAccessToken(any(), any())).thenReturn("arbitrary access token"); when(userService.getUserInfo(anyString())).thenReturn(USER_INFO); when(securityContext.getAuthentication()).thenReturn(authentication); SecurityContextHolder.setContext(securityContext); setSecurityAuthorities(authentication); + when(serviceAuthorisationApi.getServiceName(any())).thenReturn("payment_app"); when(jwtDecoder.decode(anyString())).thenReturn(getJwt()); } diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackControllerTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackControllerTest.java index 32dc02b549e..6db03a393c0 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackControllerTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackControllerTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -22,6 +23,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; class ServiceRequestUpdateCallbackControllerTest extends BaseIntegrationTest { @@ -31,6 +33,7 @@ class ServiceRequestUpdateCallbackControllerTest extends BaseIntegrationTest { private static final String PAID = "Paid"; private static final String REFERENCE = "reference"; private static final String ACCOUNT_NUMBER = "123445555"; + private static final String s2sToken = "s2s AuthToken"; @MockBean CoreCaseDataApi coreCaseDataApi; @@ -40,6 +43,7 @@ class ServiceRequestUpdateCallbackControllerTest extends BaseIntegrationTest { @BeforeEach void bareMinimumToMakeAPositiveRequest() { + when(authorisationService.isServiceAuthorized(any())).thenReturn(true); CaseData caseData = CaseData.builder().businessProcess(BusinessProcess.builder().processInstanceId("instance").camundaEvent("camunda event").build()).build(); CaseDetails caseDetails = CaseDetails.builder().build(); caseDetails.setData(caseData.toMap(objectMapper)); @@ -51,6 +55,30 @@ void bareMinimumToMakeAPositiveRequest() { given(coreCaseDataApi.submitEventForCaseWorker(any(), any(), any(), any(), any(), any(), anyBoolean(), any())).willReturn(caseDetails); } + @Test + public void whenValidPaymentCallbackIsReceivedReturnSuccess() throws Exception { + doPut(buildServiceDto(), PAYMENT_CALLBACK_URL, "") + .andExpect(status().isOk()); + } + + @Test + public void whenPaymentCallbackIsReceivedWithoutServiceAuthorisationReturn400() throws Exception { + mockMvc.perform( + MockMvcRequestBuilders.put(PAYMENT_CALLBACK_URL, "") + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(buildServiceDto()))).andExpect(status().is4xxClientError()); + } + + @Test + public void whenPaymentCallbackIsReceivedWithServiceAuthorisationButreturnsfalseReturn400() throws Exception { + when(authorisationService.isServiceAuthorized(any())).thenReturn(false); + mockMvc.perform( + MockMvcRequestBuilders.put(PAYMENT_CALLBACK_URL, "") + .header("ServiceAuthorization", s2sToken) + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(buildServiceDto()))).andExpect(status().is5xxServerError()); + } + @Test public void whenInvalidTypeOfRequestMade_ReturnMethodNotAllowed() throws Exception { @@ -96,6 +124,8 @@ private ServiceRequestUpdateDto buildServiceDto() { protected ResultActions doPut(T content, String urlTemplate, Object... uriVars) { return mockMvc.perform( MockMvcRequestBuilders.put(urlTemplate, uriVars) + .header(HttpHeaders.AUTHORIZATION, BEARER_TOKEN) + .header("ServiceAuthorization", "s2s AuthToken") .contentType(MediaType.APPLICATION_JSON) .content(toJson(content))); } @@ -104,6 +134,8 @@ protected ResultActions doPut(T content, String urlTemplate, Object... uriVa protected ResultActions doPost(T content, String urlTemplate, Object... uriVars) { return mockMvc.perform( MockMvcRequestBuilders.post(urlTemplate, uriVars) + .header(HttpHeaders.AUTHORIZATION, BEARER_TOKEN) + .header("ServiceAuthorization", "s2s AuthToken") .contentType(MediaType.APPLICATION_JSON) .content(toJson(content))); } diff --git a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackControllerTest.java b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackControllerTest.java index 673f90234a5..b64ef4426bb 100644 --- a/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackControllerTest.java +++ b/src/integrationTest/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackControllerTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -22,6 +23,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; class ServiceRequestUpdateClaimIssuedCallbackControllerTest extends BaseIntegrationTest { @@ -31,7 +33,6 @@ class ServiceRequestUpdateClaimIssuedCallbackControllerTest extends BaseIntegrat private static final String PAID = "Paid"; private static final String REFERENCE = "reference"; private static final String ACCOUNT_NUMBER = "123445555"; - @MockBean CoreCaseDataApi coreCaseDataApi; @@ -40,6 +41,7 @@ class ServiceRequestUpdateClaimIssuedCallbackControllerTest extends BaseIntegrat @BeforeEach void bareMinimumToMakeAPositiveRequest() { + when(authorisationService.isServiceAuthorized(any())).thenReturn(true); CaseData caseData = CaseData.builder().businessProcess(BusinessProcess.builder().processInstanceId("instance").camundaEvent("camunda event").build()).build(); CaseDetails caseDetails = CaseDetails.builder().build(); @@ -77,6 +79,30 @@ public void whenServiceRequestUpdateRequestButUnexpectedErrorOccurs_thenHttp5xx( .andExpect(status().is5xxServerError()); } + @Test + public void whenValidPaymentCallbackIsReceivedReturnSuccess() throws Exception { + doPut(buildServiceDto(), PAYMENT_CALLBACK_URL, "") + .andExpect(status().isOk()); + } + + @Test + public void whenPaymentCallbackIsReceivedWithoutServiceAuthorisationReturn400() throws Exception { + mockMvc.perform( + MockMvcRequestBuilders.put(PAYMENT_CALLBACK_URL, "") + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(buildServiceDto()))).andExpect(status().is4xxClientError()); + } + + @Test + public void whenPaymentCallbackIsReceivedWithServiceAuthorisationButreturnsfalseReturn400() throws Exception { + when(authorisationService.isServiceAuthorized(any())).thenReturn(false); + + doPut(buildServiceDto(), PAYMENT_CALLBACK_URL, "") + // Then: the result status must be an HTTP-4xx + .andExpect(status().is5xxServerError()); + + } + private ServiceRequestUpdateDto buildServiceDto() { return ServiceRequestUpdateDto.builder() .ccdCaseNumber(CCD_CASE_NUMBER) @@ -94,6 +120,8 @@ private ServiceRequestUpdateDto buildServiceDto() { protected ResultActions doPut(T content, String urlTemplate, Object... uriVars) { return mockMvc.perform( MockMvcRequestBuilders.put(urlTemplate, uriVars) + .header(HttpHeaders.AUTHORIZATION, BEARER_TOKEN) + .header("ServiceAuthorization", "s2s AuthToken") .contentType(MediaType.APPLICATION_JSON) .content(toJson(content))); } @@ -102,6 +130,8 @@ protected ResultActions doPut(T content, String urlTemplate, Object... uriVa protected ResultActions doPost(T content, String urlTemplate, Object... uriVars) { return mockMvc.perform( MockMvcRequestBuilders.post(urlTemplate, uriVars) + .header(HttpHeaders.AUTHORIZATION, BEARER_TOKEN) + .header("ServiceAuthorization", "s2s AuthToken") .contentType(MediaType.APPLICATION_JSON) .content(toJson(content))); } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackController.java b/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackController.java index 02faefda690..9c6bae36e15 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackController.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateCallbackController.java @@ -7,10 +7,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import uk.gov.hmcts.reform.civil.enums.FeeType; import uk.gov.hmcts.reform.civil.exceptions.InternalServerErrorException; import uk.gov.hmcts.reform.civil.model.ServiceRequestUpdateDto; +import uk.gov.hmcts.reform.civil.service.AuthorisationService; import uk.gov.hmcts.reform.civil.service.PaymentRequestUpdateCallbackService; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; @@ -22,6 +24,8 @@ public class ServiceRequestUpdateCallbackController { private final PaymentRequestUpdateCallbackService requestUpdateCallbackService; + private final AuthorisationService authorisationService; + @PutMapping(path = "/service-request-update", consumes = APPLICATION_JSON, produces = APPLICATION_JSON) @Operation(summary = "Ways to pay will call this API and send the status of payment with other details") @ApiResponses(value = { @@ -29,9 +33,15 @@ public class ServiceRequestUpdateCallbackController { @ApiResponse(responseCode = "400", description = "Bad Request"), @ApiResponse(responseCode = "500", description = "Internal Server Error") }) - public void serviceRequestUpdate(@RequestBody ServiceRequestUpdateDto serviceRequestUpdateDto) { + public void serviceRequestUpdate( + @RequestHeader("ServiceAuthorization") String s2sToken, + @RequestBody ServiceRequestUpdateDto serviceRequestUpdateDto) { try { - requestUpdateCallbackService.processCallback(serviceRequestUpdateDto, FeeType.HEARING.name()); + if (authorisationService.isServiceAuthorized(s2sToken)) { + requestUpdateCallbackService.processCallback(serviceRequestUpdateDto, FeeType.HEARING.name()); + } else { + throw (new RuntimeException("Invalid Client")); + } } catch (Exception ex) { log.error( "Payment callback is unsuccessful for the CaseID: {}", diff --git a/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackController.java b/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackController.java index 9627d311f54..8230424a778 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackController.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/controllers/fees/ServiceRequestUpdateClaimIssuedCallbackController.java @@ -7,10 +7,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import uk.gov.hmcts.reform.civil.enums.FeeType; import uk.gov.hmcts.reform.civil.exceptions.InternalServerErrorException; import uk.gov.hmcts.reform.civil.model.ServiceRequestUpdateDto; +import uk.gov.hmcts.reform.civil.service.AuthorisationService; import uk.gov.hmcts.reform.civil.service.PaymentRequestUpdateCallbackService; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; @@ -22,14 +24,21 @@ public class ServiceRequestUpdateClaimIssuedCallbackController { private final PaymentRequestUpdateCallbackService requestUpdateCallbackService; + private final AuthorisationService authorisationService; + @PutMapping(path = "/service-request-update-claim-issued", consumes = APPLICATION_JSON, produces = APPLICATION_JSON) @Operation(summary = "Ways to pay will call this API and send the status of payment with other details") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Callback processed."), @ApiResponse(responseCode = "400", description = "Bad Request")}) - public void serviceRequestUpdate(@RequestBody ServiceRequestUpdateDto serviceRequestUpdateDto) { + public void serviceRequestUpdate(@RequestHeader("ServiceAuthorization") String s2sToken, + @RequestBody ServiceRequestUpdateDto serviceRequestUpdateDto) { try { - requestUpdateCallbackService.processCallback(serviceRequestUpdateDto, FeeType.CLAIMISSUED.name()); + if (authorisationService.isServiceAuthorized(s2sToken)) { + requestUpdateCallbackService.processCallback(serviceRequestUpdateDto, FeeType.CLAIMISSUED.name()); + } else { + throw (new RuntimeException("Invalid Client")); + } } catch (Exception ex) { log.error( "Payment callback is unsuccessful for the CaseID: {}", diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/AuthorisationService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/AuthorisationService.java new file mode 100644 index 00000000000..b50f8c1f597 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/AuthorisationService.java @@ -0,0 +1,65 @@ +package uk.gov.hmcts.reform.civil.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import uk.gov.hmcts.reform.authorisation.ServiceAuthorisationApi; +import uk.gov.hmcts.reform.idam.client.IdamClient; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.List; + +@Service +@Slf4j +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class AuthorisationService { + + private final ServiceAuthorisationApi serviceAuthorisationApi; + + @Value("${civil.authorised-services}") + private List s2sAuthorisedServices; + + private final IdamClient idamClient; + + private UserInfo userInfo; + + public Boolean authoriseService(String serviceAuthHeader) { + String callingService; + try { + String bearerJwt = serviceAuthHeader.startsWith("Bearer ") ? serviceAuthHeader : "Bearer " + serviceAuthHeader; + callingService = serviceAuthorisationApi.getServiceName(bearerJwt); + log.info("Calling Service... {}", callingService); + return (callingService != null && s2sAuthorisedServices.contains(callingService)); + } catch (Exception ex) { + //do nothing + log.error("S2S token is not authorised" + ex); + } + return false; + } + + public Boolean authoriseUser(String authorisation) { + try { + userInfo = idamClient.getUserInfo(authorisation); + return (null != userInfo); + } catch (Exception ex) { + //do nothing + log.error("User token is invalid"); + } + return false; + } + + public UserInfo getUserInfo() { + return this.userInfo; + } + + public boolean isServiceAndUserAuthorized(String authorisation, String s2sToken) { + return Boolean.TRUE.equals(authoriseUser(authorisation)) + && Boolean.TRUE.equals(authoriseService(s2sToken)); + } + + public boolean isServiceAuthorized(String s2sToken) { + return Boolean.TRUE.equals(authoriseService(s2sToken)); + } +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 29ac16b639e..15754b2d272 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -129,6 +129,7 @@ idam: s2s-auth: microservice: civil_service + document_management: userRoles: "caseworker-civil,caseworker-civil-solicitor" secured: ${DOCUMENT_MANAGEMENT_SECURED:true} @@ -158,6 +159,7 @@ civil: test-user: username: ${TEST_USERNAME:test@example.com} password: ${TEST_PASSWORD:Password12!} + authorised-services: ${CIVIL_S2S_AUTHORISED_SERVICES:payment_app,ccd_data,civil_service,civil-citizen-ui} core_case_data: api: diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/AuthorisationServiceTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/AuthorisationServiceTest.java new file mode 100644 index 00000000000..1a7680539bf --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/AuthorisationServiceTest.java @@ -0,0 +1,99 @@ +package uk.gov.hmcts.reform.civil.service; + +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 org.springframework.test.util.ReflectionTestUtils; +import uk.gov.hmcts.reform.authorisation.ServiceAuthorisationApi; +import uk.gov.hmcts.reform.idam.client.IdamClient; +import uk.gov.hmcts.reform.idam.client.models.UserInfo; + +import java.util.Arrays; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class AuthorisationServiceTest { + + @InjectMocks + AuthorisationService authorisationService; + + @Mock + ServiceAuthorisationApi serviceAuthorisationApi; + + @Mock + IdamClient idamClient; + + @BeforeEach + public void setup() { + ReflectionTestUtils.setField(authorisationService, "s2sAuthorisedServices", Arrays.asList("payment_app")); + } + + @Test + public void authoriseWhenTheServiceIsCalledFromPayment() { + + when(serviceAuthorisationApi.getServiceName(any())).thenReturn("payment_app"); + assertTrue(authorisationService.authoriseService("Bearer abcasda")); + + } + + @Test + public void authoriseWhenTheServiceAuthHeaderIsNull() { + assertFalse(authorisationService.authoriseService(null)); + } + + @Test + public void doNotAuthoriseWhenTheServiceIsCalledFromUnknownApi() { + when(serviceAuthorisationApi.getServiceName(any())).thenReturn("unknown_api"); + assertFalse(authorisationService.authoriseService("Bearer abc")); + + } + + @Test + public void throwUnAuthorisedExceptionWhenS2sTokenIsMalformed() { + assertFalse(authorisationService.authoriseService("Bearer malformed")); + } + + @Test + public void authoriseUserTheServiceIsCalledWithValidToken() { + when(idamClient.getUserInfo(any())).thenReturn(UserInfo.builder().uid(UUID.randomUUID().toString()).build()); + assertTrue(authorisationService.authoriseUser("Bearer abcasda")); + } + + @Test + public void authoriseUserTheServiceIsCalledWithNullToken() { + assertFalse(authorisationService.authoriseUser(null)); + } + + @Test + public void doNotAuthoriseUserWhenCalledWithInvalidToken() { + assertFalse(authorisationService.authoriseUser("Bearer malformed")); + } + + @Test + public void checkIsAuthorizedForUserAndServiceReturnTrue() { + when(idamClient.getUserInfo(any())).thenReturn(UserInfo.builder().uid(UUID.randomUUID().toString()).build()); + when(serviceAuthorisationApi.getServiceName(any())).thenReturn("payment_app"); + assertTrue(authorisationService.isServiceAndUserAuthorized("Bearer abcasda", "s2s token")); + } + + @Test + public void checkIsAuthorizedForUserAndServiceReturnFalse() { + when(idamClient.getUserInfo(any())).thenReturn(UserInfo.builder().uid(UUID.randomUUID().toString()).build()); + when(serviceAuthorisationApi.getServiceName(any())).thenReturn("unknown_api"); + assertFalse(authorisationService.isServiceAndUserAuthorized("Bearer abcasda", "s2s token")); + } + + @Test + public void checkIsAuthorizedForServiceReturnFalse() { + when(serviceAuthorisationApi.getServiceName(any())).thenReturn("unknown_api"); + assertFalse(authorisationService.isServiceAuthorized("s2s token")); + } +} From b4793002eae804806931906e8ddf1af7bc4b34c3 Mon Sep 17 00:00:00 2001 From: neeta-hmcts <115545612+neeta-hmcts@users.noreply.github.com> Date: Fri, 24 Nov 2023 17:36:33 +0000 Subject: [PATCH 26/29] added new field for LIP Claimant formalise payment decision. (#3418) Co-authored-by: dharmendra kumar Co-authored-by: Raja Mani Co-authored-by: ElifDenizEsea <61947470+ElifDenizEsea@users.noreply.github.com> Co-authored-by: jarekPierchala <118526007+jarekPierchala@users.noreply.github.com> --- .../reform/civil/model/citizenui/ChooseHowToProceed.java | 6 ++++++ .../reform/civil/model/citizenui/ClaimantLiPResponse.java | 1 + 2 files changed, 7 insertions(+) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ChooseHowToProceed.java diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ChooseHowToProceed.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ChooseHowToProceed.java new file mode 100644 index 00000000000..c163aec3d5e --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ChooseHowToProceed.java @@ -0,0 +1,6 @@ +package uk.gov.hmcts.reform.civil.model.citizenui; + +public enum ChooseHowToProceed { + SIGN_A_SETTLEMENT_AGREEMENT, + REQUEST_A_CCJ, +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java index 782131ceb90..63d103d80b8 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/ClaimantLiPResponse.java @@ -16,6 +16,7 @@ public class ClaimantLiPResponse { private DQExtraDetailsLip applicant1DQExtraDetails; private HearingSupportLip applicant1DQHearingSupportLip; private YesOrNo applicant1SignedSettlementAgreement; + private ChooseHowToProceed applicant1ChoosesHowToProceed; @JsonIgnore public boolean hasApplicant1SignedSettlementAgreement() { From df5307fbe96ba011f02a75494806c6d930857bd4 Mon Sep 17 00:00:00 2001 From: ElifDenizEsea <61947470+ElifDenizEsea@users.noreply.github.com> Date: Mon, 27 Nov 2023 10:02:40 +0000 Subject: [PATCH 27/29] CIV-11647 Claimant list matcher (#3617) * CIV-11647 Claimant list matcher * CIV-11647 Claimant list matcher * CIV-11647 Old matcher copied to new one * CIV-11647 Old matcher copied to new one * CIV-11647 Old matcher copied to new one --------- Co-authored-by: jarekPierchala <118526007+jarekPierchala@users.noreply.github.com> --- build.gradle | 2 +- ... => CcdDashboardClaimantClaimMatcher.java} | 2 +- .../CcdDashboardDefendantClaimMatcher.java | 297 ++++++++++++++++++ .../citizenui/DashboardClaimInfoService.java | 36 ++- .../CcdClaimStatusDashboardFactoryTest.java | 54 ++-- 5 files changed, 353 insertions(+), 38 deletions(-) rename src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/{CcdDashboardClaimMatcher.java => CcdDashboardClaimantClaimMatcher.java} (99%) create mode 100644 src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java diff --git a/build.gradle b/build.gradle index 2d2f22d5414..ca6ca6fb433 100644 --- a/build.gradle +++ b/build.gradle @@ -315,7 +315,7 @@ sonarqube { property "sonar.projectKey", "civil-service" property "sonar.coverage.jacoco.xmlReportPaths", "${jacocoTestReport.reports.xml.destination.path}" property "sonar.coverage.exclusions", "**/model/**, **/config/**/*Configuration.java, **/testingsupport/**, **/*ExternalTaskListener.java, **/*BaseExternalTaskHandler.java, **/stereotypes/**, **/*Exception.java, **/EventHistoryMapper*.java, **/model/hearingvalues/**, **/enums/hearing/**, **/fees/client/**, **/enums/sdo/**, **/service/PaymentsService.java, **/RetriggerCases*.java" - property "sonar.cpd.exclusions", "**/*DocumentManagementService.java, **/*Spec*.java" + property "sonar.cpd.exclusions", "**/*DocumentManagementService.java, **/*Spec*.java, **/*CcdDashboardClaimantClaimMatcher.java" property "sonar.exclusions", "**/hmc/model/**, **/model/hearingvalues/**" property "sonar.host.url", "https://sonar.reform.hmcts.net/" } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimMatcher.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimantClaimMatcher.java similarity index 99% rename from src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimMatcher.java rename to src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimantClaimMatcher.java index fe45e29d735..0b6bb762b99 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimMatcher.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardClaimantClaimMatcher.java @@ -18,7 +18,7 @@ @Slf4j @AllArgsConstructor -public class CcdDashboardClaimMatcher implements Claim { +public class CcdDashboardClaimantClaimMatcher implements Claim { private static final LocalTime FOUR_PM = LocalTime.of(16, 1, 0); private CaseData caseData; diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java new file mode 100644 index 00000000000..03a1ebab9d1 --- /dev/null +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdDashboardDefendantClaimMatcher.java @@ -0,0 +1,297 @@ +package uk.gov.hmcts.reform.civil.model.citizenui; + +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import uk.gov.hmcts.reform.civil.enums.CaseState; +import uk.gov.hmcts.reform.civil.enums.RespondentResponsePartAdmissionPaymentTimeLRspec; +import uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec; +import uk.gov.hmcts.reform.civil.enums.YesOrNo; +import uk.gov.hmcts.reform.civil.model.CaseData; +import uk.gov.hmcts.reform.civil.model.sdo.FastTrackHearingTime; +import uk.gov.hmcts.reform.civil.model.sdo.SmallClaimsHearing; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Objects; +import java.util.Optional; + +@Slf4j +@AllArgsConstructor +public class CcdDashboardDefendantClaimMatcher implements Claim { + + private static final LocalTime FOUR_PM = LocalTime.of(16, 1, 0); + private CaseData caseData; + private FeatureToggleService featureToggleService; + + @Override + public boolean hasResponsePending() { + return caseData.getRespondent1ResponseDate() == null && !isPaperResponse(); + } + + @Override + public boolean hasResponsePendingOverdue() { + return caseData.getRespondent1ResponseDeadline() != null + && caseData.getRespondent1ResponseDeadline().isBefore(LocalDate.now().atTime(FOUR_PM)) + && caseData.hasBreathingSpace(); + } + + @Override + public boolean hasResponseDueToday() { + return caseData.getRespondent1ResponseDeadline() != null + && caseData.getRespondent1ResponseDeadline().toLocalDate().isEqual(LocalDate.now()) + && caseData.getRespondent1ResponseDeadline().isBefore(LocalDate.now().atTime(FOUR_PM)); + } + + @Override + public boolean hasResponseFullAdmit() { + return caseData.getRespondent1ClaimResponseTypeForSpec() != null + && caseData.getRespondent1ClaimResponseTypeForSpec() == RespondentResponseTypeSpec.FULL_ADMISSION; + } + + @Override + public boolean defendantRespondedWithFullAdmitAndPayImmediately() { + return hasResponseFullAdmit() + && isPayImmediately(); + } + + @Override + public boolean defendantRespondedWithFullAdmitAndPayBySetDate() { + return hasResponseFullAdmit() + && caseData.isPayBySetDate() + && (Objects.isNull(caseData.getApplicant1AcceptFullAdmitPaymentPlanSpec())); + } + + @Override + public boolean defendantRespondedWithFullAdmitAndPayByInstallments() { + return hasResponseFullAdmit() + && caseData.isPayByInstallment() + && (Objects.isNull(caseData.getApplicant1AcceptFullAdmitPaymentPlanSpec())); + } + + @Override + public boolean hasResponseDeadlineBeenExtended() { + return caseData.getRespondent1TimeExtensionDate() != null; + } + + @Override + public boolean isEligibleForCCJ() { + return caseData.getRespondent1ResponseDeadline() != null + && caseData.getRespondent1ResponseDeadline().isBefore(LocalDate.now().atTime(FOUR_PM)) + && caseData.getPaymentTypeSelection() == null; + } + + @Override + public boolean claimantConfirmedDefendantPaid() { + return caseData.getRespondent1CourtOrderPayment() != null && caseData.respondent1PaidInFull(); + } + + @Override + public boolean isSettled() { + return !caseData.isRespondentResponseFullDefence() + && (caseData.respondent1PaidInFull() + || caseData.isResponseAcceptedByClaimant()) + && Objects.isNull(caseData.getCcjPaymentDetails()) + && !caseData.hasApplicantRejectedRepaymentPlan() + || caseData.isPartAdmitClaimSettled(); + } + + @Override + public boolean isSentToCourt() { + return false; + } + + @Override + public boolean claimantRequestedCountyCourtJudgement() { + return caseData.getApplicant1DQ() != null && caseData.getApplicant1DQ().getApplicant1DQRequestedCourt() != null + && !hasSdoBeenDrawn(); + } + + @Override + public boolean isWaitingForClaimantToRespond() { + return RespondentResponseTypeSpec.FULL_DEFENCE == caseData.getRespondent1ClaimResponseTypeForSpec() + && caseData.getApplicant1ResponseDate() == null; + } + + @Override + public boolean isProceedOffline() { + return false; + } + + @Override + public boolean isPaperResponse() { + if (!featureToggleService.isLipVLipEnabled()) { + return false; + } + + return Objects.nonNull(caseData.getTakenOfflineDate()) && Objects.nonNull(caseData.getCcdState()) + && caseData.getCcdState().equals(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM); + } + + @Override + public boolean hasChangeRequestFromDefendant() { + return false; + } + + @Override + public boolean hasChangeRequestedFromClaimant() { + return false; + } + + @Override + public boolean isPassedToCountyCourtBusinessCentre() { + return false; + } + + @Override + public boolean hasClaimantAskedToSignSettlementAgreement() { + return false; + } + + @Override + public boolean hasClaimantAcceptedPartialAdmissionAmount() { + return hasDefendantStatedTheyPaid() && caseData.isResponseAcceptedByClaimant(); + } + + @Override + public boolean haveBothPartiesSignedSettlementAgreement() { + return false; + } + + @Override + public boolean hasCCJByRedetermination() { + return caseData.hasApplicantAcceptedRepaymentPlan(); + } + + @Override + public boolean hasDefendantStatedTheyPaid() { + return defendantRespondedWithPartAdmit() + && isPayImmediately() && !caseData.getApplicant1ResponseDeadlinePassed() + && !(caseData.hasApplicantRejectedRepaymentPlan() || caseData.isPartAdmitClaimNotSettled()); + } + + private boolean isPayImmediately() { + return RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY == caseData.getDefenceAdmitPartPaymentTimeRouteRequired(); + } + + @Override + public boolean defendantRespondedWithPartAdmit() { + return RespondentResponseTypeSpec.PART_ADMISSION == caseData.getRespondent1ClaimResponseTypeForSpec() + && !caseData.getApplicant1ResponseDeadlinePassed() + && !(caseData.hasApplicantRejectedRepaymentPlan() || caseData.isPartAdmitClaimNotSettled()); + } + + @Override + public boolean isHearingFormGenerated() { + return !caseData.getHearingDocuments().isEmpty(); + } + + @Override + public boolean hasSdoBeenDrawn() { + return caseData.getSDODocument().isPresent(); + } + + @Override + public boolean isBeforeHearing() { + return isBeforeSmallClaimHearing() || (isBeforeFastTrackHearing() || noHearingScheduled()); + } + + private boolean noHearingScheduled() { + return caseData.getSmallClaimsHearing() == null && caseData.getFastTrackHearingTime() == null; + } + + private boolean isBeforeSmallClaimHearing() { + return Optional.ofNullable(caseData.getSmallClaimsHearing()) + .map(SmallClaimsHearing::getDateFrom) + .map(hearingFromDate -> hearingFromDate.isAfter(LocalDate.now())) + .orElse(false); + } + + private boolean isBeforeFastTrackHearing() { + return Optional.ofNullable(caseData.getFastTrackHearingTime()) + .map(FastTrackHearingTime::getDateFrom) + .map(hearingFromDate -> hearingFromDate.isAfter(LocalDate.now())) + .orElse(false); + } + + @Override + public boolean isMoreDetailsRequired() { + return hasSdoBeenDrawn() && isBeforeHearing() && featureToggleService.isCaseProgressionEnabled(); + } + + @Override + public boolean isMediationSuccessful() { + return !hasSdoBeenDrawn() + && Objects.nonNull(caseData.getMediation()) + && Objects.nonNull(caseData.getMediation().getMediationSuccessful()) + && Objects.nonNull(caseData.getMediation().getMediationSuccessful().getMediationAgreement()); + } + + @Override + public boolean isMediationUnsuccessful() { + return !hasSdoBeenDrawn() + && Objects.nonNull(caseData.getMediation()) + && Objects.nonNull(caseData.getMediation().getUnsuccessfulMediationReason()) + && !caseData.getMediation().getUnsuccessfulMediationReason().isEmpty(); + } + + @Override + public boolean isMediationPending() { + return Objects.nonNull(caseData.getCcdState()) + && caseData.getCcdState().equals(CaseState.IN_MEDIATION) + && Objects.nonNull(caseData.getMediation()) + && Objects.nonNull(caseData.getMediation().getMediationSuccessful()) + && Objects.isNull(caseData.getMediation().getMediationSuccessful().getMediationAgreement()); + } + + @Override + public boolean isCourtReviewing() { + return (!hasSdoBeenDrawn() + && caseData.isRespondentResponseFullDefence() + && caseData.getCcdState().equals(CaseState.JUDICIAL_REFERRAL)) + || (caseData.hasApplicantRejectedRepaymentPlan()); + } + + @Override + public boolean hasClaimEnded() { + return (Objects.nonNull(caseData.getApplicant1ProceedsWithClaimSpec()) + && caseData.getApplicant1ProceedsWithClaimSpec().equals(YesOrNo.NO) + && caseData.isRespondentResponseFullDefence()) + || caseData.getApplicant1ResponseDeadlinePassed(); + } + + @Override + public boolean isClaimRejectedAndOfferSettleOutOfCourt() { + return false; + } + + @Override + public boolean claimantAcceptedOfferOutOfCourt() { + return false; + } + + @Override + public boolean hasClaimantRejectOffer() { + return false; + } + + @Override + public boolean isPartialAdmissionRejected() { + return CaseState.JUDICIAL_REFERRAL.equals(caseData.getCcdState()) + && caseData.isPartAdmitClaimSpec(); + } + + @Override + public boolean isSDOOrderCreated() { + return caseData.getHearingDate() == null + && CaseState.CASE_PROGRESSION.equals(caseData.getCcdState()); + } + + @Override + public boolean isClaimantDefaultJudgement() { + return caseData.getRespondent1ResponseDeadline() != null + && caseData.getRespondent1ResponseDeadline().isBefore(LocalDate.now().atTime(FOUR_PM)) + && caseData.getPaymentTypeSelection() != null; + } + +} diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/DashboardClaimInfoService.java b/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/DashboardClaimInfoService.java index 058ab6c0eb8..80c31e0759f 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/DashboardClaimInfoService.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/citizenui/DashboardClaimInfoService.java @@ -7,8 +7,10 @@ import uk.gov.hmcts.reform.ccd.client.model.SearchResult; import uk.gov.hmcts.reform.civil.helpers.CaseDetailsConverter; import uk.gov.hmcts.reform.civil.model.CaseData; -import uk.gov.hmcts.reform.civil.model.citizenui.CcdDashboardClaimMatcher; +import uk.gov.hmcts.reform.civil.model.citizenui.CcdDashboardClaimantClaimMatcher; +import uk.gov.hmcts.reform.civil.model.citizenui.CcdDashboardDefendantClaimMatcher; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardClaimInfo; +import uk.gov.hmcts.reform.civil.model.citizenui.DashboardClaimStatus; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardClaimStatusFactory; import uk.gov.hmcts.reform.civil.model.citizenui.DashboardResponse; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; @@ -54,7 +56,7 @@ public DashboardResponse getDashboardDefendantResponse(String authorisation, Str var ccdData = coreCaseDataService.getCCDClaimsForLipDefendant(authorisation, startIndex); int totalPages = getTotalPagesToBeListed(ccdData.getTotal() + ocmcClaims.size()); List currentPageItems = currentPage <= totalPages - ? getDashboardItemsForCurrentPage(ocmcClaims, currentPage, ccdData) : + ? getDashboardItemsForCurrentPage(ocmcClaims, currentPage, ccdData, false) : Collections.emptyList(); return DashboardResponse.builder().totalPages(totalPages).claims(currentPageItems).build(); } @@ -71,7 +73,7 @@ public DashboardResponse getDashboardClaimantResponse(String authorisation, Stri int totalPages = getTotalPagesToBeListed(getCcdClaimsCount(ccdData) + ocmcClaims.size()); List currentPageItems = currentPage <= totalPages - ? getDashboardItemsForCurrentPage(ocmcClaims, currentPage, ccdData) : + ? getDashboardItemsForCurrentPage(ocmcClaims, currentPage, ccdData, true) : Collections.emptyList(); return DashboardResponse.builder().totalPages(totalPages).claims(currentPageItems).build(); } @@ -84,7 +86,8 @@ private List getClaimsForClaimant(String authorisation, Stri private List getDashboardItemsForCurrentPage(List ocmcClaims, int currentPage, - SearchResult ccdClaims) { + SearchResult ccdClaims, + boolean isClaimant) { int startIndex = (currentPage - 1) * CASES_PER_PAGE; int endIndex = startIndex + CASES_PER_PAGE; @@ -96,7 +99,7 @@ private List getDashboardItemsForCurrentPage(List ccdClaimsCount) { int remainingRecords = CASES_PER_PAGE - ccdData.size(); @@ -114,16 +117,19 @@ private List sortOcmcCases(List ocmcCase .collect(Collectors.toList()); } - private List translateSearchResultToDashboardItems(SearchResult claims) { + private List translateSearchResultToDashboardItems(SearchResult claims, boolean isClaimant) { if (claims == null) { return Collections.emptyList(); } - return claims.getCases().stream().map(caseDetails -> translateCaseDataToDashboardClaimInfo(caseDetails)) + return claims.getCases().stream().map(caseDetails -> translateCaseDataToDashboardClaimInfo( + caseDetails, + isClaimant + )) .collect(Collectors.toList()); } - private DashboardClaimInfo translateCaseDataToDashboardClaimInfo(CaseDetails caseDetails) { + private DashboardClaimInfo translateCaseDataToDashboardClaimInfo(CaseDetails caseDetails, boolean isClaimant) { CaseData caseData = caseDetailsConverter.toCaseData(caseDetails); DashboardClaimInfo item = DashboardClaimInfo.builder().claimId(String.valueOf(caseData.getCcdCaseReference())) .createdDate(submittedDateToCreatedDate(caseData)) @@ -133,7 +139,7 @@ private DashboardClaimInfo translateCaseDataToDashboardClaimInfo(CaseDetails cas .claimAmount(nonNull(caseData.getTotalClaimAmount()) ? caseData.getTotalClaimAmount() : null) .admittedAmount(caseData.getPartAdmitPaidValuePounds()) .responseDeadlineTime(caseData.getRespondent1ResponseDeadline()) - .status(dashboardClaimStatusFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher(caseData, featureToggleService))) + .status(getStatus(isClaimant, caseData)) .build(); if (caseData.getRespondent1ResponseDeadline() != null) { item.setResponseDeadline(caseData.getRespondent1ResponseDeadline().toLocalDate()); @@ -170,4 +176,16 @@ private int getCcdClaimsCount(final SearchResult ccdClaims) { return Optional.ofNullable(ccdClaims).map(SearchResult::getTotal).orElse(0); } + + private DashboardClaimStatus getStatus(boolean isClaimant, CaseData caseData) { + return isClaimant + ? dashboardClaimStatusFactory.getDashboardClaimStatus(new CcdDashboardClaimantClaimMatcher( + caseData, + featureToggleService + )) + : dashboardClaimStatusFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( + caseData, + featureToggleService + )); + } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdClaimStatusDashboardFactoryTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdClaimStatusDashboardFactoryTest.java index 50208255a98..3b77acb3d44 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdClaimStatusDashboardFactoryTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/citizenui/CcdClaimStatusDashboardFactoryTest.java @@ -56,7 +56,7 @@ void given_hasResponsePending_whenGetStatus_thenReturnNoResponse() { .respondent1ResponseDeadline(LocalDate.now().plusDays(10).atTime(16, 0, 0)) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.NO_RESPONSE); } @@ -68,7 +68,7 @@ void given_isEligibleForCCJ_whenGetStatus_thenReturnEligibleForCCJStatus() { .respondent1ResponseDeadline(LocalDateTime.of(2022, 2, 2, 16, 0)) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.ELIGIBLE_FOR_CCJ); } @@ -81,7 +81,7 @@ void given_isEligibleForCCJ_whenGetStatus_thenReturnDefaultJudgementStatus() { .paymentTypeSelection(DJPaymentTypeSelection.IMMEDIATELY) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.DEFAULT_JUDGEMENT); } @@ -92,7 +92,7 @@ void given_hasResponseDueToday_whenGetStatus_thenReturnResponseDueNow() { .respondent1ResponseDeadline(LocalDate.now().atTime(10, 0, 0)) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.RESPONSE_DUE_NOW); } @@ -104,7 +104,7 @@ void given_moreTimeRequested_whenGetStatus_thenReturnMoreTimeRequested() { .respondent1TimeExtensionDate(LocalDateTime.now().plusDays(30)) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.MORE_TIME_REQUESTED); } @@ -113,7 +113,7 @@ void given_moreTimeRequested_whenGetStatus_thenReturnMoreTimeRequested() { void given_responseAdmitPayImmediately_whenGetStatus_thenReturnAdmitPayImmediately() { CaseData claim = getClaimWithFullAdmitResponse(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.ADMIT_PAY_IMMEDIATELY); } @@ -122,7 +122,7 @@ void given_responseAdmitPayImmediately_whenGetStatus_thenReturnAdmitPayImmediate void given_responseAdmitPayBySetDate_whenGetStatus_thenReturnAdmitPayBySetDate() { CaseData claim = getClaimWithFullAdmitResponse(RespondentResponsePartAdmissionPaymentTimeLRspec.BY_SET_DATE); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.ADMIT_PAY_BY_SET_DATE); } @@ -131,7 +131,7 @@ void given_responseAdmitPayBySetDate_whenGetStatus_thenReturnAdmitPayBySetDate() void given_responseAdmitPayByInstallments_whenGetStatus_thenReturnAdmitPayByInstallments() { CaseData claim = getClaimWithFullAdmitResponse(RespondentResponsePartAdmissionPaymentTimeLRspec.SUGGESTION_OF_REPAYMENT_PLAN); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.ADMIT_PAY_INSTALLMENTS); } @@ -145,7 +145,7 @@ void given_claimantConfirmedDefendantPaid_whenGetStatus_thenReturnClaimantAccept .respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.CLAIMANT_ACCEPTED_STATES_PAID); } @@ -158,7 +158,7 @@ void given_defendantPayedInFull_whenGetStatus_thenReturnSettled() { .respondent1ClaimResponsePaymentAdmissionForSpec(RespondentResponseTypeSpecPaidStatus.PAID_FULL_OR_MORE_THAN_CLAIMED_AMOUNT) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.SETTLED); } @@ -171,7 +171,7 @@ void given_claimantAcceptedDefendantResponse_whenGetStatus_thenReturnSettled() { .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.YES) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.SETTLED); } @@ -184,7 +184,7 @@ void given_claimantRequestedCountyCourtJudgement_whenGetStatus_thenReturnRequest .applicant1DQ(Applicant1DQ.builder().applicant1DQRequestedCourt(RequestedCourt.builder().build()).build()) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.REQUESTED_COUNTRY_COURT_JUDGEMENT); } @@ -198,7 +198,7 @@ void given_claimantAcceptedAdmission_whenGetStatus_thenReturnRelevantStatus() { .defenceAdmitPartPaymentTimeRouteRequired(RespondentResponsePartAdmissionPaymentTimeLRspec.IMMEDIATELY) .applicant1AcceptPartAdmitPaymentPlanSpec(YesOrNo.YES) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.CLAIMANT_ACCEPTED_ADMISSION_OF_AMOUNT); } @@ -210,7 +210,7 @@ void given_defendantRespondedWithPartAdmit_whenGetStatus_thenReturnRelevantStatu .respondent1ResponseDate(LocalDateTime.now()) .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.DEFENDANT_PART_ADMIT); } @@ -223,7 +223,7 @@ void given_hearingNoticeDocumentIssued_whenGetStatus_thenReturnHearingFormGenera .documentName("testDoc") .build()).build())) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.HEARING_FORM_GENERATED); } @@ -244,7 +244,7 @@ void given_hearingDateForSmallClaimIsAfterToday_and_SDOBeenDrawn_whenGetStatus_m .systemGeneratedCaseDocuments(List.of(document)) .build(); given(featureToggleService.isCaseProgressionEnabled()).willReturn(true); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.MORE_DETAILS_REQUIRED); } @@ -265,7 +265,7 @@ void given_hearingDateForFastTrackClaimIsAfterToday_and_SDOBeenDrawn_whenGetStat .systemGeneratedCaseDocuments(List.of(document)) .build(); given(featureToggleService.isCaseProgressionEnabled()).willReturn(true); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.MORE_DETAILS_REQUIRED); } @@ -280,7 +280,7 @@ void given_mediation_whenGetSatus_mediationSuccessful() { .build()) .build()) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.MEDIATION_SUCCESSFUL); } @@ -293,7 +293,7 @@ void given_mediation_whenGetStatus_mediationUnsuccessful() { .unsuccessfulMediationReason("this is a reason") .build()) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.MEDIATION_UNSUCCESSFUL); } @@ -308,7 +308,7 @@ void given_mediation_whenGetStatus_mediationPending() { .build()) .build()) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.IN_MEDIATION); } @@ -321,7 +321,7 @@ void given_court_whenGetStatus_courtReview() { .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) .applicant1ResponseDate(LocalDateTime.now()) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.WAITING_COURT_REVIEW); } @@ -334,7 +334,7 @@ void given_respondentFullDefenceAndApplicantNotProceedsWithClaim_whenGetStatus_c .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) .applicant1ResponseDate(LocalDateTime.now()) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.CLAIM_ENDED); } @@ -347,7 +347,7 @@ void given_applicantRejectPartialAdmit_whenGetStatus_rejectOffer() { .applicant1AcceptPartAdmitPaymentPlanSpec(YesOrNo.NO) .ccdState(CaseState.JUDICIAL_REFERRAL) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.CLAIMANT_REJECT_PARTIAL_ADMISSION); } @@ -376,7 +376,7 @@ void given_SDOBeenDrawn_whenGetStatus_sdoOrderCreatedRequired() { .ccdState(CaseState.CASE_PROGRESSION) .build(); DashboardClaimStatus status = - ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.SDO_ORDER_CREATED); } @@ -388,7 +388,7 @@ void given_claimantNotRespondedWithInDeadLine_whenGetStatus_claimEnded() { .applicant1ResponseDeadline(LocalDateTime.now().minusDays(1)) .build(); DashboardClaimStatus status = - ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.CLAIM_ENDED); } @@ -401,7 +401,7 @@ void given_claimantRejectsDefendantsPaymentPlan() { .applicant1AcceptPartAdmitPaymentPlanSpec(YesOrNo.NO) .ccdState(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.WAITING_COURT_REVIEW); } @@ -418,7 +418,7 @@ void givenClaimStatusInProcessHeritageSystem_WhenGetStatus_thenReturnResponseByP .ccdState(CaseState.PROCEEDS_IN_HERITAGE_SYSTEM) .build(); - DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardClaimMatcher( + DashboardClaimStatus status = ccdClaimStatusDashboardFactory.getDashboardClaimStatus(new CcdDashboardDefendantClaimMatcher( claim, featureToggleService)); assertThat(status).isEqualTo(DashboardClaimStatus.RESPONSE_BY_POST); From 683792fe165c3d8419606854effad26312846bc6 Mon Sep 17 00:00:00 2001 From: Gareth Lancaster <90632240+Gareth40343@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:55:20 +0000 Subject: [PATCH 28/29] CIV-9927 Free form order uplift (#3551) --- .../reform/civil/model/CaseDataParent.java | 10 + .../JudgeFinalOrderGenerator.java | 36 +- .../reform/civil/model/CaseDataTest.java | 367 ++++++++++-------- .../JudgeFinalOrderGeneratorTest.java | 185 ++++++++- 4 files changed, 429 insertions(+), 169 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java index 7d2a5546ce9..84f5051d9b0 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/model/CaseDataParent.java @@ -67,6 +67,7 @@ import uk.gov.hmcts.reform.civil.model.citizenui.RespondentLiPResponse; import uk.gov.hmcts.reform.civil.model.citizenui.TranslatedDocument; import uk.gov.hmcts.reform.civil.model.common.DynamicList; +import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.model.common.MappableObject; import uk.gov.hmcts.reform.civil.model.defaultjudgment.DisposalHearingBundleDJ; @@ -155,6 +156,7 @@ import java.util.Set; import static java.math.BigDecimal.ZERO; +import static java.util.Optional.ofNullable; import static uk.gov.hmcts.reform.civil.enums.YesOrNo.YES; @Jacksonized @@ -780,4 +782,12 @@ public boolean hasClaimantNotAgreedToFreeMediation() { .map(CaseDataLiP::getApplicant1ClaimMediationSpecRequiredLip) .filter(ClaimantMediationLip::hasClaimantNotAgreedToFreeMediation).isPresent(); } + + @JsonIgnore + public String getHearingLocationText() { + return ofNullable(hearingLocation) + .map(DynamicList::getValue) + .map(DynamicListElement::getLabel) + .orElse(null); + } } diff --git a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGenerator.java b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGenerator.java index d39136c1ce4..3d281db4b71 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGenerator.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGenerator.java @@ -17,8 +17,10 @@ import uk.gov.hmcts.reform.civil.model.CaseData; import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; import uk.gov.hmcts.reform.civil.model.docmosis.casepogression.JudgeFinalOrderForm; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataException; import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentHearingLocationHelper; @@ -29,8 +31,10 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.stream.Collectors; import static java.lang.String.format; import static java.util.Objects.nonNull; @@ -43,6 +47,7 @@ import static uk.gov.hmcts.reform.civil.helpers.DateFormatHelper.formatLocalDate; import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.ASSISTED_ORDER_PDF; import static uk.gov.hmcts.reform.civil.service.docmosis.DocmosisTemplates.FREE_FORM_ORDER_PDF; +import static uk.gov.hmcts.reform.civil.service.robotics.utils.RoboticsDataUtil.CIVIL_COURT_TYPE_ID; @Slf4j @Service @@ -54,6 +59,7 @@ public class JudgeFinalOrderGenerator implements TemplateDataGenerator matchingLocations = locationRefDataService.getCourtLocationsByEpimmsId( + authorisation, caseData.getCaseManagementLocation().getBaseLocation()) + .stream().filter(id -> id.getCourtTypeId().equals(CIVIL_COURT_TYPE_ID)) + .collect(Collectors.toList()); + + if (matchingLocations.size() != 1) { + throw new LocationRefDataException( + String.format( + "Unexpected amount of locations (%d) where matched against location epimms id: %s", + matchingLocations.size(), + locationEpimms + )); + } + + return LocationRefDataService.getDisplayEntry(matchingLocations.get(0)); + } + + private String getHearingLocationText(CaseData caseData, String authorisation) { + return caseData.getHearingLocationText() != null ? caseData.getHearingLocationText() + : getCaseManagementLocationText(caseData, authorisation); + } + +} diff --git a/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java b/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java index 1a3f90ae40f..9a5eea4a631 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/model/CaseDataTest.java @@ -1,5 +1,6 @@ package uk.gov.hmcts.reform.civil.model; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import uk.gov.hmcts.reform.ccd.model.Organisation; import uk.gov.hmcts.reform.ccd.model.OrganisationPolicy; @@ -11,6 +12,8 @@ import uk.gov.hmcts.reform.civil.handler.callback.user.spec.show.ResponseOneVOneShowTag; import uk.gov.hmcts.reform.civil.model.citizenui.CaseDataLiP; import uk.gov.hmcts.reform.civil.model.citizenui.ClaimantMediationLip; +import uk.gov.hmcts.reform.civil.model.common.DynamicList; +import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; import uk.gov.hmcts.reform.civil.model.common.Element; import uk.gov.hmcts.reform.civil.model.dq.RecurringExpenseLRspec; import uk.gov.hmcts.reform.civil.model.dq.RecurringIncomeLRspec; @@ -25,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.DEFENCE_TRANSLATED_DOCUMENT; import static uk.gov.hmcts.reform.civil.enums.RespondentResponseTypeSpec.FULL_ADMISSION; @@ -43,16 +47,16 @@ public class CaseDataTest { @Test public void applicant1Proceed_when1v1() { CaseData caseData = CaseData.builder() - .applicant1ProceedWithClaim(YesOrNo.YES) - .build(); + .applicant1ProceedWithClaim(YesOrNo.YES) + .build(); assertEquals(YesOrNo.YES, caseData.getApplicant1ProceedsWithClaimSpec()); } @Test public void applicant1Proceed_when2v1() { CaseData caseData = CaseData.builder() - .applicant1ProceedWithClaimSpec2v1(YesOrNo.YES) - .build(); + .applicant1ProceedWithClaimSpec2v1(YesOrNo.YES) + .build(); assertEquals(YesOrNo.YES, caseData.getApplicant1ProceedsWithClaimSpec()); } @@ -60,12 +64,12 @@ public void applicant1Proceed_when2v1() { void givenApplicantAgreedToMediation_whenHasClaimantAgreedToFreeMediation_thenTrue() { //Given CaseData caseData = CaseData.builder() - .caseDataLiP(CaseDataLiP.builder() - .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() - .hasAgreedFreeMediation(MediationDecision.Yes) - .build()) - .build()) - .build(); + .caseDataLiP(CaseDataLiP.builder() + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() + .hasAgreedFreeMediation(MediationDecision.Yes) + .build()) + .build()) + .build(); //When boolean result = caseData.hasClaimantAgreedToFreeMediation(); //Then @@ -86,12 +90,12 @@ void givenNoDataForAgreedToMediation_whenHasClaimantAgreedToFeeMediation_thenFal void givenApplicantDidNotAgreeToFreeMediation_whenHasClaimantAgreedToFeeMediation_thenFalse() { //Given CaseData caseData = CaseData.builder() - .caseDataLiP(CaseDataLiP.builder() - .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() - .hasAgreedFreeMediation(MediationDecision.No) - .build()) - .build()) - .build(); + .caseDataLiP(CaseDataLiP.builder() + .applicant1ClaimMediationSpecRequiredLip(ClaimantMediationLip.builder() + .hasAgreedFreeMediation(MediationDecision.No) + .build()) + .build()) + .build(); //When boolean result = caseData.hasClaimantAgreedToFreeMediation(); //Then @@ -122,11 +126,11 @@ void givenNotOneVTwoTwoLegalRepCaseResponsePartAdmit_whenIsRespondentResponseFul void givenOneVTwoTwoLegalRepCaseRespondent1FullDefence_whenIsRespondentResponseFullDefence_thenFalse() { //Given CaseData caseData = CaseData.builder() - .respondent1(PartyBuilder.builder().build()) - .respondent2(PartyBuilder.builder().build()) - .applicant1(PartyBuilder.builder().build()) - .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) - .build(); + .respondent1(PartyBuilder.builder().build()) + .respondent2(PartyBuilder.builder().build()) + .applicant1(PartyBuilder.builder().build()) + .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) + .build(); //When boolean result = caseData.isRespondentResponseFullDefence(); //Then @@ -137,12 +141,12 @@ void givenOneVTwoTwoLegalRepCaseRespondent1FullDefence_whenIsRespondentResponseF void givenOneVTwoTwoLegalRepCaseRespondent1And2FullDefence_whenIsRespondentResponseFullDefence_thenTrue() { //Given CaseData caseData = CaseData.builder() - .respondent1(PartyBuilder.builder().build()) - .respondent2(PartyBuilder.builder().build()) - .applicant1(PartyBuilder.builder().build()) - .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) - .respondent2ClaimResponseTypeForSpec(FULL_DEFENCE) - .build(); + .respondent1(PartyBuilder.builder().build()) + .respondent2(PartyBuilder.builder().build()) + .applicant1(PartyBuilder.builder().build()) + .respondent1ClaimResponseTypeForSpec(FULL_DEFENCE) + .respondent2ClaimResponseTypeForSpec(FULL_DEFENCE) + .build(); //When boolean result = caseData.isRespondentResponseFullDefence(); //Then @@ -153,10 +157,10 @@ void givenOneVTwoTwoLegalRepCaseRespondent1And2FullDefence_whenIsRespondentRespo void applicant_partAdmitClaimSettled() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) - .build(); + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) + .build(); //When //Then assertTrue(caseData.isPartAdmitClaimSettled()); @@ -166,10 +170,10 @@ void applicant_partAdmitClaimSettled() { void applicant_partAdmitClaimNotSettled() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) - .build(); + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) + .build(); //When //Then assertTrue(caseData.isPartAdmitClaimNotSettled()); @@ -179,8 +183,8 @@ void applicant_partAdmitClaimNotSettled() { void applicant_isClaimPartAdmitSpec() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) - .build(); + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .build(); //When //Then assertTrue(caseData.isPartAdmitClaimSpec()); @@ -190,8 +194,8 @@ void applicant_isClaimPartAdmitSpec() { void applicant_isPartAdmitIntentionToSettleClaim() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) - .build(); + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) + .build(); //When //Then assertTrue(caseData.isClaimantIntentionSettlePartAdmit()); @@ -201,8 +205,8 @@ void applicant_isPartAdmitIntentionToSettleClaim() { void applicant_isPartAdmitIntentionNotToSettleClaim() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.NO) - .build(); + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.NO) + .build(); //When //Then assertTrue(caseData.isClaimantIntentionNotSettlePartAdmit()); @@ -212,8 +216,8 @@ void applicant_isPartAdmitIntentionNotToSettleClaim() { void applicant_isPartAdmitConfirmAmountPaid() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) + .build(); //When //Then assertTrue(caseData.isClaimantConfirmAmountPaidPartAdmit()); @@ -223,8 +227,8 @@ void applicant_isPartAdmitConfirmAmountPaid() { void applicant_isPartAdmitConfirmAmountNotPaid() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) + .build(); assertTrue(caseData.isClaimantConfirmAmountNotPaidPartAdmit()); } @@ -232,11 +236,11 @@ void applicant_isPartAdmitConfirmAmountNotPaid() { public void givenRespondentUnrepresentedAndOnevOne_whenIsLRvLipOneVOne_thenTrue() { //Given CaseData caseData = CaseData.builder() - .respondent1Represented(YesOrNo.NO) - .applicant1Represented(YesOrNo.YES) - .respondent1(Party.builder().build()) - .applicant1(Party.builder().build()) - .build(); + .respondent1Represented(YesOrNo.NO) + .applicant1Represented(YesOrNo.YES) + .respondent1(Party.builder().build()) + .applicant1(Party.builder().build()) + .build(); //Then assertTrue(caseData.isLRvLipOneVOne()); } @@ -245,11 +249,11 @@ public void givenRespondentUnrepresentedAndOnevOne_whenIsLRvLipOneVOne_thenTrue( public void givenRespondentRepresentedAndOnevOne_whenIsLRvLipOneVOne_thenFalse() { //Given CaseData caseData = CaseData.builder() - .respondent1Represented(YesOrNo.YES) - .applicant1Represented(YesOrNo.YES) - .respondent1(Party.builder().build()) - .applicant1(Party.builder().build()) - .build(); + .respondent1Represented(YesOrNo.YES) + .applicant1Represented(YesOrNo.YES) + .respondent1(Party.builder().build()) + .applicant1(Party.builder().build()) + .build(); //Then assertFalse(caseData.isLRvLipOneVOne()); } @@ -258,11 +262,11 @@ public void givenRespondentRepresentedAndOnevOne_whenIsLRvLipOneVOne_thenFalse() public void givenApplicantUnrepresentedAndOnevOne_whenIsLRvLipOneVOne_thenFalse() { //Given CaseData caseData = CaseData.builder() - .respondent1Represented(YesOrNo.NO) - .applicant1Represented(YesOrNo.NO) - .respondent1(Party.builder().build()) - .applicant1(Party.builder().build()) - .build(); + .respondent1Represented(YesOrNo.NO) + .applicant1Represented(YesOrNo.NO) + .respondent1(Party.builder().build()) + .applicant1(Party.builder().build()) + .build(); //Then assertFalse(caseData.isLRvLipOneVOne()); } @@ -271,11 +275,11 @@ public void givenApplicantUnrepresentedAndOnevOne_whenIsLRvLipOneVOne_thenFalse( public void givenRespondentUnrepresentedAndApplicantUnrepresentedAndOnevOne_whenIsLipvLipOneVOne_thenTrue() { //Given CaseData caseData = CaseData.builder() - .respondent1Represented(YesOrNo.NO) - .applicant1Represented(YesOrNo.NO) - .respondent1(Party.builder().build()) - .applicant1(Party.builder().build()) - .build(); + .respondent1Represented(YesOrNo.NO) + .applicant1Represented(YesOrNo.NO) + .respondent1(Party.builder().build()) + .applicant1(Party.builder().build()) + .build(); //Then assertTrue(caseData.isLipvLipOneVOne()); } @@ -284,9 +288,9 @@ public void givenRespondentUnrepresentedAndApplicantUnrepresentedAndOnevOne_when public void givenApplicantUnrepresented_whenIsApplicant1NotRepresented_thenTrue() { //Given CaseData caseData = CaseData.builder() - .applicant1Represented(YesOrNo.NO) - .applicant1(Party.builder().build()) - .build(); + .applicant1Represented(YesOrNo.NO) + .applicant1(Party.builder().build()) + .build(); //Then assertTrue(caseData.isApplicant1NotRepresented()); } @@ -295,9 +299,9 @@ public void givenApplicantUnrepresented_whenIsApplicant1NotRepresented_thenTrue( public void givenApplicantRepresented_whenIsApplicant1NotRepresented_thenFalse() { //Given CaseData caseData = CaseData.builder() - .applicant1Represented(YesOrNo.YES) - .applicant1(Party.builder().build()) - .build(); + .applicant1Represented(YesOrNo.YES) + .applicant1(Party.builder().build()) + .build(); //Then assertFalse(caseData.isApplicant1NotRepresented()); } @@ -306,10 +310,10 @@ public void givenApplicantRepresented_whenIsApplicant1NotRepresented_thenFalse() void isClaimantNotSettlePartAdmitClaim_thenTrue() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.NO) - .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.NO) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.NO) + .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.NO) + .build(); //When //Then assertTrue(caseData.isClaimantNotSettlePartAdmitClaim()); @@ -319,10 +323,10 @@ void isClaimantNotSettlePartAdmitClaim_thenTrue() { void isClaimantNotSettlePartAdmitClaim_thenFalse() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) - .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.YES) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) + .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.YES) + .build(); //When //Then assertFalse(caseData.isClaimantNotSettlePartAdmitClaim()); @@ -332,10 +336,10 @@ void isClaimantNotSettlePartAdmitClaim_thenFalse() { void doesPartPaymentRejectedOrItsFullDefenceResponse_fullDefence() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) - .applicant1ProceedWithClaim(YesOrNo.YES) - .applicant1ProceedWithClaimSpec2v1(YesOrNo.YES) - .build(); + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.FULL_DEFENCE) + .applicant1ProceedWithClaim(YesOrNo.YES) + .applicant1ProceedWithClaimSpec2v1(YesOrNo.YES) + .build(); //When //Then assertEquals(YesOrNo.YES, caseData.doesPartPaymentRejectedOrItsFullDefenceResponse()); @@ -345,10 +349,10 @@ void doesPartPaymentRejectedOrItsFullDefenceResponse_fullDefence() { void doesPartPaymentRejectedOrItsFullDefenceResponse_partAdmitRejectYes() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.NO) - .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.NO) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.NO) + .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.NO) + .build(); //When //Then assertEquals(YesOrNo.YES, caseData.doesPartPaymentRejectedOrItsFullDefenceResponse()); @@ -358,10 +362,10 @@ void doesPartPaymentRejectedOrItsFullDefenceResponse_partAdmitRejectYes() { void doesPartPaymentRejectedOrItsFullDefenceResponse_partAdmitRejectNo() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) - .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.YES) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) + .applicant1AcceptAdmitAmountPaidSpec(YesOrNo.YES) + .build(); //When //Then assertEquals(YesOrNo.NO, caseData.doesPartPaymentRejectedOrItsFullDefenceResponse()); @@ -371,8 +375,8 @@ void doesPartPaymentRejectedOrItsFullDefenceResponse_partAdmitRejectNo() { void hasDefendantNotAgreedToFreeMediation_Yes() { //Given CaseData caseData = CaseData.builder() - .responseClaimMediationSpecRequired(YesOrNo.YES) - .build(); + .responseClaimMediationSpecRequired(YesOrNo.YES) + .build(); //When //Then assertFalse(caseData.hasDefendantNotAgreedToFreeMediation()); @@ -382,8 +386,8 @@ void hasDefendantNotAgreedToFreeMediation_Yes() { void hasDefendantNotAgreedToFreeMediation_No() { //Given CaseData caseData = CaseData.builder() - .responseClaimMediationSpecRequired(YesOrNo.NO) - .build(); + .responseClaimMediationSpecRequired(YesOrNo.NO) + .build(); //When //Then assertTrue(caseData.hasDefendantNotAgreedToFreeMediation()); @@ -393,8 +397,8 @@ void hasDefendantNotAgreedToFreeMediation_No() { void isFastTrackClaim_thenTrue() { //Given CaseData caseData = CaseData.builder() - .responseClaimTrack(AllocatedTrack.FAST_CLAIM.name()) - .build(); + .responseClaimTrack(AllocatedTrack.FAST_CLAIM.name()) + .build(); //When //Then assertTrue(caseData.isFastTrackClaim()); @@ -404,8 +408,8 @@ void isFastTrackClaim_thenTrue() { void isFastTrackClaim_thenFalse() { //Given CaseData caseData = CaseData.builder() - .responseClaimTrack(AllocatedTrack.SMALL_CLAIM.name()) - .build(); + .responseClaimTrack(AllocatedTrack.SMALL_CLAIM.name()) + .build(); //When //Then assertFalse(caseData.isFastTrackClaim()); @@ -415,8 +419,8 @@ void isFastTrackClaim_thenFalse() { void isSmallClaim_thenTrue() { //Given CaseData caseData = CaseData.builder() - .responseClaimTrack(AllocatedTrack.SMALL_CLAIM.name()) - .build(); + .responseClaimTrack(AllocatedTrack.SMALL_CLAIM.name()) + .build(); //When //Then assertTrue(caseData.isSmallClaim()); @@ -426,8 +430,8 @@ void isSmallClaim_thenTrue() { void isSmallClaim_thenFalse() { //Given CaseData caseData = CaseData.builder() - .responseClaimTrack(AllocatedTrack.FAST_CLAIM.name()) - .build(); + .responseClaimTrack(AllocatedTrack.FAST_CLAIM.name()) + .build(); //When //Then assertFalse(caseData.isSmallClaim()); @@ -437,9 +441,9 @@ void isSmallClaim_thenFalse() { void isRejectWithMediation_thenFalse() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) - .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.YES) + .applicant1PartAdmitIntentionToSettleClaimSpec(YesOrNo.YES) + .build(); //When //Then assertFalse(caseData.isRejectWithNoMediation()); @@ -449,9 +453,9 @@ void isRejectWithMediation_thenFalse() { void isRejectWithMediation_thenTrue() { //Given CaseData caseData = CaseData.builder() - .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) - .responseClaimMediationSpecRequired(YesOrNo.NO) - .build(); + .applicant1PartAdmitConfirmAmountPaidSpec(YesOrNo.NO) + .responseClaimMediationSpecRequired(YesOrNo.NO) + .build(); //When //Then assertTrue(caseData.isRejectWithNoMediation()); @@ -462,12 +466,12 @@ void shouldGetApplicantOrganisationId_whenOrganisationDetailsArePresent() { //Given String organisationId = "1245"; CaseData caseData = CaseData.builder() - .applicant1OrganisationPolicy(OrganisationPolicy.builder() - .organisation(Organisation.builder() - .organisationID(organisationId) - .build()) - .build()) - .build(); + .applicant1OrganisationPolicy(OrganisationPolicy.builder() + .organisation(Organisation.builder() + .organisationID(organisationId) + .build()) + .build()) + .build(); //When String result = caseData.getApplicantOrganisationId(); //Then @@ -488,7 +492,7 @@ void shouldReturnEmptyString_whenNoOrganisationDetailsArePresent() { void isTranslatedDocumentUploaded_thenFalse() { //Given CaseData caseData = CaseData.builder() - .systemGeneratedCaseDocuments(null).build(); + .systemGeneratedCaseDocuments(null).build(); //When //Then assertFalse(caseData.isTranslatedDocumentUploaded()); @@ -498,7 +502,7 @@ void isTranslatedDocumentUploaded_thenFalse() { void isTranslatedDocumentUploaded_thenTrue() { //Given CaseData caseData = CaseData.builder() - .systemGeneratedCaseDocuments(wrapElements(CaseDocument.builder().documentType(DEFENCE_TRANSLATED_DOCUMENT).build())).build(); + .systemGeneratedCaseDocuments(wrapElements(CaseDocument.builder().documentType(DEFENCE_TRANSLATED_DOCUMENT).build())).build(); //When //Then assertTrue(caseData.isTranslatedDocumentUploaded()); @@ -507,7 +511,7 @@ void isTranslatedDocumentUploaded_thenTrue() { @Test void getSDOOrderDocument_WhenItPresent() { CaseData caseData = CaseData.builder() - .systemGeneratedCaseDocuments(wrapElements(CaseDocument.builder().documentType(SDO_ORDER).build())).build(); + .systemGeneratedCaseDocuments(wrapElements(CaseDocument.builder().documentType(SDO_ORDER).build())).build(); //When Optional> caseDocument = caseData.getSDODocument(); //Then @@ -517,7 +521,7 @@ void getSDOOrderDocument_WhenItPresent() { @Test void getSDOOrderDocument_WhenItsNull() { CaseData caseData = CaseData.builder() - .systemGeneratedCaseDocuments(null).build(); + .systemGeneratedCaseDocuments(null).build(); //When Optional> caseDocument = caseData.getSDODocument(); //Then @@ -527,11 +531,11 @@ void getSDOOrderDocument_WhenItsNull() { void isPartAdmitPayImmediatelyAccepted_thenTrue() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) - .applicant1AcceptAdmitAmountPaidSpec(YES) - .showResponseOneVOneFlag(ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_IMMEDIATELY) - .caseAccessCategory(SPEC_CLAIM) - .build(); + .respondent1ClaimResponseTypeForSpec(RespondentResponseTypeSpec.PART_ADMISSION) + .applicant1AcceptAdmitAmountPaidSpec(YES) + .showResponseOneVOneFlag(ResponseOneVOneShowTag.ONE_V_ONE_PART_ADMIT_PAY_IMMEDIATELY) + .caseAccessCategory(SPEC_CLAIM) + .build(); //When //Then assertTrue(caseData.isPartAdmitPayImmediatelyAccepted()); @@ -549,16 +553,16 @@ void isPartAdmitPayImmediatelyAccepted_thenFalse() { @Test void shouldReturnTrueWhenResponseIsFullAdmit() { CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) - .build(); + .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) + .build(); assertTrue(caseData.isFullAdmitClaimSpec()); } @Test void shouldReturnFalseWhenResponseIsNotFullAdmit() { CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) - .build(); + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .build(); assertFalse(caseData.isFullAdmitClaimSpec()); } @@ -566,10 +570,10 @@ void shouldReturnFalseWhenResponseIsNotFullAdmit() { void shouldReturnRecurringIncomeForFullAdmitWhenTheyExist() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) - .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringIncomeFA(List.of(element( - RecurringIncomeLRspec.builder().build()))).build()) - .build(); + .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) + .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringIncomeFA(List.of(element( + RecurringIncomeLRspec.builder().build()))).build()) + .build(); //When List> results = caseData.getRecurringIncomeForRespondent1(); //Then @@ -580,10 +584,10 @@ void shouldReturnRecurringIncomeForFullAdmitWhenTheyExist() { void shouldReturnRecurringIncomeForNonFullAdmitCaseWhenTheyExist() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) - .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringIncome(List.of(element( - RecurringIncomeLRspec.builder().build()))).build()) - .build(); + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringIncome(List.of(element( + RecurringIncomeLRspec.builder().build()))).build()) + .build(); //When List> results = caseData.getRecurringIncomeForRespondent1(); //Then @@ -604,10 +608,10 @@ void shouldReturnNullForRecurringIncomeWhenRespondentDqIsNull() { void shouldReturnRecurringExpensesForFullAdmitWhenTheyExist() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) - .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringExpensesFA(List.of(element( - RecurringExpenseLRspec.builder().build()))).build()) - .build(); + .respondent1ClaimResponseTypeForSpec(FULL_ADMISSION) + .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringExpensesFA(List.of(element( + RecurringExpenseLRspec.builder().build()))).build()) + .build(); //When List> results = caseData.getRecurringExpensesForRespondent1(); @@ -619,10 +623,10 @@ void shouldReturnRecurringExpensesForFullAdmitWhenTheyExist() { void shouldReturnRecurringExpensesForNonFullAdmitWhenTheyExist() { //Given CaseData caseData = CaseData.builder() - .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) - .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringExpenses(List.of(element( - RecurringExpenseLRspec.builder().build()))).build()) - .build(); + .respondent1ClaimResponseTypeForSpec(PART_ADMISSION) + .respondent1DQ(Respondent1DQ.builder().respondent1DQRecurringExpenses(List.of(element( + RecurringExpenseLRspec.builder().build()))).build()) + .build(); //When List> results = caseData.getRecurringExpensesForRespondent1(); @@ -669,34 +673,65 @@ void shouldReturnEmptyArrayListOfManageDocumentsIfNull() { } - @Test - void shouldReturnTrueWhenRespondentSignSettlementAgreementIsNotNull() { + @Nested + class GetHearingLocationText { - //Given - CaseData caseData = CaseDataBuilder.builder() - .caseDataLip(CaseDataLiP.builder().respondentSignSettlementAgreement(YesOrNo.NO).build()) - .build(); + @Test + public void shouldReturnNull_whenHearingLocationIsNull() { + CaseData caseData = CaseData.builder().build(); + String actual = caseData.getHearingLocationText(); - //When - boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + assertNull(actual); + } - //Then - assertTrue(isRespondentSignSettlementAgreement); - } - - @Test - void shouldReturnFalseWhenRespondentSignSettlementAgreementIsNull() { + @Test + public void shouldReturnNull_whenHearingLocationValueIsNull() { + CaseData caseData = CaseData.builder() + .hearingLocation(DynamicList.builder().value(DynamicListElement.EMPTY).build()).build(); + String actual = caseData.getHearingLocationText(); - //Given - CaseData caseData = CaseDataBuilder.builder() - .caseDataLip(CaseDataLiP.builder().build()) - .build(); + assertNull(actual); + } - //When - boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + @Test + public void shouldExpectedString_whenHearingLocationValueLabelIsNotNull() { + CaseData caseData = CaseData.builder() + .hearingLocation(DynamicList.builder().value( + DynamicListElement.dynamicElement("label")).build()).build(); + String actual = caseData.getHearingLocationText(); - //Then - assertFalse(isRespondentSignSettlementAgreement); + assertEquals("label", actual); + } + + @Test + void shouldReturnTrueWhenRespondentSignSettlementAgreementIsNotNull() { + + //Given + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder().respondentSignSettlementAgreement(YesOrNo.NO).build()) + .build(); + + //When + boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + + //Then + assertTrue(isRespondentSignSettlementAgreement); + } + + @Test + void shouldReturnFalseWhenRespondentSignSettlementAgreementIsNull() { + + //Given + CaseData caseData = CaseDataBuilder.builder() + .caseDataLip(CaseDataLiP.builder().build()) + .build(); + + //When + boolean isRespondentSignSettlementAgreement = caseData.isRespondentSignSettlementAgreement(); + + //Then + assertFalse(isRespondentSignSettlementAgreement); + } } } diff --git a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGeneratorTest.java b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGeneratorTest.java index 4df8a53ee4d..c1c79423304 100644 --- a/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGeneratorTest.java +++ b/src/test/java/uk/gov/hmcts/reform/civil/service/docmosis/caseprogression/JudgeFinalOrderGeneratorTest.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.reform.civil.service.docmosis.caseprogression; import com.fasterxml.jackson.core.JsonProcessingException; +import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -35,6 +36,7 @@ import uk.gov.hmcts.reform.civil.model.common.DynamicList; import uk.gov.hmcts.reform.civil.model.common.DynamicListElement; import uk.gov.hmcts.reform.civil.model.common.MappableObject; +import uk.gov.hmcts.reform.civil.model.defaultjudgment.CaseLocationCivil; import uk.gov.hmcts.reform.civil.model.docmosis.DocmosisDocument; import uk.gov.hmcts.reform.civil.model.finalorders.AppealChoiceSecondDropdown; @@ -52,11 +54,13 @@ import uk.gov.hmcts.reform.civil.model.finalorders.OrderMadeOnDetails; import uk.gov.hmcts.reform.civil.model.finalorders.OrderMadeOnDetailsOrderWithoutNotice; import uk.gov.hmcts.reform.civil.model.finalorders.TrialNoticeProcedure; +import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataException; import uk.gov.hmcts.reform.civil.referencedata.LocationRefDataService; import uk.gov.hmcts.reform.civil.referencedata.model.LocationRefData; import uk.gov.hmcts.reform.civil.sampledata.CaseDataBuilder; import uk.gov.hmcts.reform.civil.sampledata.CaseDocumentBuilder; import uk.gov.hmcts.reform.civil.sampledata.PartyBuilder; +import uk.gov.hmcts.reform.civil.service.FeatureToggleService; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentGeneratorService; import uk.gov.hmcts.reform.civil.service.docmosis.DocumentHearingLocationHelper; import uk.gov.hmcts.reform.civil.utils.MonetaryConversions; @@ -75,8 +79,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static uk.gov.hmcts.reform.civil.documentmanagement.model.DocumentType.JUDGE_FINAL_ORDER; @@ -104,6 +111,7 @@ public class JudgeFinalOrderGeneratorTest { private static final String DATE_FORMAT = "dd/MM/yyyy"; private static final String fileFreeForm = format(FREE_FORM_ORDER_PDF.getDocumentTitle(), formatLocalDate(LocalDate.now(), DATE_FORMAT)); private static final String assistedForm = format(ASSISTED_ORDER_PDF.getDocumentTitle(), formatLocalDate(LocalDate.now(), DATE_FORMAT)); + private static final CaseLocationCivil caseManagementLocation = CaseLocationCivil.builder().baseLocation("000000").build(); List toggleList = new ArrayList(Arrays.asList(FinalOrderToggle.SHOW)); private static final CaseDocument FREE_FROM_ORDER = CaseDocumentBuilder.builder() .documentName(fileFreeForm) @@ -127,6 +135,8 @@ public class JudgeFinalOrderGeneratorTest { private DocumentHearingLocationHelper locationHelper; @Autowired private JudgeFinalOrderGenerator generator; + @MockBean + FeatureToggleService featureToggleService; private static LocationRefData locationRefData = LocationRefData.builder().siteName("SiteName") .courtAddress("1").postcode("1") @@ -144,6 +154,29 @@ public void setUp() throws JsonProcessingException { when(locationHelper.getHearingLocation(any(), any(), any())).thenReturn(locationRefData); when(locationRefDataService.getCcmccLocation(any())).thenReturn(locationRefData); + when(locationRefDataService.getCourtLocationsByEpimmsId(anyString(), anyString())).thenReturn(List.of( + locationRefData + )); + when(featureToggleService.isHmcEnabled()).thenReturn(true); + } + + @Test + void shouldGenerateFreeFormOrder_whenHmcToggleDisabled() { + when(featureToggleService.isHmcEnabled()).thenReturn(false); + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(FREE_FORM_ORDER_PDF))) + .thenReturn(new DocmosisDocument(FREE_FORM_ORDER_PDF.getDocumentTitle(), bytes)); + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER))) + .thenReturn(FREE_FROM_ORDER); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .build(); + CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); + + assertNotNull(caseDocument); + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER)); } @Test @@ -156,10 +189,12 @@ void shouldGenerateFreeFormOrder_whenNoneSelected() { CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .caseManagementLocation(caseManagementLocation) .build(); CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); assertNotNull(caseDocument); + verify(locationRefDataService).getCourtLocationsByEpimmsId(BEARER_TOKEN, caseManagementLocation.getBaseLocation()); verify(documentManagementService) .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER)); } @@ -175,10 +210,12 @@ void shouldGenerateFreeFormOrder_whenClaimantAndDefendantReferenceNotAddedToCase CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() .solicitorReferences(null) .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .caseManagementLocation(caseManagementLocation) .build(); CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); assertNotNull(caseDocument); + verify(locationRefDataService).getCourtLocationsByEpimmsId(BEARER_TOKEN, caseManagementLocation.getBaseLocation()); verify(documentManagementService) .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER)); } @@ -195,10 +232,12 @@ void shouldGenerateFreeFormOrder_whenOrderOnCourtInitiativeSelected() { .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) .orderOnCourtInitiative(FreeFormOrderValues.builder().onInitiativeSelectionTextArea("test").onInitiativeSelectionDate( LocalDate.now()).build()) + .caseManagementLocation(caseManagementLocation) .build(); CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); assertNotNull(caseDocument); + verify(locationRefDataService).getCourtLocationsByEpimmsId(BEARER_TOKEN, caseManagementLocation.getBaseLocation()); verify(documentManagementService) .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER)); } @@ -223,14 +262,158 @@ void shouldGenerateFreeFormOrder_whenOrderWithoutNoticeIsSelected() { .partyID("res-2-party-id") .partyName("Respondent2") .build()) - .build(); + .caseManagementLocation(caseManagementLocation) + .build();; CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); assertNotNull(caseDocument); + verify(locationRefDataService).getCourtLocationsByEpimmsId(BEARER_TOKEN, caseManagementLocation.getBaseLocation()); verify(documentManagementService) .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER)); } + @Test + @SneakyThrows + void shouldThrowLocationRefDataExceptionOnGeneratingFreeFormOrder_whenLocationServiceDoesNotReturnOnlyASingleLocation() { + when(locationRefDataService.getCourtLocationsByEpimmsId(BEARER_TOKEN, caseManagementLocation.getBaseLocation())) + .thenReturn(List.of(locationRefData, locationRefData)); + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(FREE_FORM_ORDER_PDF))) + .thenReturn(new DocmosisDocument(FREE_FORM_ORDER_PDF.getDocumentTitle(), bytes)); + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER))) + .thenReturn(FREE_FROM_ORDER); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .ccdState(CaseState.CASE_PROGRESSION) + .orderWithoutNotice(FreeFormOrderValues.builder().withoutNoticeSelectionTextArea("test without notice") + .withoutNoticeSelectionDate(LocalDate.now()).build()) + .respondent2(PartyBuilder.builder().individual().build().toBuilder() + .partyID("app-2-party-id") + .partyName("Applicant2") + .build()) + .applicant2(PartyBuilder.builder().soleTrader().build().toBuilder() + .partyID("res-2-party-id") + .partyName("Respondent2") + .build()) + .caseManagementLocation(caseManagementLocation) + .build();; + + assertThrows(LocationRefDataException.class, () -> generator.generate(caseData, BEARER_TOKEN), + "Unexpected amount of locations (2) where matched against location epimms id: 000000" + ); + } + + @Test + @SneakyThrows + void shouldThrowLocationRefDataExceptionOnGeneratingFreeFormOrder_whenLocationServiceReturnsCourtsWithoutCaseTypeIdOf10() { + when(locationRefDataService.getCourtLocationsByEpimmsId(BEARER_TOKEN, caseManagementLocation.getBaseLocation())) + .thenReturn(List.of(locationRefData.toBuilder().courtTypeId("5").build())); + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(FREE_FORM_ORDER_PDF))) + .thenReturn(new DocmosisDocument(FREE_FORM_ORDER_PDF.getDocumentTitle(), bytes)); + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER))) + .thenReturn(FREE_FROM_ORDER); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .ccdState(CaseState.CASE_PROGRESSION) + .orderWithoutNotice(FreeFormOrderValues.builder().withoutNoticeSelectionTextArea("test without notice") + .withoutNoticeSelectionDate(LocalDate.now()).build()) + .respondent2(PartyBuilder.builder().individual().build().toBuilder() + .partyID("app-2-party-id") + .partyName("Applicant2") + .build()) + .applicant2(PartyBuilder.builder().soleTrader().build().toBuilder() + .partyID("res-2-party-id") + .partyName("Respondent2") + .build()) + .caseManagementLocation(caseManagementLocation) + .build();; + + assertThrows(LocationRefDataException.class, () -> generator.generate(caseData, BEARER_TOKEN), + "Unexpected amount of locations (2) where matched against location epimms id: 000000" + ); + } + + @Test + void shouldGenerateFreeFormOrder_whenHearingLocationExists() { + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(FREE_FORM_ORDER_PDF))) + .thenReturn(new DocmosisDocument(FREE_FORM_ORDER_PDF.getDocumentTitle(), bytes)); + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER))) + .thenReturn(FREE_FROM_ORDER); + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .finalOrderSelection(FinalOrderSelection.FREE_FORM_ORDER) + .ccdState(CaseState.CASE_PROGRESSION) + .orderWithoutNotice(FreeFormOrderValues.builder().withoutNoticeSelectionTextArea("test without notice") + .withoutNoticeSelectionDate(LocalDate.now()).build()) + .respondent2(PartyBuilder.builder().individual().build().toBuilder() + .partyID("app-2-party-id") + .partyName("Applicant2") + .build()) + .applicant2(PartyBuilder.builder().soleTrader().build().toBuilder() + .partyID("res-2-party-id") + .partyName("Respondent2") + .build()) + .hearingLocation(DynamicList.builder() + .value(DynamicListElement.dynamicElement("hearing-location")).build()) + .build();; + CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); + + assertNotNull(caseDocument); + verify(locationRefDataService, times(0)) + .getCourtLocationsByEpimmsId(BEARER_TOKEN, caseManagementLocation.getBaseLocation()); + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(fileFreeForm, bytes, JUDGE_FINAL_ORDER)); + } + + @Test + void shouldGenerateAssistedFormOrder_whenHmcToggleDisabled() { + //Given: case data without recitals selected + when(featureToggleService.isHmcEnabled()).thenReturn(false); + when(documentGeneratorService.generateDocmosisDocument(any(MappableObject.class), eq(ASSISTED_ORDER_PDF))) + .thenReturn(new DocmosisDocument(ASSISTED_ORDER_PDF.getDocumentTitle(), bytes)); + when(documentManagementService + .uploadDocument(BEARER_TOKEN, new PDF(assistedForm, bytes, JUDGE_FINAL_ORDER))) + .thenReturn(ASSISTED_FROM_ORDER); + + CaseData caseData = CaseDataBuilder.builder().atStateNotificationAcknowledged().build().toBuilder() + .ccdState(CaseState.CASE_PROGRESSION) + .finalOrderSelection(FinalOrderSelection.ASSISTED_ORDER) + // Order made section + .finalOrderMadeSelection(NO) + // judge heard from section + .finalOrderJudgeHeardFrom(null) + // recitals section + .finalOrderRecitals(null) + // ordered section + .finalOrderOrderedThatText("order text") + // Further hearing section + .finalOrderFurtherHearingToggle(null) + .finalOrderFurtherHearingComplex(null) + // Costs section + .assistedOrderCostList(AssistedCostTypesList.COSTS_IN_THE_CASE) + .assistedOrderMakeAnOrderForCosts(null) + .assistedOrderMakeAnOrderForCosts(AssistedOrderCostDetails.builder().makeAnOrderForCostsList(null).build()) + .publicFundingCostsProtection(NO) + // Appeal section + .finalOrderAppealToggle(null) + // initiative or without notice section + .orderMadeOnDetailsList(OrderMadeOnTypes.COURTS_INITIATIVE) + .orderMadeOnDetailsOrderCourt(OrderMadeOnDetails.builder() + .ownInitiativeText("own initiative test") + .ownInitiativeDate(LocalDate.now()) + .build()) + .finalOrderGiveReasonsYesNo(NO) + .build(); + + //When: Assisted order document generation called + CaseDocument caseDocument = generator.generate(caseData, BEARER_TOKEN); + //Then: It should generate assisted order document + assertNotNull(caseDocument); + verify(documentManagementService) + .uploadDocument(BEARER_TOKEN, new PDF(assistedForm, bytes, JUDGE_FINAL_ORDER)); + } + @Test void shouldGenerateAssistedFormOrder_whenOptionalSectionsNotPresent() { //Given: case data without recitals selected From e892ae73b08f465b144884496fcf97dde84e44d1 Mon Sep 17 00:00:00 2001 From: MMNycz <94067802+MMNycz@users.noreply.github.com> Date: Mon, 27 Nov 2023 14:32:40 +0000 Subject: [PATCH 29/29] CIV-11363 add trigger event (#3633) * CIV-11363 add trigger event --- build.gradle | 2 +- .../handler/RetriggerCasesEventHandler.java | 30 ++----- src/main/resources/caseIdForRetrigger.txt | 2 +- .../RetriggerCasesEventHandlerTest.java | 86 +++++++++++++++++++ 4 files changed, 93 insertions(+), 27 deletions(-) create mode 100644 src/test/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandlerTest.java diff --git a/build.gradle b/build.gradle index ca6ca6fb433..03857cea73b 100644 --- a/build.gradle +++ b/build.gradle @@ -314,7 +314,7 @@ sonarqube { property "sonar.projectName", "CIVIL :: service" property "sonar.projectKey", "civil-service" property "sonar.coverage.jacoco.xmlReportPaths", "${jacocoTestReport.reports.xml.destination.path}" - property "sonar.coverage.exclusions", "**/model/**, **/config/**/*Configuration.java, **/testingsupport/**, **/*ExternalTaskListener.java, **/*BaseExternalTaskHandler.java, **/stereotypes/**, **/*Exception.java, **/EventHistoryMapper*.java, **/model/hearingvalues/**, **/enums/hearing/**, **/fees/client/**, **/enums/sdo/**, **/service/PaymentsService.java, **/RetriggerCases*.java" + property "sonar.coverage.exclusions", "**/model/**, **/config/**/*Configuration.java, **/testingsupport/**, **/*ExternalTaskListener.java, **/*BaseExternalTaskHandler.java, **/stereotypes/**, **/*Exception.java, **/EventHistoryMapper*.java, **/model/hearingvalues/**, **/enums/hearing/**, **/fees/client/**, **/enums/sdo/**, **/service/PaymentsService.java" property "sonar.cpd.exclusions", "**/*DocumentManagementService.java, **/*Spec*.java, **/*CcdDashboardClaimantClaimMatcher.java" property "sonar.exclusions", "**/hmc/model/**, **/model/hearingvalues/**" property "sonar.host.url", "https://sonar.reform.hmcts.net/" diff --git a/src/main/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandler.java b/src/main/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandler.java index 08e6562df3a..ecb14390ff5 100644 --- a/src/main/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandler.java +++ b/src/main/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandler.java @@ -6,9 +6,6 @@ import org.apache.commons.io.IOUtils; import org.camunda.bpm.client.task.ExternalTask; import org.springframework.stereotype.Component; -import uk.gov.hmcts.reform.ccd.client.model.CaseDataContent; -import uk.gov.hmcts.reform.ccd.client.model.Event; -import uk.gov.hmcts.reform.ccd.client.model.StartEventResponse; import uk.gov.hmcts.reform.civil.callback.CaseEvent; import uk.gov.hmcts.reform.civil.handler.tasks.BaseExternalTaskHandler; import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; @@ -18,7 +15,6 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -39,26 +35,21 @@ public void handleTask(ExternalTask externalTask) { updateCaseByEvent(caseIdForNotifyRpaOnCaseHandedOffline, RETRIGGER_CASES); } - private void updateCaseByEvent(List caseIdList, CaseEvent caseEvent) { + public void updateCaseByEvent(List caseIdList, CaseEvent caseEvent) { if (caseIdList != null && !caseIdList.isEmpty()) { log.info("Retrigger cases started for event: {}", caseEvent); caseIdList.forEach(caseId -> { try { log.info("Retrigger CaseId: {} started", caseId); - var startEventResponse = coreCaseDataService.startUpdate(caseId, caseEvent); - - Map caseDataMap = coreCaseDataService.getCase(Long.valueOf(caseId)).getData(); - - coreCaseDataService.submitUpdate(caseId, caseDataContent(startEventResponse, caseDataMap)); + coreCaseDataService.triggerEvent(Long.parseLong(caseId), caseEvent); log.info("Retrigger CaseId: {} finished", caseId); } catch (FeignException e) { log.error("ERROR Retrigger CaseId: {}", caseId); - log.error(String.format("Updating case data failed: %s", e.contentUTF8())); + log.error(String.format("Retrigger case failed: %s", e.contentUTF8())); throw e; } catch (Exception e) { - log.error("ERROR Retrigger CaseId: {}", caseId); - log.error(String.format("Updating case data failed: %s", e.getMessage())); + throw e; } log.info("Retrigger cases Finished for event: {}", caseEvent); }); @@ -68,17 +59,6 @@ private void updateCaseByEvent(List caseIdList, CaseEvent caseEvent) { } - private CaseDataContent caseDataContent(StartEventResponse startEventResponse, Map caseDataMap) { - Map data = startEventResponse.getCaseDetails().getData(); - data.putAll(caseDataMap); - - return CaseDataContent.builder() - .eventToken(startEventResponse.getToken()) - .event(Event.builder().id(startEventResponse.getEventId()).build()) - .data(data) - .build(); - } - public List readCaseIds(String file) { String data = readString(file); @@ -93,7 +73,7 @@ private String readString(String resourcePath) { return new String(readBytes(resourcePath), StandardCharsets.UTF_8); } - private byte[] readBytes(String resourcePath) { + byte[] readBytes(String resourcePath) { try (InputStream inputStream = RetriggerCasesEventHandler.class.getResourceAsStream(resourcePath)) { return IOUtils.toByteArray(inputStream); } catch (IOException e) { diff --git a/src/main/resources/caseIdForRetrigger.txt b/src/main/resources/caseIdForRetrigger.txt index 301cfca6940..75a619adbf3 100644 --- a/src/main/resources/caseIdForRetrigger.txt +++ b/src/main/resources/caseIdForRetrigger.txt @@ -1 +1 @@ -1693404277952499 +1694435036274857 diff --git a/src/test/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandlerTest.java b/src/test/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandlerTest.java new file mode 100644 index 00000000000..ac0c133583e --- /dev/null +++ b/src/test/java/uk/gov/hmcts/reform/civil/handler/RetriggerCasesEventHandlerTest.java @@ -0,0 +1,86 @@ +package uk.gov.hmcts.reform.civil.handler; + +import feign.FeignException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import uk.gov.hmcts.reform.civil.callback.CaseEvent; +import uk.gov.hmcts.reform.civil.service.CoreCaseDataService; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +class RetriggerCasesEventHandlerTest { + + @Mock + private CoreCaseDataService coreCaseDataService; + + @InjectMocks + private RetriggerCasesEventHandler retriggerCasesEventHandler; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testUpdateCaseByEvent() { + List caseIdList = Arrays.asList("1", "2", "3"); + + retriggerCasesEventHandler.updateCaseByEvent(caseIdList, CaseEvent.RETRIGGER_CASES); + + // Assertions + verify(coreCaseDataService, times(caseIdList.size())).triggerEvent(anyLong(), eq(CaseEvent.RETRIGGER_CASES)); + } + + @Test + void testUpdateCaseByEventWithFeignException() { + List caseIdList = Arrays.asList("1", "2", "3"); + + // Simulate FeignException + doThrow(FeignException.class).when(coreCaseDataService).triggerEvent(anyLong(), eq(CaseEvent.RETRIGGER_CASES)); + + // Assertions + FeignException exception = assertThrows(FeignException.class, () -> + retriggerCasesEventHandler.updateCaseByEvent(caseIdList, CaseEvent.RETRIGGER_CASES) + ); + } + + @Test + void testUpdateCaseByEventWithGenericException() { + List caseIdList = Arrays.asList("1", "2", "3"); + + doThrow(new RuntimeException("Simulated RuntimeException")).when(coreCaseDataService) + .triggerEvent(anyLong(), eq(CaseEvent.RETRIGGER_CASES)); + + RuntimeException exception = assertThrows(RuntimeException.class, () -> + retriggerCasesEventHandler.updateCaseByEvent(caseIdList, CaseEvent.RETRIGGER_CASES) + ); + + assertEquals("Simulated RuntimeException", exception.getMessage()); + } + + @Test + void testUpdateCaseByEventWithEmptyList() { + List emptyCaseIdList = Collections.emptyList(); + + retriggerCasesEventHandler.updateCaseByEvent(emptyCaseIdList, CaseEvent.RETRIGGER_CASES); + + // Assertions + verify(coreCaseDataService, never()).triggerEvent(anyLong(), eq(CaseEvent.RETRIGGER_CASES)); + } +} + +