fix(bulk-edit): cycle-3 polish — Felix C2/C3/C4/C5 + Sara coverage gaps
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 2m54s
CI / OCR Service Tests (pull_request) Successful in 39s
CI / Backend Unit Tests (pull_request) Failing after 2m56s
CI / Unit & Component Tests (push) Failing after 3m6s
CI / Backend Unit Tests (push) Failing after 2m56s
CI / OCR Service Tests (push) Successful in 34s
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 2m54s
CI / OCR Service Tests (pull_request) Successful in 39s
CI / Backend Unit Tests (pull_request) Failing after 2m56s
CI / Unit & Component Tests (push) Failing after 3m6s
CI / Backend Unit Tests (push) Failing after 2m56s
CI / OCR Service Tests (push) Successful in 34s
Felix C2 — `BatchMetadataRequest` controller now uses `@Valid` so future @Size/etc. annotations on the record actually fire. Felix C3 — Auto-clear `$effect` in `+layout.svelte` reads `bulkSelectionStore.size` inside `untrack()` so the effect only re-fires on route change, not on every checkbox toggle. Felix C4 — `BulkDocumentEditLayout` edit-mode hydration loop now lives inside `onMount` (not at top-level script) so the SvelteMap mutation is unambiguously tied to instance lifecycle, matching the pattern used by `WhoWhenSection`/`DescriptionSection` after the cycle-2 fix. Felix C5 — Replaced fully-qualified `java.util.LinkedHashSet` in `DocumentController` with a top-of-file import. Sara coverage — six new spec files / blocks pin the cycle-1 and cycle-2 behaviours that were previously untested: - `WhoWhenSection.svelte.spec.ts` — onMount seeding from initialDateIso / initialLocation; doesn't stomp parent-bound dateIso; hideDate / editMode branch - `DescriptionSection.svelte.spec.ts` — onMount seeding from initialTitle / initialDocumentLocation; doesn't stomp parent-bound values; archive-box / archive-folder fields visible only in editMode - `BulkSelectionBar.svelte.spec.ts` — Esc-scope guard tests for `<dialog>` open and `aria-expanded` popover present - `BulkDocumentEditLayout.svelte.spec.ts` — topbar reads "Massenbearbeitung" + "werden bearbeitet" in edit mode (not the upload-flavoured "hochladen"/"werden erstellt" copy) - `DocumentControllerTest.patchBulk_returns400_whenArchiveBoxExceeds255Chars` — pins the @Size validator on archiveBox via the @Valid wiring Refs #225, PR #331 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #331.
This commit is contained in:
@@ -3,6 +3,7 @@ package org.raddatz.familienarchiv.controller;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -272,7 +273,7 @@ public class DocumentController {
|
||||
// Dedupe duplicate document IDs while preserving submission order. A
|
||||
// double-click on "Alle X editieren" would otherwise hit each document
|
||||
// twice and inflate the `updated` count returned to the user.
|
||||
java.util.LinkedHashSet<UUID> uniqueIds = new java.util.LinkedHashSet<>(dto.getDocumentIds());
|
||||
LinkedHashSet<UUID> uniqueIds = new LinkedHashSet<>(dto.getDocumentIds());
|
||||
|
||||
for (UUID id : uniqueIds) {
|
||||
try {
|
||||
@@ -324,7 +325,7 @@ public class DocumentController {
|
||||
|
||||
@PostMapping(value = "/batch-metadata", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@RequirePermission(Permission.READ_ALL)
|
||||
public List<DocumentBatchSummary> batchMetadata(@RequestBody BatchMetadataRequest request, Authentication authentication) {
|
||||
public List<DocumentBatchSummary> batchMetadata(@RequestBody @Valid BatchMetadataRequest request, Authentication authentication) {
|
||||
if (request == null || request.ids() == null || request.ids().isEmpty()) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ids is required");
|
||||
}
|
||||
|
||||
@@ -996,6 +996,24 @@ class DocumentControllerTest {
|
||||
.andExpect(jsonPath("$.code").value("BULK_EDIT_TOO_MANY_IDS"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(authorities = "WRITE_ALL")
|
||||
void patchBulk_returns400_whenArchiveBoxExceeds255Chars() throws Exception {
|
||||
// Tobias C2 — DocumentBulkEditDTO.archiveBox carries @Size(max=255).
|
||||
// Without @Valid on @RequestBody this would silently land an
|
||||
// arbitrarily long string; the test pins both the annotation and
|
||||
// the controller-level @Valid wiring.
|
||||
when(userService.findByEmail(any())).thenReturn(AppUser.builder().id(UUID.randomUUID()).build());
|
||||
UUID id = UUID.randomUUID();
|
||||
String tooLong = "x".repeat(256);
|
||||
|
||||
String body = "{\"documentIds\":[\"" + id + "\"],\"archiveBox\":\"" + tooLong + "\"}";
|
||||
mockMvc.perform(patch("/api/documents/bulk")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(body))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockUser(authorities = "WRITE_ALL")
|
||||
void patchBulk_acceptsExactly500Ids_atTheCap() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user