From fe6c3850c7b2cd4b0fcc4deb7b640f11ee2fc86d Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 12 Jun 2026 13:31:49 +0200 Subject: [PATCH] refactor(geschichte): extract NIL_UUID sentinel as named constant Replace inline UUID.fromString("00000000-...") in GeschichteService.list() with a named constant NIL_UUID and add a test that verifies the sentinel is forwarded to the repository when no person filter is provided. Co-Authored-By: Claude Sonnet 4.6 --- .../geschichte/GeschichteService.java | 5 ++++- .../geschichte/GeschichteServiceTest.java | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java index 34f3ff9b..a32766c8 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/geschichte/GeschichteService.java @@ -50,6 +50,9 @@ public class GeschichteService { private static final int DEFAULT_LIMIT = 50; private static final int MAX_LIMIT = 200; + /** Sentinel used when {@code personIds} is empty to avoid invalid empty IN() SQL. */ + private static final UUID NIL_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000"); + // Matches the geschichten.title VARCHAR(255) column (V58) — the service check // turns what would be a DB-level 500 into a friendly 400. static final int MAX_TITLE_LENGTH = 255; @@ -123,7 +126,7 @@ public class GeschichteService { // When personIds is empty, personCount=0 short-circuits the IN() predicate. // Pass a sentinel UUID to avoid invalid empty IN() SQL while the predicate is skipped. Collection safePersonIds = (personIds == null || personIds.isEmpty()) - ? List.of(UUID.fromString("00000000-0000-0000-0000-000000000000")) + ? List.of(NIL_UUID) : personIds; long personCount = (personIds == null) ? 0 : personIds.size(); diff --git a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java index 73693c27..2e87c50c 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/geschichte/GeschichteServiceTest.java @@ -282,6 +282,21 @@ class GeschichteServiceTest { verify(geschichteRepository).findSummaries(any(), any(), any(), anyLong(), eq(documentId)); } + @Test + void list_passes_nil_uuid_sentinel_to_repository_when_no_person_filter_given() { + // B2: when personIds is empty/null the service must pass a sentinel NIL UUID + // so the IN() predicate is skipped without producing invalid empty-IN() SQL. + authenticateAs(reader, Permission.READ_ALL); + when(geschichteRepository.findSummaries(any(), any(), any(), anyLong(), any())) + .thenReturn(List.of()); + + geschichteService.list(null, List.of(), null, 50); + + UUID nilUUID = UUID.fromString("00000000-0000-0000-0000-000000000000"); + verify(geschichteRepository).findSummaries( + any(), any(), org.mockito.ArgumentMatchers.argThat(ids -> ids.contains(nilUUID)), anyLong(), any()); + } + @Test void list_caps_limit_at_max_when_caller_passes_huge_value() { authenticateAs(reader, Permission.READ_ALL);