package home import ( "testing" "time" ) func TestNormalizeToolOK(t *testing.T) { b := "热" tone := "hot" got, err := normalizeTool(ReplaceInput{ RowIndex: 1, SortOrder: 1, Path: "/portrait", Icon: "portrait", Label: "愈心解码", Badge: &b, BadgeTone: &tone, Enabled: true, }) if err != nil || got.Label != "愈心解码" { t.Fatalf("got=%+v err=%v", got, err) } } func TestNormalizeToolRejects(t *testing.T) { cases := []ReplaceInput{ {RowIndex: 3, Path: "/a", Icon: "ask", Label: "x"}, {RowIndex: 1, Path: "https://evil.com", Icon: "ask", Label: "x"}, {RowIndex: 1, Path: "/../etc", Icon: "ask", Label: "x"}, {RowIndex: 1, Path: "/ask", Icon: "nope", Label: "x"}, {RowIndex: 1, Path: "/ask", Icon: "ask", Label: ""}, } for i, c := range cases { if _, err := normalizeTool(c); err != ErrInvalidTools { t.Fatalf("case %d want ErrInvalidTools got %v", i, err) } } } func TestFallbackTipsChangeByDay(t *testing.T) { loc := time.FixedZone("CST", 8*3600) d1 := time.Date(2026, 8, 11, 19, 0, 0, 0, loc) d2 := time.Date(2026, 8, 12, 19, 0, 0, 0, loc) a := fallbackTips(d1, "1990-05-12", nil) b := fallbackTips(d2, "1990-05-12", nil) if a.ClothingIndex == b.ClothingIndex && a.Clothing == b.Clothing && a.Wellness == b.Wellness { t.Fatalf("expected day-varying tips, got same %+v", a) } if a.AsOf == b.AsOf { t.Fatalf("as_of should differ: %s", a.AsOf) } } func TestCurrentShichenBoundaries(t *testing.T) { loc := time.FixedZone("CST", 8*3600) cases := []struct { h, wantIdx int wantName string }{ {23, 0, "子"}, {0, 0, "子"}, {9, 5, "巳"}, {10, 5, "巳"}, {11, 6, "午"}, } for _, c := range cases { now := time.Date(2026, 8, 12, c.h, 15, 0, 0, loc) w := CurrentShichen(now) if w.Index != c.wantIdx || w.Name != c.wantName { t.Fatalf("h=%d got %d %s want %d %s", c.h, w.Index, w.Name, c.wantIdx, c.wantName) } if !w.Start.Before(now) && !w.Start.Equal(now) { t.Fatalf("start should be <= now: %v %v", w.Start, now) } if !w.End.After(now) { t.Fatalf("end should be > now") } } } func TestFallbackTipsChangeByShichen(t *testing.T) { loc := time.FixedZone("CST", 8*3600) a := fallbackTips(time.Date(2026, 8, 12, 9, 0, 0, 0, loc), "1990-05-12", nil) b := fallbackTips(time.Date(2026, 8, 12, 11, 0, 0, 0, loc), "1990-05-12", nil) if a.Clothing == b.Clothing && a.Wellness == b.Wellness && a.ClothingIndex == b.ClothingIndex { t.Fatalf("expected shichen-varying tips") } }