feat(audit): add COMMENT_ADDED and MENTION_CREATED audit events
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 2m35s
CI / OCR Service Tests (pull_request) Successful in 39s
CI / Backend Unit Tests (pull_request) Failing after 2m54s
CI / Unit & Component Tests (push) Failing after 2m38s
CI / OCR Service Tests (push) Successful in 35s
CI / Backend Unit Tests (push) Failing after 2m47s
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 2m35s
CI / OCR Service Tests (pull_request) Successful in 39s
CI / Backend Unit Tests (pull_request) Failing after 2m54s
CI / Unit & Component Tests (push) Failing after 2m38s
CI / OCR Service Tests (push) Successful in 35s
CI / Backend Unit Tests (push) Failing after 2m47s
Instruments CommentService.postComment(), postBlockComment(), and replyToComment() to fire COMMENT_ADDED after each successful save and MENTION_CREATED once per mentioned user. The shared logCommentPosted() helper avoids duplicating the two-call pattern across all three post methods. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #275.
This commit is contained in:
@@ -5,6 +5,8 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.raddatz.familienarchiv.audit.AuditKind;
|
||||
import org.raddatz.familienarchiv.audit.AuditService;
|
||||
import org.raddatz.familienarchiv.exception.DomainException;
|
||||
import org.raddatz.familienarchiv.model.AppUser;
|
||||
import org.raddatz.familienarchiv.model.DocumentComment;
|
||||
@@ -22,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anySet;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -35,6 +38,7 @@ class CommentServiceTest {
|
||||
@Mock CommentRepository commentRepository;
|
||||
@Mock UserService userService;
|
||||
@Mock NotificationService notificationService;
|
||||
@Mock AuditService auditService;
|
||||
@InjectMocks CommentService commentService;
|
||||
|
||||
// ─── postComment ──────────────────────────────────────────────────────────
|
||||
@@ -489,6 +493,135 @@ class CommentServiceTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
// ─── audit: COMMENT_ADDED and MENTION_CREATED ─────────────────────────────
|
||||
|
||||
@Test
|
||||
void postComment_logsCommentAdded() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID savedId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("hans@example.com").firstName("Hans").lastName("M").build();
|
||||
DocumentComment saved = DocumentComment.builder()
|
||||
.id(savedId).documentId(docId).authorName("Hans M").content("Hello").build();
|
||||
when(commentRepository.save(any())).thenReturn(saved);
|
||||
|
||||
commentService.postComment(docId, null, "Hello", List.of(), author);
|
||||
|
||||
verify(auditService).logAfterCommit(
|
||||
eq(AuditKind.COMMENT_ADDED),
|
||||
eq(author.getId()),
|
||||
eq(docId),
|
||||
argThat(p -> savedId.toString().equals(p.get("commentId"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void postComment_logsMentionCreated_oncePerMentionedUser() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID savedId = UUID.randomUUID();
|
||||
UUID mentionedId1 = UUID.randomUUID();
|
||||
UUID mentionedId2 = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("hans@example.com").firstName("Hans").lastName("M").build();
|
||||
AppUser mentioned1 = AppUser.builder().id(mentionedId1).email("anna@example.com").firstName("Anna").lastName("S").build();
|
||||
AppUser mentioned2 = AppUser.builder().id(mentionedId2).email("bob@example.com").firstName("Bob").lastName("J").build();
|
||||
DocumentComment saved = DocumentComment.builder()
|
||||
.id(savedId).documentId(docId).authorName("Hans M").content("Hey @Anna @Bob").build();
|
||||
when(userService.findAllById(List.of(mentionedId1, mentionedId2))).thenReturn(List.of(mentioned1, mentioned2));
|
||||
when(commentRepository.save(any())).thenReturn(saved);
|
||||
|
||||
commentService.postComment(docId, null, "Hey @Anna @Bob", List.of(mentionedId1, mentionedId2), author);
|
||||
|
||||
verify(auditService).logAfterCommit(
|
||||
eq(AuditKind.MENTION_CREATED),
|
||||
eq(author.getId()),
|
||||
eq(docId),
|
||||
argThat(p -> mentionedId1.toString().equals(p.get("mentionedUserId"))));
|
||||
verify(auditService).logAfterCommit(
|
||||
eq(AuditKind.MENTION_CREATED),
|
||||
eq(author.getId()),
|
||||
eq(docId),
|
||||
argThat(p -> mentionedId2.toString().equals(p.get("mentionedUserId"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void postComment_doesNotLogMentionCreated_whenNoMentions() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("hans@example.com").firstName("Hans").lastName("M").build();
|
||||
DocumentComment saved = DocumentComment.builder()
|
||||
.id(UUID.randomUUID()).documentId(docId).authorName("Hans M").content("Hello").build();
|
||||
when(commentRepository.save(any())).thenReturn(saved);
|
||||
|
||||
commentService.postComment(docId, null, "Hello", List.of(), author);
|
||||
|
||||
verify(auditService, never()).logAfterCommit(eq(AuditKind.MENTION_CREATED), any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void replyToComment_logsCommentAdded() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID rootId = UUID.randomUUID();
|
||||
UUID savedId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("anna@example.com").firstName("Anna").lastName("S").build();
|
||||
DocumentComment root = DocumentComment.builder()
|
||||
.id(rootId).documentId(docId).parentId(null).content("Root").authorName("Hans").build();
|
||||
DocumentComment saved = DocumentComment.builder()
|
||||
.id(savedId).documentId(docId).parentId(rootId).content("Reply").authorName("Anna S").build();
|
||||
when(commentRepository.findById(rootId)).thenReturn(Optional.of(root));
|
||||
when(commentRepository.findByParentId(rootId)).thenReturn(List.of());
|
||||
when(commentRepository.save(any())).thenReturn(saved);
|
||||
|
||||
commentService.replyToComment(docId, rootId, "Reply", List.of(), author);
|
||||
|
||||
verify(auditService).logAfterCommit(
|
||||
eq(AuditKind.COMMENT_ADDED),
|
||||
eq(author.getId()),
|
||||
eq(docId),
|
||||
argThat(p -> savedId.toString().equals(p.get("commentId"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void replyToComment_logsMentionCreated_whenMentioned() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID rootId = UUID.randomUUID();
|
||||
UUID savedId = UUID.randomUUID();
|
||||
UUID mentionedId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("anna@example.com").firstName("Anna").lastName("S").build();
|
||||
AppUser mentioned = AppUser.builder().id(mentionedId).email("bob@example.com").firstName("Bob").lastName("J").build();
|
||||
DocumentComment root = DocumentComment.builder()
|
||||
.id(rootId).documentId(docId).parentId(null).content("Root").authorName("Hans").build();
|
||||
DocumentComment saved = DocumentComment.builder()
|
||||
.id(savedId).documentId(docId).parentId(rootId).content("Hey @Bob").authorName("Anna S").build();
|
||||
when(userService.findAllById(List.of(mentionedId))).thenReturn(List.of(mentioned));
|
||||
when(commentRepository.findById(rootId)).thenReturn(Optional.of(root));
|
||||
when(commentRepository.findByParentId(rootId)).thenReturn(List.of());
|
||||
when(commentRepository.save(any())).thenReturn(saved);
|
||||
|
||||
commentService.replyToComment(docId, rootId, "Hey @Bob", List.of(mentionedId), author);
|
||||
|
||||
verify(auditService).logAfterCommit(
|
||||
eq(AuditKind.MENTION_CREATED),
|
||||
eq(author.getId()),
|
||||
eq(docId),
|
||||
argThat(p -> mentionedId.toString().equals(p.get("mentionedUserId"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void postBlockComment_logsCommentAdded() {
|
||||
UUID docId = UUID.randomUUID();
|
||||
UUID blockId = UUID.randomUUID();
|
||||
UUID savedId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("felix@example.com").firstName("Felix").lastName("B").build();
|
||||
DocumentComment saved = DocumentComment.builder()
|
||||
.id(savedId).documentId(docId).blockId(blockId).authorName("Felix B").content("Nice").build();
|
||||
when(commentRepository.save(any())).thenReturn(saved);
|
||||
|
||||
commentService.postBlockComment(docId, blockId, "Nice", List.of(), author);
|
||||
|
||||
verify(auditService).logAfterCommit(
|
||||
eq(AuditKind.COMMENT_ADDED),
|
||||
eq(author.getId()),
|
||||
eq(docId),
|
||||
argThat(p -> savedId.toString().equals(p.get("commentId"))));
|
||||
}
|
||||
|
||||
// ─── Block-level comments ────────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user