- 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)
276 lines
7.1 KiB
Go
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")
|
|
}
|
|
}
|