- Fix YAML tags in auth config struct (json -> yaml) - Update CLI configs to use pre-hashed API keys - Remove double hashing in WebSocket client - Fix port mapping (9102 -> 9103) in CLI commands - Update permission keys to use jobs:read, jobs:create, etc. - Clean up all debug logging from CLI and server - All user roles now authenticate correctly: * Admin: Can queue jobs and see all jobs * Researcher: Can queue jobs and see own jobs * Analyst: Can see status (read-only access) Multi-user authentication is now fully functional.
215 lines
6.1 KiB
Go
215 lines
6.1 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/jfraeys/fetch_ml/internal/config"
|
|
)
|
|
|
|
func TestExpandPath(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test empty path
|
|
result := config.ExpandPath("")
|
|
if result != "" {
|
|
t.Errorf("Expected empty string for empty input, got %s", result)
|
|
}
|
|
|
|
// Test normal path (no expansion)
|
|
result = config.ExpandPath("/some/path")
|
|
if result != "/some/path" {
|
|
t.Errorf("Expected /some/path, got %s", result)
|
|
}
|
|
|
|
// Test environment variable expansion
|
|
_ = os.Setenv("TEST_VAR", "test_value")
|
|
defer func() { _ = os.Unsetenv("XDG_CONFIG_HOME") }()
|
|
|
|
result = config.ExpandPath("/path/$TEST_VAR/file")
|
|
expected := "/path/test_value/file"
|
|
if result != expected {
|
|
t.Errorf("Expected %s, got %s", expected, result)
|
|
}
|
|
|
|
// Test tilde expansion (if home directory is available)
|
|
home, err := os.UserHomeDir()
|
|
if err == nil {
|
|
result = config.ExpandPath("~/test")
|
|
expected := filepath.Join(home, "test")
|
|
if result != expected {
|
|
t.Errorf("Expected %s, got %s", expected, result)
|
|
}
|
|
}
|
|
|
|
// Test combination of tilde and env vars
|
|
if err == nil {
|
|
// To ensure consistent tilde expansion for this test, temporarily set HOME
|
|
tempHomeDir := t.TempDir()
|
|
_ = os.Setenv("HOME", tempHomeDir)
|
|
defer func() { _ = os.Unsetenv("HOME") }() // Clean up HOME env var
|
|
|
|
_ = os.Setenv("TEST_DIR", "mydir")
|
|
defer func() { _ = os.Unsetenv("TEST_DIR") }()
|
|
|
|
result = config.ExpandPath("~/$TEST_DIR/file")
|
|
// The expected path should use the temporarily set HOME
|
|
expected := filepath.Join(tempHomeDir, "mydir", "file")
|
|
if result != expected {
|
|
t.Errorf("Expected %s, got %s", expected, result)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestResolveConfigPath(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Create a temporary directory for testing
|
|
tempDir := t.TempDir()
|
|
|
|
// Test with absolute path that exists
|
|
configFile := filepath.Join(tempDir, "config.yaml")
|
|
err := os.WriteFile(configFile, []byte("test: config"), 0600)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create test config file: %v", err)
|
|
}
|
|
|
|
result, err := config.ResolveConfigPath(configFile)
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing absolute path, got %v", err)
|
|
}
|
|
if result != config.ExpandPath(configFile) {
|
|
t.Errorf("Expected %s, got %s", config.ExpandPath(configFile), result)
|
|
}
|
|
|
|
// Test with relative path that doesn't exist
|
|
_, err = config.ResolveConfigPath("nonexistent.yaml")
|
|
if err == nil {
|
|
t.Error("Expected error for non-existent config file")
|
|
}
|
|
|
|
// Test with relative path that exists in current directory
|
|
relativeConfig := "relative_config.yaml"
|
|
err = os.WriteFile(relativeConfig, []byte("test: config"), 0600)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create relative config file: %v", err)
|
|
}
|
|
defer func() { _ = os.Remove(relativeConfig) }()
|
|
|
|
result, err = config.ResolveConfigPath(relativeConfig)
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing relative path, got %v", err)
|
|
}
|
|
if result != config.ExpandPath(relativeConfig) {
|
|
t.Errorf("Expected %s, got %s", config.ExpandPath(relativeConfig), result)
|
|
}
|
|
|
|
// Test with relative path that exists in configs subdirectory
|
|
configsDir := filepath.Join(tempDir, "configs")
|
|
err = os.MkdirAll(configsDir, 0750)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create configs directory: %v", err)
|
|
}
|
|
|
|
configInConfigs := filepath.Join(configsDir, "config.yaml")
|
|
err = os.WriteFile(configInConfigs, []byte("test: config"), 0600)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create config in configs directory: %v", err)
|
|
}
|
|
|
|
// Change to temp directory to test relative path resolution
|
|
originalWd, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("Failed to get current working directory: %v", err)
|
|
}
|
|
defer func() { _ = os.Chdir(originalWd) }()
|
|
|
|
err = os.Chdir(tempDir)
|
|
if err != nil {
|
|
t.Fatalf("Failed to change to temp directory: %v", err)
|
|
}
|
|
|
|
result, err = config.ResolveConfigPath("config.yaml")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for config in configs subdirectory, got %v", err)
|
|
}
|
|
// The result should be the expanded path to the config file
|
|
if !strings.Contains(result, "config.yaml") {
|
|
t.Errorf("Expected result to contain config.yaml, got %s", result)
|
|
}
|
|
}
|
|
|
|
func TestNewJobPaths(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
basePath := "/test/base"
|
|
jobPaths := config.NewJobPaths(basePath)
|
|
|
|
if jobPaths.BasePath != basePath {
|
|
t.Errorf("Expected BasePath %s, got %s", basePath, jobPaths.BasePath)
|
|
}
|
|
}
|
|
|
|
func TestJobPathsMethods(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
basePath := "/test/base"
|
|
jobPaths := config.NewJobPaths(basePath)
|
|
|
|
// Test all path methods
|
|
tests := []struct {
|
|
name string
|
|
method func() string
|
|
expected string
|
|
}{
|
|
{"PendingPath", jobPaths.PendingPath, "/test/base/pending"},
|
|
{"RunningPath", jobPaths.RunningPath, "/test/base/running"},
|
|
{"FinishedPath", jobPaths.FinishedPath, "/test/base/finished"},
|
|
{"FailedPath", jobPaths.FailedPath, "/test/base/failed"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := tt.method()
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %s, got %s", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJobPathsWithComplexBase(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
basePath := "/very/complex/base/path/with/subdirs"
|
|
jobPaths := config.NewJobPaths(basePath)
|
|
|
|
expectedPending := filepath.Join(basePath, "pending")
|
|
if jobPaths.PendingPath() != expectedPending {
|
|
t.Errorf("Expected %s, got %s", expectedPending, jobPaths.PendingPath())
|
|
}
|
|
|
|
expectedRunning := filepath.Join(basePath, "running")
|
|
if jobPaths.RunningPath() != expectedRunning {
|
|
t.Errorf("Expected %s, got %s", expectedRunning, jobPaths.RunningPath())
|
|
}
|
|
}
|
|
|
|
func TestJobPathsEmptyBase(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
jobPaths := config.NewJobPaths("")
|
|
|
|
// Should still work with empty base path
|
|
expectedPending := "pending"
|
|
if jobPaths.PendingPath() != expectedPending {
|
|
t.Errorf("Expected %s, got %s", expectedPending, jobPaths.PendingPath())
|
|
}
|
|
|
|
expectedRunning := "running"
|
|
if jobPaths.RunningPath() != expectedRunning {
|
|
t.Errorf("Expected %s, got %s", expectedRunning, jobPaths.RunningPath())
|
|
}
|
|
}
|