Merge branch 'claudedo/16172942c1424a67a0499e01cefb7d60'

This commit is contained in:
mika kuns
2026-08-10 15:08:51 +02:00
19 changed files with 1295 additions and 24 deletions
@@ -227,6 +227,68 @@ public sealed class ExternalMcpServiceTests : IDisposable
Assert.Equal("the full description text", dto.Description);
}
[Fact]
public async Task GetTask_Failed_ReturnsClassifiedFailureReason()
{
var listId = await SeedListAsync();
var task = await SeedTaskAsync(listId, status: TaskStatus.Failed);
task.FailureReason = "max_turns";
task.FailureTurnsUsed = 55;
task.FailureMaxTurns = 60;
await _tasks.UpdateAsync(task, CancellationToken.None);
var sut = BuildSut(CreateQueue());
var dto = await sut.GetTask(task.Id, CancellationToken.None);
Assert.Equal("max_turns", dto.FailureReason);
Assert.Equal(55, dto.FailureTurnsUsed);
Assert.Equal(60, dto.FailureMaxTurns);
}
[Fact]
public async Task GetTask_FailedWithoutStoredReason_ReturnsUnknownNotError()
{
// A Failed task written before this field existed has FailureReason=null in the DB —
// the MCP surface must still hand back a defined value, not null or a throw.
var listId = await SeedListAsync();
var task = await SeedTaskAsync(listId, status: TaskStatus.Failed);
var sut = BuildSut(CreateQueue());
var dto = await sut.GetTask(task.Id, CancellationToken.None);
Assert.Equal("unknown", dto.FailureReason);
Assert.Null(dto.FailureTurnsUsed);
Assert.Null(dto.FailureMaxTurns);
}
[Fact]
public async Task GetTask_NotFailed_FailureReasonIsNull()
{
var listId = await SeedListAsync();
var task = await SeedTaskAsync(listId, status: TaskStatus.Idle);
var sut = BuildSut(CreateQueue());
var dto = await sut.GetTask(task.Id, CancellationToken.None);
Assert.Null(dto.FailureReason);
}
[Fact]
public async Task GetTaskRefAsync_Failed_ReturnsClassifiedFailureReason()
{
// GetTaskRefAsync backs batch_get_tasks' default (lean) path — the same field must be
// present there, not just on the full get_task DTO.
var listId = await SeedListAsync();
var task = await SeedTaskAsync(listId, status: TaskStatus.Failed);
task.FailureReason = "error";
await _tasks.UpdateAsync(task, CancellationToken.None);
var sut = BuildSut(CreateQueue());
var dto = await sut.GetTaskRefAsync(task.Id, CancellationToken.None);
Assert.Equal("error", dto.FailureReason);
}
[Fact]
public async Task UpdateTask_OnRunning_Throws()
{