109 lines
3.3 KiB
Go
109 lines
3.3 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"telesrv/internal/domain"
|
|
)
|
|
|
|
func sampleTheme(id, creator int64, slug string) domain.Theme {
|
|
return domain.Theme{
|
|
ID: id,
|
|
AccessHash: id + 1,
|
|
CreatorUserID: creator,
|
|
Slug: slug,
|
|
Title: "T",
|
|
DocumentID: 9000 + id,
|
|
Settings: []domain.ThemeSettingsSpec{{
|
|
BaseTheme: domain.ThemeBaseDay,
|
|
AccentColor: 0x112233,
|
|
MessageColors: []int{0xaa, 0xbb},
|
|
Wallpaper: &domain.ThemeWallpaperSpec{BackgroundColors: []int{0x1, 0x2}},
|
|
}},
|
|
CreatedAt: 1700000000,
|
|
}
|
|
}
|
|
|
|
func TestMemoryThemeStoreContract(t *testing.T) {
|
|
ctx := context.Background()
|
|
s := NewThemeStore()
|
|
|
|
// 未命中读 → (zero,false,nil)。
|
|
if _, ok, err := s.GetThemeByID(ctx, 1); ok || err != nil {
|
|
t.Fatalf("get missing = ok %v err %v", ok, err)
|
|
}
|
|
|
|
a := sampleTheme(101, 7, "alpha")
|
|
if err := s.CreateTheme(ctx, a); err != nil {
|
|
t.Fatalf("create a: %v", err)
|
|
}
|
|
// slug 冲突。
|
|
if err := s.CreateTheme(ctx, sampleTheme(102, 7, "alpha")); !errors.Is(err, domain.ErrThemeSlugTaken) {
|
|
t.Fatalf("dup slug err = %v, want ErrThemeSlugTaken", err)
|
|
}
|
|
|
|
got, ok, err := s.GetThemeByID(ctx, 101)
|
|
if err != nil || !ok {
|
|
t.Fatalf("get a by id = ok %v err %v", ok, err)
|
|
}
|
|
if got.Slug != "alpha" || len(got.Settings) != 1 || got.Settings[0].BaseTheme != domain.ThemeBaseDay {
|
|
t.Fatalf("round-trip mismatch: %+v", got)
|
|
}
|
|
// Clone 隔离:改返回值不污染内部。
|
|
got.Settings[0].MessageColors[0] = 0xffff
|
|
if again, _, _ := s.GetThemeByID(ctx, 101); again.Settings[0].MessageColors[0] != 0xaa {
|
|
t.Fatalf("clone leak: internal mutated to %#x", again.Settings[0].MessageColors[0])
|
|
}
|
|
|
|
if bySlug, ok, _ := s.GetThemeBySlug(ctx, "alpha"); !ok || bySlug.ID != 101 {
|
|
t.Fatalf("get by slug = ok %v id %d", ok, bySlug.ID)
|
|
}
|
|
|
|
// update 不存在 → ErrThemeNotFound。
|
|
if err := s.UpdateTheme(ctx, sampleTheme(999, 7, "ghost")); !errors.Is(err, domain.ErrThemeNotFound) {
|
|
t.Fatalf("update missing err = %v, want ErrThemeNotFound", err)
|
|
}
|
|
|
|
// IncrementInstalls。
|
|
if err := s.IncrementInstalls(ctx, 101); err != nil {
|
|
t.Fatalf("increment: %v", err)
|
|
}
|
|
if got, _, _ := s.GetThemeByID(ctx, 101); got.InstallsCount != 1 {
|
|
t.Fatalf("installs = %d, want 1", got.InstallsCount)
|
|
}
|
|
|
|
// 安装列表顺序按安装先后。
|
|
b := sampleTheme(103, 7, "beta")
|
|
if err := s.CreateTheme(ctx, b); err != nil {
|
|
t.Fatalf("create b: %v", err)
|
|
}
|
|
const user = int64(55)
|
|
if err := s.SetInstalled(ctx, user, 103, false); err != nil {
|
|
t.Fatalf("install 103: %v", err)
|
|
}
|
|
if err := s.SetInstalled(ctx, user, 101, true); err != nil {
|
|
t.Fatalf("install 101: %v", err)
|
|
}
|
|
list, err := s.ListInstalledByUser(ctx, user)
|
|
if err != nil || len(list) != 2 {
|
|
t.Fatalf("list installed = %d err %v, want 2", len(list), err)
|
|
}
|
|
if list[0].ID != 103 || list[1].ID != 101 {
|
|
t.Fatalf("install order = [%d,%d], want [103,101]", list[0].ID, list[1].ID)
|
|
}
|
|
|
|
// 移除。
|
|
if err := s.RemoveInstalled(ctx, user, 103); err != nil {
|
|
t.Fatalf("remove: %v", err)
|
|
}
|
|
if list, _ := s.ListInstalledByUser(ctx, user); len(list) != 1 || list[0].ID != 101 {
|
|
t.Fatalf("after remove = %+v, want [101]", list)
|
|
}
|
|
|
|
// 安装不存在的主题 → ErrThemeNotFound。
|
|
if err := s.SetInstalled(ctx, user, 88888, false); !errors.Is(err, domain.ErrThemeNotFound) {
|
|
t.Fatalf("install missing theme err = %v, want ErrThemeNotFound", err)
|
|
}
|
|
}
|