Skip to content

Commit 12ef2da

Browse files
committed
Adding pact verification Test
1 parent 4784d0c commit 12ef2da

File tree

9 files changed

+204
-24
lines changed

9 files changed

+204
-24
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
SERVER_PORT=4550
2-
BASE_IMAGE=openjdk:21-jdk-slim
2+
BASE_IMAGE=openjdk:21-jdk-slim

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ applicationinsights-agent-*.jar
3030
*.log
3131

3232
.DS_Store
33-
*/.DS_Store
33+
*/.DS_Store
34+
35+
.env

build.gradle

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ plugins {
77
id 'maven-publish'
88
id "com.github.ben-manes.versions" version "0.52.0"
99
id "org.cyclonedx.bom" version "2.3.1"
10+
id "au.com.dius.pact" version "4.6.17"
1011
}
1112

1213
group = 'uk.gov.hmcts.cp'
@@ -85,7 +86,7 @@ tasks.named('test') {
8586
// Mockito must be added as an agent, see:
8687
// https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
8788
jvmArgs += [
88-
"-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('mockito-core') }}", '-Xshare:off'
89+
"-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('mockito-core') }}", '-Xshare:off'
8990
]
9091
testLogging {
9192
events "passed", "skipped", "failed"
@@ -239,7 +240,7 @@ ext {
239240
dependencies {
240241
implementation "uk.gov.hmcts.cp:api-cp-crime-schedulingandlisting-courtschedule:$apiCourtScheduleVersion"
241242
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9'
242-
implementation 'io.swagger.core.v3:swagger-core:2.2.32'
243+
implementation 'io.swagger.core.v3:swagger-core:2.2.33'
243244

244245
implementation 'org.springframework.boot:spring-boot-starter-web'
245246
implementation 'org.springframework.boot:spring-boot-starter-actuator'
@@ -258,7 +259,7 @@ dependencies {
258259
implementation group: 'ch.qos.logback', name: 'logback-core', version: logbackVersion
259260

260261
implementation group: 'io.rest-assured', name: 'rest-assured', version: '5.5.5'
261-
implementation 'org.hibernate.validator:hibernate-validator:9.0.0.Final'
262+
implementation 'org.hibernate.validator:hibernate-validator:9.0.1.Final'
262263
implementation 'org.apache.commons:commons-text:1.13.1'
263264

264265
compileOnly group: 'org.projectlombok', name: 'lombok', version: lombokVersion
@@ -272,4 +273,27 @@ dependencies {
272273
exclude group: 'junit', module: 'junit'
273274
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
274275
}
276+
277+
testImplementation 'au.com.dius.pact.provider:junit5:4.6.17'
278+
testImplementation 'au.com.dius.pact.provider:spring6:4.6.17'
279+
280+
test{
281+
useJUnitPlatform {
282+
excludeTags 'pact'
283+
}
284+
}
285+
286+
tasks.register('pactVerificationTest', Test) {
287+
useJUnitPlatform {
288+
includeTags 'pact'
289+
}
290+
systemProperty 'pact.broker.url', System.getenv('PACT_BROKER_URL')
291+
systemProperty 'pact.broker.token', System.getenv('PACT_BROKER_TOKEN')
292+
systemProperty 'pact.provider.version', System.getenv('GIT_COMMIT') ?: 'dev'
293+
systemProperty 'pact.provider.branch', System.getenv('PACT_PROVIDER_BRANCH')
294+
systemProperty 'pact.verifier.publishResults', System.getenv('PACT_VERIFIER_PUBLISH_RESULTS')
295+
systemProperty 'pact.broker.host', System.getenv('PACT_BROKER_HOST')
296+
systemProperty 'pact.env', System.getenv('PACT_ENV')
297+
}
298+
275299
}

publish-pacts.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash
2+
3+
# Load env vars from .env if available
4+
if [ -f .env ]; then
5+
set -a
6+
source .env
7+
set +a
8+
fi
9+
10+
# Export Git metadata
11+
export GIT_COMMIT=$(git rev-parse HEAD)
12+
13+
if [ -n "$GIT_BRANCH" ]; then
14+
BRANCH_NAME="$GIT_BRANCH"
15+
else
16+
BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD)
17+
fi
18+
19+
export GIT_BRANCH="$BRANCH_NAME"
20+
21+
# Run provider verification with results published
22+
gradle pactVerificationTest \
23+
-Dpact.provider.version="$GIT_COMMIT" \
24+
-Dpact.verifier.publishResults=true \
25+
-Dpact.provider.branch="$GIT_BRANCH" \
26+
-DPACT_BROKER_TOKEN="$PACT_BROKER_TOKEN" \
27+
-DPACT_BROKER_HOST="$PACT_BROKER_URL"
28+
29+
# Optional: tag provider in the broker
30+
pact-broker create-version-tag \
31+
--pacticipant "VPCourtSchedulePactProvider" \
32+
--version "$GIT_COMMIT" \
33+
--tag "$PACT_ENV" \
34+
--broker-base-url "$PACT_BROKER_URL" \
35+
--broker-token "$PACT_BROKER_TOKEN"

src/main/java/uk/gov/hmcts/cp/repositories/CourtScheduleRepository.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import org.springframework.stereotype.Repository;
44
import uk.gov.hmcts.cp.openapi.model.CourtScheduleResponse;
55

6-
@FunctionalInterface
6+
//@FunctionalInterface
77
@Repository
8-
public interface CourtScheduleRepository {
8+
public interface CourtScheduleRepository {
99

1010
CourtScheduleResponse getCourtScheduleByCaseUrn(String caseUrn);
11+
void saveCourtSchedule(final String caseUrn, final CourtScheduleResponse CourtScheduleResponse);
12+
void clearAll();
1113

1214
}
Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,66 @@
11
package uk.gov.hmcts.cp.repositories;
22

3+
import org.springframework.context.annotation.Profile;
34
import org.springframework.stereotype.Component;
4-
import uk.gov.hmcts.cp.openapi.model.CourtSchedule;
55
import uk.gov.hmcts.cp.openapi.model.CourtScheduleResponse;
6-
import uk.gov.hmcts.cp.openapi.model.CourtSitting;
6+
import uk.gov.hmcts.cp.openapi.model.CourtSchedule;
77
import uk.gov.hmcts.cp.openapi.model.Hearing;
8+
import uk.gov.hmcts.cp.openapi.model.CourtSitting;
89

910
import java.time.OffsetDateTime;
11+
import java.time.ZoneOffset;
12+
import java.time.temporal.ChronoUnit;
1013
import java.util.List;
14+
import java.util.Map;
1115
import java.util.UUID;
16+
import java.util.concurrent.ConcurrentHashMap;
1217

1318
@Component
19+
//@Profile("test")
1420
public class InMemoryCourtScheduleRepositoryImpl implements CourtScheduleRepository {
1521

22+
private final Map<String, CourtScheduleResponse> courtScheduleResponseMap = new ConcurrentHashMap<>();
23+
24+
public void saveCourtSchedule(final String caseUrn, final CourtScheduleResponse CourtScheduleResponse) {
25+
courtScheduleResponseMap.put(caseUrn, CourtScheduleResponse);
26+
}
27+
1628
public CourtScheduleResponse getCourtScheduleByCaseUrn(final String caseUrn) {
17-
final Hearing courtScheduleHearing = Hearing.builder()
29+
if (!courtScheduleResponseMap.containsKey(caseUrn)) {
30+
saveCourtSchedule(caseUrn, createCourtScheduleResponse());
31+
}
32+
return courtScheduleResponseMap.get(caseUrn);
33+
}
34+
35+
public void clearAll() {
36+
courtScheduleResponseMap.clear();
37+
}
38+
39+
private CourtScheduleResponse createCourtScheduleResponse() {
40+
41+
OffsetDateTime sittingStartTime = OffsetDateTime.now(ZoneOffset.UTC)
42+
.truncatedTo(ChronoUnit.SECONDS);
43+
44+
final Hearing hearing = Hearing.builder()
1845
.hearingId(UUID.randomUUID().toString())
1946
.listNote("Requires interpreter")
2047
.hearingDescription("Sentencing for theft case")
2148
.hearingType("Trial")
2249
.courtSittings(List.of(
2350
CourtSitting.builder()
2451
.courtHouse("Central Criminal Court")
25-
.sittingStart(OffsetDateTime.now())
26-
.sittingEnd(OffsetDateTime.now().plusMinutes(60))
52+
.sittingStart(sittingStartTime)
53+
.sittingEnd(sittingStartTime.plusMinutes(60))
2754
.judiciaryId(UUID.randomUUID().toString())
2855
.build())
2956
).build();
3057

3158
return CourtScheduleResponse.builder()
3259
.courtSchedule(List.of(
3360
CourtSchedule.builder()
34-
.hearings(List.of(courtScheduleHearing)
61+
.hearings(List.of(hearing)
3562
).build()
3663
)
3764
).build();
3865
}
39-
4066
}

src/test/java/uk/gov/hmcts/cp/controllers/CourtScheduleControllerTest.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.springframework.web.server.ResponseStatusException;
1010
import uk.gov.hmcts.cp.openapi.model.CourtSchedule;
1111
import uk.gov.hmcts.cp.openapi.model.CourtScheduleResponse;
12+
1213
import uk.gov.hmcts.cp.openapi.model.CourtSitting;
1314
import uk.gov.hmcts.cp.openapi.model.Hearing;
1415
import uk.gov.hmcts.cp.repositories.CourtScheduleRepository;
@@ -52,24 +53,24 @@ void getJudgeById_ShouldReturnJudgesWithOkStatus() {
5253
assertNotNull(responseBody.getCourtSchedule());
5354
assertEquals(1, responseBody.getCourtSchedule().size());
5455

55-
CourtSchedule schedule = responseBody.getCourtSchedule().get(0);
56-
assertNotNull(schedule.getHearings());
57-
assertEquals(1, schedule.getHearings().size());
56+
CourtSchedule courtSchedule = responseBody.getCourtSchedule().get(0);
57+
assertNotNull(courtSchedule.getHearings());
58+
assertEquals(1, courtSchedule.getHearings().size());
5859

59-
Hearing hearing = schedule.getHearings().get(0);
60+
Hearing hearing = courtSchedule.getHearings().get(0);
6061
assertNotNull(hearing.getHearingId());
6162
assertEquals("Requires interpreter", hearing.getListNote());
6263
assertEquals("Sentencing for theft case", hearing.getHearingDescription());
6364
assertEquals("Trial", hearing.getHearingType());
6465
assertNotNull(hearing.getCourtSittings());
6566
assertEquals(1, hearing.getCourtSittings().size());
6667

67-
CourtSitting sitting =
68+
CourtSitting courtSitting =
6869
hearing.getCourtSittings().get(0);
69-
assertEquals("Central Criminal Court", sitting.getCourtHouse());
70-
assertNotNull(sitting.getSittingStart());
71-
assertTrue(sitting.getSittingEnd().isAfter(sitting.getSittingStart()));
72-
assertNotNull(sitting.getJudiciaryId());
70+
assertEquals("Central Criminal Court", courtSitting.getCourtHouse());
71+
assertNotNull(courtSitting.getSittingStart());
72+
assertTrue(courtSitting.getSittingEnd().isAfter(courtSitting.getSittingStart()));
73+
assertNotNull(courtSitting.getJudiciaryId());
7374

7475
}
7576

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package uk.gov.hmcts.cp.pact.provider;
2+
3+
import au.com.dius.pact.provider.junit5.HttpTestTarget;
4+
import au.com.dius.pact.provider.junit5.PactVerificationContext;
5+
import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;
6+
import au.com.dius.pact.provider.junitsupport.Provider;
7+
import au.com.dius.pact.provider.junitsupport.State;
8+
import au.com.dius.pact.provider.junitsupport.loader.PactBroker;
9+
import au.com.dius.pact.provider.junitsupport.loader.PactBrokerAuth;
10+
import org.junit.jupiter.api.BeforeEach;
11+
import org.junit.jupiter.api.Tag;
12+
import org.junit.jupiter.api.TestTemplate;
13+
import org.junit.jupiter.api.extension.ExtendWith;
14+
import org.springframework.beans.factory.annotation.Autowired;
15+
import org.springframework.boot.test.context.SpringBootTest;
16+
import org.springframework.boot.test.web.server.LocalServerPort;
17+
import org.springframework.test.context.junit.jupiter.SpringExtension;
18+
import uk.gov.hmcts.cp.openapi.model.CourtScheduleResponse;
19+
import uk.gov.hmcts.cp.openapi.model.CourtSchedule;
20+
import uk.gov.hmcts.cp.openapi.model.Hearing;
21+
import uk.gov.hmcts.cp.openapi.model.CourtSitting;
22+
import uk.gov.hmcts.cp.repositories.CourtScheduleRepository;
23+
24+
import java.time.OffsetDateTime;
25+
import java.util.List;
26+
import java.util.UUID;
27+
28+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
29+
//@ActiveProfiles("test") // important: use the in-memory repo!
30+
@ExtendWith({SpringExtension.class, PactVerificationInvocationContextProvider.class})
31+
@Provider("VPCourtSchedulePactProvider")
32+
@PactBroker(
33+
scheme = "https",
34+
host = "${pact.broker.host}",
35+
authentication = @PactBrokerAuth(token = "${pact.broker.token}")
36+
)
37+
@Tag("pact")
38+
public class CourtScheduleProviderPactTest {
39+
40+
@Autowired
41+
private CourtScheduleRepository courtScheduleRepository;
42+
43+
@LocalServerPort
44+
private int port;
45+
46+
@BeforeEach
47+
void setupTarget(PactVerificationContext context) {
48+
System.out.println("Running test on port: " + port);
49+
context.setTarget(new HttpTestTarget("localhost", port));
50+
System.out.println("pact.verifier.publishResults: " + System.getProperty("pact.verifier.publishResults"));
51+
}
52+
53+
/* @BeforeEach
54+
public void setupTestTarget(PactVerificationContext context) {
55+
context.setTarget(new HttpTestTarget("localhost", 8080));
56+
}*/
57+
58+
@State("court schedule for case 456789 exists")
59+
public void setupCourtSchedule() {
60+
courtScheduleRepository.clearAll();
61+
var courtSitting = CourtSitting.builder()
62+
.courtHouse("Central Criminal Court")
63+
.sittingStart(OffsetDateTime.now())
64+
.sittingEnd(OffsetDateTime.now().plusMinutes(60))
65+
.judiciaryId(UUID.randomUUID().toString())
66+
.build();
67+
var hearing = Hearing.builder()
68+
.hearingId(UUID.randomUUID().toString())
69+
.listNote("Requires interpreter")
70+
.hearingDescription("Sentencing for theft case")
71+
.hearingType("Trial")
72+
.courtSittings(List.of(courtSitting))
73+
.build();
74+
75+
var schedule = CourtSchedule.builder()
76+
.hearings(List.of(hearing))
77+
.build();
78+
79+
var response = CourtScheduleResponse.builder()
80+
.courtSchedule(List.of(schedule))
81+
.build();
82+
83+
courtScheduleRepository.saveCourtSchedule("456789", response);
84+
}
85+
86+
@TestTemplate
87+
void pactVerificationTestTemplate(PactVerificationContext context) {
88+
context.verifyInteraction();
89+
}
90+
}

src/test/java/uk/gov/hmcts/cp/repositories/CourtScheduleRepositoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void getCourtScheduleByCaseUrn_shouldReturnCourtScheduleResponse() {
4242
assertNotNull(hearing.getCourtSittings());
4343
assertEquals(1, hearing.getCourtSittings().size());
4444

45-
CourtSitting sitting =
45+
CourtSitting sitting =
4646
hearing.getCourtSittings().get(0);
4747
assertEquals("Central Criminal Court", sitting.getCourtHouse());
4848
assertNotNull(sitting.getSittingStart());

0 commit comments

Comments
 (0)