Files
nexus/backend-tests/OpenClawChatServiceTests.cs
AzuTear f5552218bc
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s
feat: ship agent-first mission control v0.2.57
2026-07-31 22:39:47 +02:00

143 lines
4.8 KiB
C#

using Nexus.Api.Data;
using Nexus.Api.Models;
using Nexus.Api.Services;
using Xunit;
namespace Nexus.Api.Tests;
public sealed class OpenClawChatServiceTests
{
[Fact]
public async Task Send_uses_durable_protocol_v4_run_and_canonical_agent_session()
{
var runId = Guid.NewGuid();
var runs = new CapturingRunService(runId, ok: true);
var service = new OpenClawChatService(runs);
var invocation = new OpenClawInvocationMetadata(
"idem-chat",
"corr-chat",
"owner",
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01");
var result = await service.SendAsync(
"coordinate this work",
"browser-conversation",
"Iris",
invocation);
Assert.NotNull(runs.Request);
Assert.Equal("iris", runs.Request.AgentId);
Assert.Equal("agent:iris:main", runs.Request.SessionKey);
Assert.Equal("coordinate this work", runs.Request.Prompt);
Assert.Equal(runId, result.RunId);
Assert.Equal("OpenClaw Protocol v4", result.Runtime);
}
[Fact]
public async Task Send_does_not_claim_success_when_gateway_dispatch_is_blocked()
{
var runs = new CapturingRunService(Guid.NewGuid(), ok: false);
var service = new OpenClawChatService(runs);
var exception = await Assert.ThrowsAsync<OpenClawChatDispatchException>(
() => service.SendAsync(
"coordinate this work",
"browser-conversation",
"iris",
new OpenClawInvocationMetadata(
"idem-chat",
"corr-chat",
"owner",
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")));
Assert.Equal("blocked", exception.State);
}
private sealed class CapturingRunService(Guid runId, bool ok) :
IOpenClawRunService
{
public StartOpenClawRunRequest? Request { get; private set; }
public Task<OpenClawRunOperationDto> StartAsync(
StartOpenClawRunRequest request,
OpenClawInvocationMetadata invocation,
CancellationToken cancellationToken = default)
{
Request = request;
var run = new OpenClawRunDto(
runId,
"Chat",
request.Prompt,
request.AgentId,
request.SessionKey,
ok ? "running" : "blocked",
request.TaskId,
request.ProjectId,
null,
null,
invocation.CorrelationId,
invocation.Actor,
ok ? null : "Gateway disconnected",
null,
false,
ok,
!ok,
false,
null,
DateTimeOffset.UtcNow,
DateTimeOffset.UtcNow,
null,
null);
return Task.FromResult(new OpenClawRunOperationDto(
ok,
ok ? "running" : "blocked",
ok ? "OpenClaw accepted the run." : "Gateway disconnected.",
run,
null,
DateTimeOffset.UtcNow));
}
public Task<OpenClawRunCollectionDto> GetAsync(
OpenClawRunQuery query,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public Task<OpenClawRunDto?> GetByIdAsync(
Guid id,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public Task<OpenClawRunOperationDto?> StopAsync(
Guid id,
string? reason,
OpenClawInvocationMetadata invocation,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public Task<OpenClawRunOperationDto?> ResumeAsync(
Guid id,
string? reason,
OpenClawInvocationMetadata invocation,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public Task<OpenClawRunOperationDto?> RetryAsync(
Guid id,
string? reason,
OpenClawInvocationMetadata invocation,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public Task<OpenClawRunHistoryResponse?> GetHistoryAsync(
Guid id,
int gatewayLimit = 200,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public Task ReconcileAsync(
GatewayEventEnvelope gatewayEvent,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
}
}