feat(dashboard): enrich activity feed DTO with commentId + annotationId
ActivityFeedItemDTO gains nullable commentId and annotationId fields. DashboardService.getActivity forwards commentId from the projection and batch-resolves annotationId via the new CommentService.findAnnotationIdsByIds lookup. Both remain null for non-comment kinds, so the bulk lookup is skipped entirely when the feed has no comment rows. Refs #300. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import org.raddatz.familienarchiv.audit.AuditLogQueryService;
|
||||
import org.raddatz.familienarchiv.model.AppUser;
|
||||
import org.raddatz.familienarchiv.model.Document;
|
||||
import org.raddatz.familienarchiv.model.TranscriptionBlock;
|
||||
import org.raddatz.familienarchiv.service.CommentService;
|
||||
import org.raddatz.familienarchiv.service.DocumentService;
|
||||
import org.raddatz.familienarchiv.service.TranscriptionService;
|
||||
import org.raddatz.familienarchiv.service.UserService;
|
||||
@@ -17,6 +18,7 @@ import org.raddatz.familienarchiv.service.UserService;
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -33,6 +35,7 @@ class DashboardServiceTest {
|
||||
@Mock DocumentService documentService;
|
||||
@Mock TranscriptionService transcriptionService;
|
||||
@Mock UserService userService;
|
||||
@Mock CommentService commentService;
|
||||
|
||||
@InjectMocks DashboardService dashboardService;
|
||||
|
||||
@@ -94,7 +97,72 @@ class DashboardServiceTest {
|
||||
verify(documentService, never()).getDocumentById(docId);
|
||||
}
|
||||
|
||||
// ─── getActivity comment/annotation enrichment ────────────────────────────
|
||||
|
||||
@Test
|
||||
void getActivity_populatesCommentId_forCommentEvents() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID commentId = UUID.randomUUID();
|
||||
|
||||
ActivityFeedRow row = mockFeedRow(docId, "COMMENT_ADDED", commentId);
|
||||
when(auditLogQueryService.findActivityFeed(userId, 5)).thenReturn(List.of(row));
|
||||
when(documentService.getDocumentsByIds(List.of(docId))).thenReturn(List.of(
|
||||
Document.builder().id(docId).title("B").originalFilename("b.pdf").receivers(new HashSet<>()).build()
|
||||
));
|
||||
when(commentService.findAnnotationIdsByIds(List.of(commentId))).thenReturn(Map.of());
|
||||
|
||||
List<ActivityFeedItemDTO> items = dashboardService.getActivity(userId, 5);
|
||||
|
||||
assertThat(items).hasSize(1);
|
||||
assertThat(items.get(0).commentId()).isEqualTo(commentId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getActivity_populatesAnnotationId_viaCommentService() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID commentId = UUID.randomUUID();
|
||||
UUID annotationId = UUID.randomUUID();
|
||||
|
||||
ActivityFeedRow row = mockFeedRow(docId, "COMMENT_ADDED", commentId);
|
||||
when(auditLogQueryService.findActivityFeed(userId, 5)).thenReturn(List.of(row));
|
||||
when(documentService.getDocumentsByIds(List.of(docId))).thenReturn(List.of(
|
||||
Document.builder().id(docId).title("B").originalFilename("b.pdf").receivers(new HashSet<>()).build()
|
||||
));
|
||||
when(commentService.findAnnotationIdsByIds(List.of(commentId)))
|
||||
.thenReturn(Map.of(commentId, annotationId));
|
||||
|
||||
List<ActivityFeedItemDTO> items = dashboardService.getActivity(userId, 5);
|
||||
|
||||
assertThat(items).hasSize(1);
|
||||
assertThat(items.get(0).annotationId()).isEqualTo(annotationId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getActivity_leavesBothNull_forNonCommentKinds() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
UUID docId = UUID.randomUUID();
|
||||
|
||||
ActivityFeedRow row = mockFeedRow(docId, "TEXT_SAVED", null);
|
||||
when(auditLogQueryService.findActivityFeed(userId, 5)).thenReturn(List.of(row));
|
||||
when(documentService.getDocumentsByIds(List.of(docId))).thenReturn(List.of(
|
||||
Document.builder().id(docId).title("B").originalFilename("b.pdf").receivers(new HashSet<>()).build()
|
||||
));
|
||||
|
||||
List<ActivityFeedItemDTO> items = dashboardService.getActivity(userId, 5);
|
||||
|
||||
assertThat(items).hasSize(1);
|
||||
assertThat(items.get(0).commentId()).isNull();
|
||||
assertThat(items.get(0).annotationId()).isNull();
|
||||
verify(commentService, never()).findAnnotationIdsByIds(anyList());
|
||||
}
|
||||
|
||||
private ActivityFeedRow mockFeedRow(UUID docId, String kind) {
|
||||
return mockFeedRow(docId, kind, null);
|
||||
}
|
||||
|
||||
private ActivityFeedRow mockFeedRow(UUID docId, String kind, UUID commentId) {
|
||||
return new ActivityFeedRow() {
|
||||
public String getKind() { return kind; }
|
||||
public UUID getActorId() { return null; }
|
||||
@@ -107,7 +175,7 @@ class DashboardServiceTest {
|
||||
public boolean isYouParticipated() { return false; }
|
||||
public int getCount() { return 1; }
|
||||
public Instant getHappenedAtUntil() { return null; }
|
||||
public UUID getCommentId() { return null; }
|
||||
public UUID getCommentId() { return commentId; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user