verstak/cmd/verstak-gui/file_manager_test.go

123 lines
3.3 KiB
Go

package main
import (
"os"
"path/filepath"
"testing"
"verstak/internal/core/nodes"
)
func TestResolveOpenFolderTarget_FileNodeUsesRecordPath(t *testing.T) {
vault := t.TempDir()
got := resolveOpenFolderTarget(vault, &nodes.Node{Type: nodes.TypeFile}, filepath.Join("Parent", "Nested", "file.txt"))
want := filepath.Join(vault, "Parent", "Nested")
if got != want {
t.Fatalf("target = %q, want %q", got, want)
}
got = resolveOpenFolderTarget(vault, &nodes.Node{Type: nodes.TypeFile}, "")
if got != vault {
t.Fatalf("target without file record = %q, want vault %q", got, vault)
}
got = resolveOpenFolderTarget(vault, &nodes.Node{Type: nodes.TypeFile, FsPath: filepath.Join("Parent", "file.txt")}, "")
want = filepath.Join(vault, "Parent")
if got != want {
t.Fatalf("target with fs_path = %q, want %q", got, want)
}
}
func TestFileManagerRecursiveImportListItemsIsFlat(t *testing.T) {
app, _ := setupTestApp(t)
parent, err := app.CreateNodeFromTemplate("", "Files Parent", "folder.default")
if err != nil {
t.Fatalf("create parent: %v", err)
}
sourceRoot := filepath.Join(t.TempDir(), "drop")
if err := os.MkdirAll(filepath.Join(sourceRoot, "nested"), 0o750); err != nil {
t.Fatalf("mkdir source: %v", err)
}
if err := os.WriteFile(filepath.Join(sourceRoot, "root.txt"), []byte("root"), 0o640); err != nil {
t.Fatalf("write root file: %v", err)
}
if err := os.WriteFile(filepath.Join(sourceRoot, "nested", "deep.txt"), []byte("deep"), 0o640); err != nil {
t.Fatalf("write nested file: %v", err)
}
imported, err := app.AddPathCopy(parent.ID, sourceRoot)
if err != nil {
t.Fatalf("AddPathCopy: %v", err)
}
if len(imported) < 4 {
t.Fatalf("imported %d nodes, want folder + nested folder + files", len(imported))
}
rootItems, err := app.ListItems(parent.ID)
if err != nil {
t.Fatalf("ListItems(parent): %v", err)
}
if hasItemNamed(rootItems, "deep.txt") {
t.Fatal("parent file view includes nested file deep.txt")
}
drop := findItem(rootItems, "drop", nodes.TypeFolder)
if drop == nil {
t.Fatalf("parent file view missing imported root folder: %#v", rootItems)
}
dropItems, err := app.ListItems(drop.ID)
if err != nil {
t.Fatalf("ListItems(drop): %v", err)
}
if !hasItemNamed(dropItems, "root.txt") {
t.Fatal("imported root folder missing root.txt")
}
nested := findItem(dropItems, "nested", nodes.TypeFolder)
if nested == nil {
t.Fatalf("imported root folder missing nested folder: %#v", dropItems)
}
nestedItems, err := app.ListItems(nested.ID)
if err != nil {
t.Fatalf("ListItems(nested): %v", err)
}
if !hasItemNamed(nestedItems, "deep.txt") {
t.Fatal("nested folder missing deep.txt")
}
seen := map[string]string{}
for level, items := range map[string][]FileTreeItemDTO{
"parent": rootItems,
"drop": dropItems,
"nested": nestedItems,
} {
for _, item := range items {
if prev, ok := seen[item.ID]; ok {
t.Fatalf("file manager listed ID %s in both %s and %s", item.ID, prev, level)
}
seen[item.ID] = level
}
}
}
func findItem(items []FileTreeItemDTO, name, typ string) *FileTreeItemDTO {
for i := range items {
if items[i].Name == name && items[i].Type == typ {
return &items[i]
}
}
return nil
}
func hasItemNamed(items []FileTreeItemDTO, name string) bool {
for _, item := range items {
if item.Name == name {
return true
}
}
return false
}