Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial functional tests commit #185

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 37 additions & 1 deletion Jenkinsfile_CNP
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
#!groovy

import uk.gov.hmcts.contino.AppPipelineDsl
import uk.gov.hmcts.contino.GithubAPI
properties(
[
[
$class : 'GithubProjectProperty',
projectUrlStr: 'https://github.com/hmcts/civil-sdt'
],
pipelineTriggers([[$class: 'GitHubPushTrigger']])
]
)

@Library("Infrastructure")

env.CIVIL_SDT_DEMO_URL = "http://civil-sdt-demo.service.core-compute-demo.internal"

def type = "java"
def product = "civil"
def component = "sdt"
def branchesToSync = ['demo', 'ithc', 'perftest', 'develop']

withPipeline(type, product, component) {
enableAksStagingDeployment()
disableLegacyDeployment()
nonServiceApp()
disableLegacyDeploymentOnAAT()
}

afterAlways('test') {
// hmcts/cnp-jenkins-library may fail to copy artifacts after checkstyle error so repeat command (see /src/uk/gov/hmcts/contino/GradleBuilder.groovy)
steps.archiveArtifacts allowEmptyArchive: true, artifacts: '**/reports/checkstyle/*.html'
}

afterAlways('smoketest:preview') {
steps.archiveArtifacts allowEmptyArchive: true, artifacts: '**/Smoke Tests Report CIVIL-SDT/**/*'
}

afterAlways('smoketest:aat') {
steps.archiveArtifacts allowEmptyArchive: true, artifacts: '**/Smoke Tests Report CIVIL-SDT/**/*'
}

afterAlways('functionalTest:preview') {
steps.archiveArtifacts allowEmptyArchive: true, artifacts: '**/Functional Tests Report CIVIL-SDT/**/*'
}

afterAlways('functionalTest:aat') {
steps.archiveArtifacts allowEmptyArchive: true, artifacts: '**/Functional Tests Report CIVIL-SDT/**/*'
}
28 changes: 27 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'se.patrikerdes.use-latest-versions' version '0.2.7'

id("net.serenity-bdd.serenity-gradle-plugin") version "3.7.0"
id 'application'
id 'checkstyle'
id 'jacoco'
Expand All @@ -18,8 +18,16 @@ plugins {
id "org.jetbrains.gradle.plugin.idea-ext" version "0.7"
}

defaultTasks 'clean','test','aggregate'

group = 'uk.gov.hmcts.civil.sdt'
version = '0.0.1'
sourceCompatibility = '11'
targetCompatibility = '11'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we are using 11 only, can we use 17


repositories {
mavenCentral()
}

