Persist file categories on the index and classify archives and unknown types during idle maintenance.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -114,6 +114,135 @@ public class EntryAndSearchTests
|
||||
Assert.Contains(byDate, e => e.Name == "Movie.mkv");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Upsert_assigns_and_preserves_categories()
|
||||
{
|
||||
await using var store = await Stores.Open();
|
||||
var source = await store.AddSourceAsync(@"C:\media");
|
||||
var root = new IndexEntry
|
||||
{
|
||||
SourceId = source.Id,
|
||||
Name = "media",
|
||||
NameNorm = "media",
|
||||
IsDirectory = true,
|
||||
PathRel = "",
|
||||
LastSeenUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
root.Id = await store.Entries.UpsertAsync(root);
|
||||
var photo = new IndexEntry
|
||||
{
|
||||
SourceId = source.Id,
|
||||
ParentId = root.Id,
|
||||
Name = "shot.jpg",
|
||||
NameNorm = "shot.jpg",
|
||||
Extension = "jpg",
|
||||
PathRel = "shot.jpg",
|
||||
LastSeenUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
photo.Id = await store.Entries.UpsertAsync(photo);
|
||||
var loaded = await store.Entries.GetAsync(photo.Id);
|
||||
Assert.Equal(FileCategory.Photos, loaded!.Category);
|
||||
Assert.Equal(CategorySources.Extension, loaded.CategorySource);
|
||||
|
||||
await store.Entries.SetUserCategoryAsync(photo.Id, FileCategory.Documents, "Manual");
|
||||
photo.SizeBytes = 100;
|
||||
await store.Entries.UpsertAsync(photo);
|
||||
loaded = await store.Entries.GetAsync(photo.Id);
|
||||
Assert.Equal(FileCategory.Documents, loaded!.Category);
|
||||
Assert.Equal(CategorySources.User, loaded.CategorySource);
|
||||
|
||||
var other = new IndexEntry
|
||||
{
|
||||
SourceId = source.Id,
|
||||
ParentId = root.Id,
|
||||
Name = "clip.mkv",
|
||||
NameNorm = "clip.mkv",
|
||||
Extension = "mkv",
|
||||
PathRel = "clip.mkv",
|
||||
LastSeenUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
other.Id = await store.Entries.UpsertAsync(other);
|
||||
await store.Entries.RefreshCategoryFromChildrenAsync(root.Id);
|
||||
var folder = await store.Entries.GetAsync(root.Id);
|
||||
Assert.Equal(FileCategory.Unknown, folder!.Category);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Archive_contents_and_signature_queues()
|
||||
{
|
||||
await using var store = await Stores.Open();
|
||||
var source = await store.AddSourceAsync(@"C:\media");
|
||||
var zip = new IndexEntry
|
||||
{
|
||||
SourceId = source.Id,
|
||||
Name = "photos.zip",
|
||||
NameNorm = "photos.zip",
|
||||
Extension = "zip",
|
||||
PathRel = "photos.zip",
|
||||
LastSeenUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
zip.Id = await store.Entries.UpsertAsync(zip);
|
||||
Assert.Equal(FileCategory.Archive, (await store.Entries.GetAsync(zip.Id))!.Category);
|
||||
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
await store.Entries.UpsertAsync(new IndexEntry
|
||||
{
|
||||
SourceId = source.Id,
|
||||
ParentId = zip.Id,
|
||||
Name = $"shot{i}.jpg",
|
||||
NameNorm = $"shot{i}.jpg",
|
||||
Extension = "jpg",
|
||||
PathRel = $"photos.zip/shot{i}.jpg",
|
||||
LastSeenUtc = DateTimeOffset.UtcNow
|
||||
});
|
||||
}
|
||||
|
||||
var needing = await store.Entries.GetArchiveIdsNeedingContentClassifyAsync(10);
|
||||
Assert.Contains(zip.Id, needing);
|
||||
await store.Entries.RefreshCategoryFromChildrenAsync(zip.Id);
|
||||
var loaded = await store.Entries.GetAsync(zip.Id);
|
||||
Assert.Equal(FileCategory.Photos, loaded!.Category);
|
||||
Assert.Equal(CategorySources.ArchiveContents, loaded.CategorySource);
|
||||
Assert.Empty(await store.Entries.GetArchiveIdsNeedingContentClassifyAsync(10));
|
||||
|
||||
var mystery = new IndexEntry
|
||||
{
|
||||
SourceId = source.Id,
|
||||
Name = "mystery.bin",
|
||||
NameNorm = "mystery.bin",
|
||||
Extension = "bin",
|
||||
PathRel = "mystery.bin",
|
||||
LastSeenUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
mystery.Id = await store.Entries.UpsertAsync(mystery);
|
||||
var unknowns = await store.Entries.GetUnknownFilesForSignatureAsync(10);
|
||||
Assert.Contains(unknowns, e => e.Id == mystery.Id);
|
||||
Assert.Equal(0, await store.Entries.BackfillCheapCategoriesAsync(50));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task User_category_by_path_is_preserved()
|
||||
{
|
||||
await using var store = await Stores.Open();
|
||||
var source = await store.AddSourceAsync(@"C:\media");
|
||||
var photo = new IndexEntry
|
||||
{
|
||||
SourceId = source.Id,
|
||||
Name = "shot.jpg",
|
||||
NameNorm = "shot.jpg",
|
||||
Extension = "jpg",
|
||||
PathRel = "shot.jpg",
|
||||
LastSeenUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
photo.Id = await store.Entries.UpsertAsync(photo);
|
||||
var mutations = new Explorer.Application.LocalIndexMutations(store);
|
||||
await mutations.SetUserCategoryByPathAsync(@"C:\media\shot.jpg", FileCategory.Installer, "Manual");
|
||||
var loaded = await store.Entries.GetAsync(photo.Id);
|
||||
Assert.Equal(FileCategory.Installer, loaded!.Category);
|
||||
Assert.Equal(CategorySources.User, loaded.CategorySource);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Folder_aggregates_and_tombstones()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user