package client import ( "fmt" "os" "path/filepath" "testing" ) func TestContainsPathTraversal(t *testing.T) { cases := []struct { path string want bool }{ {"", false}, {"/home/user/docs", false}, {"C:\\Users\\alice", false}, {"~/Downloads", false}, {"../etc/passwd", true}, {"/home/user/../../etc", true}, {"foo/../bar", true}, } for _, tc := range cases { if got := containsPathTraversal(tc.path); got != tc.want { t.Errorf("containsPathTraversal(%q) = %v, want %v", tc.path, got, tc.want) } } } func TestResolveListDirPathRejectsTraversal(t *testing.T) { _, err := resolveListDirPath("../outside") if err == nil { t.Fatal("expected traversal error") } } func TestResolveListDirPathEmptyUsesHome(t *testing.T) { home, err := os.UserHomeDir() if err != nil { t.Skip("no home dir") } for _, input := range []string{"", "~", "@home"} { got, err := resolveListDirPath(input) if err != nil { t.Fatalf("resolveListDirPath(%q): %v", input, err) } if got != filepath.Clean(home) { t.Fatalf("resolveListDirPath(%q) = %q, want %q", input, got, home) } } } func TestIsBlockedDeletePath(t *testing.T) { if !isBlockedDeletePath(`C:\Windows\System32\kernel32.dll`) { t.Fatal("expected Windows system path blocked") } if !isBlockedDeletePath(`/usr/bin/bash`) { t.Fatal("expected /usr blocked") } home, err := os.UserHomeDir() if err != nil { t.Skip("no home") } if !isBlockedDeletePath(home) { t.Fatal("expected home root blocked") } tmp := filepath.Join(home, "test_delete_guard.txt") if isBlockedDeletePath(tmp) { t.Fatalf("expected user file path allowed: %s", tmp) } } func TestReadDirectoryEntriesCapsCount(t *testing.T) { dir := t.TempDir() for i := 0; i < maxListDirEntries+10; i++ { name := filepath.Join(dir, fmt.Sprintf("file_%d.txt", i)) if err := os.WriteFile(name, []byte("x"), 0o644); err != nil { t.Fatal(err) } } entries, err := readDirectoryEntries(dir) if err != nil { t.Fatal(err) } if len(entries) != maxListDirEntries { t.Fatalf("entries len = %d, want cap %d", len(entries), maxListDirEntries) } }