improved integration test

This commit is contained in:
Michael Hoennig 2025-03-11 14:49:13 +01:00
parent 5512c6682c
commit b1a785eda5

View File

@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.config;
import java.util.Map; import java.util.Map;
import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.WireMockServer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -18,8 +19,10 @@ import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static java.util.Map.entry;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ -43,70 +46,108 @@ class WebSecurityConfigIntegrationTest {
@Autowired @Autowired
private WireMockServer wireMockServer; private WireMockServer wireMockServer;
@Test @BeforeEach
public void shouldSupportPingEndpoint() { void setUp() {
// given wireMockServer.stubFor(get(anyUrl())
wireMockServer.stubFor(get(urlEqualTo("/cas/p3/serviceValidate?service=" + serviceUrl + "&ticket=test-user"))
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(200) .withStatus(200)
.withBody(""" .withBody("""
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess> <cas:authenticationFailure/>
<cas:user>test-user</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse> </cas:serviceResponse>
"""))); """)));
}
@Test
// fake Authorization header void accessToApiWithValidTokenShouldBePermitted() {
final var headers = new HttpHeaders(); // given
headers.set("Authorization", "test-user"); givenCasTicketValidationResponse("fake-cas-ticket");
// http request // http request
final var result = restTemplate.exchange( final var result = restTemplate.exchange(
"http://localhost:" + this.serverPort + "/api/ping", "http://localhost:" + this.serverPort + "/api/ping",
HttpMethod.GET, HttpMethod.GET,
new HttpEntity<>(null, headers), httpHeaders(entry("Authorization", "fake-cas-ticket")),
String.class String.class
); );
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).startsWith("pong test-user"); assertThat(result.getBody()).startsWith("pong fake-cas-ticket");
} }
@Test @Test
public void shouldSupportActuatorEndpoint() { void accessToApiWithoutTokenShouldBeDenied() {
final var result = this.restTemplate.getForEntity(
"http://localhost:" + this.serverPort + "/api/ping", String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
}
@Test
void accessToApiWithInvalidTokenShouldBeDenied() {
// given
givenCasTicketValidationResponse("fake-cas-ticket");
// when
final var result = restTemplate.exchange(
"http://localhost:" + this.serverPort + "/api/ping",
HttpMethod.GET,
httpHeaders(entry("Authorization", "WRONG-cas-ticket")),
String.class
);
// then
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
}
@Test
void accessToActuatorShouldBePermitted() {
final var result = this.restTemplate.getForEntity( final var result = this.restTemplate.getForEntity(
"http://localhost:" + this.managementPort + "/actuator", Map.class); "http://localhost:" + this.managementPort + "/actuator", Map.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
} }
@Test @Test
public void shouldSupportSwaggerUi() { void accessToSwaggerUiShouldBePermitted() {
final var result = this.restTemplate.getForEntity( final var result = this.restTemplate.getForEntity(
"http://localhost:" + this.managementPort + "/swagger-ui/index.html", String.class); "http://localhost:" + this.serverPort + "/swagger-ui/index.html", String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
} }
@Test @Test
public void shouldSupportApiDocs() { void accessToApiDocsEndpointShouldBePermitted() {
final var result = this.restTemplate.getForEntity( final var result = this.restTemplate.getForEntity(
"http://localhost:" + this.managementPort + "/v3/api-docs/swagger-config", String.class); "http://localhost:" + this.serverPort + "/v3/api-docs/swagger-config", String.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); // permitted but not configured assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).contains("\"configUrl\":\"/v3/api-docs/swagger-config\"");
} }
@Test @Test
public void shouldSupportHealthEndpoint() { void accessToActuatorEndpointShouldBePermitted() {
final var result = this.restTemplate.getForEntity( final var result = this.restTemplate.getForEntity(
"http://localhost:" + this.managementPort + "/actuator/health", Map.class); "http://localhost:" + this.managementPort + "/actuator/health", Map.class);
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody().get("status")).isEqualTo("UP"); assertThat(result.getBody().get("status")).isEqualTo("UP");
} }
@Test private void givenCasTicketValidationResponse(final String casToken) {
public void shouldSupportMetricsEndpoint() { wireMockServer.stubFor(get(urlEqualTo("/cas/p3/serviceValidate?service=" + serviceUrl + "&ticket=" + casToken))
final var result = this.restTemplate.getForEntity( .willReturn(aResponse()
"http://localhost:" + this.managementPort + "/actuator/metrics", Map.class); .withStatus(200)
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK); .withBody("""
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>${casToken}</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
""".replace("${casToken}", casToken))));
}
@SafeVarargs
private HttpEntity<?> httpHeaders(final Map.Entry<String, String>... headerValues) {
final var headers = new HttpHeaders();
for ( Map.Entry<String, String> headerValue: headerValues ) {
headers.add(headerValue.getKey(), headerValue.getValue());
}
return new HttpEntity<>(headers);
} }
} }