Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
125c592
HDPI-7213: Add CftLibTest for gen app creation
scottstewart-sl Jun 26, 2026
3dbe720
HDPI-7213: Fix issue with CCD generation and access code testing table
scottstewart-sl Jun 26, 2026
28c88b1
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jun 29, 2026
7c68b5f
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jun 29, 2026
1ab2191
Merge remote-tracking branch 'origin/master' into HDPI-7213_wiremock_…
scottstewart-sl Jun 30, 2026
4cfdd3c
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jul 1, 2026
4d4e252
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jul 2, 2026
8fb2363
Merge remote-tracking branch 'origin/master' into HDPI-7213_wiremock_…
scottstewart-sl Jul 3, 2026
f0cc400
HDPI-7213: Add regionId and caseManagementLocationNumber to test case…
scottstewart-sl Jul 3, 2026
56283a8
HDPI-7083: Wait a bit longer for access code generation
scottstewart-sl Jul 3, 2026
b1b8dae
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jul 3, 2026
adcbaa4
HDPI-7083: Wait a bit longer for access code generation
scottstewart-sl Jul 3, 2026
b9fc0b7
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jul 9, 2026
353ea66
HPI-7213: Clean up temporary code following latest merge from master
scottstewart-sl Jul 9, 2026
e459f93
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jul 10, 2026
de83638
Merge branch 'master' into HDPI-7213_wiremock_email_testing
scottstewart-sl Jul 10, 2026
81d6d1c
Try extending timeout for access codes
scottstewart-sl Jul 10, 2026
f783ca2
Merge branch 'HDPI-7213_wiremock_email_testing' of github.com:hmcts/p…
scottstewart-sl Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,8 @@ dependencies {
testImplementation group: 'io.rest-assured', name: 'rest-assured', version: '6.0.0'
testImplementation group: 'com.github.hmcts', name: 'fortify-client', version: '1.4.10', classifier: 'all'
testImplementation group: 'org.instancio', name: 'instancio', version: '5.6.0'
testImplementation group: 'com.auth0', name: 'java-jwt', version: '4.5.2'
testImplementation group: 'com.github.tomakehurst', name: 'wiremock-jre8-standalone', version: '2.35.2'

implementation(group: 'com.github.hmcts', name: 'befta-fw', version: '9.2.7') {
exclude group: 'org.apache.commons', module: 'commons-compress'
Expand Down Expand Up @@ -549,6 +551,7 @@ tasks.withType(CftlibExec).configureEach {
logger.quiet("Attaching Mockito Java agent for inline mocking")
}

environment 'ENABLE_TESTING_SUPPORT', 'true'
environment 'RSE_LIB_ADDITIONAL_DATABASES', 'pcs'
environment 'PCS_DB_USER_NAME', 'postgres'
environment 'PCS_DB_PASSWORD', 'postgres'
Expand All @@ -569,6 +572,21 @@ tasks.withType(CftlibExec).configureEach {
environment 'CCD_S2S-AUTHORISED_SERVICES_CASE_USER_ROLES', 'aac_manage_case_assignment,pcs_api'
}

cftlibTest {
environment 'ENABLE_TESTING_SUPPORT', 'true'
environment 'DB_SCHEDULER_POLLING_INTERVAL_SECONDS', '2'

// To match the fake document URLs returned by the shared Wiremock
environment 'CCD_DOCUMENT_URL_PATTERN', 'https://docstore/document/[A-Za-z0-9-]+.*'

// Use shared wiremock (8083) for the document services in CftLib tests
environment 'DM_STORE_BASE_URL', 'http://localhost:8083'
environment 'DOC_ASSEMBLY_URL', 'http://localhost:8083'

// Use wiremock spun up by tests (9400) for email, so it can be queried easily
environment 'NOTIFY_URL', 'http://localhost:9400'
}

tasks.register('highLevelDataSetup', JavaExec) {
mainClass.set("uk.gov.hmcts.reform.pcs.ccd.config.HighLevelDataSetupApp")
classpath += sourceSets.main.runtimeClasspath
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package uk.gov.hmcts.reform.pcs;


import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import uk.gov.hmcts.reform.idam.client.IdamClient;
import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase;
import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo;
import uk.gov.hmcts.reform.pcs.ccd.domain.genapp.CitizenGenAppRequest;
import uk.gov.hmcts.reform.pcs.ccd.domain.genapp.GenAppType;
import uk.gov.hmcts.reform.pcs.ccd.event.EventId;
import uk.gov.hmcts.reform.pcs.client.CcdClient;
import uk.gov.hmcts.reform.pcs.client.TestingSupportClient;
import uk.gov.hmcts.reform.pcs.model.PartyAccessCode;
import uk.gov.hmcts.reform.pcs.notification.CapturedNotification;
import uk.gov.hmcts.reform.pcs.notification.MockNotificationServer;
import uk.gov.hmcts.reform.pcs.service.AccessCodeService;
import uk.gov.hmcts.reform.pcs.service.CaseCreationService;
import uk.gov.hmcts.reform.pcs.testingsupport.model.PartyEmail;
import uk.gov.hmcts.rse.ccd.lib.test.CftlibTest;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CitizenMakeAnApplicationTest extends CftlibTest {

private static final String CITIZEN_EMAIL_ADDRESS = "test@test.com";
private static final String GEN_APP_NOTIFICATION_TEMPLATE_ID = "e5daba0d-5c66-4c76-9e0f-06646200dc89";

@Autowired
private CcdClient ccdClient;
@Autowired
private IdamClient idamClient;
@Autowired
private CaseCreationService caseCreationService;
@Autowired
private AccessCodeService accessCodeService;
@Autowired
private TestingSupportClient testingSupportClient;

private final MockNotificationServer mockNotificationServer = new MockNotificationServer();

private String solicitorToken;
private String citizenToken;

@BeforeAll
void setup() {
solicitorToken = idamClient.getAccessToken("pcs-solicitor1@test.com", "password");
citizenToken = idamClient.getAccessToken("citizen@pcs.com", "password");

mockNotificationServer.startServer();
}

@AfterAll
void tearDown() {
mockNotificationServer.stopServer();
}

@BeforeEach
void setUp() {
mockNotificationServer.resetServer();
}

@Test
void makeAnApplication() {
long caseReference = caseCreationService.createMinimalCase(solicitorToken);

List<PartyAccessCode> partyAccessCodes = accessCodeService.waitForAccessCodes(caseReference);
PartyAccessCode partyAccessCode = partyAccessCodes.getFirst();
accessCodeService.linkUserToCase(caseReference, partyAccessCode.getAccessCode(), citizenToken);

PartyEmail partyEmail = PartyEmail.builder()
.partyId(partyAccessCode.getPartyId())
.emailAddress(CITIZEN_EMAIL_ADDRESS)
.build();
testingSupportClient.setPartyEmail(partyEmail, citizenToken);

CitizenGenAppRequest citizenGenAppRequest = CitizenGenAppRequest.builder()
.applicationType(GenAppType.ADJOURN)
.needHwf(VerticalYesNo.NO)
.withoutNotice(VerticalYesNo.NO)
.hasSupportingDocuments(VerticalYesNo.NO)
.sotAccepted(VerticalYesNo.YES)
.sotFullName("Test party name")
.build();

PCSCase caseData = PCSCase.builder()
.citizenGenAppRequest(citizenGenAppRequest)
.build();

ccdClient.updateCase(EventId.makeAnApplication, caseReference, caseData, citizenToken);

List<CapturedNotification> sentNotifications = mockNotificationServer.getSentNotifications(1);

CapturedNotification sentNotification = sentNotifications.getFirst();
assertThat(sentNotification.getTemplateId()).isEqualTo(GEN_APP_NOTIFICATION_TEMPLATE_ID);
assertThat(sentNotification.getEmailAddress()).isEqualTo(CITIZEN_EMAIL_ADDRESS);
assertThat(sentNotification.getPersonalisation())
.containsKeys("caseNumber", "claimantName", "firstName", "lastName", "primaryDefendantName");
assertThat(sentNotification.getReference()).isNotBlank();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,12 @@
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import uk.gov.hmcts.ccd.sdk.type.AddressUK;
import uk.gov.hmcts.ccd.sdk.type.ListValue;
import uk.gov.hmcts.ccd.sdk.type.YesOrNo;
import uk.gov.hmcts.reform.ccd.client.CoreCaseDataApi;
import uk.gov.hmcts.reform.ccd.client.model.CaseDataContent;
import uk.gov.hmcts.reform.ccd.client.model.CaseDetails;
import uk.gov.hmcts.reform.ccd.client.model.CaseResource;
import uk.gov.hmcts.reform.ccd.client.model.Event;
import uk.gov.hmcts.reform.ccd.client.model.StartEventResponse;
import uk.gov.hmcts.reform.idam.client.IdamClient;
import uk.gov.hmcts.reform.pcs.ccd.CaseType;
import uk.gov.hmcts.reform.pcs.ccd.service.CaseRoleAssignmentService;
import uk.gov.hmcts.reform.pcs.ccd.domain.CompletionNextStep;
import uk.gov.hmcts.reform.pcs.ccd.domain.DefendantDetails;
import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase;
Expand All @@ -32,41 +25,35 @@
import uk.gov.hmcts.reform.pcs.ccd.domain.TenancyLicenceDetails;
import uk.gov.hmcts.reform.pcs.ccd.domain.TenancyLicenceType;
import uk.gov.hmcts.reform.pcs.ccd.domain.VerticalYesNo;
import uk.gov.hmcts.reform.pcs.ccd.event.EventId;
import uk.gov.hmcts.reform.pcs.client.CcdClient;
import uk.gov.hmcts.reform.pcs.postcodecourt.model.LegislativeCountry;
import uk.gov.hmcts.rse.ccd.lib.test.CftlibTest;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static uk.gov.hmcts.reform.pcs.ccd.event.EventId.createPossessionClaim;
import static uk.gov.hmcts.reform.pcs.ccd.event.EventId.resumePossessionClaim;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(OrderAnnotation.class)
class CreatePossessionClaimTest extends CftlibTest {

@MockitoBean
private CaseRoleAssignmentService caseRoleAssignmentService;

@Autowired
private CoreCaseDataApi ccdApi;
private CcdClient ccdClient;

@Autowired
private IdamClient idamClient;

@Autowired
private ObjectMapper objectMapper;

private String idamToken;
private String s2sToken;
private String solicitorToken;
private Long caseReference;

@BeforeAll
void setup() {
idamToken = idamClient.getAccessToken("pcs-solicitor1@test.com", "password");
s2sToken = generateDummyS2SToken("ccd_gw");
solicitorToken = idamClient.getAccessToken("pcs-solicitor1@test.com", "password");
}

@Test
Expand All @@ -85,19 +72,21 @@ void createPossessionClaim() {
.legislativeCountry(LegislativeCountry.ENGLAND)
.build();

CaseDetails caseDetails = startAndSubmitCreationEvent(createPossessionClaim, caseData);
CaseDetails caseDetails = ccdClient.createCase(caseData, solicitorToken);

caseReference = caseDetails.getId();
assertThat(caseReference).isNotNull();

CaseDetails retrievedCase = ccdApi.getCase(idamToken, s2sToken, Long.toString(caseReference));
CaseDetails retrievedCase = ccdClient.getCaseDetails(caseReference, solicitorToken);
assertThat(retrievedCase.getState()).isEqualTo(State.AWAITING_SUBMISSION_TO_HMCTS.name());
}

@Test
@Order(2)
void resumePossessionClaim() {
PCSCase caseData = PCSCase.builder()
.caseManagementLocationNumber(20262)
.regionId(1)
.tenancyLicenceDetails(TenancyLicenceDetails.builder()
.typeOfTenancyLicence(TenancyLicenceType.ASSURED_TENANCY)
.build())
Expand All @@ -110,11 +99,12 @@ void resumePossessionClaim() {
.completionNextStep(CompletionNextStep.SUBMIT_AND_PAY_NOW)
.build();

CaseResource caseResource = startAndSubmitUpdateEvent(resumePossessionClaim, caseData);
CaseResource caseResource
= ccdClient.updateCase(resumePossessionClaim, caseReference, caseData, solicitorToken);

assertThat(caseResource.getReference()).isNotBlank();

CaseDetails retrievedCase = ccdApi.getCase(idamToken, s2sToken, Long.toString(caseReference));
CaseDetails retrievedCase = ccdClient.getCaseDetails(caseReference, solicitorToken);

TypeReference<List<ListValue<Party>>> partyList = new TypeReference<>() {};

Expand All @@ -131,40 +121,4 @@ void resumePossessionClaim() {
assertThat(retrievedCase.getState()).isEqualTo(State.PENDING_CASE_ISSUED.name());
}

@SuppressWarnings("SameParameterValue")
private CaseDetails startAndSubmitCreationEvent(EventId eventId, PCSCase caseData) {
StartEventResponse startEventResponse = ccdApi.startCase(
idamToken,
s2sToken,
CaseType.getCaseType(),
eventId.name()
);

CaseDataContent content = CaseDataContent.builder()
.data(caseData)
.event(Event.builder().id(eventId.name()).build())
.eventToken(startEventResponse.getToken())
.build();

return ccdApi.submitCaseCreation(idamToken, s2sToken, CaseType.getCaseType(), content);
}

@SuppressWarnings("SameParameterValue")
private CaseResource startAndSubmitUpdateEvent(EventId eventId, PCSCase caseData) {
StartEventResponse startEventResponse = ccdApi.startEvent(
idamToken,
s2sToken,
Long.toString(caseReference),
eventId.name()
);

CaseDataContent content = CaseDataContent.builder()
.data(caseData)
.event(Event.builder().id(eventId.name()).build())
.eventToken(startEventResponse.getToken())
.build();

return ccdApi.createEvent(idamToken, s2sToken, Long.toString(caseReference), content);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package uk.gov.hmcts.reform.pcs.auth;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

import java.util.Date;

public class ServiceAuthorizationGenerator {

public static String generateTestS2SToken(String serviceName) {
return JWT.create().withSubject(serviceName).withIssuedAt(new Date()).sign(Algorithm.HMAC256("secret"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package uk.gov.hmcts.reform.pcs.client;

import org.springframework.stereotype.Component;
import uk.gov.hmcts.reform.ccd.client.CoreCaseDataApi;
import uk.gov.hmcts.reform.ccd.client.model.CaseDataContent;
import uk.gov.hmcts.reform.ccd.client.model.CaseDetails;
import uk.gov.hmcts.reform.ccd.client.model.CaseResource;
import uk.gov.hmcts.reform.ccd.client.model.Event;
import uk.gov.hmcts.reform.ccd.client.model.StartEventResponse;
import uk.gov.hmcts.reform.pcs.ccd.CaseType;
import uk.gov.hmcts.reform.pcs.ccd.domain.PCSCase;
import uk.gov.hmcts.reform.pcs.ccd.event.EventId;

import static uk.gov.hmcts.reform.pcs.auth.ServiceAuthorizationGenerator.generateTestS2SToken;
import static uk.gov.hmcts.reform.pcs.ccd.event.EventId.createPossessionClaim;

@Component
public class CcdClient {

private static final EventId CASE_CREATION_EVENT = createPossessionClaim;

private final CoreCaseDataApi ccdApi;
private final String serviceAuthorisation;

public CcdClient(CoreCaseDataApi ccdApi) {
this.ccdApi = ccdApi;
this.serviceAuthorisation = generateTestS2SToken("ccd_gw");
}

public CaseDetails createCase(PCSCase caseData, String authorisation) {

StartEventResponse startEventResponse = ccdApi.startCase(
authorisation,
serviceAuthorisation,
CaseType.getCaseType(),
CASE_CREATION_EVENT.name()
);

CaseDataContent caseDataContent = CaseDataContent.builder()
.data(caseData)
.event(Event.builder().id(CASE_CREATION_EVENT.name()).build())
.eventToken(startEventResponse.getToken())
.build();

return ccdApi.submitCaseCreation(authorisation, serviceAuthorisation, CaseType.getCaseType(), caseDataContent);
}

public CaseResource updateCase(EventId eventId, long caseReference, PCSCase caseData, String authorisation) {

StartEventResponse startEventResponse = ccdApi.startEvent(
authorisation,
serviceAuthorisation,
Long.toString(caseReference),
eventId.name()
);

CaseDataContent caseDataContent = CaseDataContent.builder()
.data(caseData)
.event(Event.builder().id(eventId.name()).build())
.eventToken(startEventResponse.getToken())
.build();

return ccdApi.createEvent(authorisation, serviceAuthorisation, Long.toString(caseReference), caseDataContent);
}

public CaseDetails getCaseDetails(long caseReference, String authorisation) {
return ccdApi.getCase(authorisation, serviceAuthorisation, Long.toString(caseReference));
}

}
Loading
Loading