From 6f1b11103706df600b5fdc143f0747b5b3e87d5f Mon Sep 17 00:00:00 2001 From: fretuks Date: Thu, 9 Jul 2026 10:14:44 +0200 Subject: [PATCH] implement testing --- .../promotion/PromotionIntegrationTest.java | 101 +++++++++++++++ .../promotion/RegistrationEndToEndTest.java | 120 ++++++++++++++++++ src/test/resources/application.properties | 13 ++ 3 files changed, 234 insertions(+) create mode 100644 src/test/java/dev/frederik/promotion/PromotionIntegrationTest.java create mode 100644 src/test/java/dev/frederik/promotion/RegistrationEndToEndTest.java create mode 100644 src/test/resources/application.properties diff --git a/src/test/java/dev/frederik/promotion/PromotionIntegrationTest.java b/src/test/java/dev/frederik/promotion/PromotionIntegrationTest.java new file mode 100644 index 0000000..6dc089e --- /dev/null +++ b/src/test/java/dev/frederik/promotion/PromotionIntegrationTest.java @@ -0,0 +1,101 @@ +package dev.frederik.promotion; + +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.List; +import java.util.Map; + +import static io.restassured.RestAssured.given; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@QuarkusTest +class PromotionIntegrationTest { + @Inject + DataSource dataSource; + + @Test + void platformsEndpointReturnsCurrentLaunchTargetsFromIsolatedDatabase() throws Exception { + // Given: the Quarkus app started with the isolated test database and seeded launch platforms. + + // When: the API client requests available platforms. + List platformNames = given() + .when() + .get("/platforms") + .then() + .statusCode(200) + .extract() + .jsonPath() + .getList("name"); + + // Then: the API and database expose only the current launch targets. + assertEquals(List.of("Windows", "Linux", "Mobile (Android)"), platformNames); + assertEquals(3, countCurrentPlatformsInDatabase()); + } + + @Test + void creatingUserThroughApiPersistsUserInDatabase() throws Exception { + // Given: a unique pre-registration payload. + String suffix = Long.toString(System.nanoTime()); + String username = "integration_" + suffix; + String email = username + "@example.com"; + Map payload = Map.of( + "username", username, + "email", email, + "newsletter_optin", true); + + // When: the user is created through the REST API. + Integer userId = given() + .contentType("application/json") + .body(payload) + .when() + .post("/users") + .then() + .statusCode(201) + .extract() + .path("id"); + + // Then: the returned id exists and the row is stored in the isolated database. + assertNotNull(userId); + Map row = findUserInDatabase(username); + assertEquals(email, row.get("email")); + assertEquals(Boolean.TRUE, row.get("newsletter_optin")); + } + + private int countCurrentPlatformsInDatabase() throws Exception { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement(""" + SELECT COUNT(*) + FROM platforms + WHERE name IN ('Windows', 'Linux', 'Mobile (Android)') + """); + ResultSet resultSet = statement.executeQuery()) { + resultSet.next(); + return resultSet.getInt(1); + } + } + + private Map findUserInDatabase(String username) throws Exception { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement(""" + SELECT email, newsletter_optin + FROM users + WHERE username = ? + """)) { + statement.setString(1, username); + try (ResultSet resultSet = statement.executeQuery()) { + assertTrue(resultSet.next()); + return Map.of( + "email", resultSet.getString("email"), + "newsletter_optin", resultSet.getBoolean("newsletter_optin")); + } + } + } +} diff --git a/src/test/java/dev/frederik/promotion/RegistrationEndToEndTest.java b/src/test/java/dev/frederik/promotion/RegistrationEndToEndTest.java new file mode 100644 index 0000000..1c427d9 --- /dev/null +++ b/src/test/java/dev/frederik/promotion/RegistrationEndToEndTest.java @@ -0,0 +1,120 @@ +package dev.frederik.promotion; + +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.List; +import java.util.Map; + +import static io.restassured.RestAssured.given; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@QuarkusTest +class RegistrationEndToEndTest { + @Inject + DataSource dataSource; + + @Test + void registeredPlayerCanLoginAndAccessPrivateGameDetails() throws Exception { + // Given: the isolated test database has seeded platforms and a new player wants Windows access. + String suffix = Long.toString(System.nanoTime()); + String username = "e2e_" + suffix; + String email = username + "@example.com"; + Integer windowsPlatformId = firstPlatformId(); + + // When: the player completes the public workflow through the API. + Integer userId = given() + .contentType("application/json") + .body(Map.of( + "username", username, + "email", email, + "newsletter_optin", false)) + .when() + .post("/users") + .then() + .statusCode(201) + .extract() + .path("id"); + + Integer registrationId = given() + .contentType("application/json") + .body(Map.of( + "user_id", userId, + "platform_id", windowsPlatformId)) + .when() + .post("/registrations") + .then() + .statusCode(201) + .extract() + .path("id"); + + String token = given() + .contentType("application/json") + .body(Map.of( + "username", username, + "email", email)) + .when() + .post("/auth/login") + .then() + .statusCode(200) + .extract() + .path("access_token"); + + Map details = given() + .header("Authorization", "Bearer " + token) + .when() + .get("/auth/game-details") + .then() + .statusCode(200) + .extract() + .as(Map.class); + + List> userRegistrations = given() + .when() + .get("/users/{id}/registrations", userId) + .then() + .statusCode(200) + .extract() + .as(List.class); + + // Then: the API returns protected game intel and the registration exists in the database. + assertNotNull(registrationId); + assertEquals("Authenticated build notes", details.get("title")); + assertEquals(1, userRegistrations.size()); + assertEquals("Windows", userRegistrations.get(0).get("platform_name")); + assertTrue(registrationExistsInDatabase(userId, windowsPlatformId)); + } + + private Integer firstPlatformId() { + return given() + .when() + .get("/platforms") + .then() + .statusCode(200) + .extract() + .path("[0].id"); + } + + private boolean registrationExistsInDatabase(int userId, int platformId) throws Exception { + try (Connection connection = dataSource.getConnection(); + PreparedStatement statement = connection.prepareStatement(""" + SELECT COUNT(*) + FROM registrations + WHERE user_id = ? AND platform_id = ? + """)) { + statement.setInt(1, userId); + statement.setInt(2, platformId); + try (ResultSet resultSet = statement.executeQuery()) { + resultSet.next(); + return resultSet.getInt(1) == 1; + } + } + } +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 0000000..d550119 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,13 @@ +quarkus.datasource.db-kind=h2 +quarkus.datasource.username=sa +quarkus.datasource.password=sa +quarkus.datasource.jdbc.url=jdbc:h2:mem:kernel_panic_test;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;DB_CLOSE_DELAY=-1 +quarkus.datasource.jdbc.max-size=4 + +auth.admin.username=admin +auth.admin.password=secret + +mp.jwt.verify.publickey.location=publicKey.pem +mp.jwt.verify.issuer=https://kernel-panic.local/issuer +smallrye.jwt.sign.key.location=privateKey.pem +quarkus.smallrye-jwt.enabled=true