Add host activity and DB browser, and keep dialogs, drag-drop, and idle maintenance responsive.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-28 02:03:52 +02:00
parent b72c375e87
commit b33a78dbbe
45 changed files with 3254 additions and 171 deletions

View File

@@ -178,10 +178,44 @@ public class AnalysisTests
}
}
[Fact]
public async Task Missing_files_are_tombstoned_when_loading_duplicates()
{
var (store, analysis, source) = await SeedHashedAsync(fileIdA: 1, fileIdB: 2);
await using (store)
{
File.Delete(Path.Combine(source.LastRootPath!, "a.bin"));
var classified = await analysis.GetClassifiedDuplicatesAsync();
Assert.Empty(classified);
var gone = await store.Entries.GetByPathAsync(source.Id, "a.bin");
Assert.Equal(EntryStatus.Deleted, gone!.Status);
}
}
[Fact]
public async Task Remaining_copies_still_show_when_one_duplicate_is_gone()
{
var (store, analysis, source) = await SeedHashedAsync(fileIdA: 1, fileIdB: 2);
await using (store)
{
File.WriteAllBytes(Path.Combine(source.LastRootPath!, "c.bin"), new byte[64]);
var root = await store.Entries.GetByPathAsync(source.Id, "");
await store.Entries.UpsertAsync(Hashed("c.bin", 3, source.Id, root!.Id, Enumerable.Repeat((byte)7, 32).ToArray()));
File.Delete(Path.Combine(source.LastRootPath!, "a.bin"));
var classified = Assert.Single(await analysis.GetClassifiedDuplicatesAsync());
Assert.Equal(2, classified.Group.Entries.Count);
Assert.DoesNotContain(classified.Group.Entries, e => e.PathRel == "a.bin");
}
}
private static async Task<(SqliteIndexStore Store, AnalysisService Analysis, Source Source)> SeedHashedAsync(
long fileIdA, long fileIdB)
{
var db = Path.Combine(Path.GetTempPath(), "ew-dup", Guid.NewGuid().ToString("N"), "index.db");
var rootPath = Path.Combine(Path.GetTempPath(), "ew-dup-fs", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(rootPath);
File.WriteAllBytes(Path.Combine(rootPath, "a.bin"), new byte[64]);
File.WriteAllBytes(Path.Combine(rootPath, "b.bin"), new byte[64]);
var store = new SqliteIndexStore(db, NullLogger<SqliteIndexStore>.Instance);
await store.OpenAsync();
var source = new Source
@@ -189,7 +223,7 @@ public class AnalysisTests
StableKey = "d",
DisplayName = "D",
Kind = SourceKind.NtfsLocal,
LastRootPath = @"C:\d",
LastRootPath = rootPath,
Status = SourceStatus.Online
};
source.Id = await store.Sources.UpsertAsync(source);