RegisterMcpStep built the registration URL from ctx.ExternalMcpPort, which the Update pipeline never repopulates from the existing installation, so any update silently re-registered the wizard default (47822) even when worker.config.json had a different port configured. InstallerWorkerConfig was also missing external_mcp_port entirely, so the installer had no way to read it back. Port 0 (external listener disabled) now skips registration instead of pointing Claude at 127.0.0.1:0/mcp.
66 lines
2.2 KiB
C#
66 lines
2.2 KiB
C#
using ClaudeDo.Installer.Core;
|
|
using ClaudeDo.Installer.Steps;
|
|
|
|
namespace ClaudeDo.Installer.Tests;
|
|
|
|
public sealed class RegisterMcpStepTests
|
|
{
|
|
// Progress<T> posts to the SynchronizationContext (or the ThreadPool) asynchronously,
|
|
// so asserting on captured messages right after an await needs a synchronous reporter.
|
|
private sealed class SyncProgress<T>(Action<T> report) : IProgress<T>
|
|
{
|
|
public void Report(T value) => report(value);
|
|
}
|
|
|
|
|
|
[Fact]
|
|
public void ResolveUrl_uses_the_configured_port()
|
|
{
|
|
var url = RegisterMcpStep.ResolveUrl(new InstallerWorkerConfig { ExternalMcpPort = 49999 });
|
|
|
|
Assert.Equal("http://127.0.0.1:49999/mcp", url);
|
|
}
|
|
|
|
[Fact]
|
|
public void ResolveUrl_defaults_to_47822_without_a_configured_port()
|
|
{
|
|
var url = RegisterMcpStep.ResolveUrl(new InstallerWorkerConfig());
|
|
|
|
Assert.Equal("http://127.0.0.1:47822/mcp", url);
|
|
}
|
|
|
|
[Fact]
|
|
public void ResolveUrl_is_null_when_the_external_listener_is_disabled()
|
|
{
|
|
var url = RegisterMcpStep.ResolveUrl(new InstallerWorkerConfig { ExternalMcpPort = 0 });
|
|
|
|
Assert.Null(url);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Not_selected_skips_without_loading_the_worker_config()
|
|
{
|
|
var loaded = false;
|
|
var step = new RegisterMcpStep(() => { loaded = true; return new InstallerWorkerConfig(); });
|
|
var ctx = new InstallContext { RegisterMcpWithClaude = false };
|
|
|
|
var result = await step.ExecuteAsync(ctx, new Progress<string>(_ => { }), CancellationToken.None);
|
|
|
|
Assert.True(result.Success);
|
|
Assert.False(loaded);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Disabled_external_port_skips_without_running_the_claude_cli()
|
|
{
|
|
var step = new RegisterMcpStep(() => new InstallerWorkerConfig { ExternalMcpPort = 0 });
|
|
var ctx = new InstallContext { RegisterMcpWithClaude = true };
|
|
var messages = new List<string>();
|
|
|
|
var result = await step.ExecuteAsync(ctx, new SyncProgress<string>(messages.Add), CancellationToken.None);
|
|
|
|
Assert.True(result.Success);
|
|
Assert.Contains(messages, m => m.Contains("external_mcp_port is 0", StringComparison.Ordinal));
|
|
}
|
|
}
|