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") } }