Files
user-system/internal/repository/theme_repository_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

276 lines
7.1 KiB
Go

package repository
import (
"context"
"fmt"
"sync/atomic"
"testing"
gormsqlite "gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
_ "modernc.org/sqlite"
"github.com/user-management-system/internal/domain"
)
var themeTestCounter int64
// openThemeTestDB 为每个测试打开独立的内存数据库
func openThemeTestDB(t *testing.T) *gorm.DB {
t.Helper()
id := atomic.AddInt64(&themeTestCounter, 1)
dsn := fmt.Sprintf("file:themetestdb%d?mode=memory&cache=private", id)
db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
DriverName: "sqlite",
DSN: dsn,
}), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if err != nil {
t.Fatalf("打开测试数据库失败: %v", err)
}
if err := db.AutoMigrate(&domain.ThemeConfig{}); err != nil {
t.Fatalf("数据库迁移失败: %v", err)
}
return db
}
// setupThemeTestDB 兼容性别名
func setupThemeTestDB(t *testing.T) *gorm.DB {
return openThemeTestDB(t)
}
// TestThemeConfigRepository_Create 测试创建主题
func TestThemeConfigRepository_Create(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
theme := &domain.ThemeConfig{
Name: "test-theme",
PrimaryColor: "#ff0000",
SecondaryColor: "#00ff00",
Enabled: true,
}
if err := repo.Create(ctx, theme); err != nil {
t.Fatalf("Create() error = %v", err)
}
if theme.ID == 0 {
t.Error("创建后主题ID不应为0")
}
}
// TestThemeConfigRepository_GetByID 测试根据ID获取主题
func TestThemeConfigRepository_GetByID(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
theme := &domain.ThemeConfig{
Name: "getbyid-theme",
PrimaryColor: "#0000ff",
Enabled: true,
}
repo.Create(ctx, theme)
found, err := repo.GetByID(ctx, theme.ID)
if err != nil {
t.Fatalf("GetByID() error = %v", err)
}
if found.Name != "getbyid-theme" {
t.Errorf("Name = %v, want getbyid-theme", found.Name)
}
}
// TestThemeConfigRepository_GetByName 测试根据名称获取主题
func TestThemeConfigRepository_GetByName(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
theme := &domain.ThemeConfig{
Name: "unique-theme-name",
PrimaryColor: "#ffff00",
Enabled: true,
}
repo.Create(ctx, theme)
found, err := repo.GetByName(ctx, "unique-theme-name")
if err != nil {
t.Fatalf("GetByName() error = %v", err)
}
if found.ID != theme.ID {
t.Errorf("ID = %v, want %v", found.ID, theme.ID)
}
}
// TestThemeConfigRepository_GetByName_NotFound 测试名称不存在
func TestThemeConfigRepository_GetByName_NotFound(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
_, err := repo.GetByName(ctx, "not-exist-theme")
if err == nil {
t.Error("GetByName() should return error for non-existent theme")
}
}
// TestThemeConfigRepository_Update 测试更新主题
func TestThemeConfigRepository_Update(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
theme := &domain.ThemeConfig{
Name: "update-test",
PrimaryColor: "#000000",
Enabled: true,
}
repo.Create(ctx, theme)
theme.PrimaryColor = "#ffffff"
if err := repo.Update(ctx, theme); err != nil {
t.Fatalf("Update() error = %v", err)
}
found, _ := repo.GetByID(ctx, theme.ID)
if found.PrimaryColor != "#ffffff" {
t.Errorf("PrimaryColor = %v, want #ffffff", found.PrimaryColor)
}
}
// TestThemeConfigRepository_Delete 测试删除主题
func TestThemeConfigRepository_Delete(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
theme := &domain.ThemeConfig{
Name: "delete-test",
Enabled: true,
}
repo.Create(ctx, theme)
if err := repo.Delete(ctx, theme.ID); err != nil {
t.Fatalf("Delete() error = %v", err)
}
_, err := repo.GetByID(ctx, theme.ID)
if err == nil {
t.Error("删除后查询应返回错误")
}
}
// TestThemeConfigRepository_List 测试获取已启用主题列表
func TestThemeConfigRepository_List(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
repo.Create(ctx, &domain.ThemeConfig{Name: "enabled1", Enabled: true})
repo.Create(ctx, &domain.ThemeConfig{Name: "enabled2", Enabled: true})
repo.Create(ctx, &domain.ThemeConfig{Name: "disabled1", Enabled: false})
themes, err := repo.List(ctx)
if err != nil {
t.Fatalf("List() error = %v", err)
}
// List filters by enabled=true
if len(themes) < 2 {
t.Errorf("len(themes) = %d, want at least 2", len(themes))
}
}
// TestThemeConfigRepository_ListAll 测试获取所有主题列表
func TestThemeConfigRepository_ListAll(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
repo.Create(ctx, &domain.ThemeConfig{Name: "all1", Enabled: true})
repo.Create(ctx, &domain.ThemeConfig{Name: "all2", Enabled: false})
themes, err := repo.ListAll(ctx)
if err != nil {
t.Fatalf("ListAll() error = %v", err)
}
if len(themes) != 2 {
t.Errorf("len(themes) = %d, want 2", len(themes))
}
}
// TestThemeConfigRepository_GetDefault 测试获取默认主题
func TestThemeConfigRepository_GetDefault(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
// 创建一个默认主题
repo.Create(ctx, &domain.ThemeConfig{
Name: "default-theme",
IsDefault: true,
Enabled: true,
})
defaultTheme, err := repo.GetDefault(ctx)
if err != nil {
t.Fatalf("GetDefault() error = %v", err)
}
if defaultTheme.Name != "default-theme" {
t.Errorf("Name = %v, want default-theme", defaultTheme.Name)
}
}
// TestThemeConfigRepository_GetDefault_NoDefault 测试无默认主题时返回默认配置
func TestThemeConfigRepository_GetDefault_NoDefault(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
// 不创建任何主题
defaultTheme, err := repo.GetDefault(ctx)
if err != nil {
t.Fatalf("GetDefault() error = %v", err)
}
// 应该返回内置默认配置
if defaultTheme.Name != "default" {
t.Errorf("Name = %v, want default", defaultTheme.Name)
}
}
// TestThemeConfigRepository_SetDefault 测试设置默认主题
func TestThemeConfigRepository_SetDefault(t *testing.T) {
db := setupThemeTestDB(t)
repo := NewThemeConfigRepository(db)
ctx := context.Background()
// 创建两个主题
theme1 := &domain.ThemeConfig{Name: "theme1", IsDefault: true, Enabled: true}
theme2 := &domain.ThemeConfig{Name: "theme2", IsDefault: false, Enabled: true}
repo.Create(ctx, theme1)
repo.Create(ctx, theme2)
// 设置 theme2 为默认
if err := repo.SetDefault(ctx, theme2.ID); err != nil {
t.Fatalf("SetDefault() error = %v", err)
}
// 验证 theme1 不再是默认
t1, _ := repo.GetByID(ctx, theme1.ID)
if t1.IsDefault {
t.Error("theme1 should not be default anymore")
}
// 验证 theme2 现在是默认
t2, _ := repo.GetByID(ctx, theme2.ID)
if !t2.IsDefault {
t.Error("theme2 should be default")
}
}