openclaw/apps/windows/tests/Clawdbot.Windows.Tests/ExecApprovalTests.cs
TAPUZE 7f33621721 feat(windows): Add Windows companion app (Phase 0-2)
- System tray icon with connection status
- Exec approval dialogs with queue and timeout
- Settings persistence to JSON (%LOCALAPPDATA%\Clawdbot)
- Auto-start on login via Windows Registry
- Notification sounds for approvals and connection events
- WebView2 Control UI embedding
- 23 unit tests passing
- Build scripts and Inno Setup installer template
- Community build guide documentation

Phase 0: Protocol models, WebSocket client, logging
Phase 1: Tray icon, exec approval dialogs, Control UI
Phase 2: Settings, auto-start, sounds, settings UI
2026-01-27 11:12:39 +02:00

168 lines
5.1 KiB
C#

using Clawdbot.Windows.Core;
namespace Clawdbot.Windows.Tests;
/// <summary>
/// Phase 1 tests for Exec Approval functionality
/// </summary>
[Trait("Category", "Phase1")]
public class ExecApprovalTests
{
[Fact]
public void ExecApprovalDecision_AllowOnce_ToWireFormat_ReturnsAllowOnce()
{
// Act
var wireFormat = ExecApprovalDecision.AllowOnce.ToWireFormat();
// Assert
Assert.Equal("allow-once", wireFormat);
}
[Fact]
public void ExecApprovalDecision_AllowAlways_ToWireFormat_ReturnsAllowAlways()
{
// Act
var wireFormat = ExecApprovalDecision.AllowAlways.ToWireFormat();
// Assert
Assert.Equal("allow-always", wireFormat);
}
[Fact]
public void ExecApprovalDecision_Deny_ToWireFormat_ReturnsDeny()
{
// Act
var wireFormat = ExecApprovalDecision.Deny.ToWireFormat();
// Assert
Assert.Equal("deny", wireFormat);
}
[Fact]
public void GatewayExecApprovalRequest_IsExpired_WhenPastExpiryTime_ReturnsTrue()
{
// Arrange
var request = new GatewayExecApprovalRequest
{
Id = "test-id",
Request = new ExecApprovalPromptRequest
{
Command = "echo hello",
Cwd = "/tmp",
Host = "localhost",
Security = "ask",
Ask = "always"
},
CreatedAtMs = DateTimeOffset.UtcNow.AddMinutes(-5).ToUnixTimeMilliseconds(),
ExpiresAtMs = DateTimeOffset.UtcNow.AddMinutes(-1).ToUnixTimeMilliseconds() // Expired 1 min ago
};
// Act & Assert
Assert.True(request.IsExpired);
}
[Fact]
public void GatewayExecApprovalRequest_IsExpired_WhenNotPastExpiryTime_ReturnsFalse()
{
// Arrange
var request = new GatewayExecApprovalRequest
{
Id = "test-id",
Request = new ExecApprovalPromptRequest
{
Command = "echo hello",
Cwd = "/tmp",
Host = "localhost",
Security = "ask",
Ask = "always"
},
CreatedAtMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
ExpiresAtMs = DateTimeOffset.UtcNow.AddMinutes(5).ToUnixTimeMilliseconds() // Expires in 5 min
};
// Act & Assert
Assert.False(request.IsExpired);
}
[Fact]
public void GatewayExecApprovalRequest_TimeRemaining_WhenNotExpired_ReturnsPositiveTimeSpan()
{
// Arrange
var expiresAt = DateTimeOffset.UtcNow.AddMinutes(5);
var request = new GatewayExecApprovalRequest
{
Id = "test-id",
Request = new ExecApprovalPromptRequest
{
Command = "echo hello",
Cwd = "/tmp",
Host = "localhost",
Security = "ask",
Ask = "always"
},
CreatedAtMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
ExpiresAtMs = expiresAt.ToUnixTimeMilliseconds()
};
// Act
var remaining = request.TimeRemaining;
// Assert
Assert.True(remaining.TotalSeconds > 0);
Assert.True(remaining.TotalMinutes <= 5);
}
[Fact]
public void GatewayExecApprovalRequest_TimeRemaining_WhenExpired_ReturnsZero()
{
// Arrange
var request = new GatewayExecApprovalRequest
{
Id = "test-id",
Request = new ExecApprovalPromptRequest
{
Command = "echo hello",
Cwd = "/tmp",
Host = "localhost",
Security = "ask",
Ask = "always"
},
CreatedAtMs = DateTimeOffset.UtcNow.AddMinutes(-10).ToUnixTimeMilliseconds(),
ExpiresAtMs = DateTimeOffset.UtcNow.AddMinutes(-5).ToUnixTimeMilliseconds() // Expired 5 min ago
};
// Act
var remaining = request.TimeRemaining;
// Assert
Assert.Equal(TimeSpan.Zero, remaining);
}
[Fact]
public void ExecApprovalPromptRequest_Properties_CanBeSetAndRetrieved()
{
// Arrange & Act
var request = new ExecApprovalPromptRequest
{
Command = "npm install",
Cwd = "C:\\Projects\\MyApp",
Host = "DESKTOP-123",
Security = "sandbox",
Ask = "once",
AgentId = "agent-456",
ResolvedPath = "C:\\Program Files\\nodejs\\npm.cmd",
SessionKey = "session-789"
};
// Assert
Assert.Equal("npm install", request.Command);
Assert.Equal("C:\\Projects\\MyApp", request.Cwd);
Assert.Equal("DESKTOP-123", request.Host);
Assert.Equal("sandbox", request.Security);
Assert.Equal("once", request.Ask);
Assert.Equal("agent-456", request.AgentId);
Assert.Equal("C:\\Program Files\\nodejs\\npm.cmd", request.ResolvedPath);
Assert.Equal("session-789", request.SessionKey);
}
}