test: add SshTunnelCommandLine, ExecApprovalV2Result, and McpToolBridge coverage gaps (#245)

- SshTunnelCommandLine: 7 new tests covering CanForwardBrowserProxyPort
  boundary values and BuildArguments whitespace trimming
- ExecApprovalV2Result: test ToString() includes code and reason
- McpToolBridge: test custom serverName/serverVersion via constructor;
  test that null arguments value is accepted (not just missing arguments)

All tests pass (Shared + Tray).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
github-actions[bot] 2026-05-01 09:54:46 -07:00 committed by GitHub
parent dc640eef32
commit 61ef7d14c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 0 deletions

View File

@ -63,6 +63,15 @@ public class ExecApprovalV2RoutingTests
Assert.NotEmpty(result.Reason);
}
[Fact]
public void V2Result_ToString_IncludesCodeAndReason()
{
var result = ExecApprovalV2Result.SecurityDeny("access denied");
var text = result.ToString();
Assert.Contains("SecurityDeny", text);
Assert.Contains("access denied", text);
}
// -------------------------------------------------------------------------
// 2. NullHandler — always unavailable, never throws (rail 1, 19)
// -------------------------------------------------------------------------

View File

@ -349,4 +349,34 @@ public class McpToolBridgeTests
Assert.Equal(-32603, error.GetProperty("code").GetInt32());
Assert.DoesNotContain("secret-internal-detail", error.GetProperty("message").GetString());
}
[Fact]
public async Task Initialize_ReturnsCustomServerNameAndVersion()
{
var bridge = new McpToolBridge(
() => new List<INodeCapability>(),
serverName: "my-mcp-server",
serverVersion: "1.2.3");
var resp = await bridge.HandleRequestAsync(@"{""jsonrpc"":""2.0"",""id"":1,""method"":""initialize""}");
using var doc = JsonDocument.Parse(resp!);
var serverInfo = doc.RootElement.GetProperty("result").GetProperty("serverInfo");
Assert.Equal("my-mcp-server", serverInfo.GetProperty("name").GetString());
Assert.Equal("1.2.3", serverInfo.GetProperty("version").GetString());
}
[Fact]
public async Task ToolsCall_NullArguments_IsAccepted()
{
var fake = new FakeCapability("alpha", "alpha.echo");
var bridge = CreateBridge(new List<INodeCapability> { fake });
var resp = await bridge.HandleRequestAsync(
@"{""jsonrpc"":""2.0"",""id"":1,""method"":""tools/call"",""params"":{""name"":""alpha.echo"",""arguments"":null}}");
using var doc = JsonDocument.Parse(resp!);
Assert.True(doc.RootElement.TryGetProperty("result", out var result));
Assert.False(result.GetProperty("isError").GetBoolean());
}
}

View File

@ -170,6 +170,25 @@ public class SshTunnelCommandLineTests
Assert.ThrowsAny<ArgumentException>(() =>
SshTunnelCommandLine.BuildArguments(user, host, remotePort, localPort));
}
[Fact]
public void BuildArguments_TrimsWhitespaceFromUserAndHost()
{
var args = SshTunnelCommandLine.BuildArguments(" scott ", " mac-mini.local ", 18789, 28789);
Assert.EndsWith("scott@mac-mini.local", args);
}
[Theory]
[InlineData(1, 1, true)]
[InlineData(18789, 28789, true)]
[InlineData(65533, 65533, true)]
[InlineData(65534, 28789, false)]
[InlineData(28789, 65534, false)]
[InlineData(0, 28789, false)]
public void CanForwardBrowserProxyPort_ReturnsExpected(int remotePort, int localPort, bool expected)
{
Assert.Equal(expected, SshTunnelCommandLine.CanForwardBrowserProxyPort(remotePort, localPort));
}
}
public class GatewaySelfInfoTests