using System.Text.Json.Nodes; using MoShiro.Measurement; using MoShiro.Protocol; using MoShiro.TestSupport; namespace MoShiro.Backend.Tests; /// Exercises the complete Backend → Agent → Dialer desired task update with an isolated Backend fixture. [Trait("Category", "Slow")] public sealed class AgentTaskSetEndToEndTests : IClassFixture { private readonly BackendFixture _backend; public AgentTaskSetEndToEndTests(BackendFixture backend) { _backend = backend; } [Fact] public async Task LineTaskSet_FollowsTheDesiredState_AndIsPushedToTheDialer() { await using AgentHarness agent = await AgentHarness.StartAsync(_backend); await agent.OverrideLineTasksAsync(rateHz: 30); await using DialerSimulator dialer = await agent.ConnectDialerAsync(); LineTask udp = (await dialer.WaitForTasksAsync(s => s.Tasks.Any(t => t.Kind == "quic_ping" && t.Port == agent.App.QuicPorts[0]))) .Tasks.Single(t => t.Kind == "quic_ping"); JsonNode tasks = await _backend.GetJsonAsync(_backend.Admin, "/api/admin/tasks"); JsonNode mine = tasks["items"]!.AsArray().Single(t => t!["agent_id"]?.GetValue() == agent.Id && t["kind"]!.GetValue() == "quic_ping")!; using HttpResponseMessage disabled = await _backend.Admin.PatchAsync("/api/admin/tasks/" + mine["id"]!.GetValue(), BackendFixture.Json(new JsonObject { ["enabled"] = false }, "application/merge-patch+json")); disabled.EnsureSuccessStatusCode(); LineTaskSet next = await dialer.WaitForTasksAsync(s => s.Tasks.All(t => t.Kind != "quic_ping") && s.Version > 0); Assert.DoesNotContain(next.Tasks, t => t.Id == udp.Id); } }