java {
toolchain {
Expand Down Expand Up @@ -221,6 +229,14 @@ allprojects {
apply plugin: 'java'

dependencies {
implementation 'org.apache.xmlbeans:xmlbeans:3.1.0'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use 5.1.1 version as this is latest for xmlbeans

testImplementation 'net.serenity-bdd:serenity-core:3.2.0'
testImplementation 'net.serenity-bdd:serenity-junit:3.2.0'
Copy link
Collaborator

@kiran-yenigala-hmcts kiran-yenigala-hmcts Jul 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use 3.8.1 version as this is latest for serenity-core and serenity-junit

testImplementation 'io.rest-assured:rest-assured:4.4.0'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use 5.3.1 version as this is latest

implementation 'io.rest-assured:json-path:4.4.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2'
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check these as well for the latest versions

testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.7.2'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.3.1.Final', 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombokVersion
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.10'
Expand Down Expand Up @@ -370,6 +386,10 @@ allprojects {
testImplementation group: 'com.github.hmcts.civil-sdt-common', name: 'producers-api', version: sdtCommonVersion, classifier: 'test'
}

serenity {
reports = ["single-page-html"]
}

configurations.configureEach {
collect { configuration ->
configuration.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j'
Expand Down Expand Up @@ -558,6 +578,8 @@ subprojects { subproject ->
generateCucumberReports.enabled = false
useJUnitPlatform()

testLogging.showStandardStreams = true
systemProperties System.getProperties()
testLogging {
events "passed", "skipped", "failed"
}
Expand Down Expand Up @@ -744,3 +766,7 @@ cucumberReports {
outputDir = file("${rootDir}/target/cucumber")
reports = files("${rootDir}/target/cucumber.json")
}

gradle.startParameter.continueOnFailure = true

test.finalizedBy(aggregate)
23 changes: 23 additions & 0 deletions src/functionalTest/java/functions/XMLFunctions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package functions;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking, the package structure should mirror that of the main source classes. Store the functional test classes under src/functionalTest/java/uk/gov/moj/sdt so that the package for this class becomes uk.gov.moj.sdt.functions.

The same comment applies to all the other classes.


import io.restassured.response.Response;

public class XMLFunctions {

public String removeNamespaces(String xmlResponse) {
return xmlResponse.replaceAll("xmlns.*?(\"|\').*?(\"|\')", "")
.replaceAll("(<)(\\w+:)(.*?>)", "$1$3")
.replaceAll("(</)(\\w+:)(.*?>)", "$1$3");
}

public String getCleanResponse(Response response) {
String xmlResponse = response.asString();
xmlResponse = removeNamespaces(xmlResponse);
return xmlResponse;
}

public int generateRandomNumber(){
final int randomNumber = (int)(Math.random() * 10000);
return randomNumber;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import io.restassured.RestAssured;
import io.restassured.response.Response;
import net.serenitybdd.junit.runners.SerenityRunner;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the name of the file ends with .txt

//import net.serenitybdd.SerenityJUnit5Extension.runners.SerenityRunner;

import net.thucydides.core.annotations.Step;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;

@RunWith(SerenityRunner.class)
public class ValidGetBulkFeedback{

@Step("Given the soap request body")
public File soapRequestBody() {
return new File(getClass().getClassLoader().getResource("getBulkFeedback.xml").getFile());
}

@Step("When we send the soap request and get the response")
public Response soapResponse(File file) {
Response response = RestAssured
.given()
.baseUri("http://civil-sdt-demo.service.core-compute-demo.internal")
.basePath("/producers/service/sdtapi")
.header("Content-Type", "application/soap+xml;charset=UTF-8")
//.header("Content-Length", "1356")
.body(file)
.post();
return response;
}

@Step("Then the status code should be 200")
public void checkStatusCode(Response response) {
response.then().statusCode(200);
response.prettyPrint();
}

// @Test
// public void getBulkFeedback() {
// File file = soapRequestBody();
// Response response = soapResponse(file);
// checkStatusCode(response);
// String xPathResult = response.xmlPath().get("html.head.title");
// //String title = doc.getString("html.head.title");
// //var result = Integer.parseInt(String.valueOf(xPathResult));
// assertThat(xPathResult, containsString("502 Bad Gateway"));

// }
}
85 changes: 85 additions & 0 deletions src/functionalTest/java/steps/ClaimStatusSteps.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package steps;

import net.thucydides.core.annotations.Step;
import io.restassured.RestAssured;
import io.restassured.response.Response;

import java.nio.file.Files;
import java.nio.file.Paths;
Comment on lines +3 to +8
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Organise these imports. If you're using Visual Studio Code the shortcut is option + shift + o (assuming you are using a Mac).



Comment on lines +9 to +10
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove one of these blank lines.

public class ClaimStatusSteps {

private String xml;
private Response response;
private int randomNumber;

@Step("Given the soap request body")
public String soapRequestBody() {
String xmlContent = "";
try {
xmlContent = new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("statusUpdate.xml").toURI())));
} catch (Exception e) {
e.printStackTrace();
}
Comment on lines +19 to +24
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code for reading a file is duplicated in the IssueWarrant and MCOLJudgment classes. It would be better to put it in a method in a separate utility class and call that instead.

In the event of an exception being raised it would be better to fail the test rather than handling it and carrying on as is done here. This would make it easier to debug. In JUnit you can explicitly fail a test using org.junit.jupiter.api.Assertions.fail - I don't know if Serenity offers an equivalent. If not you could just let the method throw the exception by adding throws <exception class name> to the signature.


randomNumber = (int)(Math.random() * 10000); // Generate a random number
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the XMLFunctions.generateRandomNumber() method here rather than duplicating the code in it.

xmlContent = xmlContent.replace("RANDOM_NUMBER", Integer.toString(randomNumber)); // Replace the token

return xmlContent;
}

@Step("When we send the soap request and get the response")
public Response soapResponse(String xml) {
Response response = RestAssured
.given()
.baseUri("http://civil-sdt-demo.service.core-compute-demo.internal")
.basePath("/producers/service/sdtapi")
.header("Content-Type", "application/soap+xml;charset=UTF-8")
.body(xml)
.post();
return response;
}

@Step("Then the status code should be 200")
public void checkStatusCode(Response response) {
response.then().statusCode(200);
response.prettyPrint();
}

public String removeNamespaces(String xmlResponse) {
return xmlResponse.replaceAll("xmlns.*?(\"|\').*?(\"|\')", "")
.replaceAll("(<)(\\w+:)(.*?>)", "$1$3")
.replaceAll("(</)(\\w+:)(.*?>)", "$1$3");
}

public String getCleanResponse() {
String xmlResponse = response.asString();
xmlResponse = removeNamespaces(xmlResponse);
return xmlResponse;
}
Comment on lines +50 to +60
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods don't appear to be used and are duplicates of those on the XMLFunctions class. Remove them from this class.


public String getXml() {
return xml;
}

public void setXml(String xml) {
this.xml = xml;
}

public Response getResponse() {
return response;
}

public void setResponse(Response response) {
this.response = response;
}

public int getRandomNumber() {
return randomNumber;
}

public void setRandomNumber(int randomNumber) {
this.randomNumber = randomNumber;
}
}
65 changes: 65 additions & 0 deletions src/functionalTest/java/submitBulk/ClaimStatusUpdate.java
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Organise the imports on this class (see comment for ClaimStatusSteps class).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class needs to have a package line saying what package it is in.

Note that convention states that package names should all be in lower case. It would also make sense to create an "operations" package into which the get bulk feedback and submit bulk packages can be placed to group them logically. Taking this into account, and the comment about package names for the XMLFunctions class, I'd suggest the following package structure:

uk.gov.moj.sdt.operations
uk.gov.moj.sdt.operations.getbulkfeedback
uk.gov.moj.sdt.operations.submitbulk

The package line for this class would therefore be:
package uk.gov.moj.sdt.operations.submitbulk;

Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import net.serenitybdd.junit.runners.SerenityRunner;
import net.thucydides.core.annotations.Steps;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Comment on lines +3 to +5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are JUnit4 classes. Replace them with the JUnit5 equivalents:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

More details about replacing @RunWith with @ExtendWith can be found in the comment for that line.

import io.restassured.path.xml.XmlPath;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.matchesRegex;
import static org.hamcrest.CoreMatchers.containsString;
import org.junit.jupiter.api.Assertions;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace this with import static org.junit.jupiter.api.Assertions.assertEquals. You'll then be able to remove Assertions. from before assertEquals() on line 34.

import steps.ClaimStatusSteps;


Comment on lines +14 to +15
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove one of these blank lines.

@RunWith(SerenityRunner.class)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be replaced with the JUnit5 equivalent which is @ExtendWith(SerenityJUnit5Extension.class)

public class ClaimStatusUpdate {

@Steps
ClaimStatusSteps claimStatusSteps;

@Before
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to @BeforeEach (the JUnit5 equivalent).

public void setUp() {
claimStatusSteps.setXml(claimStatusSteps.soapRequestBody());
claimStatusSteps.setResponse(claimStatusSteps.soapResponse(claimStatusSteps.getXml()));
}

@Test
public void claimStatusUpdateResponseCode() {
XmlPath xmlPath = new XmlPath(claimStatusSteps.getCleanResponse()).setRoot("Envelope.Body.bulkResponse");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a constant for Envelope.Body.bulkResponse and use that instead. As it's also used in the MCOLJudgment and IssueWarrant classes you may want to create it as a public constant on a new parent class and have the three classes inherit from it.

String xmlResponseCode = xmlPath.getString("status.@code");

assertThat(xmlResponseCode, equalTo("Ok"));
Assertions.assertEquals(200, claimStatusSteps.getResponse().getStatusCode());

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this blank line.

}

@Test
public void validateCustRefClaimStatusUpdate() {
XmlPath xmlPath = new XmlPath(claimStatusSteps.getCleanResponse()).setRoot("Envelope.Body.bulkResponse");
String customerReference = xmlPath.getString("customerReference");

assertThat(customerReference, equalTo(Integer.toString(claimStatusSteps.getRandomNumber())));
}

@Test
public void validateSDTBulkRefClaimStatusUpdate() {
XmlPath xmlPath = new XmlPath(claimStatusSteps.getCleanResponse()).setRoot("Envelope.Body.bulkResponse");
String sdtBulkReference = xmlPath.getString("sdtBulkReference");

assertThat(sdtBulkReference, matchesRegex("MCOL-\\d+-\\d+"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regular expression can be changed to MCOL-\\d{14}-\\d{9} (i.e. the second part should be exactly 14 digits and the third part exactly 9 digits) to more accurately reflect the format - see SdtBulkReferenceGenerator.getSdtBulkReference.

}

@Test
public void claimStatusUpdateResponseStructure() {
claimStatusSteps.checkStatusCode(claimStatusSteps.getResponse());

String xmlResponse = claimStatusSteps.getCleanResponse();

assertThat(xmlResponse, containsString("status"));
assertThat(xmlResponse, containsString("customerReference"));
assertThat(xmlResponse, containsString("code"));
assertThat(xmlResponse, containsString("sdtBulkReference"));
}
}
Loading