252 lines
11 KiB
Java
252 lines
11 KiB
Java
|
|
package com.timeline.user.service;
|
||
|
|
|
||
|
|
import com.timeline.user.dao.PreferencesMapper;
|
||
|
|
import com.timeline.user.entity.UserPreferences;
|
||
|
|
import com.timeline.user.service.impl.PreferencesServiceImpl;
|
||
|
|
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 static org.junit.jupiter.api.Assertions.*;
|
||
|
|
import static org.mockito.ArgumentMatchers.*;
|
||
|
|
import static org.mockito.Mockito.*;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 用户偏好设置服务测试
|
||
|
|
* User Preferences Service Test
|
||
|
|
*
|
||
|
|
* Tests for Requirements 7.5, 7.6 (Theme Customization backend)
|
||
|
|
*/
|
||
|
|
public class PreferencesServiceTest {
|
||
|
|
|
||
|
|
@Mock
|
||
|
|
private PreferencesMapper preferencesMapper;
|
||
|
|
|
||
|
|
@InjectMocks
|
||
|
|
private PreferencesServiceImpl preferencesService;
|
||
|
|
|
||
|
|
@BeforeEach
|
||
|
|
void setUp() {
|
||
|
|
MockitoAnnotations.openMocks(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testGetUserPreferences_CreatesDefaultWhenNotExists() {
|
||
|
|
// Given: 新用户ID
|
||
|
|
String userId = "test-user-123";
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(null);
|
||
|
|
when(preferencesMapper.insert(any(UserPreferences.class))).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 获取用户偏好设置
|
||
|
|
UserPreferences preferences = preferencesService.getUserPreferences(userId);
|
||
|
|
|
||
|
|
// Then: 应该返回默认设置
|
||
|
|
assertNotNull(preferences, "Preferences should not be null");
|
||
|
|
assertEquals(userId, preferences.getUserId(), "User ID should match");
|
||
|
|
assertEquals("auto", preferences.getThemeMode(), "Default theme mode should be auto");
|
||
|
|
assertEquals("default", preferences.getColorScheme(), "Default color scheme should be default");
|
||
|
|
assertEquals("grid", preferences.getGalleryLayout(), "Default gallery layout should be grid");
|
||
|
|
assertEquals("grid", preferences.getTimelineLayout(), "Default timeline layout should be grid");
|
||
|
|
assertEquals("grid", preferences.getAlbumLayout(), "Default album layout should be grid");
|
||
|
|
assertEquals("medium", preferences.getCardSize(), "Default card size should be medium");
|
||
|
|
assertEquals("chronological", preferences.getTimelineDisplayMode(), "Default timeline display mode should be chronological");
|
||
|
|
|
||
|
|
verify(preferencesMapper, times(1)).findByUserId(userId);
|
||
|
|
verify(preferencesMapper, times(1)).insert(any(UserPreferences.class));
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateThemePreferences_Light() {
|
||
|
|
// Given: 用户ID和主题设置
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
when(preferencesMapper.updateTheme(userId, "light", "blue")).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 更新为浅色主题
|
||
|
|
preferencesService.updateThemePreferences(userId, "light", "blue");
|
||
|
|
|
||
|
|
// Then: 应该调用更新方法
|
||
|
|
verify(preferencesMapper, times(1)).updateTheme(userId, "light", "blue");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateThemePreferences_Dark() {
|
||
|
|
// Given: 用户ID和主题设置
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
when(preferencesMapper.updateTheme(userId, "dark", "purple")).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 更新为深色主题
|
||
|
|
preferencesService.updateThemePreferences(userId, "dark", "purple");
|
||
|
|
|
||
|
|
// Then: 应该调用更新方法
|
||
|
|
verify(preferencesMapper, times(1)).updateTheme(userId, "dark", "purple");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateThemePreferences_Auto() {
|
||
|
|
// Given: 用户ID和主题设置
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
when(preferencesMapper.updateTheme(userId, "auto", "default")).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 更新为自动主题
|
||
|
|
preferencesService.updateThemePreferences(userId, "auto", "default");
|
||
|
|
|
||
|
|
// Then: 应该调用更新方法
|
||
|
|
verify(preferencesMapper, times(1)).updateTheme(userId, "auto", "default");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateThemePreferences_InvalidThemeMode() {
|
||
|
|
// Given: 用户ID和无效的主题模式
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
|
||
|
|
// When & Then: 应该抛出异常
|
||
|
|
assertThrows(IllegalArgumentException.class, () -> {
|
||
|
|
preferencesService.updateThemePreferences(userId, "invalid", "default");
|
||
|
|
}, "Should throw exception for invalid theme mode");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateLayoutPreferences() {
|
||
|
|
// Given: 用户ID和布局设置
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
when(preferencesMapper.updateLayout(userId, "list", "grid", "list", "large")).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 更新布局偏好
|
||
|
|
preferencesService.updateLayoutPreferences(userId, "list", "grid", "list", "large");
|
||
|
|
|
||
|
|
// Then: 应该调用更新方法
|
||
|
|
verify(preferencesMapper, times(1)).updateLayout(userId, "list", "grid", "list", "large");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateLayoutPreferences_PartialUpdate() {
|
||
|
|
// Given: 用户ID和部分布局设置
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
when(preferencesMapper.updateLayout(userId, "list", "grid", "grid", "small")).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 只更新部分布局偏好
|
||
|
|
preferencesService.updateLayoutPreferences(userId, "list", null, null, "small");
|
||
|
|
|
||
|
|
// Then: 应该使用现有值填充null字段
|
||
|
|
verify(preferencesMapper, times(1)).updateLayout(userId, "list", "grid", "grid", "small");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateLayoutPreferences_InvalidLayout() {
|
||
|
|
// Given: 用户ID和无效的布局
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
|
||
|
|
// When & Then: 应该抛出异常
|
||
|
|
assertThrows(IllegalArgumentException.class, () -> {
|
||
|
|
preferencesService.updateLayoutPreferences(userId, "invalid", null, null, null);
|
||
|
|
}, "Should throw exception for invalid layout");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateLayoutPreferences_InvalidCardSize() {
|
||
|
|
// Given: 用户ID和无效的卡片大小
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
|
||
|
|
// When & Then: 应该抛出异常
|
||
|
|
assertThrows(IllegalArgumentException.class, () -> {
|
||
|
|
preferencesService.updateLayoutPreferences(userId, null, null, null, "invalid");
|
||
|
|
}, "Should throw exception for invalid card size");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateTimelineDisplayPreferences() {
|
||
|
|
// Given: 用户ID和时间线显示模式
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
when(preferencesMapper.updateTimelineDisplay(userId, "grouped")).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 更新时间线显示偏好
|
||
|
|
preferencesService.updateTimelineDisplayPreferences(userId, "grouped");
|
||
|
|
|
||
|
|
// Then: 应该调用更新方法
|
||
|
|
verify(preferencesMapper, times(1)).updateTimelineDisplay(userId, "grouped");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateTimelineDisplayPreferences_Masonry() {
|
||
|
|
// Given: 用户ID和时间线显示模式
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
when(preferencesMapper.updateTimelineDisplay(userId, "masonry")).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 更新为瀑布流显示
|
||
|
|
preferencesService.updateTimelineDisplayPreferences(userId, "masonry");
|
||
|
|
|
||
|
|
// Then: 应该调用更新方法
|
||
|
|
verify(preferencesMapper, times(1)).updateTimelineDisplay(userId, "masonry");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testUpdateTimelineDisplayPreferences_InvalidMode() {
|
||
|
|
// Given: 用户ID和无效的显示模式
|
||
|
|
String userId = "test-user-123";
|
||
|
|
UserPreferences existing = createDefaultPreferences(userId);
|
||
|
|
when(preferencesMapper.findByUserId(userId)).thenReturn(existing);
|
||
|
|
|
||
|
|
// When & Then: 应该抛出异常
|
||
|
|
assertThrows(IllegalArgumentException.class, () -> {
|
||
|
|
preferencesService.updateTimelineDisplayPreferences(userId, "invalid");
|
||
|
|
}, "Should throw exception for invalid display mode");
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
public void testCreateDefaultPreferences() {
|
||
|
|
// Given: 新用户ID
|
||
|
|
String userId = "test-user-123";
|
||
|
|
when(preferencesMapper.insert(any(UserPreferences.class))).thenReturn(1);
|
||
|
|
|
||
|
|
// When: 创建默认偏好设置
|
||
|
|
UserPreferences preferences = preferencesService.createDefaultPreferences(userId);
|
||
|
|
|
||
|
|
// Then: 应该创建包含所有默认值的偏好设置
|
||
|
|
assertNotNull(preferences, "Preferences should not be null");
|
||
|
|
assertEquals(userId, preferences.getUserId(), "User ID should match");
|
||
|
|
assertEquals("auto", preferences.getThemeMode(), "Default theme mode should be auto");
|
||
|
|
assertEquals("default", preferences.getColorScheme(), "Default color scheme should be default");
|
||
|
|
assertEquals("grid", preferences.getGalleryLayout(), "Default gallery layout should be grid");
|
||
|
|
assertEquals("medium", preferences.getCardSize(), "Default card size should be medium");
|
||
|
|
assertEquals("chronological", preferences.getTimelineDisplayMode(), "Default timeline display mode should be chronological");
|
||
|
|
|
||
|
|
verify(preferencesMapper, times(1)).insert(any(UserPreferences.class));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper method to create default preferences for testing
|
||
|
|
private UserPreferences createDefaultPreferences(String userId) {
|
||
|
|
UserPreferences preferences = new UserPreferences();
|
||
|
|
preferences.setUserId(userId);
|
||
|
|
preferences.setThemeMode("auto");
|
||
|
|
preferences.setColorScheme("default");
|
||
|
|
preferences.setGalleryLayout("grid");
|
||
|
|
preferences.setTimelineLayout("grid");
|
||
|
|
preferences.setAlbumLayout("grid");
|
||
|
|
preferences.setCardSize("medium");
|
||
|
|
preferences.setTimelineDisplayMode("chronological");
|
||
|
|
return preferences;
|
||
|
|
}
|
||
|
|
}
|