using Nexus.Api.Services; using Nexus.Api.Integrations; using Nexus.Api.Data; using Microsoft.Extensions.Configuration; using Xunit; namespace Nexus.Api.Tests; public class AgentServiceTests { [Fact] public async Task GetAgentsAsync_ReturnsCorrectCount() { var configPath = CreateAgentConfigFile(); var config = CreateConfiguration(configPath); var runtime = new FakeRuntime(); var service = new AgentService(config, runtime); var agents = await service.GetAgentsAsync(CancellationToken.None); Assert.True(agents.Count >= 4, $"Expected at least 4 agents, got {agents.Count}"); } [Fact] public async Task GetAgentAsync_Iris_ReturnsOrchestrator() { var configPath = CreateAgentConfigFile(); var config = CreateConfiguration(configPath); var runtime = new FakeRuntime(); var service = new AgentService(config, runtime); var agent = await service.GetAgentAsync("iris", CancellationToken.None); Assert.NotNull(agent); Assert.Equal("Orchestrator", agent.Role); } [Fact] public async Task GetAgentAsync_Unknown_ReturnsNull() { var configPath = CreateAgentConfigFile(); var config = CreateConfiguration(configPath); var runtime = new FakeRuntime(); var service = new AgentService(config, runtime); var agent = await service.GetAgentAsync("nonexistent", CancellationToken.None); Assert.Null(agent); } private static IConfiguration CreateConfiguration(string configPath) => new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["AgentConfigPath"] = configPath }) .Build(); private static string CreateAgentConfigFile() { var path = Path.Combine(Path.GetTempPath(), $"agent-config-{Guid.NewGuid():N}.json"); File.WriteAllText(path, """ { "agents": { "defaults": { "workspace": "/workspace/default", "model": { "primary": "deepseek/deepseek-v4-flash" } }, "list": [ { "id": "iris", "name": "iris" }, { "id": "programmer", "name": "programmer" }, { "id": "reviewer", "name": "reviewer" }, { "id": "architekt", "name": "architekt" } ] } } """); return path; } } public sealed class FakeRuntime : IAgentRuntime { public string Name => "FakeRuntime"; public Task GetStatusAsync(CancellationToken cancellationToken = default) => Task.FromResult(new AgentRuntimeStatus( Runtime: "OpenClaw", Status: OperationalStatus.Online, Latency: TimeSpan.FromMilliseconds(10), Detail: "Fake runtime for testing")); public Task ChatAsync(string message, string conversationId, string agentId, CancellationToken cancellationToken = default) => Task.FromResult(new AgentChatResult( Runtime: "OpenClaw", AgentId: agentId, ConversationId: conversationId, Content: "Echo: " + message)); }