Skip to content
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
52 changes: 29 additions & 23 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
buildscript {
ext {
flywayVersion = '11.20.3'
postgresqlVersion = '42.7.10'
flywayVersion = '12.6.1'
postgresqlVersion = '42.7.11'
}
dependencies {
classpath("org.postgresql:postgresql:$postgresqlVersion") // must be compatible with flyway version
Expand All @@ -15,12 +15,12 @@ plugins {
id 'pmd'
id 'jacoco'
id 'io.spring.dependency-management' version '1.1.7'
id 'org.springframework.boot' version '3.5.11'
id 'org.springframework.boot' version '4.0.6'
id 'org.owasp.dependencycheck' version '12.2.0'
id 'com.github.ben-manes.versions' version '0.53.0'
id 'org.sonarqube' version '7.2.3.7755'
id 'com.github.ben-manes.versions' version '0.54.0'
id 'org.sonarqube' version '7.3.0.8198'
id 'org.flywaydb.flyway' version "$flywayVersion"
id 'io.freefair.lombok' version '9.2.0'
id 'io.freefair.lombok' version '9.5.0'
}

group = 'uk.gov.hmcts.dts'
Expand Down Expand Up @@ -79,7 +79,7 @@ test {

ext.getVaultSecret = { String secretName ->
new ByteArrayOutputStream().withStream { os ->
exec {
project.exec {
commandLine 'az', 'keyvault', 'secret', 'show', '--vault-name', 'fact-aat', '-o', 'tsv', '--query', 'value', '--name', secretName
standardOutput = os
}
Expand Down Expand Up @@ -194,36 +194,41 @@ repositories {
}

def versions = [
reformLogging : '6.1.9',
reformLogging : '8.0.0',
springBoot : springBoot.class.package.implementationVersion,
flyway : "$flywayVersion",
postgresql : "$postgresqlVersion"
]

dependencies {
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webmvc'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-resource-server'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '4.3.1'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security-oauth2-resource-server'
implementation group:'org.springframework.boot', name:'spring-boot-flyway'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '5.0.1'
implementation group: 'org.reactivestreams', name: 'reactive-streams', version: '1.0.4'
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.8.16'
implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '3.0.3'
implementation group: 'com.github.hmcts.java-logging', name: 'logging', version: versions.reformLogging
implementation group: 'com.github.hmcts.java-logging', name: 'logging-appinsights', version: versions.reformLogging
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-hystrix', version: '2.2.10.RELEASE'
implementation group: 'org.postgresql', name: 'postgresql', version: versions.postgresql
implementation group: 'org.flywaydb', name: 'flyway-core', version: versions.flyway
implementation group: 'com.launchdarkly', name: 'launchdarkly-java-server-sdk', version: '7.12.0'
implementation group: 'com.launchdarkly', name: 'launchdarkly-java-server-sdk', version: '7.13.4'
implementation group: 'commons-fileupload', name: 'commons-fileupload', version: '1.6.0'
implementation group: 'com.googlecode.owasp-java-html-sanitizer', name: 'owasp-java-html-sanitizer', version: '20240325.1'
implementation group: 'com.google.guava', name: 'guava', version: '33.5.0-jre'
implementation group: 'com.googlecode.owasp-java-html-sanitizer', name: 'owasp-java-html-sanitizer', version: '20260313.1'
implementation group: 'com.google.guava', name: 'guava', version: '33.6.0-jre'
implementation 'net.logstash.logback:logstash-logback-encoder:9.0'
implementation group: 'io.github.resilience4j', name: 'resilience4j-spring-boot3', version: '2.3.0'
implementation group: 'io.github.resilience4j', name: 'resilience4j-spring-boot4', version: '2.4.0'

//testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-webmvc-test'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator-test'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa-test'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-security-oauth2-resource-server-test'

testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
testImplementation group: 'com.github.hmcts', name: 'fortify-client', version: '1.4.10'
testImplementation group: 'org.springframework.security', name: 'spring-security-test', version: '7.0.3'
testImplementation group: 'org.springframework.security', name: 'spring-security-test', version: '7.0.5'

integrationTestImplementation sourceSets.main.runtimeClasspath
integrationTestImplementation sourceSets.test.runtimeClasspath
Expand All @@ -233,14 +238,15 @@ dependencies {


functionalTestImplementation sourceSets.integrationTest.runtimeClasspath
functionalTestImplementation group: 'io.rest-assured', name: 'rest-assured', version: '5.5.7'
functionalTestImplementation group: 'io.rest-assured', name: 'rest-assured', version: '6.0.0'

smokeTestImplementation sourceSets.functionalTest.runtimeClasspath

runtimeOnly group: 'org.flywaydb', name: 'flyway-database-postgresql', version: versions.flyway
}

mainClassName = 'uk.gov.hmcts.dts.fact.Application'
application {
mainClass = 'uk.gov.hmcts.dts.fact.Application'
}

bootJar {
getArchiveFileName().set(provider {
Expand Down Expand Up @@ -287,7 +293,7 @@ task migratePostgresDatabase(type: FlywayMigrateTask) {
}

task fortifyScan(type: JavaExec) {
main = "uk.gov.hmcts.fortifyclient.FortifyClientMainApp"
mainClass.set("uk.gov.hmcts.fortifyclient.FortifyClientMainApp")
classpath += sourceSets.test.runtimeClasspath
jvmArgs = ['--add-opens=java.base/java.lang.reflect=ALL-UNNAMED']
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package uk.gov.hmcts.dts.fact;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import tools.jackson.core.JacksonException;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.cfg.DateTimeFeature;
import tools.jackson.databind.json.JsonMapper;
import uk.gov.hmcts.dts.fact.model.Court;
import uk.gov.hmcts.dts.fact.model.CourtReference;
import uk.gov.hmcts.dts.fact.model.CourtReferenceWithHistoricalName;
Expand Down Expand Up @@ -245,7 +245,7 @@ void shouldReturnNotFoundForEmptyCourtTypes() {
}

@Test
void shouldRetrieveCurrentCourtByHistoricalCourtName() throws JsonProcessingException {
void shouldRetrieveCurrentCourtByHistoricalCourtName() throws JacksonException {
final String name = "Edinburgh Employment Tribunal";

// Creating court history
Expand All @@ -271,7 +271,7 @@ void shouldRetrieveCurrentCourtByHistoricalCourtName() throws JsonProcessingExce
}

@Test
void shouldReturnNoContentsForNonExistingCourtHistoricalName() throws JsonProcessingException {
void shouldReturnNoContentsForNonExistingCourtHistoricalName() throws JacksonException {

// Creating court history
Response response1 = createCourtHistory();
Expand All @@ -286,15 +286,14 @@ void shouldReturnNoContentsForNonExistingCourtHistoricalName() throws JsonProces
cleanUp();
}

private Response createCourtHistory() throws JsonProcessingException {
private Response createCourtHistory() throws JacksonException {

final CourtHistory courtHistory = new CourtHistory(null, TEST_SEARCH_COURT_ID, TEST_SEARCH_COURT_NAME,
LocalDateTime.parse("2024-02-03T10:15:30"),
LocalDateTime.parse("2007-12-03T10:15:30"), "court-name-cy");
final ObjectMapper mapper = new ObjectMapper();

mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
ObjectMapper mapper = JsonMapper.builder()
.disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
.build();
String newCourtHistoryJson = mapper.writeValueAsString(courtHistory);

return doPostRequest(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package uk.gov.hmcts.dts.fact;

import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import tools.jackson.databind.ObjectMapper;
import uk.gov.hmcts.dts.fact.model.CourtReferenceWithDistance;
import uk.gov.hmcts.dts.fact.model.CourtWithDistance;
import uk.gov.hmcts.dts.fact.model.ServiceAreaWithCourtReferencesWithDistance;
import uk.gov.hmcts.dts.fact.util.FunctionalTestBase;
import uk.gov.hmcts.dts.fact.util.TestUtil;

import java.util.Comparator;
import java.util.List;
Expand All @@ -22,13 +25,14 @@
class SearchEndpointTest extends FunctionalTestBase {

private static final String SEARCH_ENDPOINT = "/search/";
private static final ObjectMapper OBJECT_MAPPER = TestUtil.objectMapper();

@Test
void shouldRetrieve10CourtDetailsSortedByDistance() {
final var response = doGetRequest(SEARCH_ENDPOINT + "results.json?postcode=OX1 1RZ");
assertThat(response.statusCode()).isEqualTo(OK.value());

final List<CourtWithDistance> courts = response.body().jsonPath().getList(".", CourtWithDistance.class);
final List<CourtWithDistance> courts = deserializeCourts(response);
assertThat(courts.size()).isEqualTo(10);
assertThat(courts).isSortedAccordingTo(Comparator.comparing(CourtWithDistance::getDistance));
}
Expand All @@ -39,7 +43,7 @@ void shouldRetrieve10CourtDetailsByAreaOfLawSortedByDistance() {
final var response = doGetRequest(SEARCH_ENDPOINT + "results.json?includeClosed=true&postcode=OX1 1RZ&aol=" + aol);
assertThat(response.statusCode()).isEqualTo(OK.value());

final List<CourtWithDistance> courts = response.body().jsonPath().getList(".", CourtWithDistance.class);
final List<CourtWithDistance> courts = deserializeCourts(response);
assertThat(courts.size()).isEqualTo(10);
assertThat(courts).isSortedAccordingTo(Comparator.comparing(CourtWithDistance::getDistance));
assertTrue(courts
Expand All @@ -54,15 +58,13 @@ void postcodeSearchShouldSupportWelsh() {
final var welshResponse = doGetRequest(SEARCH_ENDPOINT + "results.json?postcode=CF10 1ET", Map.of(ACCEPT_LANGUAGE, "cy"));
assertThat(welshResponse.statusCode()).isEqualTo(OK.value());

final List<CourtWithDistance> welshCourts = welshResponse.body().jsonPath()
.getList(".", CourtWithDistance.class);
final List<CourtWithDistance> welshCourts = deserializeCourts(welshResponse);
assertThat(welshCourts.get(0).getAddresses().get(0).getTownName()).isEqualTo("Caerdydd");

final var englishResponse = doGetRequest(SEARCH_ENDPOINT + "results.json?includeClosed=true&postcode=CF10 1ET");
assertThat(englishResponse.statusCode()).isEqualTo(OK.value());

final List<CourtWithDistance> englishCourts = englishResponse.body().jsonPath()
.getList(".", CourtWithDistance.class);
final List<CourtWithDistance> englishCourts = deserializeCourts(englishResponse);
assertThat(englishCourts.get(0).getAddresses().get(0).getTownName()).isEqualTo("Cardiff");
}

Expand All @@ -71,15 +73,13 @@ void nameSearchShouldSupportWelsh() {
final var welshResponse = doGetRequest(SEARCH_ENDPOINT + "results.json?q=caerdydd", Map.of(ACCEPT_LANGUAGE, "cy"));
assertThat(welshResponse.statusCode()).isEqualTo(OK.value());

final List<CourtWithDistance> welshCourts = welshResponse.body().jsonPath()
.getList(".", CourtWithDistance.class);
final List<CourtWithDistance> welshCourts = deserializeCourts(welshResponse);
assertThat(welshCourts.get(0).getAddresses().get(0).getTownName()).isEqualTo("Caerdydd");

final var englishResponse = doGetRequest(SEARCH_ENDPOINT + "results.json?q=cardiff");
assertThat(englishResponse.statusCode()).isEqualTo(OK.value());

final List<CourtWithDistance> englishCourts = englishResponse.body().jsonPath()
.getList(".", CourtWithDistance.class);
final List<CourtWithDistance> englishCourts = deserializeCourts(englishResponse);
assertThat(englishCourts.get(0).getAddresses().get(0).getTownName()).isEqualTo("Cardiff");
}

Expand Down Expand Up @@ -306,4 +306,12 @@ void shouldReturnOpenOrClosedCourtsWhenIncludeClosedIsTrueForProbate() {
false)));

}

private List<CourtWithDistance> deserializeCourts(final Response response) {
try {
return OBJECT_MAPPER.readerForListOf(CourtWithDistance.class).readValue(response.asString());
} catch (Exception exception) {
throw new RuntimeException("Unable to deserialize search response", exception);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package uk.gov.hmcts.dts.fact.admin;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import tools.jackson.core.JacksonException;
import uk.gov.hmcts.dts.fact.model.admin.Audit;
import uk.gov.hmcts.dts.fact.model.admin.OpeningTime;
import uk.gov.hmcts.dts.fact.util.AdminFunctionalTestBase;
Expand Down Expand Up @@ -41,7 +41,7 @@ class AdminAuditEndpointTest extends AdminFunctionalTestBase {


@BeforeEach
void setUpTestData() throws JsonProcessingException {
void setUpTestData() throws JacksonException {
setUpOpeningTimes();
}

Expand Down Expand Up @@ -108,7 +108,7 @@ void shouldBeForbiddenForGettingAllAudits() {

/************************************************************* utility methods. ***************************************************************/

private void setUpOpeningTimes() throws JsonProcessingException {
private void setUpOpeningTimes() throws JacksonException {
Response response = doGetRequest(ADMINISTRATIVE_COURT_OPENING_TIMES_PATH, Map.of(AUTHORIZATION, BEARER + authenticatedToken));
final List<OpeningTime> currentOpeningTimes = response.body().jsonPath().getList(".", OpeningTime.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package uk.gov.hmcts.dts.fact.admin;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import tools.jackson.core.JacksonException;
import uk.gov.hmcts.dts.fact.model.admin.AdditionalLink;
import uk.gov.hmcts.dts.fact.util.AdminFunctionalTestBase;

Expand Down Expand Up @@ -75,7 +75,7 @@ void shouldNotRetrieveAdditionalLinkWhenCourtSlugNotFound() {
/************************************************************* Update Request Tests. ***************************************************************/

@Test
void shouldUpdateAdditionalLink() throws JsonProcessingException {
void shouldUpdateAdditionalLink() throws JacksonException {
final List<AdditionalLink> currentAdditionalLink = getCurrentAdditionalLink();
final List<AdditionalLink> expectedAdditionalLink = addNewAdditionalLink(currentAdditionalLink);
final String updatedJson = objectMapper().writeValueAsString(expectedAdditionalLink);
Expand Down Expand Up @@ -104,13 +104,13 @@ void shouldUpdateAdditionalLink() throws JsonProcessingException {
}

@Test
void shouldRequireATokenWhenUpdatingAdditionalLinks() throws JsonProcessingException {
void shouldRequireATokenWhenUpdatingAdditionalLinks() throws JacksonException {
final var response = doPutRequest(PLYMOUTH_COMBINED_COURT_ADDITIONAL_LINK_PATH, getTestAdditionalLink());
assertThat(response.statusCode()).isEqualTo(UNAUTHORIZED.value());
}

@Test
void shouldBeForbiddenForUpdatingAdditionalLinks() throws JsonProcessingException {
void shouldBeForbiddenForUpdatingAdditionalLinks() throws JacksonException {
final var response = doPutRequest(
PLYMOUTH_COMBINED_COURT_ADDITIONAL_LINK_PATH,
Map.of(AUTHORIZATION, BEARER + forbiddenToken), getTestAdditionalLink()
Expand All @@ -119,7 +119,7 @@ void shouldBeForbiddenForUpdatingAdditionalLinks() throws JsonProcessingExceptio
}

@Test
void shouldNotUpdateAdditionalLinkWhenCourtSlugNotFound() throws JsonProcessingException {
void shouldNotUpdateAdditionalLinkWhenCourtSlugNotFound() throws JacksonException {
final var response = doPutRequest(
COURT_NOT_FIND_PATH,
Map.of(AUTHORIZATION, BEARER + superAdminToken),
Expand All @@ -144,7 +144,7 @@ private List<AdditionalLink> addNewAdditionalLink(final List<AdditionalLink> add
return updatedAdditionalLinks;
}

private static String getTestAdditionalLink() throws JsonProcessingException {
private static String getTestAdditionalLink() throws JacksonException {
final List<AdditionalLink> additionalLink = Arrays.asList(
new AdditionalLink(TEST_URL,TEST_DESCRIPTION,TEST_DESCRIPTION_CY)
);
Expand Down
Loading