diff options
| author | historia <[not public]> | 2026-09-18 16:13:49 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 16:13:49 -0400 |
| commit | 194164a77eb4f2479b94c19e6f0e1278ab608781 (patch) | |
| tree | 53413add8ed6f32a34d1733397e380cc98ef70ef /internal/validate/p2_hardening_test.go | |
| parent | 67e01aab85607b9e601185c7d62dff576af3bb43 (diff) | |
| download | thehouseoficarus-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.go | 50 |
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) + } +} |
