feat(status): add WaitingForChildren task status value
This commit is contained in:
@@ -15,6 +15,7 @@ public class TaskEntityConfiguration : IEntityTypeConfiguration<TaskEntity>
|
|||||||
TaskStatus.Queued => "queued",
|
TaskStatus.Queued => "queued",
|
||||||
TaskStatus.Running => "running",
|
TaskStatus.Running => "running",
|
||||||
TaskStatus.WaitingForReview => "waiting_for_review",
|
TaskStatus.WaitingForReview => "waiting_for_review",
|
||||||
|
TaskStatus.WaitingForChildren => "waiting_for_children",
|
||||||
TaskStatus.Done => "done",
|
TaskStatus.Done => "done",
|
||||||
TaskStatus.Failed => "failed",
|
TaskStatus.Failed => "failed",
|
||||||
TaskStatus.Cancelled => "cancelled",
|
TaskStatus.Cancelled => "cancelled",
|
||||||
@@ -28,6 +29,7 @@ public class TaskEntityConfiguration : IEntityTypeConfiguration<TaskEntity>
|
|||||||
"queued" => TaskStatus.Queued,
|
"queued" => TaskStatus.Queued,
|
||||||
"running" => TaskStatus.Running,
|
"running" => TaskStatus.Running,
|
||||||
"waiting_for_review" => TaskStatus.WaitingForReview,
|
"waiting_for_review" => TaskStatus.WaitingForReview,
|
||||||
|
"waiting_for_children" => TaskStatus.WaitingForChildren,
|
||||||
"done" => TaskStatus.Done,
|
"done" => TaskStatus.Done,
|
||||||
"failed" => TaskStatus.Failed,
|
"failed" => TaskStatus.Failed,
|
||||||
"cancelled" => TaskStatus.Cancelled,
|
"cancelled" => TaskStatus.Cancelled,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ public enum TaskStatus
|
|||||||
Queued,
|
Queued,
|
||||||
Running,
|
Running,
|
||||||
WaitingForReview,
|
WaitingForReview,
|
||||||
|
WaitingForChildren,
|
||||||
Done,
|
Done,
|
||||||
Failed,
|
Failed,
|
||||||
Cancelled,
|
Cancelled,
|
||||||
|
|||||||
96
tests/ClaudeDo.Data.Tests/CreateChildTests.cs
Normal file
96
tests/ClaudeDo.Data.Tests/CreateChildTests.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
using ClaudeDo.Data;
|
||||||
|
using ClaudeDo.Data.Models;
|
||||||
|
using ClaudeDo.Data.Repositories;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;
|
||||||
|
|
||||||
|
namespace ClaudeDo.Data.Tests;
|
||||||
|
|
||||||
|
public sealed class CreateChildTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly string _dbPath;
|
||||||
|
private readonly ClaudeDoDbContext _ctx;
|
||||||
|
|
||||||
|
public CreateChildTests()
|
||||||
|
{
|
||||||
|
_dbPath = Path.Combine(Path.GetTempPath(), $"claudedo_test_{Guid.NewGuid():N}.db");
|
||||||
|
var options = new DbContextOptionsBuilder<ClaudeDoDbContext>()
|
||||||
|
.UseSqlite($"Data Source={_dbPath}")
|
||||||
|
.Options;
|
||||||
|
_ctx = new ClaudeDoDbContext(options);
|
||||||
|
_ctx.Database.EnsureCreated();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_ctx.Dispose();
|
||||||
|
try { File.Delete(_dbPath); } catch { }
|
||||||
|
try { File.Delete(_dbPath + "-wal"); } catch { }
|
||||||
|
try { File.Delete(_dbPath + "-shm"); } catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> SeedListAsync(string id = "l1")
|
||||||
|
{
|
||||||
|
_ctx.Lists.Add(new ListEntity { Id = id, Name = "Test List", CreatedAt = DateTime.UtcNow });
|
||||||
|
await _ctx.SaveChangesAsync();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Task 1 ----
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WaitingForChildren_roundtrips_through_value_converter()
|
||||||
|
{
|
||||||
|
await SeedListAsync();
|
||||||
|
var taskId = Guid.NewGuid().ToString();
|
||||||
|
_ctx.Tasks.Add(new TaskEntity
|
||||||
|
{
|
||||||
|
Id = taskId,
|
||||||
|
ListId = "l1",
|
||||||
|
Title = "Parent",
|
||||||
|
Status = TaskStatus.WaitingForChildren,
|
||||||
|
CreatedAt = DateTime.UtcNow,
|
||||||
|
});
|
||||||
|
await _ctx.SaveChangesAsync();
|
||||||
|
_ctx.ChangeTracker.Clear();
|
||||||
|
|
||||||
|
var loaded = await _ctx.Tasks.AsNoTracking().FirstAsync(t => t.Id == taskId);
|
||||||
|
Assert.Equal(TaskStatus.WaitingForChildren, loaded.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Task 2 ----
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CreateChild_attaches_to_non_planning_parent_and_stamps_createdBy()
|
||||||
|
{
|
||||||
|
await SeedListAsync();
|
||||||
|
var parentId = "p1";
|
||||||
|
_ctx.Tasks.Add(new TaskEntity
|
||||||
|
{
|
||||||
|
Id = parentId,
|
||||||
|
ListId = "l1",
|
||||||
|
Title = "Parent",
|
||||||
|
Status = TaskStatus.Running,
|
||||||
|
PlanningPhase = PlanningPhase.None,
|
||||||
|
CreatedAt = DateTime.UtcNow,
|
||||||
|
});
|
||||||
|
await _ctx.SaveChangesAsync();
|
||||||
|
|
||||||
|
var child = await new TaskRepository(_ctx).CreateChildAsync(
|
||||||
|
"p1", "Refactor X", "desc", commitType: null, createdBy: "p1");
|
||||||
|
|
||||||
|
Assert.Equal("p1", child.ParentTaskId);
|
||||||
|
Assert.Equal("p1", child.CreatedBy);
|
||||||
|
Assert.Equal(TaskStatus.Idle, child.Status);
|
||||||
|
Assert.Equal("l1", child.ListId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CreateChild_throws_when_parent_missing()
|
||||||
|
{
|
||||||
|
await SeedListAsync();
|
||||||
|
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||||
|
new TaskRepository(_ctx).CreateChildAsync("nope", "T", null, null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user