add theming

This commit is contained in:
mr0xb 2026-08-24 15:43:03 -04:00
commit 8639799f6d
10 changed files with 1069 additions and 287 deletions

View file

@ -313,7 +313,7 @@ func TestDeriveDailyFilename(t *testing.T) {
func TestGroupByDay_Partitioning(t *testing.T) {
access, errors := makeMultiDayEntries()
days := GroupByDay("report.html", access, errors, nil)
days := GroupByDay("report.html", access, errors, nil, "")
if len(days) != 2 {
t.Fatalf("expected 2 days, got %d", len(days))
}
@ -327,7 +327,7 @@ func TestGroupByDay_Partitioning(t *testing.T) {
func TestGroupByDay_RequestCounts(t *testing.T) {
access, errors := makeMultiDayEntries()
days := GroupByDay("report.html", access, errors, nil)
days := GroupByDay("report.html", access, errors, nil, "")
if days[0].Data.TotalRequests != 1 {
t.Errorf("day1 requests = %d, want 1", days[0].Data.TotalRequests)
}
@ -338,7 +338,7 @@ func TestGroupByDay_RequestCounts(t *testing.T) {
func TestGroupByDay_ErrorPartitioning(t *testing.T) {
access, errors := makeMultiDayEntries()
days := GroupByDay("report.html", access, errors, nil)
days := GroupByDay("report.html", access, errors, nil, "")
if len(days[0].Data.ErrorEntries) != 1 {
t.Errorf("day1 error entries = %d, want 1", len(days[0].Data.ErrorEntries))
}
@ -349,7 +349,7 @@ func TestGroupByDay_ErrorPartitioning(t *testing.T) {
func TestGroupByDay_Filenames(t *testing.T) {
access, errors := makeMultiDayEntries()
days := GroupByDay("report.html", access, errors, nil)
days := GroupByDay("report.html", access, errors, nil, "")
if days[0].Filename != "report-2024-02-20.html" {
t.Errorf("day1 filename = %q, want report-2024-02-20.html", days[0].Filename)
}
@ -364,7 +364,7 @@ func TestGroupByDay_GeoFiltering(t *testing.T) {
"1.1.1.1": {IP: "1.1.1.1", Lat: 37.7, Lon: -97.8, Country: "United States", CountryCode: "US"},
"2.2.2.2": {IP: "2.2.2.2", Lat: 51.5, Lon: -0.1, Country: "United Kingdom", CountryCode: "GB"},
}
days := GroupByDay("report.html", access, errors, geoPoints)
days := GroupByDay("report.html", access, errors, geoPoints, "")
// day1 only has 1.1.1.1
if len(days[0].Data.GeoLocations) != 1 {
t.Errorf("day1 geo = %d, want 1", len(days[0].Data.GeoLocations))
@ -379,7 +379,7 @@ func TestGroupByDay_GeoFiltering(t *testing.T) {
}
func TestGroupByDay_EmptyInput(t *testing.T) {
days := GroupByDay("report.html", nil, nil, nil)
days := GroupByDay("report.html", nil, nil, nil, "")
if len(days) != 0 {
t.Errorf("expected 0 days, got %d", len(days))
}
@ -387,7 +387,7 @@ func TestGroupByDay_EmptyInput(t *testing.T) {
func TestGroupByDay_StatsComputed(t *testing.T) {
access, errors := makeMultiDayEntries()
days := GroupByDay("report.html", access, errors, nil)
days := GroupByDay("report.html", access, errors, nil, "")
// day2 has one 500 → error rate 50%
if days[1].Data.ErrorRate < 49.9 || days[1].Data.ErrorRate > 50.1 {
t.Errorf("day2 error rate = %.2f, want ~50.0", days[1].Data.ErrorRate)
@ -506,6 +506,112 @@ func TestGenerateHTML_NoBackLinkByDefault(t *testing.T) {
}
}
// ── Theme selection ────────────────────────────────────────────────────────
func TestThemeNames_ContainsAllThemes(t *testing.T) {
names := ThemeNames()
for _, want := range []string{"cyberpunk", "purplerain", "cactus"} {
found := false
for _, n := range names {
if n == want {
found = true
break
}
}
if !found {
t.Errorf("ThemeNames() = %v, missing %q", names, want)
}
}
}
func TestGenerateHTML_DefaultThemeWhenEmpty(t *testing.T) {
data := makeTestData()
ComputeStats(&data)
// Theme left as zero value "".
html, err := GenerateHTML(data)
if err != nil {
t.Fatalf("GenerateHTML error: %v", err)
}
if !strings.Contains(html, cyberpunkTheme.Chart1) {
t.Error("expected cyberpunk theme colors when Theme is empty")
}
}
func TestGenerateHTML_UnknownThemeFallsBackToDefault(t *testing.T) {
data := makeTestData()
ComputeStats(&data)
data.Theme = "does-not-exist"
html, err := GenerateHTML(data)
if err != nil {
t.Fatalf("GenerateHTML error: %v", err)
}
if !strings.Contains(html, cyberpunkTheme.Chart1) {
t.Error("expected fallback to cyberpunk theme colors for unknown theme name")
}
}
func TestGenerateHTML_PurplerainTheme(t *testing.T) {
data := makeTestData()
ComputeStats(&data)
data.Theme = "purplerain"
html, err := GenerateHTML(data)
if err != nil {
t.Fatalf("GenerateHTML error: %v", err)
}
if !strings.Contains(html, purplerainTheme.Chart1) {
t.Error("expected purplerain theme colors in output")
}
if strings.Contains(html, cyberpunkTheme.Chart1) {
t.Error("did not expect cyberpunk theme colors when purplerain is selected")
}
}
func TestGenerateHTML_CactusTheme(t *testing.T) {
data := makeTestData()
ComputeStats(&data)
data.Theme = "cactus"
data.GeoLocations = []GeoPoint{
{IP: "1.1.1.1", Lat: 37.751, Lon: -97.822, Country: "United States", CountryCode: "US", Count: 2},
}
html, err := GenerateHTML(data)
if err != nil {
t.Fatalf("GenerateHTML error: %v", err)
}
if !strings.Contains(html, cactusTheme.Chart1) {
t.Error("expected cactus theme colors in output")
}
if !strings.Contains(html, "light_all") {
t.Error("expected cactus theme to use a light map basemap")
}
}
func TestGenerateIndexHTML_ThemeApplied(t *testing.T) {
idx := makeTestIndexData()
idx.Theme = "purplerain"
html, err := GenerateIndexHTML(idx)
if err != nil {
t.Fatalf("GenerateIndexHTML error: %v", err)
}
if !strings.Contains(html, purplerainTheme.Chart1) {
t.Error("expected purplerain theme colors in index output")
}
}
func TestGroupByDay_PropagatesTheme(t *testing.T) {
access, errors := makeMultiDayEntries()
days := GroupByDay("report.html", access, errors, nil, "cactus")
for _, d := range days {
if d.Data.Theme != "cactus" {
t.Errorf("day %s Theme = %q, want cactus", d.Filename, d.Data.Theme)
}
}
}
func TestGenerateHTML_DayTitleInHeader(t *testing.T) {
data := makeTestData()
ComputeStats(&data)