package util import "testing" func TestFormatDate(t *testing.T) { tests := []struct { iso, date, dateTime string }{ {"2024-03-05T07:08:09.123Z", "2024-03-05", "2024-03-05 07:08:09 UTC"}, {"2024-12-31T23:59:59Z", "2024-12-31", "2024-12-31 23:59:59 UTC"}, // A non-UTC offset is converted to UTC, which moves the day. {"2024-01-01T01:00:00+02:00", "2023-12-31", "2023-12-31 23:00:00 UTC"}, // git's %ci / %ai format, converted to UTC. {"2025-01-02 10:00:00 +0000", "2025-01-02", "2025-01-02 10:00:00 UTC"}, {"2024-05-01 12:00:00 +0200", "2024-05-01", "2024-05-01 10:00:00 UTC"}, // A stored commit date in RFC 1123 form. {"Thu, 2 Jan 2025 10:00:00 +0000", "2025-01-02", "2025-01-02 10:00:00 UTC"}, {"not a date", "not a date", "not a date"}, {"", "", ""}, } for _, tt := range tests { if got := FormatDate(tt.iso); got != tt.date { t.Errorf("FormatDate(%q) = %q, want %q", tt.iso, got, tt.date) } if got := FormatDateTime(tt.iso); got != tt.dateTime { t.Errorf("FormatDateTime(%q) = %q, want %q", tt.iso, got, tt.dateTime) } } } func TestLabelTextColor(t *testing.T) { tests := []struct{ hex, want string }{ {"#ffffff", "#000000"}, {"#000000", "#ffffff"}, {"#ffff00", "#000000"}, {"#0000ff", "#ffffff"}, {"#808080", "#000000"}, // 128/255 is just above the 0.5 threshold {"bogus", "#ffffff"}, } for _, tt := range tests { if got := LabelTextColor(tt.hex); got != tt.want { t.Errorf("LabelTextColor(%q) = %q, want %q", tt.hex, got, tt.want) } } } func TestPaginate(t *testing.T) { tests := []struct { raw, total, per int want Page }{ {1, 0, 20, Page{1, 1, 0}}, {999, 45, 20, Page{3, 3, 40}}, {0, 45, 20, Page{1, 3, 0}}, {2, 45, 20, Page{2, 3, 20}}, } for _, tt := range tests { if got := Paginate(tt.raw, tt.total, tt.per); got != tt.want { t.Errorf("Paginate(%d,%d,%d) = %+v, want %+v", tt.raw, tt.total, tt.per, got, tt.want) } } } func TestContentDisposition(t *testing.T) { tests := []struct{ in, want string }{ {"a.txt", `attachment; filename="a.txt"; filename*=UTF-8''a.txt`}, {`dir/e"vil.txt`, `attachment; filename="e_vil.txt"; filename*=UTF-8''e%22vil.txt`}, {"ü.txt", `attachment; filename="ü.txt"; filename*=UTF-8''%C3%BC.txt`}, {"", `attachment; filename="file"; filename*=UTF-8''`}, {"it's.txt", `attachment; filename="it's.txt"; filename*=UTF-8''it%27s.txt`}, } for _, tt := range tests { if got := ContentDisposition("attachment", tt.in); got != tt.want { t.Errorf("ContentDisposition(%q) =\n%q\nwant\n%q", tt.in, got, tt.want) } } } func TestValidNames(t *testing.T) { for _, s := range []string{"ab", "a-b_1"} { if !ValidUsername(s) { t.Errorf("ValidUsername(%q) = false", s) } } for _, s := range []string{"", "a.b", "a b", "a/b"} { if ValidUsername(s) { t.Errorf("ValidUsername(%q) = true", s) } } } func TestFormatDateTimeSQLite(t *testing.T) { if got := FormatDateTime("2026-09-15 12:14:56"); got != "2026-09-15 12:14:56 UTC" { t.Fatalf("got %q", got) } }