218 lines
7.2 KiB
Java
218 lines
7.2 KiB
Java
|
|
package com.timeline.user.service;
|
||
|
|
|
||
|
|
import com.timeline.user.dao.ReactionMapper;
|
||
|
|
import com.timeline.user.dao.UserMapper;
|
||
|
|
import com.timeline.user.entity.Reaction;
|
||
|
|
import com.timeline.user.entity.User;
|
||
|
|
import com.timeline.user.service.impl.ReactionServiceImpl;
|
||
|
|
import org.junit.jupiter.api.BeforeEach;
|
||
|
|
import org.junit.jupiter.api.Test;
|
||
|
|
import org.mockito.InjectMocks;
|
||
|
|
import org.mockito.Mock;
|
||
|
|
import org.mockito.MockitoAnnotations;
|
||
|
|
|
||
|
|
import java.util.*;
|
||
|
|
|
||
|
|
import static org.junit.jupiter.api.Assertions.*;
|
||
|
|
import static org.mockito.ArgumentMatchers.*;
|
||
|
|
import static org.mockito.Mockito.*;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reaction Service Unit Tests
|
||
|
|
*/
|
||
|
|
class ReactionServiceTest {
|
||
|
|
|
||
|
|
@Mock
|
||
|
|
private ReactionMapper reactionMapper;
|
||
|
|
|
||
|
|
@Mock
|
||
|
|
private UserMapper userMapper;
|
||
|
|
|
||
|
|
@InjectMocks
|
||
|
|
private ReactionServiceImpl reactionService;
|
||
|
|
|
||
|
|
@BeforeEach
|
||
|
|
void setUp() {
|
||
|
|
MockitoAnnotations.openMocks(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void testGetReactionSummary_Success() {
|
||
|
|
// Arrange
|
||
|
|
String entityType = "STORY_ITEM";
|
||
|
|
String entityId = "story123";
|
||
|
|
String currentUserId = "user1";
|
||
|
|
|
||
|
|
List<Reaction> reactions = new ArrayList<>();
|
||
|
|
Reaction reaction1 = new Reaction();
|
||
|
|
reaction1.setEntityType(entityType);
|
||
|
|
reaction1.setEntityId(entityId);
|
||
|
|
reaction1.setUserId("user1");
|
||
|
|
reaction1.setReactionType("LIKE");
|
||
|
|
reactions.add(reaction1);
|
||
|
|
|
||
|
|
Reaction reaction2 = new Reaction();
|
||
|
|
reaction2.setEntityType(entityType);
|
||
|
|
reaction2.setEntityId(entityId);
|
||
|
|
reaction2.setUserId("user2");
|
||
|
|
reaction2.setReactionType("LOVE");
|
||
|
|
reactions.add(reaction2);
|
||
|
|
|
||
|
|
when(reactionMapper.findByEntity(entityType, entityId)).thenReturn(reactions);
|
||
|
|
when(reactionMapper.findByEntityAndUser(entityType, entityId, currentUserId)).thenReturn(reaction1);
|
||
|
|
|
||
|
|
User user1 = new User();
|
||
|
|
user1.setUserId("user1");
|
||
|
|
user1.setUsername("User One");
|
||
|
|
when(userMapper.selectByUserId("user1")).thenReturn(user1);
|
||
|
|
|
||
|
|
User user2 = new User();
|
||
|
|
user2.setUserId("user2");
|
||
|
|
user2.setUsername("User Two");
|
||
|
|
when(userMapper.selectByUserId("user2")).thenReturn(user2);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
Map<String, Object> summary = reactionService.getReactionSummary(entityType, entityId, currentUserId);
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
assertNotNull(summary);
|
||
|
|
assertEquals(entityType, summary.get("entityType"));
|
||
|
|
assertEquals(entityId, summary.get("entityId"));
|
||
|
|
assertEquals("LIKE", summary.get("userReaction"));
|
||
|
|
|
||
|
|
@SuppressWarnings("unchecked")
|
||
|
|
Map<String, Integer> counts = (Map<String, Integer>) summary.get("counts");
|
||
|
|
assertEquals(1, counts.get("LIKE"));
|
||
|
|
assertEquals(1, counts.get("LOVE"));
|
||
|
|
assertEquals(0, counts.get("LAUGH"));
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void testAddOrUpdateReaction_NewReaction() {
|
||
|
|
// Arrange
|
||
|
|
String userId = "user1";
|
||
|
|
String entityType = "PHOTO";
|
||
|
|
String entityId = "photo123";
|
||
|
|
String reactionType = "LOVE";
|
||
|
|
|
||
|
|
when(reactionMapper.findByEntityAndUser(entityType, entityId, userId)).thenReturn(null);
|
||
|
|
when(reactionMapper.insert(any(Reaction.class))).thenReturn(1);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
reactionService.addOrUpdateReaction(userId, entityType, entityId, reactionType);
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
verify(reactionMapper, times(1)).insert(any(Reaction.class));
|
||
|
|
verify(reactionMapper, never()).updateReactionType(anyString(), anyString(), anyString(), anyString());
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void testAddOrUpdateReaction_UpdateExisting() {
|
||
|
|
// Arrange
|
||
|
|
String userId = "user1";
|
||
|
|
String entityType = "STORY_ITEM";
|
||
|
|
String entityId = "story123";
|
||
|
|
String newReactionType = "WOW";
|
||
|
|
|
||
|
|
Reaction existingReaction = new Reaction();
|
||
|
|
existingReaction.setEntityType(entityType);
|
||
|
|
existingReaction.setEntityId(entityId);
|
||
|
|
existingReaction.setUserId(userId);
|
||
|
|
existingReaction.setReactionType("LIKE");
|
||
|
|
|
||
|
|
when(reactionMapper.findByEntityAndUser(entityType, entityId, userId)).thenReturn(existingReaction);
|
||
|
|
when(reactionMapper.updateReactionType(entityType, entityId, userId, newReactionType)).thenReturn(1);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
reactionService.addOrUpdateReaction(userId, entityType, entityId, newReactionType);
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
verify(reactionMapper, times(1)).updateReactionType(entityType, entityId, userId, newReactionType);
|
||
|
|
verify(reactionMapper, never()).insert(any(Reaction.class));
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void testRemoveReaction_Success() {
|
||
|
|
// Arrange
|
||
|
|
String userId = "user1";
|
||
|
|
String entityType = "PHOTO";
|
||
|
|
String entityId = "photo123";
|
||
|
|
|
||
|
|
when(reactionMapper.delete(entityType, entityId, userId)).thenReturn(1);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
reactionService.removeReaction(userId, entityType, entityId);
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
verify(reactionMapper, times(1)).delete(entityType, entityId, userId);
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void testAddOrUpdateReaction_InvalidEntityType() {
|
||
|
|
// Arrange
|
||
|
|
String userId = "user1";
|
||
|
|
String entityType = "INVALID_TYPE";
|
||
|
|
String entityId = "entity123";
|
||
|
|
String reactionType = "LIKE";
|
||
|
|
|
||
|
|
// Act & Assert
|
||
|
|
assertThrows(IllegalArgumentException.class, () -> {
|
||
|
|
reactionService.addOrUpdateReaction(userId, entityType, entityId, reactionType);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void testAddOrUpdateReaction_InvalidReactionType() {
|
||
|
|
// Arrange
|
||
|
|
String userId = "user1";
|
||
|
|
String entityType = "STORY_ITEM";
|
||
|
|
String entityId = "story123";
|
||
|
|
String reactionType = "INVALID_REACTION";
|
||
|
|
|
||
|
|
// Act & Assert
|
||
|
|
assertThrows(IllegalArgumentException.class, () -> {
|
||
|
|
reactionService.addOrUpdateReaction(userId, entityType, entityId, reactionType);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void testGetReactionSummary_OneReactionPerUserConstraint() {
|
||
|
|
// Arrange
|
||
|
|
String entityType = "STORY_ITEM";
|
||
|
|
String entityId = "story123";
|
||
|
|
String userId = "user1";
|
||
|
|
|
||
|
|
// User has one reaction
|
||
|
|
List<Reaction> reactions = new ArrayList<>();
|
||
|
|
Reaction reaction = new Reaction();
|
||
|
|
reaction.setEntityType(entityType);
|
||
|
|
reaction.setEntityId(entityId);
|
||
|
|
reaction.setUserId(userId);
|
||
|
|
reaction.setReactionType("LIKE");
|
||
|
|
reactions.add(reaction);
|
||
|
|
|
||
|
|
when(reactionMapper.findByEntity(entityType, entityId)).thenReturn(reactions);
|
||
|
|
when(reactionMapper.findByEntityAndUser(entityType, entityId, userId)).thenReturn(reaction);
|
||
|
|
|
||
|
|
User user = new User();
|
||
|
|
user.setUserId(userId);
|
||
|
|
user.setUsername("Test User");
|
||
|
|
when(userMapper.selectByUserId(userId)).thenReturn(user);
|
||
|
|
|
||
|
|
// Act
|
||
|
|
Map<String, Object> summary = reactionService.getReactionSummary(entityType, entityId, userId);
|
||
|
|
|
||
|
|
// Assert
|
||
|
|
assertEquals("LIKE", summary.get("userReaction"));
|
||
|
|
|
||
|
|
@SuppressWarnings("unchecked")
|
||
|
|
List<Map<String, Object>> recentReactions = (List<Map<String, Object>>) summary.get("recentReactions");
|
||
|
|
|
||
|
|
// Verify only one reaction per user
|
||
|
|
long userReactionCount = reactions.stream()
|
||
|
|
.filter(r -> r.getUserId().equals(userId))
|
||
|
|
.count();
|
||
|
|
assertEquals(1, userReactionCount);
|
||
|
|
}
|
||
|
|
}
|