package main import ( "os" "path/filepath" "strings" "testing" ) func TestListTrashShowsDeletedNodesAndPhysicalEntries(t *testing.T) { app, _ := setupTestApp(t) n, err := app.CreateNodeFromTemplate("", "Trash Me", "folder.default") if err != nil { t.Fatalf("create node: %v", err) } if err := app.DeleteNode(n.ID); err != nil { t.Fatalf("DeleteNode: %v", err) } trash, err := app.ListTrash() if err != nil { t.Fatalf("ListTrash: %v", err) } var foundNode bool for _, node := range trash.Nodes { if node.ID == n.ID && node.Title == "Trash Me" && node.DeletedAt != "" { foundNode = true break } } if !foundNode { t.Fatalf("deleted node %s missing from trash nodes: %#v", n.ID, trash.Nodes) } var foundPhysical bool for _, entry := range trash.Entries { if strings.Contains(entry.Name, n.ID) && entry.IsDir { foundPhysical = true break } } if !foundPhysical { t.Fatalf("physical trash entry for %s missing: %#v", n.ID, trash.Entries) } } func TestRestoreTrashNodeRestoresAncestorPathOnlyForSelectedChild(t *testing.T) { app, vault := setupTestApp(t) parent, err := app.CreateNodeFromTemplate("", "Documents", "folder.default") if err != nil { t.Fatalf("create parent: %v", err) } child, err := app.CreateNodeFromTemplate(parent.ID, "Specs", "folder.default") if err != nil { t.Fatalf("create child: %v", err) } other, err := app.CreateNodeFromTemplate(parent.ID, "Drafts", "folder.default") if err != nil { t.Fatalf("create other: %v", err) } if err := app.DeleteNode(parent.ID); err != nil { t.Fatalf("DeleteNode: %v", err) } if err := app.RestoreTrashNode(child.ID); err != nil { t.Fatalf("RestoreTrashNode(child): %v", err) } for _, id := range []string{parent.ID, child.ID} { if _, err := app.nodes.GetActive(id); err != nil { t.Fatalf("node %s should be active after restore: %v", id, err) } } if _, err := app.nodes.GetActive(other.ID); err == nil { t.Fatalf("unselected sibling should remain deleted") } if _, err := os.Stat(filepath.Join(vault, "Documents", "Specs")); err != nil { t.Fatalf("restored child path missing: %v", err) } } func TestRestoreTrashNodeFromNestedDeletedFolderRestoresFullPath(t *testing.T) { app, vault := setupTestApp(t) parent, err := app.CreateNodeFromTemplate("", "Verstak", "folder.default") if err != nil { t.Fatalf("create parent: %v", err) } templates, err := app.CreateNodeFromTemplate(parent.ID, "templates", "folder.default") if err != nil { t.Fatalf("create templates: %v", err) } registry, err := app.CreateNodeFromTemplate(templates.ID, "registry.go", "folder.default") if err != nil { t.Fatalf("create registry: %v", err) } other, err := app.CreateNodeFromTemplate(templates.ID, "other.go", "folder.default") if err != nil { t.Fatalf("create other: %v", err) } if err := app.DeleteNode(parent.ID); err != nil { t.Fatalf("DeleteNode: %v", err) } if err := app.RestoreTrashNode(registry.ID); err != nil { t.Fatalf("RestoreTrashNode(registry): %v", err) } for _, id := range []string{parent.ID, templates.ID, registry.ID} { if _, err := app.nodes.GetActive(id); err != nil { t.Fatalf("node %s should be active after restore: %v", id, err) } } if _, err := app.nodes.GetActive(other.ID); err == nil { t.Fatalf("unselected nested sibling should remain deleted") } if _, err := os.Stat(filepath.Join(vault, "Verstak", "templates", "registry.go")); err != nil { t.Fatalf("restored nested path missing: %v", err) } } func TestTrashCountPurgeAndEmpty(t *testing.T) { app, _ := setupTestApp(t) a, _ := app.CreateNodeFromTemplate("", "Trash A", "folder.default") b, _ := app.CreateNodeFromTemplate("", "Trash B", "folder.default") if err := app.DeleteNode(a.ID); err != nil { t.Fatalf("delete A: %v", err) } if err := app.DeleteNode(b.ID); err != nil { t.Fatalf("delete B: %v", err) } count, err := app.TrashCount() if err != nil { t.Fatalf("TrashCount: %v", err) } if count != 2 { t.Fatalf("TrashCount = %d, want 2", count) } if err := app.PurgeTrashNodesJSON(`["` + a.ID + `"]`); err != nil { t.Fatalf("PurgeTrashNodesJSON: %v", err) } count, _ = app.TrashCount() if count != 1 { t.Fatalf("TrashCount after purge = %d, want 1", count) } if err := app.EmptyTrash(); err != nil { t.Fatalf("EmptyTrash: %v", err) } count, _ = app.TrashCount() if count != 0 { t.Fatalf("TrashCount after empty = %d, want 0", count) } }