aboutsummaryrefslogtreecommitdiff
path: root/internal/admin/fixes_regression_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/admin/fixes_regression_test.go')
-rw-r--r--internal/admin/fixes_regression_test.go49
1 files changed, 49 insertions, 0 deletions
diff --git a/internal/admin/fixes_regression_test.go b/internal/admin/fixes_regression_test.go
new file mode 100644
index 0000000..3d7d19f
--- /dev/null
+++ b/internal/admin/fixes_regression_test.go
@@ -0,0 +1,49 @@
+package admin
+
+import (
+ "path/filepath"
+ "testing"
+)
+
+// TestResolveRoomSubdirRejectsEscape covers the traversal guard used by the
+// room-directory API handlers (rename dir, move room, create empty room, bulk
+// edit). Every escaping form must be rejected.
+func TestResolveRoomSubdirRejectsEscape(t *testing.T) {
+ s := &AdminServer{dataDir: t.TempDir()}
+ for _, bad := range []string{"..", "../items", "../../etc", "/etc", "a/../../b", `..\items`, "town/../../x"} {
+ if _, err := s.resolveRoomSubdir(bad); err == nil {
+ t.Fatalf("accepted escaping dir %q", bad)
+ }
+ }
+ for _, ok := range []string{"", ".", "town", "town/sub"} {
+ got, err := s.resolveRoomSubdir(ok)
+ if err != nil {
+ t.Fatalf("rejected valid dir %q: %v", ok, err)
+ }
+ if ok != "" && ok != "." && got != filepath.FromSlash(ok) {
+ t.Fatalf("dir %q resolved to %q", ok, got)
+ }
+ }
+}
+
+// TestUndoHistorySurvivesReload: the editor documents that undo history is
+// persisted across sessions; NewUndoStack must load what save wrote.
+func TestUndoHistorySurvivesReload(t *testing.T) {
+ dir := t.TempDir()
+ us := NewUndoStack(dir)
+ us.Push(ChangeDesc{
+ Description: "edit x",
+ FilePath: filepath.Join(dir, "x.yaml"),
+ OldContent: []byte("old"),
+ NewContent: []byte("new"),
+ })
+
+ reloaded := NewUndoStack(dir)
+ info := reloaded.Info()
+ if !info.CanUndo || info.StackSize != 1 {
+ t.Fatalf("history did not survive reload: %+v", info)
+ }
+ if info.UndoDesc == "" {
+ t.Fatal("undo description empty after reload")
+ }
+}