diff --git a/pom.xml b/pom.xml index ff5a0d33..bc6bfe96 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,6 @@ de.remsfal.service.entity.dto\** - githubDeploy @@ -85,7 +84,6 @@ org.jboss.logmanager.LogManager - ${maven.home} ${maven.multiModuleProjectDirectory}/target/site/jacoco/jacoco.exec @@ -114,7 +112,6 @@ ${project.build.directory}/${project.build.finalName}-runner org.jboss.logmanager.LogManager - ${maven.home} diff --git a/remsfal-service/pom.xml b/remsfal-service/pom.xml index 7a1985df..6e65bb43 100644 --- a/remsfal-service/pom.xml +++ b/remsfal-service/pom.xml @@ -22,6 +22,12 @@ + + org.awaitility + awaitility + 4.2.0 + test + io.quarkus.platform quarkus-bom diff --git a/remsfal-service/src/main/java/de/remsfal/service/boundary/authentication/GoogleAuthenticator.java b/remsfal-service/src/main/java/de/remsfal/service/boundary/authentication/GoogleAuthenticator.java index 279db3d1..c0dc0fe3 100644 --- a/remsfal-service/src/main/java/de/remsfal/service/boundary/authentication/GoogleAuthenticator.java +++ b/remsfal-service/src/main/java/de/remsfal/service/boundary/authentication/GoogleAuthenticator.java @@ -53,24 +53,24 @@ public class GoogleAuthenticator { * For maximum efficiency, a single globally-shared instance of the GoogleIdTokenVerifier. */ private final GoogleIdTokenVerifier tokenVerifier = new GoogleIdTokenVerifier - .Builder(transport, jsonFactory) - .build(); + .Builder(transport, jsonFactory) + .build(); public URI getAuthorizationCodeURI(final String redirectUri, final String state) { return UriBuilder.fromUri(authServerURL) - .queryParam("response_type", authResponseType) - .queryParam("client_id", authClientId) - .queryParam("redirect_uri", redirectUri) - .queryParam("scope", authScopes) - .queryParam("state", state) - .build(); + .queryParam("response_type", authResponseType) + .queryParam("client_id", authClientId) + .queryParam("redirect_uri", redirectUri) + .queryParam("scope", authScopes) + .queryParam("state", state) + .build(); } public GoogleIdToken getIdToken(final String code, final URI redirectUri) { try { final GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, - authClientId, authClientSecret, code, redirectUri.toASCIIString()) - .execute(); + authClientId, authClientSecret, code, redirectUri.toASCIIString()) + .execute(); return verifyIdToken(response.getIdToken()); } catch (IOException e) { throw new ForbiddenException("Unable to extract ID token", e); @@ -88,4 +88,4 @@ private GoogleIdToken verifyIdToken(final String idToken) throws IOException { } } -} +} \ No newline at end of file diff --git a/remsfal-service/src/test/java/de/remsfal/service/boundary/AuthenticationResourceMockitoTest.java b/remsfal-service/src/test/java/de/remsfal/service/boundary/AuthenticationResourceMockitoTest.java index 3c35b04b..7680a8a0 100644 --- a/remsfal-service/src/test/java/de/remsfal/service/boundary/AuthenticationResourceMockitoTest.java +++ b/remsfal-service/src/test/java/de/remsfal/service/boundary/AuthenticationResourceMockitoTest.java @@ -4,6 +4,8 @@ import io.quarkus.test.junit.QuarkusTest; import io.restassured.matcher.RestAssuredMatchers; +import jakarta.transaction.Transactional; +import org.awaitility.Awaitility; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -20,6 +22,8 @@ import jakarta.ws.rs.core.Response.Status; +import java.util.concurrent.TimeUnit; + @QuarkusTest class AuthenticationResourceMockitoTest extends AbstractResourceTest { @@ -32,109 +36,120 @@ class AuthenticationResourceMockitoTest extends AbstractResourceTest { void session_SUCCESS_userIsCreated() { final String code = "anyRandomCode"; final GoogleIdToken.Payload idTokenPayload = new GoogleIdToken.Payload() - .setSubject(TestData.USER_TOKEN_1) - .setEmail(TestData.USER_EMAIL_1); + .setSubject(TestData.USER_TOKEN_1) + .setEmail(TestData.USER_EMAIL_1); when(authenticator.getIdToken(eq(code), any())) - .thenReturn(new GoogleIdToken(new JsonWebSignature.Header(), idTokenPayload, new byte[1], new byte[1])); + .thenReturn(new GoogleIdToken(new JsonWebSignature.Header(), idTokenPayload, new byte[1], new byte[1])); long enties = entityManager - .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) - .setParameter("email", TestData.USER_EMAIL_1) - .getSingleResult(); + .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) + .setParameter("email", TestData.USER_EMAIL_1) + .getSingleResult(); assertEquals(0, enties); given() - .when() - .queryParam("code", code) - .queryParam("state", "/my/callback") - .queryParam("anyOtherParam", "toBeIgnored") - .redirects().follow(false) - .get(BASE_PATH + "/session") - .then() - .statusCode(Status.FOUND.getStatusCode()) - .header("location", Matchers.equalTo("http://localhost:8081/my/callback")) - .cookie("remsfal_session", RestAssuredMatchers.detailedCookie() - .path("/") - .sameSite("Strict") - .maxAge(60 * 30)); + .when() + .queryParam("code", code) + .queryParam("state", "/my/callback") + .queryParam("anyOtherParam", "toBeIgnored") + .redirects().follow(false) + .get(BASE_PATH + "/session") + .then() + .statusCode(Status.FOUND.getStatusCode()) + .header("location", Matchers.equalTo("http://localhost:8081/my/callback")) + .cookie("remsfal_session", RestAssuredMatchers.detailedCookie() + .path("/") + .sameSite("Strict") + .maxAge(60 * 30)); enties = entityManager - .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) - .setParameter("email", TestData.USER_EMAIL_1) - .getSingleResult(); + .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) + .setParameter("email", TestData.USER_EMAIL_1) + .getSingleResult(); assertEquals(1, enties); } - @Test - void session_SUCCESS_userAlreadyExists() { + void session_SUCCESS_userAlreadyExists() { final String code = "anyRandomCode"; final GoogleIdToken.Payload idTokenPayload = new GoogleIdToken.Payload() - .setSubject(TestData.USER_TOKEN_1) - .setEmail(TestData.USER_EMAIL_1); + .setSubject(TestData.USER_TOKEN_1) + .setEmail(TestData.USER_EMAIL_1); when(authenticator.getIdToken(eq(code), any())) - .thenReturn(new GoogleIdToken(new JsonWebSignature.Header(), idTokenPayload, new byte[1], new byte[1])); + .thenReturn(new GoogleIdToken(new JsonWebSignature.Header(), idTokenPayload, new byte[1], new byte[1])); setupTestUsers(); long enties = entityManager - .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) - .setParameter("email", TestData.USER_EMAIL_1) - .getSingleResult(); + .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) + .setParameter("email", TestData.USER_EMAIL_1) + .getSingleResult(); assertEquals(1, enties); given() - .when() - .queryParam("code", code) - .queryParam("anyOtherParam", "toBeIgnored") - .redirects().follow(false) - .get(BASE_PATH + "/session") - .then() - .statusCode(Status.FOUND.getStatusCode()) - .header("location", Matchers.equalTo("http://localhost:8081/")) - .cookie("remsfal_session", RestAssuredMatchers.detailedCookie() - .path("/") - .sameSite("Strict") - .maxAge(60 * 30)); + .when() + .queryParam("code", code) + .queryParam("anyOtherParam", "toBeIgnored") + .redirects().follow(false) + .get(BASE_PATH + "/session") + .then() + .statusCode(Status.FOUND.getStatusCode()) + .header("location", Matchers.equalTo("http://localhost:8081/")) + .cookie("remsfal_session", RestAssuredMatchers.detailedCookie() + .path("/") + .sameSite("Strict") + .maxAge(60 * 30)); enties = entityManager - .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) - .setParameter("email", TestData.USER_EMAIL_1) - .getSingleResult(); + .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) + .setParameter("email", TestData.USER_EMAIL_1) + .getSingleResult(); assertEquals(1, enties); - // TODO: Use Awaitility to test AuthenticationEvent + + // // Awaitility check with separate transactional assertion method + + Awaitility.await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> assertUserCount(TestData.USER_EMAIL_1, 1)); + } + + @Transactional + void assertUserCount(String email, long expectedCount) { + long actualCount = entityManager + .createQuery("SELECT count(user) FROM UserEntity user where user.email = :email", Long.class) + .setParameter("email", email) + .getSingleResult(); + assertEquals(expectedCount, actualCount); } @Test void session_FAILED_noCode() { given() - .when() - .get(BASE_PATH + "/session") - .then() - .statusCode(Status.UNAUTHORIZED.getStatusCode()); + .when() + .get(BASE_PATH + "/session") + .then() + .statusCode(Status.UNAUTHORIZED.getStatusCode()); } @Test void session_FAILED_errorIsProvided() { given() - .queryParam("error", "Any Error from Google") - .when() - .get(BASE_PATH + "/session") - .then() - .statusCode(Status.UNAUTHORIZED.getStatusCode()); + .queryParam("error", "Any Error from Google") + .when() + .get(BASE_PATH + "/session") + .then() + .statusCode(Status.UNAUTHORIZED.getStatusCode()); } @Test void session_FAILED_invalidToken() { when(authenticator.getIdToken(any(), any())) - .thenReturn(null); + .thenReturn(null); given() - .when() - .queryParam("code", "anyValidCode") - .get(BASE_PATH + "/session") - .then() - .statusCode(Status.FORBIDDEN.getStatusCode()); + .when() + .queryParam("code", "anyValidCode") + .get(BASE_PATH + "/session") + .then() + .statusCode(Status.FORBIDDEN.getStatusCode()); } } \ No newline at end of file