StreamRecorder/pkg/utils/paths_test.go
2025-08-11 00:06:34 -05:00

236 lines
5.8 KiB
Go

package utils
import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"
)
func TestSafeJoin(t *testing.T) {
tests := []struct {
name string
base string
elements []string
want string
}{
{
name: "basic join",
base: "data",
elements: []string{"events", "test-event"},
want: filepath.Join("data", "events", "test-event"),
},
{
name: "empty elements",
base: "data",
elements: []string{},
want: "data",
},
{
name: "with path separators",
base: "data/events",
elements: []string{"test-event", "1080p"},
want: filepath.Join("data", "events", "test-event", "1080p"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := SafeJoin(tt.base, tt.elements...)
if got != tt.want {
t.Errorf("SafeJoin() = %v, want %v", got, tt.want)
}
})
}
}
func TestEnsureDir(t *testing.T) {
tempDir, err := os.MkdirTemp("", "utils_test_*")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
testPath := filepath.Join(tempDir, "test", "nested", "directory")
// Test creating nested directories
err = EnsureDir(testPath)
if err != nil {
t.Errorf("EnsureDir() failed: %v", err)
}
// Verify directory was created
if _, err := os.Stat(testPath); os.IsNotExist(err) {
t.Errorf("Directory was not created: %s", testPath)
}
// Test with existing directory (should not fail)
err = EnsureDir(testPath)
if err != nil {
t.Errorf("EnsureDir() failed on existing directory: %v", err)
}
}
func TestPathExists(t *testing.T) {
tempDir, err := os.MkdirTemp("", "utils_test_*")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
// Test existing path
if !PathExists(tempDir) {
t.Errorf("PathExists() should return true for existing path: %s", tempDir)
}
// Test non-existing path
nonExistentPath := filepath.Join(tempDir, "does-not-exist")
if PathExists(nonExistentPath) {
t.Errorf("PathExists() should return false for non-existent path: %s", nonExistentPath)
}
// Test with file
testFile := filepath.Join(tempDir, "test.txt")
f, err := os.Create(testFile)
if err != nil {
t.Fatalf("Failed to create test file: %v", err)
}
f.Close()
if !PathExists(testFile) {
t.Errorf("PathExists() should return true for existing file: %s", testFile)
}
}
func TestIsValidPath(t *testing.T) {
tests := []struct {
name string
path string
want bool
}{
{"empty path", "", false},
{"valid path", "data/events/test", true},
{"path with colon", "data:events", false},
{"path with pipe", "data|events", false},
{"path with question mark", "data?events", false},
{"path with asterisk", "data*events", false},
{"path with quotes", "data\"events", false},
{"path with angle brackets", "data<events>", false},
{"normal windows path", "C:\\data\\events", true}, // Windows path separators are actually OK
{"unix path", "/home/user/data", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := IsValidPath(tt.path)
if got != tt.want {
t.Errorf("IsValidPath(%q) = %v, want %v", tt.path, got, tt.want)
}
})
}
}
func TestNormalizePath(t *testing.T) {
tests := []struct {
name string
path string
want string
}{
{
name: "windows backslashes",
path: "data\\events\\test",
want: filepath.Join("data", "events", "test"),
},
{
name: "unix forward slashes",
path: "data/events/test",
want: filepath.Join("data", "events", "test"),
},
{
name: "mixed slashes",
path: "data\\events/test\\file",
want: filepath.Join("data", "events", "test", "file"),
},
{
name: "redundant separators",
path: "data//events\\\\test",
want: filepath.Join("data", "events", "test"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := NormalizePath(tt.path)
if got != tt.want {
t.Errorf("NormalizePath(%q) = %q, want %q", tt.path, got, tt.want)
}
})
}
}
func TestGetRelativePath(t *testing.T) {
tempDir, err := os.MkdirTemp("", "utils_test_*")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
basePath := tempDir
targetPath := filepath.Join(tempDir, "subdir", "file.txt")
rel, err := GetRelativePath(basePath, targetPath)
if err != nil {
t.Errorf("GetRelativePath() failed: %v", err)
}
expected := filepath.Join("subdir", "file.txt")
if rel != expected {
t.Errorf("GetRelativePath() = %q, want %q", rel, expected)
}
// Test with invalid paths
_, err = GetRelativePath("", "")
if err == nil {
t.Error("GetRelativePath() should fail with empty paths")
}
}
func TestValidateWritablePath(t *testing.T) {
tempDir, err := os.MkdirTemp("", "utils_test_*")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tempDir)
// Test writable path
writablePath := filepath.Join(tempDir, "test", "file.txt")
err = ValidateWritablePath(writablePath)
if err != nil {
t.Errorf("ValidateWritablePath() failed for writable path: %v", err)
}
// Verify directory was created
dir := filepath.Dir(writablePath)
if _, err := os.Stat(dir); os.IsNotExist(err) {
t.Errorf("Directory should have been created: %s", dir)
}
// Test with read-only directory (if supported by OS)
if runtime.GOOS != "windows" { // Skip on Windows as it's more complex
readOnlyDir := filepath.Join(tempDir, "readonly")
os.MkdirAll(readOnlyDir, 0755)
os.Chmod(readOnlyDir, 0444) // Read-only
defer os.Chmod(readOnlyDir, 0755) // Restore permissions for cleanup
readOnlyPath := filepath.Join(readOnlyDir, "file.txt")
err = ValidateWritablePath(readOnlyPath)
if err == nil {
t.Error("ValidateWritablePath() should fail for read-only directory")
}
if !strings.Contains(err.Error(), "not writable") {
t.Errorf("Expected 'not writable' error, got: %v", err)
}
}
}