Skip to content

Commit

Permalink
EPA-171: Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasrichner-oviva committed Dec 5, 2024
1 parent a6ab26d commit 6332a9d
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static com.oviva.ehealthid.relyingparty.svc.ValidationException.*;
import static com.oviva.ehealthid.relyingparty.util.LocaleUtils.getNegotiatedLocale;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.oviva.ehealthid.auth.AuthException;
import com.oviva.ehealthid.fedclient.FederationException;
import com.oviva.ehealthid.relyingparty.svc.AuthenticationException;
Expand All @@ -21,11 +20,8 @@
import jakarta.ws.rs.core.UriInfo;
import jakarta.ws.rs.ext.ExceptionMapper;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.resteasy.util.MediaTypeHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.spi.LoggingEventBuilder;
Expand Down Expand Up @@ -135,22 +131,4 @@ private LoggingEventBuilder addRequestContext(LoggingEventBuilder builder) {

return builder.addKeyValue("httpRequest", map);
}

interface MediaTypeNegotiator {
MediaType bestMatch(List<MediaType> desiredMediaType, List<MediaType> supportedMediaTypes);
}

private static class ResteasyMediaTypeNegotiator implements MediaTypeNegotiator {

@Override
public MediaType bestMatch(
List<MediaType> desiredMediaType, List<MediaType> supportedMediaTypes) {

// note: resteasy needs mutable lists
return MediaTypeHelper.getBestMatch(
new ArrayList<>(desiredMediaType), new ArrayList<>(supportedMediaTypes));
}
}

public record Problem(@JsonProperty("type") String type, @JsonProperty("title") String title) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
import static org.mockito.Mockito.*;

