236 lines
5.8 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|