package constants import ( "os" "path/filepath" "runtime" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // ============================================================================ // XDG Base Directory Tests // ============================================================================ func TestGetXDGConfigHome(t *testing.T) { // Save original env var and restore after test originalEnv := os.Getenv(EnvXDGConfigHome) defer os.Setenv(EnvXDGConfigHome, originalEnv) homeDir, err := os.UserHomeDir() require.NoError(t, err) t.Run("default without env var", func(t *testing.T) { os.Unsetenv(EnvXDGConfigHome) got := GetXDGConfigHome() want := filepath.Join(homeDir, XDGConfigHomeDefault) assert.Equal(t, want, got) }) t.Run("respects XDG_CONFIG_HOME on Linux only", func(t *testing.T) { customPath := "/custom/config" os.Setenv(EnvXDGConfigHome, customPath) got := GetXDGConfigHome() if runtime.GOOS == OSLinux { // Linux should respect XDG_CONFIG_HOME assert.Equal(t, customPath, got) } else { // macOS and Windows should ignore XDG_CONFIG_HOME want := filepath.Join(homeDir, XDGConfigHomeDefault) assert.Equal(t, want, got) } }) } func TestGetXDGDataHome(t *testing.T) { // Save original env var and restore after test originalEnv := os.Getenv(EnvXDGDataHome) defer os.Setenv(EnvXDGDataHome, originalEnv) homeDir, err := os.UserHomeDir() require.NoError(t, err) t.Run("default without env var", func(t *testing.T) { os.Unsetenv(EnvXDGDataHome) got := GetXDGDataHome() want := filepath.Join(homeDir, XDGDataHomeDefault) assert.Equal(t, want, got) }) t.Run("respects XDG_DATA_HOME on Linux only", func(t *testing.T) { customPath := "/custom/data" os.Setenv(EnvXDGDataHome, customPath) got := GetXDGDataHome() if runtime.GOOS == OSLinux { // Linux should respect XDG_DATA_HOME assert.Equal(t, customPath, got) } else { // macOS and Windows should ignore XDG_DATA_HOME want := filepath.Join(homeDir, XDGDataHomeDefault) assert.Equal(t, want, got) } }) } func TestGetXDGCacheHome(t *testing.T) { // Save original env var and restore after test originalEnv := os.Getenv(EnvXDGCacheHome) defer os.Setenv(EnvXDGCacheHome, originalEnv) homeDir, err := os.UserHomeDir() require.NoError(t, err) t.Run("default without env var", func(t *testing.T) { os.Unsetenv(EnvXDGCacheHome) got := GetXDGCacheHome() want := filepath.Join(homeDir, XDGCacheHomeDefault) assert.Equal(t, want, got) }) t.Run("respects XDG_CACHE_HOME on Linux only", func(t *testing.T) { customPath := "/custom/cache" os.Setenv(EnvXDGCacheHome, customPath) got := GetXDGCacheHome() if runtime.GOOS == OSLinux { // Linux should respect XDG_CACHE_HOME assert.Equal(t, customPath, got) } else { // macOS and Windows should ignore XDG_CACHE_HOME want := filepath.Join(homeDir, XDGCacheHomeDefault) assert.Equal(t, want, got) } }) } func TestGetConfigPathsXDG(t *testing.T) { // This test verifies XDG behavior on Linux if runtime.GOOS != OSLinux { t.Skip("Skipping Linux-specific XDG test") } // Save original env vars and restore after test originalConfigHome := os.Getenv(EnvXDGConfigHome) defer os.Setenv(EnvXDGConfigHome, originalConfigHome) t.Run("respects XDG_CONFIG_HOME for MPV config", func(t *testing.T) { customPath := "/custom/xdg/config" os.Setenv(EnvXDGConfigHome, customPath) got := GetConfigPaths("/home/user") // Installer config is now stored in MPV config directory for convenience assert.Equal(t, filepath.Join(customPath, AppNameMPV), got.InstallerConfigDir) assert.Equal(t, filepath.Join(customPath, AppNameMPV), got.MPVConfigDir) assert.Equal(t, filepath.Join(customPath, AppNameMPV, ConfigBackupsDir), got.ConfigBackupsDir) }) t.Run("default paths when XDG not set", func(t *testing.T) { os.Unsetenv(EnvXDGConfigHome) got := GetConfigPaths("/home/user") // Should use default ~/.config/mpv for everything (installer config in MPV dir) // (not the mock "/home/user" since getConfigHome() calls os.UserHomeDir()) assert.True(t, filepath.IsAbs(got.InstallerConfigDir), "expected absolute path") assert.Contains(t, got.InstallerConfigDir, ".config/mpv") assert.Contains(t, got.MPVConfigDir, ".config/mpv") assert.Contains(t, got.ConfigBackupsDir, ".config/mpv/conf_backups") }) } func TestGetMPVConfigPathWithHomeXDG(t *testing.T) { // This test verifies XDG behavior on Linux if runtime.GOOS != OSLinux { t.Skip("Skipping Linux-specific XDG test") } // Save original env vars and restore after test originalConfigHome := os.Getenv(EnvXDGConfigHome) defer os.Setenv(EnvXDGConfigHome, originalConfigHome) t.Run("respects XDG_CONFIG_HOME", func(t *testing.T) { customPath := "/custom/xdg/config" os.Setenv(EnvXDGConfigHome, customPath) got, err := GetMPVConfigPathWithHome() require.NoError(t, err) assert.Equal(t, filepath.Join(customPath, AppNameMPV, MPVConfigFileName), got) }) t.Run("default when XDG not set", func(t *testing.T) { os.Unsetenv(EnvXDGConfigHome) got, err := GetMPVConfigPathWithHome() require.NoError(t, err) // Should end with default ~/.config/mpv/mpv.conf assert.Contains(t, got, ".config/mpv/mpv.conf") }) } func TestGetInstallerConfigFilePathWithHomeXDG(t *testing.T) { // This test verifies XDG behavior on Linux if runtime.GOOS != OSLinux { t.Skip("Skipping Linux-specific XDG test") } // Save original env vars and restore after test originalConfigHome := os.Getenv(EnvXDGConfigHome) defer os.Setenv(EnvXDGConfigHome, originalConfigHome) t.Run("respects XDG_CONFIG_HOME", func(t *testing.T) { customPath := "/custom/xdg/config" os.Setenv(EnvXDGConfigHome, customPath) got, err := GetInstallerConfigFilePathWithHome() require.NoError(t, err) // Installer config is now stored in MPV config directory assert.Equal(t, filepath.Join(customPath, AppNameMPV, ConfigFileName), got) }) t.Run("default when XDG not set", func(t *testing.T) { os.Unsetenv(EnvXDGConfigHome) got, err := GetInstallerConfigFilePathWithHome() require.NoError(t, err) // Should end with default ~/.config/mpv/mpv-manager.json (installer config in MPV dir) assert.Contains(t, got, ".config/mpv/mpv-manager.json") }) } // ============================================================================ // Original Tests // ============================================================================ func TestGetConfigPaths(t *testing.T) { // Save original env var and restore after test originalEnv := os.Getenv(EnvXDGConfigHome) defer os.Setenv(EnvXDGConfigHome, originalEnv) tests := []struct { name string homeDir string wantHome string wantInstallerConfigDir string wantMPVConfigDir string wantPortableConfigDir string wantConfigBackupsDir string }{ { name: "macOS home directory", homeDir: "/Users/test", wantHome: "/Users/test", wantInstallerConfigDir: "/Users/test/.config/mpv", // Installer config in MPV dir wantMPVConfigDir: "/Users/test/.config/mpv", wantPortableConfigDir: "portable_config", wantConfigBackupsDir: "/Users/test/.config/mpv/conf_backups", }, { name: "Empty home directory defaults to .", homeDir: "", wantHome: "", wantInstallerConfigDir: ".config/mpv", // Installer config in MPV dir wantMPVConfigDir: ".config/mpv", wantPortableConfigDir: "portable_config", wantConfigBackupsDir: ".config/mpv/conf_backups", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Note: Can't easily test Windows paths in same test since runtime.GOOS is fixed // This test focuses on Unix paths if runtime.GOOS == "windows" { t.Skip("Skipping Unix path tests on Windows") } // Clear XDG env var for consistent default behavior os.Unsetenv(EnvXDGConfigHome) got := GetConfigPaths(tt.homeDir) if runtime.GOOS == OSLinux { // On Linux, XDG is used so paths use actual home directory assert.NotEmpty(t, got.InstallerConfigDir) assert.NotEmpty(t, got.MPVConfigDir) // Installer config is now in MPV config directory assert.Contains(t, got.InstallerConfigDir, ".config/mpv") assert.Contains(t, got.MPVConfigDir, ".config/mpv") assert.Contains(t, got.ConfigBackupsDir, ".config/mpv/conf_backups") assert.Equal(t, tt.wantPortableConfigDir, got.PortableConfigDir) } else if tt.homeDir != "" { // macOS uses homeDir parameter assert.Equal(t, tt.wantHome, got.HomeDir) assert.Equal(t, tt.wantInstallerConfigDir, got.InstallerConfigDir) assert.Equal(t, tt.wantMPVConfigDir, got.MPVConfigDir) assert.Equal(t, tt.wantPortableConfigDir, got.PortableConfigDir) assert.Equal(t, tt.wantConfigBackupsDir, got.ConfigBackupsDir) } else { // For empty homeDir, just verify non-empty paths are returned assert.NotEmpty(t, got.HomeDir) assert.NotEmpty(t, got.InstallerConfigDir) assert.NotEmpty(t, got.MPVConfigDir) assert.Equal(t, tt.wantPortableConfigDir, got.PortableConfigDir) } }) } } func TestGetConfigPathsWindows(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("Skipping Windows-specific test on Unix") } homeDir := "C:\\Users\\test" got := GetConfigPaths(homeDir) assert.Equal(t, "C:\\Users\\test", got.HomeDir) // Windows: installer config goes in mpv/portable_config assert.Equal(t, "C:\\Users\\test\\mpv\\portable_config", got.InstallerConfigDir) assert.Equal(t, "C:\\Users\\test\\mpv\\portable_config", got.MPVConfigDir) assert.Equal(t, "portable_config", got.PortableConfigDir) assert.Equal(t, "C:\\Users\\test\\mpv\\portable_config", got.ConfigBackupsDir) } func TestGetMPVConfigPath(t *testing.T) { tests := []struct { name string basePath string isWindows bool want string }{ { name: "Unix/Linux MPV config path", basePath: "/home/user/.config/mpv", isWindows: false, want: "/home/user/.config/mpv/mpv.conf", }, { name: "Windows portable MPV config path", basePath: "C:\\Program Files\\mpv", isWindows: true, want: "C:\\Program Files\\mpv\\portable_config\\mpv.conf", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.isWindows != (runtime.GOOS == "windows") { t.Skip("Skipping platform-specific test") } got := GetMPVConfigPath(tt.basePath) assert.Equal(t, tt.want, got) }) } } func TestGetMPVConfigDir(t *testing.T) { tests := []struct { name string basePath string isWindows bool want string }{ { name: "Unix/Linux MPV config dir", basePath: "/home/user/.config/mpv", isWindows: false, want: "/home/user/.config/mpv", }, { name: "Windows portable MPV config dir", basePath: "C:\\Program Files\\mpv", isWindows: true, want: "C:\\Program Files\\mpv\\portable_config", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.isWindows != (runtime.GOOS == "windows") { t.Skip("Skipping platform-specific test") } got := GetMPVConfigDir(tt.basePath) assert.Equal(t, tt.want, got) }) } } func TestGetMPVConfigBackupDir(t *testing.T) { tests := []struct { name string mpvConfigDir string isWindows bool want string }{ { name: "Unix/Linux MPV config backup dir", mpvConfigDir: "/home/user/.config/mpv", isWindows: false, want: "/home/user/.config/mpv/conf_backups", }, { name: "Windows portable MPV config backup dir", mpvConfigDir: "C:\\Program Files\\mpv\\portable_config", isWindows: true, want: "C:\\Program Files\\mpv\\portable_config", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.isWindows != (runtime.GOOS == "windows") { t.Skip("Skipping platform-specific test") } got := GetMPVConfigBackupDir(tt.mpvConfigDir) assert.Equal(t, tt.want, got) }) } } func TestGetPortableConfigPath(t *testing.T) { tests := []struct { name string installDir string isWindows bool want string }{ { name: "Portable config path Unix/Linux", installDir: "/opt/mpv", isWindows: false, want: "/opt/mpv/portable_config", }, { name: "Portable config path Windows", installDir: "C:\\Program Files\\mpv", isWindows: true, want: "C:\\Program Files\\mpv\\portable_config", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.isWindows && runtime.GOOS != "windows" { t.Skip("Skipping Windows-specific test") } got := GetPortableConfigPath(tt.installDir) assert.Equal(t, tt.want, got) }) } } func TestGetInstallerConfigPath(t *testing.T) { // Save original env var and restore after test originalEnv := os.Getenv(EnvXDGConfigHome) defer os.Setenv(EnvXDGConfigHome, originalEnv) tests := []struct { name string homeDir string isWindows bool isLinux bool want string wantSuffix string // Used on Linux where actual home dir is used }{ { name: "Installer config path Unix/macOS", homeDir: "/home/user", isWindows: false, isLinux: false, want: "/home/user/.config/mpv", // Installer config in MPV dir wantSuffix: "/.config/mpv", }, { name: "Installer config path Windows", homeDir: "C:\\Users\\test", isWindows: true, want: "C:\\Users\\test\\mpv\\portable_config", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.isWindows && runtime.GOOS != "windows" { t.Skip("Skipping Windows-specific test") } if tt.isLinux && runtime.GOOS != OSLinux { t.Skip("Skipping Linux-specific test") } // Clear XDG env var for consistent default behavior os.Unsetenv(EnvXDGConfigHome) got := GetInstallerConfigPath(tt.homeDir) if runtime.GOOS == OSLinux { // On Linux, the actual home directory is used via XDG assert.True(t, filepath.IsAbs(got), "expected absolute path on Linux") assert.Contains(t, got, ".config/mpv", "expected path to contain .config/mpv") } else if tt.isWindows && runtime.GOOS == "windows" { assert.Equal(t, tt.want, got) } else { // macOS uses homeDir parameter assert.Equal(t, tt.want, got) } }) } } func TestGetInstallerConfigFilePath(t *testing.T) { // Save original env var and restore after test originalEnv := os.Getenv(EnvXDGConfigHome) defer os.Setenv(EnvXDGConfigHome, originalEnv) tests := []struct { name string homeDir string isWindows bool want string wantSuffix string }{ { name: "Installer config file path Unix/macOS", homeDir: "/home/user", isWindows: false, want: "/home/user/.config/mpv/mpv-manager.json", // Installer config in MPV dir wantSuffix: "/.config/mpv/mpv-manager.json", }, { name: "Installer config file path Windows", homeDir: "C:\\Users\\test", isWindows: true, want: "C:\\Users\\test\\mpv\\portable_config\\mpv-manager.json", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.isWindows && runtime.GOOS != "windows" { t.Skip("Skipping Windows-specific test") } // Clear XDG env var for consistent default behavior os.Unsetenv(EnvXDGConfigHome) got := GetInstallerConfigFilePath(tt.homeDir) if runtime.GOOS == OSLinux { // On Linux, the actual home directory is used via XDG assert.True(t, filepath.IsAbs(got), "expected absolute path on Linux") assert.Contains(t, got, ".config/mpv/mpv-manager.json", "expected path to contain config file in MPV dir") } else if tt.isWindows && runtime.GOOS == "windows" { assert.Equal(t, tt.want, got) } else { // macOS uses homeDir parameter assert.Equal(t, tt.want, got) } }) } } func TestFormatBackupFileName(t *testing.T) { tests := []struct { name string timestamp string want string }{ { name: "Simple timestamp", timestamp: "2006-01-02", want: "2006-01-02-mpv.conf.bak", }, { name: "Full timestamp", timestamp: "2006-01-02-150405", want: "2006-01-02-150405-mpv.conf.bak", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := FormatBackupFileName(tt.timestamp) assert.Equal(t, tt.want, got) }) } } func TestFormatFullBackupFileName(t *testing.T) { tests := []struct { name string timestamp string want string }{ { name: "Simple timestamp", timestamp: "2006-01-02", want: "2006-01-02_mpv.conf", }, { name: "Full timestamp", timestamp: "2006-01-02-150405", want: "2006-01-02-150405_mpv.conf", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := FormatFullBackupFileName(tt.timestamp) assert.Equal(t, tt.want, got) }) } } func TestGetTimestampedBackupPath(t *testing.T) { tests := []struct { name string backupDir string filename string isWindows bool want string }{ { name: "Timestamped backup path Windows", backupDir: "C:\\Users\\test\\.config\\install-mpv", filename: "2006-01-02-150405_mpv.conf", isWindows: true, want: "C:\\Users\\test\\.config\\install-mpv\\2006-01-02-150405_mpv.conf", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.isWindows && runtime.GOOS != "windows" { t.Skip("Skipping Windows-specific test") } got := GetTimestampedBackupPath(tt.backupDir, tt.filename) assert.Equal(t, tt.want, got) }) } }