aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/api_colors_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/admin/api_colors_test.go')
-rw-r--r--internal/admin/api_colors_test.go70
1 files changed, 67 insertions, 3 deletions
diff --git a/internal/admin/api_colors_test.go b/internal/admin/api_colors_test.go
index cb63714..1f5d3eb 100644
--- a/internal/admin/api_colors_test.go
+++ b/internal/admin/api_colors_test.go
@@ -17,7 +17,7 @@ func newColorsTestServer(t *testing.T) (*AdminServer, string) {
t.Helper()
dir := t.TempDir()
path := filepath.Join(dir, "config.yaml")
- if err := os.WriteFile(path, []byte("tick_length: 600\ndefault_colors:\n room_name: \"74 bold\"\n"), 0644); err != nil {
+ if err := os.WriteFile(path, []byte("tick_length: 600\ndefault_colors:\n room_name: \"74 bold\"\nconstant_colors:\n hp_bar_low: \"A7\"\n"), 0644); err != nil {
t.Fatal(err)
}
loaded, err := config.Load(path)
@@ -43,8 +43,12 @@ func TestColorsGet(t *testing.T) {
if len(cats) != len(colorCategories) {
t.Fatalf("categories count: got %d want %d", len(cats), len(colorCategories))
}
+ constCats, _ := out["constant_categories"].([]any)
+ if len(constCats) != len(constantCategories) {
+ t.Fatalf("constant_categories count: got %d want %d", len(constCats), len(constantCategories))
+ }
preview, _ := out["preview"].([]any)
- if len(preview) < 6 {
+ if len(preview) < 7 {
t.Fatalf("preview sections too few: %d", len(preview))
}
}
@@ -103,6 +107,53 @@ func TestColorsSaveRejectsUnknownKey(t *testing.T) {
}
}
+func TestConstantsSaveAndPersist(t *testing.T) {
+ s, path := newColorsTestServer(t)
+ before, ok := s.cfg.ConstantColors["hp_bar_low"]
+ if !ok || before == "" {
+ t.Fatalf("constant not pre-populated: got %q", before)
+ }
+ body := map[string]any{"constant_colors": map[string]string{"hp_bar_low": "FF bold"}}
+ b, _ := json.Marshal(body)
+ req := httptest.NewRequest(http.MethodPost, "/api/colors", bytes.NewReader(b))
+ req.Header.Set("Content-Type", "application/json")
+ w := httptest.NewRecorder()
+ s.saveColors(w, req)
+ if w.Code != http.StatusOK {
+ t.Fatalf("save status %d: %s", w.Code, w.Body.String())
+ }
+ if s.cfg.ConstantColors["hp_bar_low"] == before {
+ t.Fatalf("constant live map not updated")
+ }
+ if s.cfg.ConstantColors["hp_bar_low"] != "FF bold" {
+ t.Fatalf("constant live value = %q", s.cfg.ConstantColors["hp_bar_low"])
+ }
+ if s.cfg.DefaultColors["room_name"] != "74 bold" {
+ t.Fatalf("player color leaked from constant save: room_name=%q", s.cfg.DefaultColors["room_name"])
+ }
+ raw, err := os.ReadFile(path)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Contains(raw, []byte("FF bold")) {
+ t.Fatalf("config.yaml not persisted with new constant value; got:\n%s", string(raw))
+ }
+}
+
+func TestConstantsSaveRejectsPlayerKey(t *testing.T) {
+ s, _ := newColorsTestServer(t)
+ // Player categories like "room_name" are not legal constant keys.
+ body := map[string]any{"constant_colors": map[string]string{"room_name": "FF"}}
+ b, _ := json.Marshal(body)
+ req := httptest.NewRequest(http.MethodPost, "/api/colors", bytes.NewReader(b))
+ req.Header.Set("Content-Type", "application/json")
+ w := httptest.NewRecorder()
+ s.saveColors(w, req)
+ if w.Code != http.StatusBadRequest {
+ t.Fatalf("expected 400, got %d: %s", w.Code, w.Body.String())
+ }
+}
+
func TestColorsOffAllowed(t *testing.T) {
s, _ := newColorsTestServer(t)
body := map[string]any{"colors": map[string]string{"mob": "off"}}
@@ -119,6 +170,7 @@ func TestColorsOffAllowed(t *testing.T) {
func TestColorsReset(t *testing.T) {
s, _ := newColorsTestServer(t)
s.cfg.DefaultColors["room_name"] = "FF"
+ s.cfg.ConstantColors["hp_bar_low"] = "FF"
req := httptest.NewRequest(http.MethodPost, "/api/colors/reset", nil)
w := httptest.NewRecorder()
s.handleColorsReset(w, req)
@@ -128,6 +180,9 @@ func TestColorsReset(t *testing.T) {
if s.cfg.DefaultColors["room_name"] != "74 bold" {
t.Fatalf("reset did not restore builtin; got %q", s.cfg.DefaultColors["room_name"])
}
+ if s.cfg.ConstantColors["hp_bar_low"] != "A7" {
+ t.Fatalf("constant reset did not restore builtin; got %q", s.cfg.ConstantColors["hp_bar_low"])
+ }
}
func TestColorsPreviewExhaustive(t *testing.T) {
@@ -153,12 +208,21 @@ func TestColorsPreviewExhaustive(t *testing.T) {
for _, cat := range colorCategories {
if cat.Name == "currency_pickup" ||
cat.Name == "map_blocked" || cat.Name == "sequence" ||
- cat.Name == "science_mod" {
+ cat.Name == "science_mod" ||
+ // `error` and `warning` used to be previewed as HP-bar proxies;
+ // the bars now paint with the real hp_bar_* constants, so these
+ // two combat-message categories have no natural example slot.
+ cat.Name == "error" || cat.Name == "warning" {
continue
}
if !seen[cat.Name] {
t.Errorf("preview missing category: %s", cat.Name)
}
}
+ for _, cat := range constantCategories {
+ if !seen[cat.Name] {
+ t.Errorf("preview missing constant category: %s", cat.Name)
+ }
+ }
_ = io.Discard
} \ No newline at end of file