fix(installer): read the persisted MCP port on update instead of the wizard default
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.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user