package config import ( "encoding/json" "os" "path/filepath" "runtime" "testing" "gitgud.io/mike/mpv-manager/pkg/constants" "github.com/stretchr/testify/assert" ) func resetGlobalConfig() { globalConfig = nil } func TestRemoveApp(t *testing.T) { tests := []struct { name string apps []InstalledApp appName string wantRemoved bool wantCount int }{ { name: "remove existing app", apps: []InstalledApp{ {AppName: "MPV"}, {AppName: "IINA"}, }, appName: "MPV", wantRemoved: true, wantCount: 1, }, { name: "remove non-existent app", apps: []InstalledApp{ {AppName: "MPV"}, {AppName: "IINA"}, }, appName: "VLC", wantRemoved: false, wantCount: 2, }, { name: "remove from empty list", apps: []InstalledApp{}, appName: "MPV", wantRemoved: false, wantCount: 0, }, { name: "remove last app", apps: []InstalledApp{ {AppName: "MPV"}, }, appName: "MPV", wantRemoved: true, wantCount: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := removeApp(tt.apps, tt.appName) assert.Equal(t, tt.wantCount, len(got)) if tt.wantRemoved { for _, app := range got { assert.NotEqual(t, tt.appName, app.AppName) } } }) } } func TestGetPortableConfigPath(t *testing.T) { tests := []struct { name string mpvDir string want string }{ { name: "absolute path", mpvDir: "/home/user/mpv", want: "/home/user/mpv/portable_config", }, { name: "relative path", mpvDir: "./mpv", want: "mpv/portable_config", }, { name: "windows path", mpvDir: "C:\\Program Files\\mpv", want: "C:\\Program Files\\mpv/portable_config", }, { name: "empty path", mpvDir: "", want: "portable_config", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := GetPortableConfigPath(tt.mpvDir) assert.Equal(t, tt.want, got) }) } } func TestGetConfigDir(t *testing.T) { originalHome := os.Getenv("HOME") defer func() { os.Setenv("HOME", originalHome) }() tests := []struct { name string setHome bool homeValue string expectCurrent bool }{ { name: "with valid home directory", setHome: true, homeValue: "/home/user", expectCurrent: false, }, { name: "without home directory", setHome: false, expectCurrent: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.setHome { os.Setenv("HOME", tt.homeValue) if runtime.GOOS == "windows" { os.Setenv("USERPROFILE", tt.homeValue) } } else { os.Unsetenv("HOME") if runtime.GOOS == "windows" { os.Unsetenv("USERPROFILE") } } got := GetConfigDir() if tt.expectCurrent { assert.Equal(t, ".", got) } else { assert.Contains(t, got, tt.homeValue) assert.Contains(t, got, ".config") // Installer config is now stored in MPV config directory assert.Contains(t, got, constants.AppNameMPV) } }) } } func TestLoad(t *testing.T) { t.Run("load new config", func(t *testing.T) { resetGlobalConfig() config, err := Load() assert.NoError(t, err) assert.NotNil(t, config) assert.False(t, config.AutoUpdate) assert.NotNil(t, config.InstalledApps) }) t.Run("load existing config", func(t *testing.T) { resetGlobalConfig() // Set HOME before creating config to ensure correct path originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) tempDir := t.TempDir() os.Setenv("HOME", tempDir) // Installer config is now stored in MPV config directory configDir := filepath.Join(tempDir, ".config", constants.AppNameMPV) configFile := filepath.Join(configDir, constants.ConfigFileName) err := os.MkdirAll(configDir, 0755) assert.NoError(t, err) testConfig := Config{ LastCheck: "2024-01-01", AutoUpdate: true, InstallPath: "/custom/path", InstalledApps: []InstalledApp{ {AppName: "MPV", AppType: "flatpak"}, }, } data, err := json.MarshalIndent(testConfig, "", " ") assert.NoError(t, err) err = os.WriteFile(configFile, data, 0644) assert.NoError(t, err) config, err := Load() assert.NoError(t, err) assert.NotNil(t, config) assert.Equal(t, "2024-01-01", config.LastCheck) assert.True(t, config.AutoUpdate) assert.Equal(t, "/custom/path", config.InstallPath) assert.Len(t, config.InstalledApps, 1) }) t.Run("return cached config", func(t *testing.T) { resetGlobalConfig() config1, _ := Load() config2, _ := Load() assert.Same(t, config1, config2) }) } func TestSave(t *testing.T) { t.Run("save config to file", func(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) config, _ := Load() config.InstallPath = "/test/path" config.AutoUpdate = true err := Save() assert.NoError(t, err) // Installer config is now stored in MPV config directory configFile := filepath.Join(tempDir, ".config", constants.AppNameMPV, constants.ConfigFileName) assert.FileExists(t, configFile) data, err := os.ReadFile(configFile) assert.NoError(t, err) var loaded Config err = json.Unmarshal(data, &loaded) assert.NoError(t, err) assert.Equal(t, "/test/path", loaded.InstallPath) assert.True(t, loaded.AutoUpdate) }) t.Run("error without loaded config", func(t *testing.T) { resetGlobalConfig() err := Save() assert.Error(t, err) }) } func TestSetInstallPath(t *testing.T) { t.Run("set install path", func(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) SetInstallPath("/custom/install/path") path := GetInstallPath() assert.Equal(t, "/custom/install/path", path) }) t.Run("empty install path", func(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) SetInstallPath("") path := GetInstallPath() assert.NotEmpty(t, path) }) } func TestGetInstallPath(t *testing.T) { t.Run("get custom install path", func(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) config, _ := Load() config.InstallPath = "/custom/path" path := GetInstallPath() assert.Equal(t, "/custom/path", path) }) t.Run("get default install path", func(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) path := GetInstallPath() assert.Contains(t, path, tempDir) assert.Contains(t, path, "mpv") }) } func TestSetUOSCVersion(t *testing.T) { resetGlobalConfig() SetUOSCVersion("4.0.0") version := GetUOSCVersion() assert.Equal(t, "4.0.0", version) } func TestGetUOSCVersion(t *testing.T) { resetGlobalConfig() config, _ := Load() config.UOSCVersion = "3.5.0" version := GetUOSCVersion() assert.Equal(t, "3.5.0", version) } func TestAddInstalledApp(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) app := InstalledApp{ AppName: "MPV", AppType: "flatpak", InstallMethod: "mpv-flatpak", InstalledDate: "2024-01-01", AppVersion: "0.36.0", } err := AddInstalledApp(app) assert.NoError(t, err) apps := GetInstalledApps() assert.Len(t, apps, 1) assert.Equal(t, "MPV", apps[0].AppName) assert.True(t, IsAppInstalled("MPV")) } func TestRemoveInstalledApp(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) app := InstalledApp{AppName: "MPV"} AddInstalledApp(app) err := RemoveInstalledApp("MPV") assert.NoError(t, err) assert.False(t, IsAppInstalled("MPV")) assert.Len(t, GetInstalledApps(), 0) } func TestRemoveInstalledAppByType(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) AddInstalledApp(InstalledApp{AppName: "MPV", AppType: "flatpak"}) AddInstalledApp(InstalledApp{AppName: "Celluloid", AppType: "flatpak"}) AddInstalledApp(InstalledApp{AppName: "IINA", AppType: "app"}) err := RemoveInstalledAppByType("flatpak") assert.NoError(t, err) apps := GetInstalledApps() assert.Len(t, apps, 1) assert.Equal(t, "IINA", apps[0].AppName) } func TestGetInstalledApps(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) config, _ := Load() config.InstalledApps = []InstalledApp{ {AppName: "MPV"}, {AppName: "IINA"}, } apps := GetInstalledApps() assert.Len(t, apps, 2) } func TestIsAppInstalled(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) config, _ := Load() config.InstalledApps = []InstalledApp{ {AppName: "MPV"}, {AppName: "IINA"}, } assert.True(t, IsAppInstalled("MPV")) assert.True(t, IsAppInstalled("IINA")) assert.False(t, IsAppInstalled("VLC")) } func TestAudioLanguagePrefs(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) langs := []string{"en", "es"} err := SetAudioLanguagePrefs(langs) assert.NoError(t, err) prefs := GetAudioLanguagePrefs() assert.Equal(t, langs, prefs) } func TestSubtitleLanguagePrefs(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) langs := []string{"en", "fr", "de"} err := SetSubtitleLanguagePrefs(langs) assert.NoError(t, err) prefs := GetSubtitleLanguagePrefs() assert.Equal(t, langs, prefs) } func TestManagerInPATH(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) err := SetManagerInPATH(true) assert.NoError(t, err) assert.True(t, GetManagerInPATH()) err = SetManagerInPATH(false) assert.NoError(t, err) assert.False(t, GetManagerInPATH()) } func TestManagerBinPath(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) err := SetManagerBinPath("/usr/local/bin/mpv-manager") assert.NoError(t, err) assert.Equal(t, "/usr/local/bin/mpv-manager", GetManagerBinPath()) } func TestGetMPVConfigPath(t *testing.T) { resetGlobalConfig() tempDir := t.TempDir() originalHome := os.Getenv("HOME") defer os.Setenv("HOME", originalHome) os.Setenv("HOME", tempDir) path := GetMPVConfigPath() assert.Contains(t, path, tempDir) assert.Contains(t, path, ".config") assert.Contains(t, path, "mpv") config, _ := Load() config.MPVConfigPath = "/custom/mpv/path" path = GetMPVConfigPath() assert.Equal(t, "/custom/mpv/path", path) }