using MyAgent.Core; using Xunit; namespace MyAgent.Tests.Core; public sealed class TaskRegistryTests { [Fact] public void StartLease_NewerTaskCancelsPreviousAndOldTaskCannotComplete() { var registry = new TaskRegistry(); var first = CreateTask("first"); var second = CreateTask("second"); var firstLease = registry.StartLease(first, ["message-1"]); var secondLease = registry.StartLease(second, ["message-2"]); Assert.True(firstLease.Token.IsCancellationRequested); Assert.True(secondLease.CancelledPrevious); Assert.False(registry.Complete(first.TaskId, "late", firstLease.Generation)); Assert.True(registry.IsCurrent(secondLease)); Assert.True(registry.TryGet(first.TaskId, out var firstState)); Assert.Equal("cancelled", firstState!.Status); Assert.Equal("cancelled_by_newer_message", firstState.CancellationReason); } [Fact] public void Complete_IsIdempotentAndClearsCurrentOwner() { var registry = new TaskRegistry(); var task = CreateTask("only"); var lease = registry.StartLease(task, ["message-1"]); Assert.True(registry.Complete(task.TaskId, "ok", lease.Generation)); Assert.False(registry.Complete(task.TaskId, "again", lease.Generation)); Assert.False(registry.IsCurrent(lease)); } private static AgentTaskState CreateTask(string id) => new() { TaskId = id, ThreadId = "group:1:user:1", GroupId = "1", UserId = "1", MergedText = id }; }