From 2a1508c6a5cbbdd041ca793eae6b3b774b5e236c Mon Sep 17 00:00:00 2001 From: Stefan Mogeritsch Date: Tue, 14 Apr 2026 12:53:28 +0200 Subject: [PATCH] chore(tests): standardize schema usage with constants and resolve IDE warnings - Replaced hardcoded schema names with constants (`TEST_SCHEMA`, `CONTROL_SCHEMA`) across multiple tests. - Resolved IDE warnings by removing unused variables (`result`), suppressing `SqlResolve`, and using ASCII-compliant strings. - Corrected typos in test data (`testdb` -> `test_db`, `Produktions` -> `Production`). - Improved readability and maintainability in migration and tenant registry tests by introducing companion object constants. --- .../bewerbe/BewerbeZeitplanIntegrationTest.kt | 4 +- .../migration/DomainHierarchyMigrationTest.kt | 10 ++--- .../service/tenant/JdbcTenantRegistryTest.kt | 44 +++++++++++-------- .../usecase/NennungBillingIntegrationTest.kt | 15 +++---- ...DevOps_Entries-Isolation-Test-Finalized.md | 6 ++- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/bewerbe/BewerbeZeitplanIntegrationTest.kt b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/bewerbe/BewerbeZeitplanIntegrationTest.kt index 986ec65d..c142012a 100644 --- a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/bewerbe/BewerbeZeitplanIntegrationTest.kt +++ b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/bewerbe/BewerbeZeitplanIntegrationTest.kt @@ -72,7 +72,7 @@ class BewerbeZeitplanIntegrationTest { // GIVEN val request = CreateBewerbRequest( klasse = "A", - bezeichnung = "Springpferdeprüfung", + bezeichnung = "Springpferdepruefung", pausenStarterIntervall = 20, pausenDauerMinuten = 15, pausenBezeichnung = "Platzpflege", @@ -95,7 +95,7 @@ class BewerbeZeitplanIntegrationTest { // GIVEN val bewerb = bewerbService.create(turnierId, CreateBewerbRequest( klasse = "L", - bezeichnung = "Standardspringprüfung" + bezeichnung = "Standardspringpruefung" )) val patchRequest = UpdateZeitplanRequest( geplantesDatum = null, diff --git a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/migration/DomainHierarchyMigrationTest.kt b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/migration/DomainHierarchyMigrationTest.kt index 6b167d9a..8b92292b 100644 --- a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/migration/DomainHierarchyMigrationTest.kt +++ b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/migration/DomainHierarchyMigrationTest.kt @@ -15,6 +15,8 @@ import java.sql.Connection class DomainHierarchyMigrationTest { companion object { + private const val TEST_SCHEMA = "event_test" + @Container @JvmStatic val postgres = PostgreSQLContainer("postgres:16-alpine").apply { @@ -26,19 +28,17 @@ class DomainHierarchyMigrationTest { @Test fun `tenant migration creates domain hierarchy tables`() { - val schema = "event_test" - // Run tenant migrations (V1 + V2) Flyway.configure() .dataSource(postgres.jdbcUrl, postgres.username, postgres.password) .locations("classpath:db/tenant") - .schemas(schema) + .schemas(TEST_SCHEMA) .baselineOnMigrate(true) .load() .migrate() java.sql.DriverManager.getConnection(postgres.jdbcUrl, postgres.username, postgres.password).use { conn -> - setSearchPath(conn, schema) + setSearchPath(conn, TEST_SCHEMA) val expected = setOf( "veranstaltungen", "turniere", @@ -47,7 +47,7 @@ class DomainHierarchyMigrationTest { "teilnehmer_konten", "turnier_kassa" ) - val actual = loadTables(conn, schema, expected) + val actual = loadTables(conn, TEST_SCHEMA, expected) assertEquals(expected, actual, "Alle erwarteten Tabellen müssen existieren") } } diff --git a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/tenant/JdbcTenantRegistryTest.kt b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/tenant/JdbcTenantRegistryTest.kt index 2cef1150..da3be065 100644 --- a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/tenant/JdbcTenantRegistryTest.kt +++ b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/tenant/JdbcTenantRegistryTest.kt @@ -6,33 +6,41 @@ import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Test import org.springframework.jdbc.core.JdbcTemplate +@Suppress("SqlResolve") class JdbcTenantRegistryTest { + companion object { + private const val CONTROL_SCHEMA = "control" + private const val TENANTS_TABLE = "$CONTROL_SCHEMA.tenants" + private const val EVENT_A = "event_a" + private const val EVENT_LOCKED = "event_locked" + } + @Test fun `lookup returns tenant from control schema`() { - val ds = JdbcDataSource().apply { setURL("jdbc:h2:mem:testdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;DB_CLOSE_DELAY=-1") } + val ds = JdbcDataSource().apply { setURL("jdbc:h2:mem:test_db;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;DB_CLOSE_DELAY=-1") } val jdbc = JdbcTemplate(ds) - jdbc.execute("CREATE SCHEMA IF NOT EXISTS control") - // DDL an Produktions‑SQL angelehnt: Spalte 'status' unquoted, damit Inserts ohne Quoting funktionieren - jdbc.execute("CREATE TABLE control.tenants(event_id VARCHAR PRIMARY KEY, schema_name VARCHAR NOT NULL, db_url VARCHAR NULL, status VARCHAR NOT NULL)") - jdbc.update("INSERT INTO control.tenants(event_id, schema_name, db_url, status) VALUES (?,?,?,?)", - "event_a", "event_a", null, "ACTIVE") + jdbc.execute("CREATE SCHEMA IF NOT EXISTS $CONTROL_SCHEMA") + // DDL an Production-SQL angelehnt: Spalte 'status' unquoted, damit Inserts ohne Quoting funktionieren + jdbc.execute("CREATE TABLE $TENANTS_TABLE(event_id VARCHAR PRIMARY KEY, schema_name VARCHAR NOT NULL, db_url VARCHAR NULL, status VARCHAR NOT NULL)") + jdbc.update("INSERT INTO $TENANTS_TABLE(event_id, schema_name, db_url, status) VALUES (?,?,?,?)", + EVENT_A, EVENT_A, null, "ACTIVE") val registry = JdbcTenantRegistry(jdbc) - val tenant = registry.lookup("event_a") + val tenant = registry.lookup(EVENT_A) assertNotNull(tenant) - assertEquals("event_a", tenant!!.eventId) - assertEquals("event_a", tenant.schemaName) + assertEquals(EVENT_A, tenant!!.eventId) + assertEquals(EVENT_A, tenant.schemaName) assertEquals(Tenant.Status.ACTIVE, tenant.status) } @Test fun `lookup returns null for unknown event`() { - val ds = JdbcDataSource().apply { setURL("jdbc:h2:mem:testdb2;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;DB_CLOSE_DELAY=-1") } + val ds = JdbcDataSource().apply { setURL("jdbc:h2:mem:test_db2;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;DB_CLOSE_DELAY=-1") } val jdbc = JdbcTemplate(ds) - jdbc.execute("CREATE SCHEMA IF NOT EXISTS control") - jdbc.execute("CREATE TABLE control.tenants(event_id VARCHAR PRIMARY KEY, schema_name VARCHAR NOT NULL, db_url VARCHAR NULL, status VARCHAR NOT NULL)") + jdbc.execute("CREATE SCHEMA IF NOT EXISTS $CONTROL_SCHEMA") + jdbc.execute("CREATE TABLE $TENANTS_TABLE(event_id VARCHAR PRIMARY KEY, schema_name VARCHAR NOT NULL, db_url VARCHAR NULL, status VARCHAR NOT NULL)") val registry = JdbcTenantRegistry(jdbc) val tenant = registry.lookup("does_not_exist") @@ -42,15 +50,15 @@ class JdbcTenantRegistryTest { @Test fun `lookup maps locked status`() { - val ds = JdbcDataSource().apply { setURL("jdbc:h2:mem:testdb3;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;DB_CLOSE_DELAY=-1") } + val ds = JdbcDataSource().apply { setURL("jdbc:h2:mem:test_db3;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH;DB_CLOSE_DELAY=-1") } val jdbc = JdbcTemplate(ds) - jdbc.execute("CREATE SCHEMA IF NOT EXISTS control") - jdbc.execute("CREATE TABLE control.tenants(event_id VARCHAR PRIMARY KEY, schema_name VARCHAR NOT NULL, db_url VARCHAR NULL, status VARCHAR NOT NULL)") - jdbc.update("INSERT INTO control.tenants(event_id, schema_name, db_url, status) VALUES (?,?,?,?)", - "event_locked", "event_locked", null, "LOCKED") + jdbc.execute("CREATE SCHEMA IF NOT EXISTS $CONTROL_SCHEMA") + jdbc.execute("CREATE TABLE $TENANTS_TABLE(event_id VARCHAR PRIMARY KEY, schema_name VARCHAR NOT NULL, db_url VARCHAR NULL, status VARCHAR NOT NULL)") + jdbc.update("INSERT INTO $TENANTS_TABLE(event_id, schema_name, db_url, status) VALUES (?,?,?,?)", + EVENT_LOCKED, EVENT_LOCKED, null, "LOCKED") val registry = JdbcTenantRegistry(jdbc) - val tenant = registry.lookup("event_locked") + val tenant = registry.lookup(EVENT_LOCKED) assertNotNull(tenant) assertEquals(Tenant.Status.LOCKED, tenant!!.status) diff --git a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/usecase/NennungBillingIntegrationTest.kt b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/usecase/NennungBillingIntegrationTest.kt index 5dd1035e..3acdea7c 100644 --- a/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/usecase/NennungBillingIntegrationTest.kt +++ b/backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/usecase/NennungBillingIntegrationTest.kt @@ -81,7 +81,7 @@ class NennungBillingIntegrationTest { id = Uuid.random(), turnierId = turnierId, klasse = "L", - bezeichnung = "Standardspringprüfung", + bezeichnung = "Standardspringpruefung", nenngeldCent = 2500, // 25,00 EUR hoeheCm = 120 )) @@ -96,7 +96,7 @@ class NennungBillingIntegrationTest { ) // WHEN: Nennung einreichen - val result = nennungUseCases.nennungEinreichen(request) + nennungUseCases.nennungEinreichen(request) // THEN: Konto muss existieren und Saldo muss -25,00 EUR sein (Gebühr) val konto = kontoService.getKonto(turnierId, reiterId) @@ -134,21 +134,20 @@ class NennungBillingIntegrationTest { // WHEN nennungUseCases.nennungEinreichen(request) - // THEN: Wir prüfen nur ob es nicht kracht. + // THEN: Wir prüfen nur, ob es nicht kracht. // In einem echten Test mit Mockito/MockK könnten wir prüfen: - // verify { mailService.sendNennungsBestätigung(email, any(), any(), any()) } - // Da MailService in Spring registriert ist und JavaMailSender null ist, loggt er nur. + // verify {mailService.sendNennungsBestaetigung(email, any(), any(), any()) } assertNotNull(mailService) } @Test - fun `nachnennung bucht zusätzlich Nachnenngebühr`() = kotlinx.coroutines.runBlocking { - // GIVEN: Ein Bewerb mit Nenngeld und Nachnenngebühr + fun `nachnennung bucht zusaetzlich Nachnenngebuehr`() = kotlinx.coroutines.runBlocking { + // GIVEN: Ein Bewerb mit Nenngeld und Nachnenngebuehr val bewerb = bewerbRepository.create(Bewerb( id = Uuid.random(), turnierId = turnierId, klasse = "M", - bezeichnung = "Zeitspringprüfung", + bezeichnung = "Springframework", nenngeldCent = 3000, nachnenngebuehrCent = 1500, hoeheCm = 130 diff --git a/docs/99_Journal/2026-04-14_DevOps_Entries-Isolation-Test-Finalized.md b/docs/99_Journal/2026-04-14_DevOps_Entries-Isolation-Test-Finalized.md index cd7c76ca..82ca9ea1 100644 --- a/docs/99_Journal/2026-04-14_DevOps_Entries-Isolation-Test-Finalized.md +++ b/docs/99_Journal/2026-04-14_DevOps_Entries-Isolation-Test-Finalized.md @@ -27,11 +27,15 @@ Zusätzlich gab es IDE-Warnungen bezüglich nicht auflösbarer Symbole in SQL-St 3. **Verifizierung & Cleanup:** - Alle 10 Tests im Modul (inkl. der neu aktivierten Isolation-Tests) laufen erfolgreich durch. - - IDE-Warnungen wurden durch Verwendung von String-Konstanten/Interpolation (`$CONTROL_SCHEMA`) und Entfernung ungenutzter Code-Fragmente (`nennungRepository`, `random()`) behoben. + - IDE-Warnungen in `EntriesIsolationIntegrationTest` und `JdbcTenantRegistryTest` wurden durch `@Suppress("SqlResolve")`, Verwendung von String-Konstanten/Interpolation (`$CONTROL_SCHEMA`) und Entfernung ungenutzter Code-Fragmente (`nennungRepository`, `random()`, `registerDataSource`) behoben. + - Typos wie "testdb" -> "test_db" und "Produktions" -> "Production" wurden korrigiert. + - Behebung von IDE-Warnungen in `NennungBillingIntegrationTest`, `BewerbeZeitplanIntegrationTest` und `DomainHierarchyMigrationTest` durch Entfernung ungenutzter Variablen (`result`), Ersetzen von Umlauten in Funktionsnamen/Strings durch ASCII-Zeichen und Verwendung von Konstanten für Schema-Namen (`TEST_SCHEMA`). - Fehlende Spring-Konfigurations-Metadaten für `multitenancy.*` wurden in `additional-spring-configuration-metadata.json` ergänzt. ## Betroffene Dateien - `backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/tenant/EntriesIsolationIntegrationTest.kt`: Reaktiviert und repariert. +- `backend/services/entries/entries-service/src/test/kotlin/at/mocode/entries/service/tenant/JdbcTenantRegistryTest.kt`: Bereinigt und optimiert. +- `backend/services/entries/entries-service/src/main/resources/META-INF/additional-spring-configuration-metadata.json`: Metadaten ergänzt. ## Handover - Der `EntriesIsolationIntegrationTest` dient nun als Referenz für Multi-Tenancy Tests mit echten PostgreSQL-Containern. Bei weiteren Tests dieser Art sollte auf das Exposed-Schema-Caching geachtet werden.