aboutsummaryrefslogtreecommitdiff
path: root/internal/validate/p2_hardening_test.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-18 16:13:49 -0400
committerhistoria <[not public]>2026-09-18 16:13:49 -0400
commit194164a77eb4f2479b94c19e6f0e1278ab608781 (patch)
tree53413add8ed6f32a34d1733397e380cc98ef70ef /internal/validate/p2_hardening_test.go
parent67e01aab85607b9e601185c7d62dff576af3bb43 (diff)
downloadthehouseoficarus-194164a77eb4f2479b94c19e6f0e1278ab608781.tar.gz
fix: more casino, economy, gameplay, security, and world data hardening gaps
Diffstat (limited to 'internal/validate/p2_hardening_test.go')
-rw-r--r--internal/validate/p2_hardening_test.go50
1 files changed, 50 insertions, 0 deletions
diff --git a/internal/validate/p2_hardening_test.go b/internal/validate/p2_hardening_test.go
new file mode 100644
index 0000000..68ae48f
--- /dev/null
+++ b/internal/validate/p2_hardening_test.go
@@ -0,0 +1,50 @@
+package validate
+
+import (
+ "path/filepath"
+ "testing"
+)
+
+// TestValidateRejectsNonPositiveExit: an exit with room <= 0 renders as a
+// blocked direction but passes every other check, so it must be reported
+// unless always_blocked: true expresses the intent.
+func TestValidateRejectsNonPositiveExit(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"), "name: Blocked\nexits:\n north:\n room: 0\n")
+ issues := validateRooms(newSource(dir))
+ if !containsMsg(issues, "non-positive") {
+ t.Fatalf("non-positive exit not reported: %+v", issues)
+ }
+}
+
+// TestValidateRejectsEmptyObjectEntry: an objects: entry that is neither a
+// local definition nor a file reference disappears at runtime, so it must be
+// an error instead of a silent no-op.
+func TestValidateRejectsEmptyObjectEntry(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"),
+ "name: Empty\nobjects:\n - aliases: []\n description: []\n hidden: false\n name: \"\"\n")
+ issues := validateRooms(newSource(dir))
+ if !containsMsg(issues, "resolves to nothing") {
+ t.Fatalf("empty object entry not reported: %+v", issues)
+ }
+}
+
+// TestValidateRejectsDropTableInRoomTrigger: room on_enter/on_exit and
+// on_traverse steps consume drop_table like every other trigger block, so a
+// typo'd table id must be reported rather than silently awarding nothing.
+func TestValidateRejectsDropTableInRoomTrigger(t *testing.T) {
+ dir := t.TempDir()
+ writeFile(t, filepath.Join(dir, "rooms", "1.yaml"),
+ "name: Loot\nexits:\n north:\n room: 1\n on_traverse:\n - steps:\n - drop_table:\n - table: no_such_table\n weight: 100\n")
+ if issues := validateRooms(newSource(dir)); !containsMsg(issues, "no_such_table") {
+ t.Fatalf("unknown drop table in an exit trigger not reported: %+v", issues)
+ }
+
+ // on_enter is validated by validateRoomTriggers.
+ writeFile(t, filepath.Join(dir, "rooms", "2.yaml"),
+ "name: Loot2\non_enter:\n - steps:\n - drop_table:\n - table: no_such_table\n weight: 100\n")
+ if issues := validateRoomTriggers(newSource(dir)); !containsMsg(issues, "no_such_table") {
+ t.Fatalf("unknown drop table in on_enter not reported: %+v", issues)
+ }
+}