@@ -48,6 +48,26 @@ public class AnnotationService {
|
||||
return annotationRepository.save(annotation);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public DocumentAnnotation createOcrAnnotation(UUID documentId, CreateAnnotationDTO dto,
|
||||
UUID userId, String fileHash,
|
||||
List<List<Double>> polygon) {
|
||||
DocumentAnnotation annotation = DocumentAnnotation.builder()
|
||||
.documentId(documentId)
|
||||
.pageNumber(dto.getPageNumber())
|
||||
.x(dto.getX())
|
||||
.y(dto.getY())
|
||||
.width(dto.getWidth())
|
||||
.height(dto.getHeight())
|
||||
.color(dto.getColor())
|
||||
.fileHash(fileHash)
|
||||
.createdBy(userId)
|
||||
.polygon(polygon)
|
||||
.build();
|
||||
|
||||
return annotationRepository.save(annotation);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteAnnotation(UUID documentId, UUID annotationId, UUID userId) {
|
||||
DocumentAnnotation annotation = annotationRepository
|
||||
|
||||
@@ -260,6 +260,55 @@ class AnnotationServiceTest {
|
||||
verify(annotationRepository).save(any());
|
||||
}
|
||||
|
||||
// ─── createOcrAnnotation ──────────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
void createOcrAnnotation_skipsOverlapCheck_andSavesWithPolygon() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID userId = UUID.randomUUID();
|
||||
CreateAnnotationDTO dto = new CreateAnnotationDTO(1, 0.1, 0.1, 0.8, 0.04, "#00C7B1");
|
||||
List<List<Double>> polygon = List.of(
|
||||
List.of(0.1, 0.1), List.of(0.9, 0.11),
|
||||
List.of(0.89, 0.14), List.of(0.11, 0.13));
|
||||
when(annotationRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
|
||||
DocumentAnnotation result = annotationService.createOcrAnnotation(
|
||||
docId, dto, userId, "filehash", polygon);
|
||||
|
||||
assertThat(result.getPolygon()).isEqualTo(polygon);
|
||||
assertThat(result.getDocumentId()).isEqualTo(docId);
|
||||
verify(annotationRepository).save(any());
|
||||
verify(annotationRepository, never()).findByDocumentIdAndPageNumber(any(), any(int.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createOcrAnnotation_savesWithNullPolygon_whenPolygonNotProvided() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID userId = UUID.randomUUID();
|
||||
CreateAnnotationDTO dto = new CreateAnnotationDTO(1, 0.1, 0.1, 0.8, 0.04, "#00C7B1");
|
||||
when(annotationRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
|
||||
DocumentAnnotation result = annotationService.createOcrAnnotation(
|
||||
docId, dto, userId, "filehash", null);
|
||||
|
||||
assertThat(result.getPolygon()).isNull();
|
||||
verify(annotationRepository).save(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createOcrAnnotation_doesNotCheckOverlap_evenWhenOverlappingAnnotationExists() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID userId = UUID.randomUUID();
|
||||
CreateAnnotationDTO dto = new CreateAnnotationDTO(1, 0.1, 0.1, 0.3, 0.3, "#00C7B1");
|
||||
when(annotationRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
|
||||
annotationService.createOcrAnnotation(docId, dto, userId, "hash", null);
|
||||
|
||||
verify(annotationRepository, never()).findByDocumentIdAndPageNumber(any(), any(int.class));
|
||||
}
|
||||
|
||||
// ─── overlaps — partial overlap cases ────────────────────────────────────
|
||||
|
||||
@Test
|
||||
void createAnnotation_noConflict_whenAnnotationIsAbove() {
|
||||
// x ranges overlap, y ranges don't — existing is ABOVE the new annotation
|
||||
|
||||
Reference in New Issue
Block a user