using ClaudeDo.Installer.Checks; using ClaudeDo.Installer.Core; namespace ClaudeDo.Installer.Tests.Checks; public sealed class PermissionModeAutoCheckTests : IDisposable { private readonly string _dir; private const string HelpWithAuto = "Options:\n --permission-mode Permission mode (choices: \"acceptEdits\", \"auto\", \"bypassPermissions\", \"manual\", \"dontAsk\", \"plan\")\n"; private const string HelpWithoutAuto = "Options:\n --permission-mode Permission mode (choices: \"acceptEdits\", \"bypassPermissions\", \"manual\")\n"; public PermissionModeAutoCheckTests() { _dir = Path.Combine(Path.GetTempPath(), $"cdpermmode_{Guid.NewGuid():N}"); Directory.CreateDirectory(_dir); File.WriteAllText(Path.Combine(_dir, "claude.exe"), ""); } public void Dispose() { try { Directory.Delete(_dir, recursive: true); } catch { } } private ClaudeCliLookup MakeLookup(FakeProcessRunner runner) => new(runner, pathOverride: _dir, pathExtOverride: ".exe"); [Fact] public async Task Auto_listed_in_help_reports_ok() { var runner = new FakeProcessRunner((0, "2.1.230"), (0, HelpWithAuto)); var check = new PermissionModeAutoCheck(MakeLookup(runner)); var result = await check.RunAsync(new InstallContext(), CancellationToken.None); Assert.Equal(CheckStatus.Ok, result.Status); Assert.Equal(CheckSeverity.Warning, result.Severity); } [Fact] public async Task Auto_missing_from_help_reports_failed_with_hint() { var runner = new FakeProcessRunner((0, "2.1.230"), (0, HelpWithoutAuto)); var check = new PermissionModeAutoCheck(MakeLookup(runner)); var result = await check.RunAsync(new InstallContext(), CancellationToken.None); Assert.Equal(CheckStatus.Failed, result.Status); Assert.Equal(CheckSeverity.Warning, result.Severity); Assert.NotNull(result.HintKey); } [Fact] public async Task Help_not_determinable_reports_unknown() { var runner = new FakeProcessRunner((0, "2.1.230"), (1, "")); var check = new PermissionModeAutoCheck(MakeLookup(runner)); var result = await check.RunAsync(new InstallContext(), CancellationToken.None); Assert.Equal(CheckStatus.Unknown, result.Status); } [Fact] public async Task Cli_missing_reports_unknown() { var emptyDir = Path.Combine(Path.GetTempPath(), $"cdpermmode_empty_{Guid.NewGuid():N}"); Directory.CreateDirectory(emptyDir); try { var runner = new FakeProcessRunner(); var check = new PermissionModeAutoCheck(new ClaudeCliLookup(runner, pathOverride: emptyDir, pathExtOverride: ".exe")); var ctx = new InstallContext { ClaudeBin = "claudedo_totally_missing_cmd_9f3a1" }; var result = await check.RunAsync(ctx, CancellationToken.None); Assert.Equal(CheckStatus.Unknown, result.Status); Assert.Empty(runner.Calls); } finally { Directory.Delete(emptyDir, recursive: true); } } }