Skip to content

Commit

Permalink
Pact testing (#275)
Browse files Browse the repository at this point in the history
* Added Pact test for ccd case disposer consuming delete end point of WA/TM

Rebased from master

* Updated Jenkins_Cnp file to accommodate pact testing

* Updated build.gradle to resolve ANTLR dependency issue

* Updated the pact version to resolve the pact publish issue

* Made review changes

---------

Co-authored-by: Muhammad Husain <[email protected]>
  • Loading branch information
mhisltd and Muhammad Husain authored Aug 3, 2023
1 parent ce743ed commit 1979d80
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 27 deletions.
15 changes: 15 additions & 0 deletions Jenkinsfile_CNP
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import uk.gov.hmcts.contino.GradleBuilder
import uk.gov.hmcts.contino.Kubectl
import uk.gov.hmcts.contino.GithubAPI
import uk.gov.hmcts.pipeline.TeamConfig
import uk.gov.hmcts.contino.AppPipelineDsl

def type = "java"
def product = "ccd"
Expand Down Expand Up @@ -117,11 +118,16 @@ withPipeline(type, product, component) {
env.DOCUMENT_STORE_HOST = "http://dm-store-aat.service.core-compute-aat.internal"
env.ROLE_ASSIGNMENT_HOST = "http://am-role-assignment-service-aat.service.core-compute-aat.internal"
env.LOG_AND_AUDIT_HOST = "http://lau-case-backend-aat.service.core-compute-aat.internal"
env.PACT_BROKER_FULL_URL = "https://pact-broker.platform.hmcts.net"
env.PACT_BROKER_URL = "pact-broker.platform.hmcts.net"
env.PACT_BROKER_PORT = "443"
env.PACT_BROKER_SCHEME = "https"

def githubApi = new GithubAPI(this)
if (!githubApi.getLabelsbyPattern(env.BRANCH_NAME, "keep-helm")) {
enableCleanupOfHelmReleaseAlways()
}
enablePactAs([AppPipelineDsl.PactRoles.CONSUMER, AppPipelineDsl.PactRoles.PROVIDER])
}

onNonPR() {
Expand All @@ -135,6 +141,15 @@ withPipeline(type, product, component) {
env.DOCUMENT_STORE_HOST = "http://dm-store-aat.service.core-compute-aat.internal"
env.ROLE_ASSIGNMENT_HOST = "http://am-role-assignment-service-aat.service.core-compute-aat.internal"
env.LOG_AND_AUDIT_HOST = "http://lau-case-backend-aat.service.core-compute-aat.internal"
env.PACT_BROKER_FULL_URL = "https://pact-broker.platform.hmcts.net"
env.PACT_BROKER_URL = "pact-broker.platform.hmcts.net"
env.PACT_BROKER_PORT = "443"
env.PACT_BROKER_SCHEME = "https"
enablePactAs([PactRoles.CONSUMER, AppPipelineDsl.PactRoles.PROVIDER])
}

afterSuccess('pact-provider-verification') {
steps.archiveArtifacts allowEmptyArchive: true, artifacts: 'build/reports/tests/**/*'
}

afterAlways('akschartsinstall') {
Expand Down
121 changes: 94 additions & 27 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
plugins {
id 'application'
id 'checkstyle'
id 'pmd'
id 'jacoco'
id 'io.spring.dependency-management' version '1.1.2'
id 'org.springframework.boot' version '3.1.2'
id 'org.owasp.dependencycheck' version '8.3.1'
id 'com.github.ben-manes.versions' version '0.47.0'
id 'org.sonarqube' version '4.3.0.3225'
id 'uk.gov.hmcts.java' version '0.12.43'
id 'io.freefair.lombok' version '8.1.0'
id 'org.flywaydb.flyway' version '9.21.1'
id "info.solidsoft.pitest" version '1.9.11'
id 'application'
id 'checkstyle'
id 'pmd'
id 'jacoco'
id 'io.spring.dependency-management' version '1.1.2'
id 'org.springframework.boot' version '3.1.2'
id 'org.owasp.dependencycheck' version '8.3.1'
id 'com.github.ben-manes.versions' version '0.47.0'
id 'org.sonarqube' version '4.3.0.3225'
id 'uk.gov.hmcts.java' version '0.12.43'
id 'io.freefair.lombok' version '8.1.0'
id 'org.flywaydb.flyway' version '9.21.1'
id "info.solidsoft.pitest" version '1.9.11'
id "au.com.dius.pact" version '4.4.0-beta.2'
}

group = 'uk.gov.hmcts.reform'
Expand Down Expand Up @@ -46,6 +47,15 @@ sourceSets {
resources.srcDir file('src/integrationTest/resources')
}

contractTest {
java {
compileClasspath += main.output
runtimeClasspath += main.output
srcDir file('src/contractTest/java')
}
resources.srcDir file('src/contractTest/resources')
}

}

tasks.withType(JavaCompile) {
Expand Down Expand Up @@ -114,6 +124,10 @@ pmd {
ruleSetFiles = files("config/pmd/ruleset.xml")
}

static def getCheckedOutGitCommitHash() {
'git rev-parse --verify --short HEAD'.execute().text.trim()
}

jacocoTestReport {
executionData(test)
reports {
Expand Down Expand Up @@ -236,9 +250,27 @@ def versions = [
springSecurity : '6.1.2',
testcontainers : '1.18.3',
wiremock : '2.35.0',
pactVersion : '4.4.0-beta.2',
serenity : '3.1.20',
]

ext['jackson.version'] = '2.14.1'
project.ext.pacticipantVersion = getCheckedOutGitCommitHash()

rootProject.tasks.named("processTestResources") {
duplicatesStrategy = 'include'
}

rootProject.tasks.named("processFunctionalTestResources") {
duplicatesStrategy = 'include'
}

rootProject.tasks.named("processIntegrationTestResources") {
duplicatesStrategy = 'include'
}
rootProject.tasks.named("processContractTestResources") {
duplicatesStrategy = 'include'
}

dependencies {

Expand Down Expand Up @@ -294,12 +326,59 @@ dependencies {
functionalTestImplementation sourceSets.main.runtimeClasspath
functionalTestImplementation sourceSets.test.runtimeClasspath

functionalTestCompileOnly group: 'org.apiguardian', name: 'apiguardian-api' , version: versions.apiGuardian
integrationTestCompileOnly group: 'org.apiguardian', name: 'apiguardian-api' , version: versions.apiGuardian
functionalTestCompileOnly group: 'org.apiguardian', name: 'apiguardian-api', version: versions.apiGuardian
integrationTestCompileOnly group: 'org.apiguardian', name: 'apiguardian-api', version: versions.apiGuardian

//pact contract testing
contractTestImplementation group: 'au.com.dius.pact.consumer', name: 'junit5', version: versions.pactVersion
contractTestImplementation group: 'au.com.dius.pact.consumer', name: 'junit', version: versions.pactVersion
contractTestRuntimeOnly(group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: versions.junit)
contractTestImplementation(group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: versions.junit)

contractTestImplementation sourceSets.main.runtimeClasspath
contractTestImplementation sourceSets.test.runtimeClasspath
}

mainClassName = 'uk.gov.hmcts.reform.ccd.ApplicationBootstrap'

task runAndPublishConsumerPactTests(type: Test){
logger.lifecycle("Runs pact Tests")
testClassesDirs = sourceSets.contractTest.output.classesDirs
classpath = sourceSets.contractTest.runtimeClasspath

}

runAndPublishConsumerPactTests.finalizedBy pactPublish

pact {
broker {
pactBrokerUrl = System.getenv("PACT_BROKER_FULL_URL") ?: 'http://localhost:80'
}
publish {
pactDirectory = 'build/pacts'
tags = [System.getenv("PACT_BRANCH_NAME") ?: 'Dev']
version = project.pacticipantVersion
}
}

task contract(type: Test, description: 'Runs the pact contract tests.', group: 'Verification') {
description = "Runs the consumer Pact tests"
useJUnitPlatform()
testClassesDirs = sourceSets.contractTest.output.classesDirs
classpath = sourceSets.contractTest.runtimeClasspath
}

task runProviderPactVerification(type: Test) {
logger.lifecycle("Runs provider pact Tests")
testClassesDirs = sourceSets.contractTest.output.classesDirs
classpath = sourceSets.contractTest.runtimeClasspath
systemProperty 'pact.verifier.publishResults', System.getProperty('pact.verifier.publishResults')
systemProperty 'pact.provider.version', project.pacticipantVersion
}

runProviderPactVerification.dependsOn contract
runProviderPactVerification.finalizedBy pactVerify

bootJar {
getArchiveFileName().set(provider {
'ccd-case-disposer.jar'
Expand All @@ -313,15 +392,3 @@ bootJar {
wrapper {
distributionType = Wrapper.DistributionType.ALL
}

rootProject.tasks.named("processTestResources") {
duplicatesStrategy = 'include'
}

rootProject.tasks.named("processFunctionalTestResources") {
duplicatesStrategy = 'include'
}

rootProject.tasks.named("processIntegrationTestResources") {
duplicatesStrategy = 'include'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package uk.gov.hmcts.reform.ccd;

import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.http.HttpHeaders;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.springframework.http.HttpHeaders.AUTHORIZATION;

@Slf4j
@ExtendWith(PactConsumerTestExt.class)
@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestPropertySource(locations = {"classpath:application.properties"})
public abstract class SpringBootContractBaseTest {

public static final String PACT_TEST_EMAIL_VALUE = "[email protected]";
public static final String PACT_TEST_PASSWORD_VALUE = "London01";
public static final String PACT_TEST_CLIENT_ID_VALUE = "pact";
public static final String PACT_TEST_CLIENT_SECRET_VALUE = "pactsecret";
public static final String PACT_TEST_SCOPES_VALUE = "openid profile roles";
public static final String SERVICE_AUTHORIZATION = "ServiceAuthorization";
public static final String AUTH_TOKEN = "Bearer someAuthorizationToken";
public static final String SERVICE_AUTH_TOKEN = "Bearer someServiceAuthorizationToken";


public HttpHeaders getHttpHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add(SERVICE_AUTHORIZATION, SERVICE_AUTH_TOKEN);
headers.add(AUTHORIZATION, AUTH_TOKEN);
return headers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package uk.gov.hmcts.reform.ccd.consumer.wa;

import au.com.dius.pact.consumer.MockServer;
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
import au.com.dius.pact.consumer.junit5.PactTestFor;
import au.com.dius.pact.core.model.PactSpecVersion;
import au.com.dius.pact.core.model.RequestResponsePact;
import au.com.dius.pact.core.model.annotations.Pact;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import uk.gov.hmcts.reform.ccd.SpringBootContractBaseTest;

public class TaskManagerDeleteTaskConsumerTest extends SpringBootContractBaseTest {

private static final String WA_URL = "/task";
private static final String WA_DELETE_TASK = WA_URL + "/delete";

@Pact(provider = "wa_task_management_api_delete_task_by_id", consumer = "wa_task_management_api")
public RequestResponsePact executeDeleteTaskById201(PactDslWithProvider builder) {

return builder
.given("delete a task using case reference id")
.uponReceiving("Request to delete")
.path(WA_DELETE_TASK)
.method(HttpMethod.POST.toString())
.body(deleteTaskWithRequest(), String.valueOf(ContentType.JSON))
.matchHeader(SERVICE_AUTHORIZATION, SERVICE_AUTH_TOKEN)
.willRespondWith()
.status(HttpStatus.CREATED.value())
.toPact();
}

@Test
@PactTestFor(pactMethod = "executeDeleteTaskById201", pactVersion = PactSpecVersion.V3)
void testDeleteTaskByTaskId201(MockServer mockServer) {

RestAssured
.given()
.headers(getHttpHeaders())
.contentType(ContentType.JSON)
.body(deleteTaskWithRequest())
.post(mockServer.getUrl() + WA_DELETE_TASK)
.then()
.statusCode(201);

}

private String deleteTaskWithRequest() {
return """
{
"deleteCaseTasksAction": {
"caseRef": "1234567890123456"
}
}
""";
}
}
8 changes: 8 additions & 0 deletions src/contractTest/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
core_case_data.api.url=${ccd_casedatastore_baseurl:http://localhost:3451}
ccd.jurisdictionid=SSCS
ccd.casetype=Benefit
ccd.eventid.create=createTestCase
idam.api.url=${IDAM_API_URL:http://localhost:8891}
idam.oauth2.user.email=${IDAM_LAU_SYSTEMUPDATE_USER:[email protected]}
idam.oauth2.user.password=${IDAM_LAU_SYSTEMUPDATE_PASSWORD:Pa55word11}
idam.client.secret=${IDAM_OAUTH2_CLIENT_SECRET:AAAAAAAAAAA}

0 comments on commit 1979d80

Please sign in to comment.