refactor(tags): remove tag entity and all references
Drops TagEntity, TagRepository, and tag wiring across data layer, worker, and UI. Adds RemoveTags migration to clean up schema. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,7 +52,6 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
private readonly ClaudeDoDbContext _ctx;
|
||||
private readonly TaskRepository _tasks;
|
||||
private readonly ListRepository _lists;
|
||||
private readonly TagRepository _tags;
|
||||
private readonly ExternalFakeHubContext _hub = new();
|
||||
private readonly HubBroadcaster _broadcaster;
|
||||
|
||||
@@ -61,7 +60,6 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
_ctx = _db.CreateContext();
|
||||
_tasks = new TaskRepository(_ctx);
|
||||
_lists = new ListRepository(_ctx);
|
||||
_tags = new TagRepository(_ctx);
|
||||
_broadcaster = new HubBroadcaster(_hub);
|
||||
}
|
||||
|
||||
@@ -89,12 +87,8 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
return task;
|
||||
}
|
||||
|
||||
// QueueService is needed by ExternalMcpService's constructor. For tests that
|
||||
// only exercise UpdateTask / DeleteTask / SetTaskTags / ListTags / ListTags,
|
||||
// we never call its WakeQueue/RunNow/CancelTask paths, so a real QueueService
|
||||
// built with the same approach used in QueueServiceTests is sufficient.
|
||||
private ExternalMcpService BuildSut(QueueService queue) =>
|
||||
new(_tasks, _lists, queue, _broadcaster, _tags,
|
||||
new(_tasks, _lists, queue, _broadcaster,
|
||||
TaskStateServiceBuilder.Build(_db.CreateFactory()).State);
|
||||
|
||||
private QueueService CreateQueue()
|
||||
@@ -129,54 +123,6 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
Assert.NotNull(await _tasks.GetByIdAsync(task.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListTags_ReturnsSeededAndCustomTags()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
var task = await SeedTaskAsync(listId);
|
||||
await _tasks.SetTagsAsync(task.Id, new[] { "agent", "custom-tag" });
|
||||
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
var tags = await sut.ListTags(CancellationToken.None);
|
||||
|
||||
Assert.Contains(tags, t => t.Name == "agent");
|
||||
Assert.Contains(tags, t => t.Name == "custom-tag");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddTask_WithTags_AttachesTags()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
var dto = await sut.AddTask(
|
||||
listId, "scope-creep handoff", "desc", "claude-cli",
|
||||
queueImmediately: false,
|
||||
tags: new[] { "agent", "custom" },
|
||||
CancellationToken.None);
|
||||
|
||||
var tags = await _tasks.GetTagsAsync(dto.Id);
|
||||
Assert.Contains(tags, t => t.Name == "agent");
|
||||
Assert.Contains(tags, t => t.Name == "custom");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddTask_NullTags_BehavesAsBefore()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
var dto = await sut.AddTask(
|
||||
listId, "no tags", null, "claude-cli",
|
||||
queueImmediately: false, tags: null, CancellationToken.None);
|
||||
|
||||
Assert.Empty(await _tasks.GetTagsAsync(dto.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateTask_PatchesNonNullFieldsOnly()
|
||||
{
|
||||
@@ -185,29 +131,13 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
var dto = await sut.UpdateTask(task.Id, "new title", null, null, null, CancellationToken.None);
|
||||
var dto = await sut.UpdateTask(task.Id, "new title", null, null, CancellationToken.None);
|
||||
|
||||
Assert.Equal("new title", dto.Title);
|
||||
var loaded = await _tasks.GetByIdAsync(task.Id);
|
||||
Assert.Equal("new title", loaded!.Title);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateTask_TagsReplaceFullSet()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
var task = await SeedTaskAsync(listId);
|
||||
await _tasks.SetTagsAsync(task.Id, new[] { "agent" });
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
await sut.UpdateTask(task.Id, null, null, null, new[] { "manual" }, CancellationToken.None);
|
||||
|
||||
var tags = await _tasks.GetTagsAsync(task.Id);
|
||||
Assert.Single(tags);
|
||||
Assert.Equal("manual", tags[0].Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateTask_OnRunning_Throws()
|
||||
{
|
||||
@@ -217,7 +147,7 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
sut.UpdateTask(task.Id, "x", null, null, null, CancellationToken.None));
|
||||
sut.UpdateTask(task.Id, "x", null, null, CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -227,15 +157,14 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
sut.UpdateTask("does-not-exist", "x", null, null, null, CancellationToken.None));
|
||||
sut.UpdateTask("does-not-exist", "x", null, null, CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteTask_RemovesTaskAndTagJoins()
|
||||
public async Task DeleteTask_RemovesTask()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
var task = await SeedTaskAsync(listId);
|
||||
await _tasks.SetTagsAsync(task.Id, new[] { "agent" });
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
@@ -265,34 +194,4 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
sut.DeleteTask("does-not-exist", CancellationToken.None));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetTaskTags_ReplacesTagSetAndBroadcasts()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
var task = await SeedTaskAsync(listId);
|
||||
await _tasks.SetTagsAsync(task.Id, new[] { "agent" });
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
var dto = await sut.SetTaskTags(task.Id, new[] { "manual" }, CancellationToken.None);
|
||||
|
||||
var tags = await _tasks.GetTagsAsync(task.Id);
|
||||
Assert.Single(tags);
|
||||
Assert.Equal("manual", tags[0].Name);
|
||||
Assert.Contains(_hub.RecordingClients.Proxy.Calls,
|
||||
c => c.Method == "TaskUpdated" && (string)c.Args[0]! == task.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetTaskTags_OnRunning_Throws()
|
||||
{
|
||||
var listId = await SeedListAsync();
|
||||
var task = await SeedTaskAsync(listId, status: TaskStatus.Running);
|
||||
var queue = CreateQueue();
|
||||
var sut = BuildSut(queue);
|
||||
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||
sut.SetTaskTags(task.Id, new[] { "manual" }, CancellationToken.None));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user