Files
narratio/internal/app/cleanup_targets_test.go

104 lines
3.9 KiB
Go

package app
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestCleanValidateScopedDirAndFile(t *testing.T) {
root := t.TempDir()
dirTarget := filepath.Join(root, "runs", "run-1")
fileTarget := filepath.Join(root, "cache", "a.flac")
if err := os.MkdirAll(dirTarget, 0o755); err != nil {
t.Fatalf("MkdirAll(dirTarget) error = %v", err)
}
if err := os.MkdirAll(filepath.Dir(fileTarget), 0o755); err != nil {
t.Fatalf("MkdirAll(file parent) error = %v", err)
}
if err := os.WriteFile(fileTarget, []byte("audio"), 0o644); err != nil {
t.Fatalf("WriteFile(fileTarget) error = %v", err)
}
if _, err := validateScopedDir(root, dirTarget, "test.dir"); err != nil {
t.Fatalf("validateScopedDir() error = %v", err)
}
if _, err := validateScopedFile(root, fileTarget, "test.file"); err != nil {
t.Fatalf("validateScopedFile() error = %v", err)
}
}
func TestCleanValidateScopedTargetSafetyRules(t *testing.T) {
root := t.TempDir()
outside := t.TempDir()
target := filepath.Join(root, "runs", "run-1")
if err := os.MkdirAll(target, 0o755); err != nil {
t.Fatalf("MkdirAll(target) error = %v", err)
}
fileTarget := filepath.Join(root, "cache", "a.flac")
if err := os.MkdirAll(filepath.Dir(fileTarget), 0o755); err != nil {
t.Fatalf("MkdirAll(file parent) error = %v", err)
}
if err := os.WriteFile(fileTarget, []byte("audio"), 0o644); err != nil {
t.Fatalf("WriteFile(fileTarget) error = %v", err)
}
symlinkTarget := filepath.Join(root, "symlink")
if err := os.Symlink(target, symlinkTarget); err != nil {
t.Fatalf("Symlink() error = %v", err)
}
if _, err := validateScopedDir(root, root, "test.root"); err == nil || !strings.Contains(err.Error(), "refusing to delete root directory") {
t.Fatalf("validateScopedDir(root) error = %v, want root deletion rejection", err)
}
if _, err := validateScopedDir(root, filepath.Join(outside, "x"), "test.outside"); err == nil || !strings.Contains(err.Error(), "outside root") {
t.Fatalf("validateScopedDir(outside) error = %v, want outside-root rejection", err)
}
if _, err := validateScopedDir(root, fileTarget, "test.file-as-dir"); err == nil || !strings.Contains(err.Error(), "is not a directory") {
t.Fatalf("validateScopedDir(file) error = %v, want not-a-directory rejection", err)
}
if _, err := validateScopedFile(root, target, "test.dir-as-file"); err == nil || !strings.Contains(err.Error(), "is a directory") {
t.Fatalf("validateScopedFile(dir) error = %v, want is-a-directory rejection", err)
}
if _, err := validateScopedDir(root, symlinkTarget, "test.symlink"); err == nil || !strings.Contains(err.Error(), "refusing to delete symlink path") {
t.Fatalf("validateScopedDir(symlink) error = %v, want symlink rejection", err)
}
}
func TestCleanableRootChildrenRejectsSymlinkChild(t *testing.T) {
root := t.TempDir()
realChild := filepath.Join(root, "runs")
if err := os.MkdirAll(realChild, 0o755); err != nil {
t.Fatalf("MkdirAll(realChild) error = %v", err)
}
if err := os.Symlink(realChild, filepath.Join(root, "link")); err != nil {
t.Fatalf("Symlink() error = %v", err)
}
_, _, err := cleanableRootChildren(root, "test.root.children")
if err == nil || !strings.Contains(err.Error(), "refusing to delete symlink path") {
t.Fatalf("cleanableRootChildren() error = %v, want symlink rejection", err)
}
}
func TestCleanValidateScopedTargetMissing(t *testing.T) {
root := t.TempDir()
missingDir := filepath.Join(root, "runs", "missing")
got, err := validateScopedDir(root, missingDir, "test.missing")
if err != nil {
t.Fatalf("validateScopedDir(missing) error = %v", err)
}
if got.Exists {
t.Fatalf("validateScopedDir(missing).Exists = true, want false")
}
missingFile := filepath.Join(root, "cache", "missing.flac")
got, err = validateScopedFile(root, missingFile, "test.missing.file")
if err != nil {
t.Fatalf("validateScopedFile(missing) error = %v", err)
}
if got.Exists {
t.Fatalf("validateScopedFile(missing).Exists = true, want false")
}
}