diff --git a/backend/src/test/java/org/raddatz/familienarchiv/repository/DocumentRepositoryTest.java b/backend/src/test/java/org/raddatz/familienarchiv/repository/DocumentRepositoryTest.java index 51ab05b4..c5637ee5 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/repository/DocumentRepositoryTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/repository/DocumentRepositoryTest.java @@ -4,8 +4,10 @@ import org.junit.jupiter.api.Test; import org.raddatz.familienarchiv.PostgresContainerConfig; import org.raddatz.familienarchiv.config.FlywayConfig; import org.raddatz.familienarchiv.model.Document; +import org.raddatz.familienarchiv.model.DocumentAnnotation; import org.raddatz.familienarchiv.model.DocumentStatus; import org.raddatz.familienarchiv.model.Person; +import org.raddatz.familienarchiv.model.TranscriptionBlock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; @@ -20,6 +22,7 @@ import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -34,6 +37,12 @@ class DocumentRepositoryTest { @Autowired private PersonRepository personRepository; + @Autowired + private AnnotationRepository annotationRepository; + + @Autowired + private TranscriptionBlockRepository transcriptionBlockRepository; + // ─── save and findById ──────────────────────────────────────────────────── @Test @@ -253,4 +262,116 @@ class DocumentRepositoryTest { assertThat(results).hasSize(1); } + + // ─── findSegmentationQueue ──────────────────────────────────────────────── + + @Test + void findSegmentationQueue_excludes_PLACEHOLDER_documents() { + documentRepository.save(uploaded("Hochgeladener Brief")); + documentRepository.save(Document.builder() + .title("Platzhalter").originalFilename("placeholder.pdf") + .status(DocumentStatus.PLACEHOLDER).build()); + + List result = documentRepository.findSegmentationQueue(10); + + assertThat(result).extracting(TranscriptionQueueProjection::getTitle) + .containsExactly("Hochgeladener Brief") + .doesNotContain("Platzhalter"); + } + + @Test + void findSegmentationQueue_excludes_documents_that_already_have_annotations() { + Document withAnnotation = documentRepository.save(uploaded("Mit Annotation")); + documentRepository.save(uploaded("Ohne Annotation")); + annotationRepository.save(annotation(withAnnotation.getId())); + + List result = documentRepository.findSegmentationQueue(10); + + assertThat(result).extracting(TranscriptionQueueProjection::getTitle) + .containsExactly("Ohne Annotation") + .doesNotContain("Mit Annotation"); + } + + // ─── findTranscriptionQueue ─────────────────────────────────────────────── + + @Test + void findTranscriptionQueue_returns_documents_with_annotations_below_90pct_reviewed() { + Document doc = documentRepository.save(uploaded("Tagebuch")); + DocumentAnnotation ann = annotationRepository.save(annotation(doc.getId())); + // One block, not reviewed → 0 / 1 = 0% < 90% + transcriptionBlockRepository.save(block(doc.getId(), ann.getId(), "Text", false)); + + List result = documentRepository.findTranscriptionQueue(10); + + assertThat(result).extracting(TranscriptionQueueProjection::getTitle) + .contains("Tagebuch"); + } + + @Test + void findTranscriptionQueue_returns_zero_textedBlockCount_when_no_transcription_blocks() { + Document doc = documentRepository.save(uploaded("Nur Annotation")); + annotationRepository.save(annotation(doc.getId())); + // No transcription blocks at all — annotationCount=1, textedBlockCount=0 + + List result = documentRepository.findTranscriptionQueue(10); + + assertThat(result).hasSize(1); + assertThat(result.get(0).getTextedBlockCount()).isEqualTo(0); + assertThat(result.get(0).getAnnotationCount()).isEqualTo(1); + } + + // ─── findReadyToReadQueue ───────────────────────────────────────────────── + + @Test + void findReadyToReadQueue_returns_documents_with_at_least_90pct_reviewed() { + Document doc = documentRepository.save(uploaded("Urkunde")); + DocumentAnnotation ann = annotationRepository.save(annotation(doc.getId())); + // One block, reviewed → 1 / 1 = 100% >= 90% + transcriptionBlockRepository.save(block(doc.getId(), ann.getId(), "Text", true)); + + List result = documentRepository.findReadyToReadQueue(10); + + assertThat(result).extracting(TranscriptionQueueProjection::getTitle) + .contains("Urkunde"); + } + + // ─── findWeeklyStats ────────────────────────────────────────────────────── + + @Test + void findWeeklyStats_returns_zeros_when_database_is_empty() { + TranscriptionWeeklyStatsProjection stats = documentRepository.findWeeklyStats(); + + assertThat(stats.getSegmentationCount()).isEqualTo(0L); + assertThat(stats.getTranscriptionCount()).isEqualTo(0L); + assertThat(stats.getReadyCount()).isEqualTo(0L); + } + + // ─── seeding helpers ───────────────────────────────────────────────────── + + private Document uploaded(String title) { + return Document.builder() + .title(title) + .originalFilename(title.toLowerCase().replace(" ", "_") + ".pdf") + .status(DocumentStatus.UPLOADED) + .build(); + } + + private DocumentAnnotation annotation(UUID documentId) { + return DocumentAnnotation.builder() + .documentId(documentId) + .pageNumber(1) + .x(0.1).y(0.1).width(0.5).height(0.3) + .color("#ff0000") + .build(); + } + + private TranscriptionBlock block(UUID documentId, UUID annotationId, String text, boolean reviewed) { + return TranscriptionBlock.builder() + .documentId(documentId) + .annotationId(annotationId) + .text(text) + .sortOrder(0) + .reviewed(reviewed) + .build(); + } }