Skip to content

Commit

Permalink
Merge branch 'master' into PUB-2618-Dependency-Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisS1512 authored Oct 25, 2024
2 parents 69e206d + 7aac30f commit ac22c0e
Show file tree
Hide file tree
Showing 25 changed files with 359 additions and 142 deletions.
16 changes: 13 additions & 3 deletions Jenkinsfile_CNP
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

@Library("Infrastructure")

import uk.gov.hmcts.contino.GradleBuilder

def type = "java"
def product = "pip"
def component = "publication-services"

GradleBuilder builder = new GradleBuilder(this, product)

def setupTestSecrets() {
def bootstap_env = env.ENV == "prod" || env.ENV == "demo" || env.ENV == "sbox" ? env.ENV : "stg"
azureKeyVault(
Expand All @@ -20,7 +24,9 @@ def setupTestSecrets() {
secret('app-pip-subscription-management-scope', 'SUBSCRIPTION_MANAGEMENT_AZ_API'),
secret('app-pip-publication-services-scope', 'PUBLICATION_SERVICES_AZ_API'),
secret('app-pip-account-management-scope', 'ACCOUNT_MANAGEMENT_AZ_API'),
secret('app-tenant', 'TENANT_ID')
secret('app-tenant', 'TENANT_ID'),
secret('app-pip-data-management-id', 'CLIENT_ID_FT'),
secret('app-pip-data-management-pwd', 'CLIENT_SECRET_FT')
]) {
env.NOTIFY_API_KEY = "${NOTIFY_API_KEY}"
env.APP_URI = "${APP_URI}"
Expand All @@ -32,6 +38,8 @@ def setupTestSecrets() {
env.SUBSCRIPTION_MANAGEMENT_AZ_API = "${SUBSCRIPTION_MANAGEMENT_AZ_API}"
env.TENANT_ID = "${TENANT_ID}"
env.PI_TEAM_EMAIL = "${PI_TEAM_EMAIL}"
env.CLIENT_ID_FT = "${CLIENT_ID_FT}"
env.CLIENT_SECRET_FT = "${CLIENT_SECRET_FT}"
}
}

Expand All @@ -45,8 +53,6 @@ static Map<String, Object> secret(String secretName, String envVariable) {

withPipeline(type, product, component) {

// loadVaultSecrets(apiSecrets)

onMaster() {
env.ENV = 'stg'
}
Expand All @@ -67,4 +73,8 @@ withPipeline(type, product, component) {
enableAksStagingDeployment()
disableLegacyDeployment()
enableApiGatewayTest()

afterAlways('test') {
builder.gradle('integration')
}
}
87 changes: 49 additions & 38 deletions README.md

Large diffs are not rendered by default.

38 changes: 35 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ java {
}

sourceSets {
functionalTest {
integrationTest {
java {
compileClasspath += main.output
runtimeClasspath += main.output
Expand All @@ -31,6 +31,15 @@ sourceSets {
resources.srcDir file('src/integrationTest/resources')
}

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

smokeTest {
java {
compileClasspath += main.output
Expand All @@ -42,6 +51,9 @@ sourceSets {
}

configurations {
integrationTestImplementation.extendsFrom testImplementation
integrationTestRuntimeOnly.extendsFrom runtimeOnly

functionalTestImplementation.extendsFrom testImplementation
functionalTestRuntimeOnly.extendsFrom runtimeOnly

Expand Down Expand Up @@ -74,6 +86,13 @@ test {
failFast = true
}

task integration(type: Test) {
description = "Runs integration tests"
group = "Verification"
testClassesDirs = sourceSets.integrationTest.output.classesDirs
classpath = sourceSets.integrationTest.runtimeClasspath
}

task functional(type: Test) {
description = "Runs functional tests"
group = "Verification"
Expand All @@ -95,13 +114,13 @@ checkstyle {

pmd {
toolVersion = "7.6.0"
sourceSets = [sourceSets.main, sourceSets.test, sourceSets.functionalTest, sourceSets.smokeTest]
sourceSets = [sourceSets.main, sourceSets.test, sourceSets.integrationTest, sourceSets.functionalTest, sourceSets.smokeTest]
reportsDir = file("$project.buildDir/reports/pmd")
ruleSetFiles = files("config/pmd/ruleset.xml")
}

jacocoTestReport {
executionData(test)
executionData(test, integration)
reports {
xml.required = true
csv.required = false
Expand Down Expand Up @@ -195,6 +214,7 @@ dependencies {
testImplementation group: 'org.testcontainers', name: 'junit-jupiter'
testImplementation group: 'io.github.hakky54', name: 'logcaptor', version: '2.9.3'
testImplementation group: 'com.github.hmcts', name: 'fortify-client', version: '1.4.4', classifier: 'all'
functionalTestImplementation group: 'io.rest-assured', name: 'rest-assured'
}

task fortifyScan(type: JavaExec) {
Expand All @@ -217,6 +237,18 @@ bootJar {
}
}

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

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

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

wrapper {
distributionType = Wrapper.DistributionType.ALL
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<policies>
<inbound>
<validate-jwt token-value="@((String)context.Request.Body.As<JObject>(preserveContent: true)["bearer"])" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
<openid-config url="https://login.microsoftonline.com/{TENANT_ID}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>{CLIENT_ID}</audience>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package uk.gov.hmcts.pip.publication.services;

import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import uk.gov.hmcts.pip.publication.services.utils.FunctionalTestBase;
import uk.gov.hmcts.pip.publication.services.utils.OAuthClient;
import uk.gov.hmcts.reform.pip.publication.services.Application;
import uk.gov.hmcts.reform.pip.publication.services.models.request.WelcomeEmail;

import java.util.Map;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
import static org.springframework.http.HttpStatus.OK;

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {Application.class, OAuthClient.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles(profiles = "functional")
class NotificationEmailTests extends FunctionalTestBase {
private static final String BEARER = "Bearer ";

private static final String NOTIFY_URL = "/notify";
private static final String MEDIA_WELCOME_EMAIL_URL = NOTIFY_URL + "/welcome-email";

private static final String TEST_EMAIL = "test_user@justice.gov.uk";
private static final String TEST_FULL_NAME = "test user";

@Test
void shouldSendMediaWelcomeEmailForNewUser() {
WelcomeEmail requestBody = new WelcomeEmail(TEST_EMAIL, false, TEST_FULL_NAME);

final Response response = doPostRequest(MEDIA_WELCOME_EMAIL_URL,
Map.of(AUTHORIZATION, BEARER + accessToken),
requestBody);

assertThat(response.getStatusCode()).isEqualTo(OK.value());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package uk.gov.hmcts.pip.publication.services.utils;

public class AuthException extends RuntimeException {
private static final long serialVersionUID = -326686171637352006L;

public AuthException(String error) {
super(error);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package uk.gov.hmcts.pip.publication.services.utils;

import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.CollectionUtils;
import uk.gov.hmcts.reform.pip.publication.services.Application;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static io.restassured.RestAssured.given;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;

@SpringBootTest(classes = {Application.class, OAuthClient.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FunctionalTestBase extends RedisConfigurationTestBase {

protected static final String CONTENT_TYPE_VALUE = "application/json";

@Autowired
private OAuthClient authClient;

protected String accessToken;

@Value("${test-url}")
private String testUrl;

@BeforeEach
void setUp() {
RestAssured.baseURI = testUrl;
accessToken = authClient.generateAccessToken();
}

protected Response doPostRequest(final String path, final Map<String, String> additionalHeaders,
final Object body) {
return given()
.relaxedHTTPSValidation()
.headers(getRequestHeaders(additionalHeaders))
.body(body)
.when()
.post(path)
.thenReturn();
}

private static Map<String, String> getRequestHeaders(final Map<String, String> additionalHeaders) {
final Map<String, String> headers = new ConcurrentHashMap<>(Map.of(CONTENT_TYPE, CONTENT_TYPE_VALUE));
if (!CollectionUtils.isEmpty(additionalHeaders)) {
headers.putAll(additionalHeaders);
}
return headers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package uk.gov.hmcts.pip.publication.services.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import static io.restassured.RestAssured.given;

@Component
public class OAuthClient {

@Value("${CLIENT_ID_FT}")
private String clientId;

@Value("${CLIENT_SECRET_FT}")
private String clientSecret;

@Value("${TENANT_ID}")
private String tenantId;

@Value("${APP_URI}")
private String scope;

public String generateAccessToken() {
String token = given()
.relaxedHTTPSValidation()
.header("content-type", "application/x-www-form-urlencoded")
.formParam("client_id", clientId)
.formParam("scope", scope + "/.default")
.formParam("client_secret", clientSecret)
.formParam("grant_type", "client_credentials")
.baseUri("https://login.microsoftonline.com/" + tenantId + "/oauth2/v2.0/token")
.post()
.body()
.jsonPath()
.get("access_token");

if (token == null) {
throw new AuthException("Unable to generate access token for the API");
}
return token;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package uk.gov.hmcts.pip.publication.services.utils;

import com.redis.testcontainers.RedisContainer;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;

@Testcontainers
@SuppressWarnings("checkstyle:HideUtilityClassConstructorCheck")
public class RedisConfigurationTestBase {
private static final String REDIS_IMAGE_NAME = "redis:latest";
private static final int REDIS_PORT = 6379;

@Container
private static RedisContainer redisContainer = new RedisContainer(DockerImageName.parse(REDIS_IMAGE_NAME))
.withExposedPorts(REDIS_PORT);

@DynamicPropertySource
static void registerRedisProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.redis.host", redisContainer::getHost);
registry.add("spring.data.redis.port", () -> redisContainer.getMappedPort(REDIS_PORT).toString());
}
}
7 changes: 7 additions & 0 deletions src/functionalTest/resources/application-functional.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
rate-limit:
email:
capacity:
standard: 20
high: 50
interval-in-minutes: 1
test-url: ${TEST_URL:http://localhost:8081}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import uk.gov.hmcts.reform.pip.publication.services.Application;
import uk.gov.hmcts.reform.pip.publication.services.utils.RedisConfigurationFunctionalTestBase;
import uk.gov.hmcts.reform.pip.publication.services.utils.RedisConfigurationTestBase;

import java.io.OutputStream;
import java.nio.file.Files;
Expand All @@ -27,8 +27,8 @@
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@DirtiesContext
@ActiveProfiles("functional")
class SwaggerPublisherTest extends RedisConfigurationFunctionalTestBase {
@ActiveProfiles("integration")
class SwaggerPublisherTest extends RedisConfigurationTestBase {

@Autowired
private MockMvc mvc;
Expand Down
Loading

0 comments on commit ac22c0e

Please sign in to comment.