Merge branch 'main' into claudedo/4e19605838a3404f98624cb0e90195da
# Conflicts: # docs/open.md # src/ClaudeDo.Installer/CLAUDE.md # src/ClaudeDo.Installer/Pages/SystemCheckPage/SystemCheckPageView.xaml # src/ClaudeDo.Installer/Pages/SystemCheckPage/SystemCheckPageViewModel.cs
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using ClaudeDo.Installer.Checks;
|
||||
using ClaudeDo.Installer.Checks.Interfaces;
|
||||
using ClaudeDo.Installer.Core;
|
||||
using ClaudeDo.Installer.Tests.Pages.SystemCheckPage;
|
||||
using Vm = ClaudeDo.Installer.Pages.DiagnosePage.DiagnosePageViewModel;
|
||||
|
||||
namespace ClaudeDo.Installer.Tests.Pages.DiagnosePage;
|
||||
|
||||
public sealed class DiagnosePageViewModelTests
|
||||
{
|
||||
private sealed class FakeOwnerResolver : IPortOwnerResolver
|
||||
{
|
||||
private readonly string? _owner;
|
||||
public FakeOwnerResolver(string? owner) => _owner = owner;
|
||||
public Task<string?> FindOwningProcessNameAsync(int port, CancellationToken ct) => Task.FromResult(_owner);
|
||||
}
|
||||
|
||||
private static int GetFreePort()
|
||||
{
|
||||
var listener = new TcpListener(IPAddress.Loopback, 0);
|
||||
listener.Start();
|
||||
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
||||
listener.Stop();
|
||||
return port;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Loading_the_page_does_not_run_checks()
|
||||
{
|
||||
var check = FakeEnvironmentCheck.Ok("a");
|
||||
var vm = new Vm(
|
||||
new InstallContext(),
|
||||
() => new EnvironmentCheckService(new IEnvironmentCheck[] { check }),
|
||||
() => new InstallerWorkerConfig());
|
||||
|
||||
await vm.LoadAsync();
|
||||
|
||||
Assert.Equal(0, check.CallCount);
|
||||
Assert.False(vm.Checks.HasRun);
|
||||
Assert.Empty(vm.Checks.Rows);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Clicking_check_runs_once_and_a_second_click_during_the_run_starts_no_new_run()
|
||||
{
|
||||
var gate = new TaskCompletionSource();
|
||||
var slow = new FakeEnvironmentCheck("slow", CheckSeverity.Error, async (_, _) =>
|
||||
{
|
||||
await gate.Task;
|
||||
return CheckResult.Ok("slow", CheckSeverity.Error, "checks.slow.title", "ok");
|
||||
});
|
||||
|
||||
var factoryCalls = 0;
|
||||
var vm = new Vm(
|
||||
new InstallContext(),
|
||||
() =>
|
||||
{
|
||||
factoryCalls++;
|
||||
return new EnvironmentCheckService(new IEnvironmentCheck[] { slow });
|
||||
},
|
||||
() => new InstallerWorkerConfig());
|
||||
|
||||
await vm.LoadAsync();
|
||||
|
||||
var firstRun = vm.Checks.RunChecksCommand.ExecuteAsync(null);
|
||||
Assert.True(vm.Checks.IsRunning);
|
||||
|
||||
await vm.Checks.RunChecksCommand.ExecuteAsync(null); // second click while the first run is still in flight
|
||||
|
||||
Assert.Equal(1, factoryCalls);
|
||||
Assert.Equal(1, slow.CallCount);
|
||||
|
||||
gate.SetResult();
|
||||
await firstRun;
|
||||
|
||||
Assert.False(vm.Checks.IsRunning);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Checks_run_against_the_installed_configuration_not_context_defaults()
|
||||
{
|
||||
InstallContext? capturedCtx = null;
|
||||
var probe = new FakeEnvironmentCheck("probe", CheckSeverity.Warning, (ctx, _) =>
|
||||
{
|
||||
capturedCtx = ctx;
|
||||
return Task.FromResult(CheckResult.Ok("probe", CheckSeverity.Warning, "checks.probe.title", "ok"));
|
||||
});
|
||||
|
||||
var sharedContext = new InstallContext { InstallDirectory = @"C:\Program Files\ClaudeDo" };
|
||||
var vm = new Vm(
|
||||
sharedContext,
|
||||
() => new EnvironmentCheckService(new IEnvironmentCheck[] { probe }),
|
||||
() => new InstallerWorkerConfig { ClaudeBin = @"C:\installed\claude.exe", SignalRPort = 55555 });
|
||||
|
||||
await vm.LoadAsync();
|
||||
await vm.Checks.RunChecksCommand.ExecuteAsync(null);
|
||||
|
||||
Assert.NotNull(capturedCtx);
|
||||
Assert.Equal(@"C:\installed\claude.exe", capturedCtx!.ClaudeBin);
|
||||
Assert.Equal(55555, capturedCtx.SignalRPort);
|
||||
Assert.Equal(@"C:\Program Files\ClaudeDo", capturedCtx.InstallDirectory);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Worker_already_running_on_the_installed_signalr_port_reports_ok()
|
||||
{
|
||||
var port = GetFreePort();
|
||||
using var occupying = new TcpListener(IPAddress.Loopback, port);
|
||||
occupying.Start();
|
||||
|
||||
var sharedContext = new InstallContext { ExternalMcpPort = GetFreePort() };
|
||||
var vm = new Vm(
|
||||
sharedContext,
|
||||
() => new EnvironmentCheckService(new IEnvironmentCheck[] { new PortCheck(new FakeOwnerResolver("ClaudeDo.Worker")) }),
|
||||
() => new InstallerWorkerConfig { SignalRPort = port });
|
||||
|
||||
await vm.LoadAsync();
|
||||
await vm.Checks.RunChecksCommand.ExecuteAsync(null);
|
||||
|
||||
var row = Assert.Single(vm.Checks.Rows);
|
||||
Assert.Equal(CheckStatus.Ok, row.Status);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user