import com.github.mustachejava.util.HtmlEscaper;
import com.oviva.ehealthid.auth.AuthException;
import com.oviva.ehealthid.fedclient.FederationException;
import com.oviva.ehealthid.relyingparty.svc.AuthenticationException;
import com.oviva.ehealthid.relyingparty.svc.ValidationException;
import com.oviva.ehealthid.relyingparty.ws.ThrowableExceptionMapper.Problem;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.ServerErrorException;
import jakarta.ws.rs.core.*;
import java.io.StringWriter;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -145,7 +145,6 @@ void toResponse_authentication() {
void toResponse_withBody() {

when(uriInfo.getRequestUri()).thenReturn(REQUEST_URI);
when(headers.getAcceptableMediaTypes()).thenReturn(List.of(MediaType.WILDCARD_TYPE));
mockHeaders("de-DE");

// when
Expand All @@ -157,27 +156,6 @@ void toResponse_withBody() {
assertNotNull(res.getEntity());
}

@Test
void toResponse_withJson() {

when(headers.getAcceptableMediaTypes())
.thenReturn(
List.of(
MediaType.APPLICATION_JSON_TYPE,
MediaType.TEXT_HTML_TYPE,
MediaType.WILDCARD_TYPE));

var msg = "Ooops! An error :/";

// when
var res = mapper.toResponse(new ValidationException(new Message(msg)));

// then
assertEquals(400, res.getStatus());
assertEquals(MediaType.APPLICATION_JSON_TYPE, res.getMediaType());
assertEquals(new Problem("/server_error", msg), res.getEntity());
}

@Test
void toResponse_withBody_Unauthorized() {
// when
Expand All @@ -201,17 +179,51 @@ void toResponse_withBody_seeOthers() {
}

@Test
void toResponse_withBody_withValidationExc() {
void toResponse_withBody_withValidationException() {

when(headers.getAcceptableMediaTypes()).thenReturn(List.of(MediaType.WILDCARD_TYPE));
doReturn("de-DE").when(headers).getHeaderString("Accept-Language");

// when
var res = mapper.toResponse(new ValidationException(new Message("error.invalidSession", null)));

// then
assertEquals(400, res.getStatus());
System.out.println(res.getEntity());
assertEquals(MediaType.TEXT_HTML_TYPE, res.getMediaType());
assertNotNull(res.getEntity());
}

@Test
void toResponse_withBody_withFederationException() {

doReturn("de-DE").when(headers).getHeaderString("Accept-Language");
doReturn(URI.create("https://example.com")).when(uriInfo).getRequestUri();
doReturn(null).when(headers).getHeaderString("user-agent");

// when
var res =
mapper.toResponse(
new FederationException("Nope!", FederationException.Reason.BAD_FEDERATION_MASTER));

// then
assertEquals(500, res.getStatus());
assertEquals(MediaType.TEXT_HTML_TYPE, res.getMediaType());
assertNotNull(res.getEntity());
}

@Test
void toResponse_withBody_withAuthenticationException() {

doReturn("de-DE").when(headers).getHeaderString("Accept-Language");
doReturn(URI.create("https://example.com")).when(uriInfo).getRequestUri();
doReturn(null).when(headers).getHeaderString("user-agent");

// when
var res =
mapper.toResponse(
new AuthException("Nope!", AuthException.Reason.INVALID_ID_TOKEN));

// then
assertEquals(500, res.getStatus());
assertEquals(MediaType.TEXT_HTML_TYPE, res.getMediaType());
assertNotNull(res.getEntity());
}
Expand All @@ -221,7 +233,6 @@ void toResponse_withBody_withValidationExc() {
void toResponse_withBody_withValidationExceptionAndDynamicContent(
String language, String messageKey, String message) {

when(headers.getAcceptableMediaTypes()).thenReturn(List.of(MediaType.WILDCARD_TYPE));
doReturn(language).when(headers).getHeaderString("Accept-Language");

// when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public Reason reason() {
public enum Reason {
UNKNOWN,
INVALID_PAR_URI,
MISSING_PAR_URI,
MISSING_PAR_ENDPOINT,
FAILED_PAR_REQUEST,
MISSING_AUTHORIZATION_URL,
MISSING_AUTHORIZATION_ENDPOINT,
MISSING_OPENID_CONFIGURATION_IN_ENTITY_STATEMENT,
INVALID_ID_TOKEN
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@ public class AuthExceptions {
private AuthExceptions() {}

public static AuthException invalidParRequestUri(String uri) {
// the field is called `request_uri`, hence the uri instead of url naming
return new AuthException(
"invalid par request_uri '%s'".formatted(uri), AuthException.Reason.INVALID_PAR_URI);
}

public static AuthException missingAuthorizationUrl(String sub) {
public static AuthException missingAuthorizationEndpoint(String sub) {
return new AuthException(
"entity statement of '%s' has no authorization url configuration".formatted(sub),
AuthException.Reason.MISSING_AUTHORIZATION_URL);
"entity statement of '%s' has no authorization endpoint configuration".formatted(sub),
AuthException.Reason.MISSING_AUTHORIZATION_ENDPOINT);
}

public static AuthException missingParUrl(String sub) {
public static AuthException missingParEndpoint(String sub) {
return new AuthException(
"entity statement of '%s' has no pushed authorization request configuration".formatted(sub),
AuthException.Reason.MISSING_PAR_URI);
"entity statement of '%s' has no pushed authorization request endpoint configuration"
.formatted(sub),
AuthException.Reason.MISSING_PAR_ENDPOINT);
}

public static AuthException failedParRequest(String issuer, Exception cause) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private URI buildAuthorizationUrl(String parRequestUri, EntityStatement trustedE
var authzEndpoint = openidConfig.authorizationEndpoint();

if (authzEndpoint == null || authzEndpoint.isBlank()) {
throw AuthExceptions.missingAuthorizationUrl(trustedEntityStatement.sub());
throw AuthExceptions.missingAuthorizationEndpoint(trustedEntityStatement.sub());
}

return UriBuilder.fromUri(authzEndpoint)
Expand All @@ -126,7 +126,7 @@ private ParResponse doPushedAuthorizationRequest(
var openidConfig = getIdpOpenIdProvider(trustedEntityStatement);
var parEndpoint = openidConfig.pushedAuthorizationRequestEndpoint();
if (parEndpoint == null || parEndpoint.isBlank()) {
throw AuthExceptions.missingParUrl(trustedEntityStatement.sub());
throw AuthExceptions.missingParEndpoint(trustedEntityStatement.sub());
}

return openIdClient.requestPushedUri(URI.create(parEndpoint), builder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.oviva.ehealthid.auth;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class AuthExceptionsTest {

@Test
void invalidParRequestUri() {
var got = AuthExceptions.invalidParRequestUri("https://example.com");
assertEquals(AuthException.Reason.INVALID_PAR_URI, got.reason());
}

@Test
void missingAuthorizationEndpoint() {
var got = AuthExceptions.missingAuthorizationEndpoint("https://example.com");
assertEquals(AuthException.Reason.MISSING_AUTHORIZATION_ENDPOINT, got.reason());
}

@Test
void missingParEndpoint() {
var got = AuthExceptions.missingParEndpoint("https://example.com");
assertEquals(AuthException.Reason.MISSING_PAR_ENDPOINT, got.reason());
}

@Test
void failedParRequest() {
var cause = new IllegalArgumentException();
var got = AuthExceptions.failedParRequest("https://fedmaster.example.com", cause);

assertEquals(AuthException.Reason.FAILED_PAR_REQUEST, got.reason());
assertEquals(cause, got.getCause());
}

@Test
void missingOpenIdConfigurationInEntityStatement() {
var got = AuthExceptions.missingOpenIdConfigurationInEntityStatement("https://example.com");

assertEquals(
AuthException.Reason.MISSING_OPENID_CONFIGURATION_IN_ENTITY_STATEMENT, got.reason());
}

@Test
void badIdTokenSignature() {
var got = AuthExceptions.badIdTokenSignature("https://example.com");
assertEquals(AuthException.Reason.INVALID_ID_TOKEN, got.reason());
}

@Test
void badIdToken() {
var cause = new IllegalArgumentException();
var got = AuthExceptions.badIdToken("https://example.com", cause);
assertEquals(AuthException.Reason.INVALID_ID_TOKEN, got.reason());
assertEquals(cause, got.getCause());
}
}

0 comments on commit 6332a9d

Please sign in to comment.