using ClaudeDo.Data.Repositories; using ClaudeDo.Data; using ClaudeDo.Data.Models; using Microsoft.EntityFrameworkCore; namespace ClaudeDo.Data.Tests; public sealed class TicketFieldsTests : IDisposable { private readonly string _dbPath; public TicketFieldsTests() { _dbPath = Path.Combine(Path.GetTempPath(), $"claudedo_ticketfields_{Guid.NewGuid():N}.db"); using var ctx = NewContext(); ctx.Database.EnsureCreated(); } public void Dispose() { foreach (var suffix in new[] { "", "-wal", "-shm" }) try { File.Delete(_dbPath + suffix); } catch { } } private ClaudeDoDbContext NewContext() { var options = new DbContextOptionsBuilder() .UseSqlite($"Data Source={_dbPath}") .Options; return new ClaudeDoDbContext(options); } [Fact] public async Task TicketRef_and_TicketProjectId_round_trip() { await using var ctx = NewContext(); var list = new ListEntity { Id = "l1", Name = "L", DefaultCommitType = "feat", CreatedAt = DateTime.UtcNow }; ctx.Lists.Add(list); ctx.ListConfigs.Add(new ListConfigEntity { ListId = "l1", TicketProjectId = 393 }); ctx.Tasks.Add(new TaskEntity { Id = "t1", ListId = "l1", Title = "T", CreatedAt = DateTime.UtcNow, TicketRef = "bandel:1234", }); await ctx.SaveChangesAsync(); await using var read = NewContext(); Assert.Equal("bandel:1234", (await read.Tasks.SingleAsync()).TicketRef); Assert.Equal(393, (await read.ListConfigs.SingleAsync()).TicketProjectId); } [Fact] public async Task TicketFields_default_to_null() { await using var ctx = NewContext(); ctx.Lists.Add(new ListEntity { Id = "l1", Name = "L", DefaultCommitType = "feat", CreatedAt = DateTime.UtcNow }); ctx.ListConfigs.Add(new ListConfigEntity { ListId = "l1" }); ctx.Tasks.Add(new TaskEntity { Id = "t1", ListId = "l1", Title = "T", CreatedAt = DateTime.UtcNow }); await ctx.SaveChangesAsync(); await using var read = NewContext(); Assert.Null((await read.Tasks.SingleAsync()).TicketRef); Assert.Null((await read.ListConfigs.SingleAsync()).TicketProjectId); } [Fact] public async Task TicketFallbackListId_round_trips_and_survives_a_settings_save() { await using (var ctx = NewContext()) await new AppSettingsRepository(ctx).SetTicketFallbackListIdAsync("l-fallback"); // The general settings save must not wipe it — UpdateAsync's copy block doesn't carry it. await using (var ctx = NewContext()) { var repo = new AppSettingsRepository(ctx); await repo.UpdateAsync(await repo.GetAsync()); } await using var read = NewContext(); Assert.Equal("l-fallback", (await new AppSettingsRepository(read).GetAsync()).TicketFallbackListId); } [Fact] public async Task Blank_TicketFallbackListId_is_stored_as_null() { await using (var ctx = NewContext()) await new AppSettingsRepository(ctx).SetTicketFallbackListIdAsync(" "); await using var read = NewContext(); Assert.Null((await new AppSettingsRepository(read).GetAsync()).TicketFallbackListId); } }