//go:build !windows package tui import ( "os" "path/filepath" "strings" "testing" "gitgud.io/mike/mpv-manager/pkg/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func isolatePATHManagerHome(t *testing.T) string { t.Helper() t.Cleanup(func() { _, _ = config.Reload() }) home := t.TempDir() t.Setenv("HOME", home) t.Setenv("XDG_CONFIG_HOME", filepath.Join(home, ".config")) t.Setenv("SHELL", "/bin/bash") require.NoError(t, os.WriteFile(filepath.Join(home, ".bashrc"), []byte("# user settings\n"), 0o640)) _, err := config.Reload() require.NoError(t, err) return home } func TestManagerPATHInstallIsIdempotentAndRemovalCleansState(t *testing.T) { home := isolatePATHManagerHome(t) require.NoError(t, applyManagerPATHOperation(false, func(string) {})) require.NoError(t, applyManagerPATHOperation(false, func(string) {})) info, err := currentManagerPATHInfo() require.NoError(t, err) binaryInfo, err := os.Stat(info.BinaryPath) require.NoError(t, err) assert.NotZero(t, binaryInfo.Mode()&0o111) aliasTarget, err := os.Readlink(info.AliasPath) require.NoError(t, err) assert.Equal(t, info.BinaryPath, aliasTarget) shellConfig, err := os.ReadFile(filepath.Join(home, ".bashrc")) require.NoError(t, err) assert.Equal(t, 1, strings.Count(string(shellConfig), managedPATHStart)) assert.Equal(t, 1, strings.Count(string(shellConfig), managedPATHEnd)) assert.NotContains(t, string(shellConfig), "alias mpv-install=") assert.True(t, config.GetManagerInPATH()) assert.Equal(t, info.BinaryPath, config.GetManagerBinPath()) require.NoError(t, applyManagerPATHOperation(true, func(string) {})) _, err = os.Lstat(info.BinaryPath) assert.ErrorIs(t, err, os.ErrNotExist) _, err = os.Lstat(info.AliasPath) assert.ErrorIs(t, err, os.ErrNotExist) shellConfig, err = os.ReadFile(filepath.Join(home, ".bashrc")) require.NoError(t, err) assert.NotContains(t, string(shellConfig), managedPATHStart) assert.Contains(t, string(shellConfig), "# user settings") assert.False(t, config.GetManagerInPATH()) assert.Empty(t, config.GetManagerBinPath()) } func TestManagerPATHInstallRollsBackWhenShellConfigCannotBeReplaced(t *testing.T) { home := isolatePATHManagerHome(t) bashrc := filepath.Join(home, ".bashrc") target := filepath.Join(home, "real-bashrc") require.NoError(t, os.WriteFile(target, []byte("# real\n"), 0o640)) require.NoError(t, os.Remove(bashrc)) require.NoError(t, os.Symlink(target, bashrc)) err := applyManagerPATHOperation(false, func(string) {}) require.Error(t, err) assert.Contains(t, err.Error(), "non-regular") info, infoErr := currentManagerPATHInfo() require.NoError(t, infoErr) _, statErr := os.Lstat(info.BinaryPath) assert.ErrorIs(t, statErr, os.ErrNotExist) _, statErr = os.Lstat(info.AliasPath) assert.ErrorIs(t, statErr, os.ErrNotExist) linkTarget, linkErr := os.Readlink(bashrc) require.NoError(t, linkErr) assert.Equal(t, target, linkTarget) assert.False(t, config.GetManagerInPATH()) } func TestRemoveManagedPATHTextCleansDuplicateBlocksAndLegacyAlias(t *testing.T) { binary := "/home/user/.local/bin/mpv-manager" content := strings.Join([]string{ "before", managedPATHStart, "export PATH='/old':\"$PATH\"", managedPATHEnd, "alias mpv-install='" + binary + "'", managedPATHStart, "export PATH='/old':\"$PATH\"", managedPATHEnd, "after", "", }, "\n") clean := removeManagedPATHText(content, binary) assert.NotContains(t, clean, managedPATHStart) assert.NotContains(t, clean, "alias mpv-install=") assert.Contains(t, clean, "before") assert.Contains(t, clean, "after") }