diff --git a/tests/OpenClaw.Shared.Tests/ExecApprovalV2RoutingTests.cs b/tests/OpenClaw.Shared.Tests/ExecApprovalV2RoutingTests.cs index 0246b54..6fc2e2b 100644 --- a/tests/OpenClaw.Shared.Tests/ExecApprovalV2RoutingTests.cs +++ b/tests/OpenClaw.Shared.Tests/ExecApprovalV2RoutingTests.cs @@ -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) // ------------------------------------------------------------------------- diff --git a/tests/OpenClaw.Shared.Tests/McpToolBridgeTests.cs b/tests/OpenClaw.Shared.Tests/McpToolBridgeTests.cs index 198141c..164957d 100644 --- a/tests/OpenClaw.Shared.Tests/McpToolBridgeTests.cs +++ b/tests/OpenClaw.Shared.Tests/McpToolBridgeTests.cs @@ -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(), + 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 { 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()); + } } diff --git a/tests/OpenClaw.Shared.Tests/ModelsTests.cs b/tests/OpenClaw.Shared.Tests/ModelsTests.cs index bef5095..c6b3d39 100644 --- a/tests/OpenClaw.Shared.Tests/ModelsTests.cs +++ b/tests/OpenClaw.Shared.Tests/ModelsTests.cs @@ -170,6 +170,25 @@ public class SshTunnelCommandLineTests Assert.ThrowsAny(() => 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