package com.timeline.user.service; import com.timeline.user.dao.CommentMapper; import com.timeline.user.dto.CommentDto; import com.timeline.user.dto.CommentEventDto; import com.timeline.user.dto.CreateCommentRequest; import com.timeline.user.entity.Comment; import com.timeline.user.entity.User; import com.timeline.user.service.impl.CommentServiceImpl; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.messaging.simp.SimpMessagingTemplate; import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; /** * WebSocket通知测试 * Tests for WebSocket notifications in CommentService */ @ExtendWith(MockitoExtension.class) class CommentWebSocketTest { @Mock private CommentMapper commentMapper; @Mock private UserService userService; @Mock private SimpMessagingTemplate messagingTemplate; @InjectMocks private CommentServiceImpl commentService; private User testUser; private Comment testComment; @BeforeEach void setUp() { testUser = new User(); testUser.setUserId("user123"); testUser.setUsername("testuser"); testUser.setNickname("Test User"); testComment = new Comment(); testComment.setId(1L); testComment.setInstanceId("comment123"); testComment.setEntityType("STORY"); testComment.setEntityId("story456"); testComment.setUserId("user123"); testComment.setContent("Test comment"); testComment.setCreateTime(LocalDateTime.now()); testComment.setUpdateTime(LocalDateTime.now()); testComment.setIsDelete(0); } @Test void testCreateComment_ShouldBroadcastWebSocketEvent() { // Arrange CreateCommentRequest request = new CreateCommentRequest(); request.setEntityType("STORY"); request.setEntityId("story456"); request.setContent("Test comment"); when(commentMapper.insert(any(Comment.class))).thenReturn(1); when(commentMapper.findByInstanceId(anyString())).thenReturn(testComment); when(userService.getUserByUserId("user123")).thenReturn(testUser); // Act CommentDto result = commentService.createComment("user123", request); // Assert assertNotNull(result); assertEquals("Test comment", result.getContent()); // Verify WebSocket message was sent ArgumentCaptor topicCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(CommentEventDto.class); verify(messagingTemplate, times(1)).convertAndSend( topicCaptor.capture(), eventCaptor.capture() ); // Verify topic format String expectedTopic = "/topic/comments/STORY/story456"; assertEquals(expectedTopic, topicCaptor.getValue()); // Verify event content CommentEventDto event = eventCaptor.getValue(); assertEquals(CommentEventDto.CommentEventType.CREATED, event.getEventType()); assertEquals("STORY", event.getEntityType()); assertEquals("story456", event.getEntityId()); assertNotNull(event.getComment()); assertEquals("Test comment", event.getComment().getContent()); } @Test void testUpdateComment_ShouldBroadcastWebSocketEvent() { // Arrange String updatedContent = "Updated comment"; Comment updatedComment = new Comment(); updatedComment.setInstanceId("comment123"); updatedComment.setEntityType("STORY"); updatedComment.setEntityId("story456"); updatedComment.setUserId("user123"); updatedComment.setContent(updatedContent); updatedComment.setCreateTime(LocalDateTime.now().minusHours(1)); updatedComment.setUpdateTime(LocalDateTime.now()); updatedComment.setIsDelete(0); when(commentMapper.findByInstanceId("comment123")).thenReturn(testComment, updatedComment); when(commentMapper.updateContent("comment123", updatedContent)).thenReturn(1); when(userService.getUserByUserId("user123")).thenReturn(testUser); // Act CommentDto result = commentService.updateComment("comment123", "user123", updatedContent); // Assert assertNotNull(result); // Verify WebSocket message was sent ArgumentCaptor topicCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(CommentEventDto.class); verify(messagingTemplate, times(1)).convertAndSend( topicCaptor.capture(), eventCaptor.capture() ); // Verify event CommentEventDto event = eventCaptor.getValue(); assertEquals(CommentEventDto.CommentEventType.UPDATED, event.getEventType()); assertEquals("STORY", event.getEntityType()); assertEquals("story456", event.getEntityId()); } @Test void testDeleteComment_ShouldBroadcastWebSocketEvent() { // Arrange when(commentMapper.findByInstanceId("comment123")).thenReturn(testComment); when(commentMapper.softDelete("comment123")).thenReturn(1); // Act commentService.deleteComment("comment123", "user123", null); // Assert // Verify WebSocket message was sent ArgumentCaptor topicCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(CommentEventDto.class); verify(messagingTemplate, times(1)).convertAndSend( topicCaptor.capture(), eventCaptor.capture() ); // Verify event CommentEventDto event = eventCaptor.getValue(); assertEquals(CommentEventDto.CommentEventType.DELETED, event.getEventType()); assertEquals("STORY", event.getEntityType()); assertEquals("story456", event.getEntityId()); assertEquals("comment123", event.getCommentId()); assertNull(event.getComment()); // Comment data should be null for delete events } @Test void testWebSocketBroadcast_ShouldNotFailMainOperation_WhenWebSocketFails() { // Arrange CreateCommentRequest request = new CreateCommentRequest(); request.setEntityType("STORY"); request.setEntityId("story456"); request.setContent("Test comment"); when(commentMapper.insert(any(Comment.class))).thenReturn(1); when(commentMapper.findByInstanceId(anyString())).thenReturn(testComment); when(userService.getUserByUserId("user123")).thenReturn(testUser); // Simulate WebSocket failure doThrow(new RuntimeException("WebSocket error")) .when(messagingTemplate).convertAndSend(anyString(), any()); // Act - should not throw exception CommentDto result = commentService.createComment("user123", request); // Assert - main operation should succeed despite WebSocket failure assertNotNull(result); assertEquals("Test comment", result.getContent()); // Verify the WebSocket send was attempted verify(messagingTemplate, times(1)).convertAndSend(anyString(), any()); } }