From c0a1f04df573b26e6472b00fb1c140ea9f725c28 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 8 May 2026 11:38:29 +0200 Subject: [PATCH] chore(documents): density endpoint produces=application/json (#385) Co-Authored-By: Claude Sonnet 4.6 --- .../document/DocumentController.java | 2 +- .../document/DocumentControllerTest.java | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentController.java b/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentController.java index 7d353051..53b50f03 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentController.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/document/DocumentController.java @@ -390,7 +390,7 @@ public class DocumentController { return ResponseEntity.ok(documentService.searchDocuments(q, from, to, senderId, receiverId, tags, tagQ, status, sort, dir, operator, pageable)); } - @GetMapping("/density") + @GetMapping(value = "/density", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity density( @RequestParam(required = false) String q, @RequestParam(required = false) UUID senderId, diff --git a/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentControllerTest.java index e30283fc..82e60083 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentControllerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/document/DocumentControllerTest.java @@ -44,6 +44,7 @@ import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -1267,6 +1268,24 @@ class DocumentControllerTest { .andExpect(jsonPath("$.maxDate").value("1915-09-01")); } + // Pins produces=APPLICATION_JSON_VALUE on the density mapping so the OpenAPI/TypeScript + // codegen records application/json instead of the wildcard. Without produces= the + // request-mapping accepts any Accept header and the OpenAPI emit falls back to the + // wildcard. Sending an Accept header that JSON cannot satisfy must NOT return 200 — + // Spring rejects with 406 (HttpMediaTypeNotAcceptableException), which our + // GlobalExceptionHandler may surface as 400. Either way it proves the route is + // locked to JSON. + @Test + @WithMockUser + void density_declaresApplicationJsonContentType() throws Exception { + when(documentService.getDensity(any(), any(), any(), any(), any(), any(), any())).thenReturn( + new DocumentDensityResult(List.of(), null, null)); + + mockMvc.perform(get("/api/documents/density") + .accept(MediaType.APPLICATION_XML)) + .andExpect(status().is4xxClientError()); + } + @Test @WithMockUser void density_emitsPrivateCacheControlHeader() throws Exception {