From 4cf01a0f1d10a34cfd9130bfd40d796a3dcf9ea0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 16 Apr 2026 12:07:14 +0200 Subject: [PATCH] test(#240): add TranscriptionQueueControllerTest Verifies 401/403/200 responses for all four endpoints. Matches the @WebMvcTest + @RequirePermission pattern used across the project. Co-Authored-By: Claude Sonnet 4.6 --- .../TranscriptionQueueControllerTest.java | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 backend/src/test/java/org/raddatz/familienarchiv/controller/TranscriptionQueueControllerTest.java diff --git a/backend/src/test/java/org/raddatz/familienarchiv/controller/TranscriptionQueueControllerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/controller/TranscriptionQueueControllerTest.java new file mode 100644 index 00000000..10e9165b --- /dev/null +++ b/backend/src/test/java/org/raddatz/familienarchiv/controller/TranscriptionQueueControllerTest.java @@ -0,0 +1,151 @@ +package org.raddatz.familienarchiv.controller; + +import org.junit.jupiter.api.Test; +import org.raddatz.familienarchiv.config.SecurityConfig; +import org.raddatz.familienarchiv.dto.TranscriptionQueueItemDTO; +import org.raddatz.familienarchiv.dto.TranscriptionWeeklyStatsDTO; +import org.raddatz.familienarchiv.repository.DocumentRepository; +import org.raddatz.familienarchiv.repository.PersonRepository; +import org.raddatz.familienarchiv.security.PermissionAspect; +import org.raddatz.familienarchiv.service.CustomUserDetailsService; +import org.raddatz.familienarchiv.service.TranscriptionQueueService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; +import org.springframework.context.annotation.Import; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.web.servlet.MockMvc; + +import java.time.LocalDate; +import java.util.List; +import java.util.UUID; + +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(TranscriptionQueueController.class) +@Import({SecurityConfig.class, PermissionAspect.class, AopAutoConfiguration.class}) +class TranscriptionQueueControllerTest { + + @Autowired MockMvc mockMvc; + + @MockitoBean TranscriptionQueueService transcriptionQueueService; + @MockitoBean DocumentRepository documentRepository; + @MockitoBean PersonRepository personRepository; + @MockitoBean CustomUserDetailsService customUserDetailsService; + + private static final TranscriptionQueueItemDTO ITEM = new TranscriptionQueueItemDTO( + UUID.fromString("00000000-0000-0000-0000-000000000001"), + "Testbrief", + LocalDate.of(1920, 6, 15), + 3, 1, 0 + ); + + private static final TranscriptionWeeklyStatsDTO STATS = new TranscriptionWeeklyStatsDTO(2L, 5L, 1L); + + // ─── segmentation-queue ─────────────────────────────────────────────────── + + @Test + void getSegmentationQueue_returns401_whenUnauthenticated() throws Exception { + mockMvc.perform(get("/api/transcription/segmentation-queue")) + .andExpect(status().isUnauthorized()); + } + + @Test + @WithMockUser + void getSegmentationQueue_returns403_whenNoReadAllPermission() throws Exception { + mockMvc.perform(get("/api/transcription/segmentation-queue")) + .andExpect(status().isForbidden()); + } + + @Test + @WithMockUser(authorities = "READ_ALL") + void getSegmentationQueue_returns200_withItems() throws Exception { + when(transcriptionQueueService.getSegmentationQueue()).thenReturn(List.of(ITEM)); + + mockMvc.perform(get("/api/transcription/segmentation-queue")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].title").value("Testbrief")) + .andExpect(jsonPath("$[0].annotationCount").value(3)); + } + + // ─── transcription-queue ────────────────────────────────────────────────── + + @Test + void getTranscriptionQueue_returns401_whenUnauthenticated() throws Exception { + mockMvc.perform(get("/api/transcription/transcription-queue")) + .andExpect(status().isUnauthorized()); + } + + @Test + @WithMockUser + void getTranscriptionQueue_returns403_whenNoReadAllPermission() throws Exception { + mockMvc.perform(get("/api/transcription/transcription-queue")) + .andExpect(status().isForbidden()); + } + + @Test + @WithMockUser(authorities = "READ_ALL") + void getTranscriptionQueue_returns200_withItems() throws Exception { + when(transcriptionQueueService.getTranscriptionQueue()).thenReturn(List.of(ITEM)); + + mockMvc.perform(get("/api/transcription/transcription-queue")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].title").value("Testbrief")); + } + + // ─── ready-to-read ──────────────────────────────────────────────────────── + + @Test + void getReadyToRead_returns401_whenUnauthenticated() throws Exception { + mockMvc.perform(get("/api/transcription/ready-to-read")) + .andExpect(status().isUnauthorized()); + } + + @Test + @WithMockUser + void getReadyToRead_returns403_whenNoReadAllPermission() throws Exception { + mockMvc.perform(get("/api/transcription/ready-to-read")) + .andExpect(status().isForbidden()); + } + + @Test + @WithMockUser(authorities = "READ_ALL") + void getReadyToRead_returns200_withItems() throws Exception { + when(transcriptionQueueService.getReadyToReadQueue()).thenReturn(List.of(ITEM)); + + mockMvc.perform(get("/api/transcription/ready-to-read")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].reviewedBlockCount").value(0)); + } + + // ─── weekly-stats ───────────────────────────────────────────────────────── + + @Test + void getWeeklyStats_returns401_whenUnauthenticated() throws Exception { + mockMvc.perform(get("/api/transcription/weekly-stats")) + .andExpect(status().isUnauthorized()); + } + + @Test + @WithMockUser + void getWeeklyStats_returns403_whenNoReadAllPermission() throws Exception { + mockMvc.perform(get("/api/transcription/weekly-stats")) + .andExpect(status().isForbidden()); + } + + @Test + @WithMockUser(authorities = "READ_ALL") + void getWeeklyStats_returns200_withStats() throws Exception { + when(transcriptionQueueService.getWeeklyStats()).thenReturn(STATS); + + mockMvc.perform(get("/api/transcription/weekly-stats")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.segmentationCount").value(2)) + .andExpect(jsonPath("$.transcriptionCount").value(5)) + .andExpect(jsonPath("$.readyCount").value(1)); + } +}