refactor(training-export): route export services through owning services
SegmentationTrainingExportService and TrainingDataExportService each injected TranscriptionBlockRepository, AnnotationRepository and DocumentRepository directly. They now go through: - TranscriptionBlockQueryService (extended) for the three eligible-block queries — used over TranscriptionService to keep SenderModelService → TrainingDataExportService → TranscriptionService cycle-free. - AnnotationService.findById (new) — read API on the annotation domain. - DocumentService.findById (already added in #417 commit 3). The TrainingDataExportServiceTest @DataJpaTest delegates the new service reads to the real JPA repositories via Mockito stubs in the new makeService helper, so the integration coverage stays unchanged. Refs #417 (C6.2 violations #6 and #7). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,7 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@@ -60,7 +61,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(manualBlock(docId, annotId, "Liebe Mutter"));
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
StreamingResponseBody body = service.exportToZip();
|
||||
byte[] zipBytes = stream(body);
|
||||
@@ -79,7 +80,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(block);
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
StreamingResponseBody body = service.exportToZip();
|
||||
assertThat(zipEntryNames(stream(body))).isEmpty();
|
||||
@@ -92,7 +93,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(manualBlock(docId, annotId, "Liebe Tante"));
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
StreamingResponseBody body = service.exportToZip();
|
||||
byte[] zipBytes = stream(body);
|
||||
@@ -110,7 +111,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(block);
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
StreamingResponseBody body = service.exportToZip();
|
||||
assertThat(zipEntryNames(stream(body))).isNotEmpty();
|
||||
@@ -127,7 +128,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(block);
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
StreamingResponseBody body = service.exportToZip();
|
||||
assertThat(zipEntryNames(stream(body))).isEmpty();
|
||||
@@ -143,7 +144,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(manualBlock(docId, annotId, "Zweite Zeile"));
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
byte[] zipBytes = stream(service.exportToZip());
|
||||
var names = zipEntryNames(zipBytes);
|
||||
@@ -160,7 +161,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(manualBlock(docId, annotId, expectedText));
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
byte[] zipBytes = stream(service.exportToZip());
|
||||
String xmlContent = readZipEntry(zipBytes, ".xml");
|
||||
@@ -174,7 +175,7 @@ class TrainingDataExportServiceTest {
|
||||
blockRepository.save(manualBlock(docId, annotId, "A & B < C > D"));
|
||||
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
byte[] zipBytes = stream(service.exportToZip());
|
||||
String xmlContent = readZipEntry(zipBytes, ".xml");
|
||||
@@ -196,7 +197,7 @@ class TrainingDataExportServiceTest {
|
||||
when(fileService.downloadFileBytes("fail.pdf")).thenThrow(new FileService.StorageFileNotFoundException("missing"));
|
||||
when(fileService.downloadFileBytes("ok.pdf")).thenReturn(minimalPdfBytes);
|
||||
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
byte[] zipBytes = stream(service.exportToZip());
|
||||
var names = zipEntryNames(zipBytes);
|
||||
@@ -209,13 +210,34 @@ class TrainingDataExportServiceTest {
|
||||
@Test
|
||||
void queryEligibleBlocks_returnsEmpty_whenNoEnrolledDocuments() {
|
||||
FileService fileService = mockFileService();
|
||||
TrainingDataExportService service = new TrainingDataExportService(blockRepository, annotationRepository, documentRepository, fileService);
|
||||
TrainingDataExportService service = makeService(fileService);
|
||||
|
||||
assertThat(service.queryEligibleBlocks()).isEmpty();
|
||||
}
|
||||
|
||||
// ─── helpers ─────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Builds the export service with mocked owning services that transparently
|
||||
* delegate every read to the real JPA repositories provided by {@code @DataJpaTest}.
|
||||
* Keeps the integration test green after #417's layering refactor without
|
||||
* pulling the full transcription/annotation/document service trees into scope.
|
||||
*/
|
||||
private TrainingDataExportService makeService(FileService fileService) {
|
||||
TranscriptionBlockQueryService blockQueryService = mock(TranscriptionBlockQueryService.class);
|
||||
AnnotationService annotationService = mock(AnnotationService.class);
|
||||
DocumentService documentService = mock(DocumentService.class);
|
||||
when(blockQueryService.findEligibleKurrentBlocks())
|
||||
.thenAnswer(inv -> blockRepository.findEligibleKurrentBlocks());
|
||||
when(blockQueryService.findManualKurrentBlocksByPerson(any(UUID.class)))
|
||||
.thenAnswer(inv -> blockRepository.findManualKurrentBlocksByPerson(inv.getArgument(0)));
|
||||
when(annotationService.findById(any(UUID.class)))
|
||||
.thenAnswer(inv -> annotationRepository.findById(inv.getArgument(0)));
|
||||
when(documentService.findById(any(UUID.class)))
|
||||
.thenAnswer(inv -> documentRepository.findById(inv.getArgument(0)));
|
||||
return new TrainingDataExportService(blockQueryService, annotationService, documentService, fileService);
|
||||
}
|
||||
|
||||
private UUID enrolledDoc(String filename) {
|
||||
Document doc = documentRepository.save(Document.builder()
|
||||
.title(filename).originalFilename(filename).filePath(filename)
|
||||
|
||||
Reference in New Issue
Block a user