Files
felhom-controller/controller/internal/web/funcmap_test.go
T
admin 5dc277f2b1 D0 Part 2: design system v2 — tokens, meter/tag/metarow, funcmap remap, dashboard + stacks
- style.css: navy token palette (--bg-0/1/2, --line, --text-1/2/3, --blue,
  --warn, --crit), single 2px radius, all box-shadows and the bg grid
  overlay removed, fonts via --font-ui/--font-data.
- Components: .meter (3px hairline track, blue nominal fill, neutral
  70/85 ticks, warn/crit flag), .tag (square 2px state chip + dot, pulse
  on progress, reduced-motion respected), .metarow (icon + text, no
  container), .panel/.list/.section-h primitives, boxless .stats with
  hairline dividers, buttons 2px (danger = crit outline).
- funcmap: stateColor -> run/progress/warn/neutral/off (stopped is
  neutral, NOT red — operator-approved exception-color change),
  usageColor/tempColor -> nominal/warn/crit (thresholds unchanged);
  stateLabel Hungarian copy untouched (guarded by test).
- layout.html: sprite nav icons (layout-grid/cloud/shield/cpu/wrench/
  settings), alert banner emoji -> triangle-alert/info icons.
- dashboard.html: meters with disk warn/crit flags (Fogyóban a hely /
  Kritikusan kevés hely), boxless stats (Leállítva 0 muted, >0 amber),
  single-panel stack list with 2px state edges, tags instead of badges,
  icon action buttons.
- stacks.html: state tag + metarow rows; catalog keeps its grid.
- setup minimalCSS retokened to v2 (drops GitHub-dark hexes).
- Tests: §8 truth tables for stateColor/usageColor/tempColor +
  stateLabel byte-identity guard (red-proven vs pre-change funcmap:
  stopped->red and 0->green failed as required).
2026-07-02 14:22:27 +02:00

114 lines
3.0 KiB
Go

package web
import (
"testing"
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
)
// TASK-D0 §8 truth tables. These are the semantic contract of the v2 re-skin:
// every class suffix the templates key on comes from these three functions.
func TestStateColorTruthTable(t *testing.T) {
s := &Server{}
fm := s.templateFuncMap()
stateColor := fm["stateColor"].(func(stacks.ContainerState) string)
cases := []struct {
state stacks.ContainerState
want string
}{
{stacks.StateRunning, "run"},
{stacks.StateStarting, "progress"},
{stacks.StateDeploying, "progress"},
{stacks.StateUnhealthy, "warn"},
{stacks.StateRestarting, "warn"}, // a restart loop is a problem, not progress
{stacks.StateStopped, "neutral"}, // deliberately NOT red — customer-stopped is not an emergency
{stacks.StateExited, "neutral"},
{stacks.StatePaused, "neutral"},
{stacks.StateNotDeployed, "off"},
{stacks.ContainerState("bogus"), "off"},
}
for _, c := range cases {
if got := stateColor(c.state); got != c.want {
t.Errorf("stateColor(%q) = %q, want %q", c.state, got, c.want)
}
}
}
func TestUsageColorTruthTable(t *testing.T) {
s := &Server{}
fm := s.templateFuncMap()
usageColor := fm["usageColor"].(func(float64) string)
cases := []struct {
percent float64
want string
}{
{0, "nominal"},
{69.9, "nominal"},
{70, "warn"},
{84.9, "warn"},
{85, "crit"},
{100, "crit"},
}
for _, c := range cases {
if got := usageColor(c.percent); got != c.want {
t.Errorf("usageColor(%v) = %q, want %q", c.percent, got, c.want)
}
}
}
func TestTempColorTruthTable(t *testing.T) {
s := &Server{}
fm := s.templateFuncMap()
tempColor := fm["tempColor"].(func(float64) string)
// thresholds unchanged from v1: >75 crit, >=60 warn, else nominal
cases := []struct {
celsius float64
want string
}{
{40, "nominal"},
{59.9, "nominal"},
{60, "warn"},
{75, "warn"},
{75.1, "crit"},
{90, "crit"},
}
for _, c := range cases {
if got := tempColor(c.celsius); got != c.want {
t.Errorf("tempColor(%v) = %q, want %q", c.celsius, got, c.want)
}
}
}
// TestStateLabelUnchanged guards the Hungarian copy against accidental edits
// during the re-skin — labels must stay byte-identical to pre-D0.
func TestStateLabelUnchanged(t *testing.T) {
s := &Server{}
fm := s.templateFuncMap()
stateLabel := fm["stateLabel"].(func(stacks.ContainerState) string)
cases := []struct {
state stacks.ContainerState
want string
}{
{stacks.StateRunning, "Fut"},
{stacks.StateStarting, "Indulás..."},
{stacks.StateDeploying, "Telepítés..."},
{stacks.StateUnhealthy, "Nem egészséges"},
{stacks.StateStopped, "Leállítva"},
{stacks.StateExited, "Leállítva"},
{stacks.StateRestarting, "Újraindítás..."},
{stacks.StateNotDeployed, "Nincs telepítve"},
{stacks.StatePaused, "Szüneteltetve"},
{stacks.ContainerState("bogus"), "Ismeretlen"},
}
for _, c := range cases {
if got := stateLabel(c.state); got != c.want {
t.Errorf("stateLabel(%q) = %q, want %q", c.state, got, c.want)
}
}
}