package version import ( "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestReplaceAndRestoreUpdateFileKeepRecoverableBackup(t *testing.T) { directory := t.TempDir() target := filepath.Join(directory, "manager") replacement := filepath.Join(directory, "manager.new") backup := filepath.Join(directory, "manager.backup") require.NoError(t, os.WriteFile(target, []byte("known-good"), 0o755)) require.NoError(t, os.WriteFile(replacement, []byte("candidate"), 0o755)) require.NoError(t, replaceUpdateFile(target, replacement, backup)) content, err := os.ReadFile(target) require.NoError(t, err) assert.Equal(t, "candidate", string(content)) content, err = os.ReadFile(backup) require.NoError(t, err) assert.Equal(t, "known-good", string(content)) require.NoError(t, restoreUpdateFile(target, backup)) content, err = os.ReadFile(target) require.NoError(t, err) assert.Equal(t, "known-good", string(content)) assert.NoFileExists(t, backup) } func TestRollbackAppliedTargetRequiresBackup(t *testing.T) { directory := t.TempDir() targetPath := filepath.Join(directory, "manager") require.NoError(t, os.WriteFile(targetPath, []byte("candidate"), 0o755)) journal := &UpdateJournal{Targets: []UpdateTarget{{ Role: "primary", Path: targetPath, BackupPath: filepath.Join(directory, "missing.backup"), Applied: true, }}} err := rollbackUpdateTargets(journal) require.Error(t, err) assert.Contains(t, err.Error(), "required primary backup unavailable") assert.Equal(t, "rollback_failed", journal.Targets[0].Outcome) content, readErr := os.ReadFile(targetPath) require.NoError(t, readErr) assert.Equal(t, "candidate", string(content), "failed rollback must not remove the remaining executable") } func TestUpdateHelperCommandPreservesTerminalDescriptors(t *testing.T) { cmd := newUpdateHelperCommand("manager-helper", "transaction.json") assert.Same(t, os.Stdin, cmd.Stdin) assert.Same(t, os.Stdout, cmd.Stdout) assert.Same(t, os.Stderr, cmd.Stderr) assert.Equal(t, []string{"manager-helper", "--update-helper=transaction.json"}, cmd.Args) relaunch := newRelaunchedTUICommand("manager", "transaction.json", true) assert.Same(t, os.Stdin, relaunch.Stdin) assert.Same(t, os.Stdout, relaunch.Stdout) assert.Same(t, os.Stderr, relaunch.Stderr) assert.Equal(t, []string{"manager", "--post-update=transaction.json", "--post-update-restart=tui"}, relaunch.Args) }