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() .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 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(() => new TaskRepository(_ctx).CreateChildAsync("nope", "T", null, null, null)); } }