package admin import ( "testing" "time" ) func TestPercentChange(t *testing.T) { if s := percentChange(0, 10); s != "+0%" { t.Fatalf("prev0") } if s := percentChange(10, 15); s == "" { t.Fatalf("empty") } } func TestPreviousWindow(t *testing.T) { s := time.Date(2025, 1, 1, 0, 0, 0, 0, time.Local) e := s.Add(7 * 24 * time.Hour).Add(-time.Second) ps, pe := previousWindow(s, e) if !pe.Before(s) { t.Fatalf("pe not before start") } if ps.After(pe) { t.Fatalf("ps after pe") } } func TestDaysBetween(t *testing.T) { s := time.Date(2025, 1, 1, 0, 0, 0, 0, time.Local) e := time.Date(2025, 1, 03, 23, 59, 59, 0, time.Local) ds := daysBetween(s, e) if len(ds) != 3 { t.Fatalf("expect3") } } func TestParseSalesTrendRange_PrefersStartEnd(t *testing.T) { now := time.Date(2026, 3, 3, 12, 0, 0, 0, time.UTC) s, e := parseSalesTrendRange("week", "2026-01-01", "2026-01-10", now, nil) if !s.Equal(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)) { t.Fatalf("unexpected start: %v", s) } if !e.Equal(time.Date(2026, 1, 10, 23, 59, 59, 0, time.UTC)) { t.Fatalf("unexpected end: %v", e) } } func TestParseSalesTrendRange_AliasAndAllFallback(t *testing.T) { now := time.Date(2026, 3, 3, 12, 0, 0, 0, time.UTC) sWeek, eWeek := parseSalesTrendRange("week", "", "", now, nil) if !eWeek.Equal(now) { t.Fatalf("week end should be now") } if sWeek.Sub(eWeek) != -7*24*time.Hour { t.Fatalf("week should be 7 days") } sMonth, eMonth := parseSalesTrendRange("month", "", "", now, nil) if !eMonth.Equal(now) { t.Fatalf("month end should be now") } if sMonth.Sub(eMonth) != -30*24*time.Hour { t.Fatalf("month should be 30 days") } sAllFallback, eAllFallback := parseSalesTrendRange("all", "", "", now, nil) if !eAllFallback.Equal(now) { t.Fatalf("all fallback end should be now") } if sAllFallback.Sub(eAllFallback) != -30*24*time.Hour { t.Fatalf("all fallback should be 30 days") } allStart := time.Date(2025, 1, 15, 10, 0, 0, 0, time.UTC) sAll, eAll := parseSalesTrendRange("all", "", "", now, &allStart) if !sAll.Equal(time.Date(2025, 1, 15, 0, 0, 0, 0, time.UTC)) { t.Fatalf("all start should align to date start, got: %v", sAll) } if !eAll.Equal(now) { t.Fatalf("all end should be now") } } func TestParseSalesTrendRange_CustomSpanCap(t *testing.T) { now := time.Date(2026, 3, 3, 12, 0, 0, 0, time.UTC) s, e := parseSalesTrendRange("custom", "2025-01-01", "2026-12-31", now, nil) expectedStart := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC) expectedEnd := expectedStart.Add(365 * 24 * time.Hour).Add(-time.Second) if !s.Equal(expectedStart) { t.Fatalf("unexpected custom start: %v", s) } if !e.Equal(expectedEnd) { t.Fatalf("unexpected custom end: %v", e) } } func TestShouldUseMonthlyGranularityForAll(t *testing.T) { start := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC) endLong := start.Add(181 * 24 * time.Hour) endShort := start.Add(180 * 24 * time.Hour) if !shouldUseMonthlyGranularityForAll("all", "day", start, endLong) { t.Fatalf("expected monthly for all with >180 days") } if shouldUseMonthlyGranularityForAll("all", "day", start, endShort) { t.Fatalf("should not switch for exactly 180 days") } if shouldUseMonthlyGranularityForAll("week", "day", start, endLong) { t.Fatalf("non-all rangeType should not switch") } if shouldUseMonthlyGranularityForAll("all", "month", start, endLong) { t.Fatalf("non-day granularity should not switch") } }