Files
user-system/internal/service/theme_test.go
long-agent 582ad7a069 test: add comprehensive test coverage and improve code quality
- Add new test files for auth, service, and handler modules
- Improve test organization and coverage
- Refactor code for better maintainability
- Add captcha, settings, stats, and theme handler tests
- Add auth module tests (CAS, OAuth, password, SSO, state)
- Add service layer tests for auth, export, permissions, roles
- All Go tests pass (exit code 0)
- All frontend tests pass (325 tests in 59 files)
2026-04-17 20:43:50 +08:00

275 lines
7.5 KiB
Go

package service_test
import (
"context"
"testing"
"github.com/user-management-system/internal/domain"
"github.com/user-management-system/internal/repository"
"github.com/user-management-system/internal/service"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// =============================================================================
// Theme Service Tests - TDD approach
// =============================================================================
func setupThemeServiceTestEnv(t *testing.T) (*service.ThemeService, *gorm.DB) {
t.Helper()
db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
DriverName: "sqlite",
DSN: "file:theme_svc_test?mode=memory&cache=shared",
}), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
t.Fatalf("failed to connect database: %v", err)
}
if err := db.AutoMigrate(&domain.ThemeConfig{}); err != nil {
t.Fatalf("failed to migrate: %v", err)
}
themeRepo := repository.NewThemeConfigRepository(db)
return service.NewThemeService(themeRepo), db
}
func TestThemeService_CreateTheme(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
t.Run("创建主题成功", func(t *testing.T) {
req := &service.CreateThemeRequest{
Name: "test-theme",
PrimaryColor: "#1976d2",
}
theme, err := svc.CreateTheme(ctx, req)
if err != nil {
t.Fatalf("CreateTheme failed: %v", err)
}
if theme.Name != "test-theme" {
t.Errorf("期望 Name=test-theme, 得到 %s", theme.Name)
}
if theme.PrimaryColor != "#1976d2" {
t.Errorf("期望 PrimaryColor=#1976d2, 得到 %s", theme.PrimaryColor)
}
})
t.Run("创建主题失败-危险脚本", func(t *testing.T) {
req := &service.CreateThemeRequest{
Name: "dangerous-theme",
CustomJS: "<script>alert('xss')</script>",
}
_, err := svc.CreateTheme(ctx, req)
if err == nil {
t.Error("期望返回错误但没有")
}
})
t.Run("创建主题失败-事件处理器", func(t *testing.T) {
req := &service.CreateThemeRequest{
Name: "dangerous-theme-2",
CustomJS: "onclick='alert(1)'",
}
_, err := svc.CreateTheme(ctx, req)
if err == nil {
t.Error("期望返回错误但没有")
}
})
t.Run("创建主题失败-名称重复", func(t *testing.T) {
req := &service.CreateThemeRequest{
Name: "test-theme",
}
_, err := svc.CreateTheme(ctx, req)
if err == nil {
t.Error("期望返回错误但没有")
}
})
}
func TestThemeService_ListThemes(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
// 创建测试数据
svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "theme1"})
svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "theme2"})
t.Run("获取主题列表", func(t *testing.T) {
themes, err := svc.ListThemes(ctx)
if err != nil {
t.Fatalf("ListThemes failed: %v", err)
}
if len(themes) < 2 {
t.Errorf("期望至少2个主题, 得到 %d", len(themes))
}
})
}
func TestThemeService_GetDefaultTheme(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
t.Run("获取默认主题-无数据时返回默认配置", func(t *testing.T) {
theme, err := svc.GetDefaultTheme(ctx)
// 无数据时应返回错误或默认配置
if err != nil && theme == nil {
// 这是预期行为
return
}
if theme != nil && theme.Name == "default" {
// 返回了默认配置
return
}
t.Log("GetDefaultTheme 行为正常")
})
}
func TestThemeService_GetActiveTheme(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
t.Run("获取活动主题", func(t *testing.T) {
theme, err := svc.GetActiveTheme(ctx)
if err != nil {
t.Fatalf("GetActiveTheme failed: %v", err)
}
if theme == nil {
t.Error("主题不应为空")
}
})
}
func TestThemeService_DeleteTheme(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
t.Run("删除不存在的主题", func(t *testing.T) {
err := svc.DeleteTheme(ctx, 9999)
if err == nil {
t.Error("期望返回错误但没有")
}
})
t.Run("删除主题成功", func(t *testing.T) {
theme, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "to-delete"})
err := svc.DeleteTheme(ctx, theme.ID)
if err != nil {
t.Errorf("删除主题失败: %v", err)
}
})
t.Run("删除默认主题失败", func(t *testing.T) {
theme, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "default-theme", IsDefault: true})
err := svc.DeleteTheme(ctx, theme.ID)
if err == nil {
t.Error("期望返回错误但没有")
}
})
}
func TestThemeService_SetDefaultTheme(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
t.Run("设置不存在的主题为默认", func(t *testing.T) {
err := svc.SetDefaultTheme(ctx, 9999)
if err == nil {
t.Error("期望返回错误但没有")
}
})
t.Run("设置禁用的主题为默认失败", func(t *testing.T) {
theme, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "disabled-theme"})
// 禁用主题
disabled := false
svc.UpdateTheme(ctx, theme.ID, &service.UpdateThemeRequest{Enabled: &disabled})
err := svc.SetDefaultTheme(ctx, theme.ID)
if err == nil {
t.Error("期望返回错误但没有")
}
})
}
func TestThemeService_GetTheme(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
t.Run("获取存在的主题", func(t *testing.T) {
created, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "get-theme-test"})
theme, err := svc.GetTheme(ctx, created.ID)
if err != nil {
t.Fatalf("GetTheme failed: %v", err)
}
if theme.Name != "get-theme-test" {
t.Errorf("期望 Name=get-theme-test, 得到 %s", theme.Name)
}
})
t.Run("获取不存在的主题", func(t *testing.T) {
_, err := svc.GetTheme(ctx, 9999)
if err == nil {
t.Error("期望返回错误但没有")
}
})
}
func TestThemeService_ListAllThemes(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
// 创建测试数据
svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "all-theme1"})
svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "all-theme2"})
t.Run("获取所有主题", func(t *testing.T) {
themes, err := svc.ListAllThemes(ctx)
if err != nil {
t.Fatalf("ListAllThemes failed: %v", err)
}
if len(themes) < 2 {
t.Errorf("期望至少2个主题, 得到 %d", len(themes))
}
})
}
func TestThemeService_UpdateTheme(t *testing.T) {
svc, _ := setupThemeServiceTestEnv(t)
ctx := context.Background()
t.Run("更新主题成功", func(t *testing.T) {
created, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "update-theme-test"})
updated, err := svc.UpdateTheme(ctx, created.ID, &service.UpdateThemeRequest{
PrimaryColor: "#ff0000",
})
if err != nil {
t.Fatalf("UpdateTheme failed: %v", err)
}
if updated.PrimaryColor != "#ff0000" {
t.Errorf("期望 PrimaryColor=#ff0000, 得到 %s", updated.PrimaryColor)
}
})
t.Run("更新不存在的主题", func(t *testing.T) {
_, err := svc.UpdateTheme(ctx, 9999, &service.UpdateThemeRequest{})
if err == nil {
t.Error("期望返回错误但没有")
}
})
t.Run("更新主题带危险CSS", func(t *testing.T) {
created, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "update-dangerous"})
_, err := svc.UpdateTheme(ctx, created.ID, &service.UpdateThemeRequest{
CustomCSS: "<script>alert('xss')</script>",
})
if err == nil {
t.Error("期望返回错误但没有")
}
})
}