Refactor ILibraryService and LibraryService to support new metadata handling features, including remote image management and enhanced label summaries. Update LabelSummary to include ImagePath for better visual representation. Revise MetadataMatchViewModel and MetadataScanViewModel to accommodate new image loading logic. Enhance README.md to document these updates and new functionalities.
This commit is contained in:
@@ -1,84 +1,85 @@
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NSubstitute;
|
||||
using PLib.Application.Abstractions;
|
||||
using PLib.Application.Library;
|
||||
using PLib.Domain.Videos;
|
||||
using Shouldly;
|
||||
|
||||
namespace PLib.Tests.Library;
|
||||
|
||||
public sealed class LabelTests
|
||||
{
|
||||
private readonly InMemoryVideoRepository _videos = new();
|
||||
private readonly InMemoryLabelRepository _labels = new();
|
||||
private readonly VideoItem _video = new(@"C:\videos\a.mp4", "a", 1_000, DateTimeOffset.UnixEpoch);
|
||||
|
||||
public LabelTests() => _videos.Seed(_video);
|
||||
|
||||
[Fact]
|
||||
public async Task A_name_used_for_the_first_time_creates_the_label()
|
||||
{
|
||||
var label = await CreateService().AttachLabelAsync(_video.Id, "Комедия", LabelKind.Tag, Token);
|
||||
|
||||
label.Name.ShouldBe("Комедия");
|
||||
_video.Labels.ShouldHaveSingleItem();
|
||||
(await _labels.GetAllAsync(Token)).ShouldHaveSingleItem();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task The_same_name_in_another_case_reuses_the_label_that_already_exists()
|
||||
{
|
||||
var service = CreateService();
|
||||
|
||||
var first = await service.AttachLabelAsync(_video.Id, "Комедия", LabelKind.Tag, Token);
|
||||
var second = await service.AttachLabelAsync(_video.Id, " комедия ", LabelKind.Tag, Token);
|
||||
|
||||
second.Id.ShouldBe(first.Id);
|
||||
(await _labels.GetAllAsync(Token)).ShouldHaveSingleItem();
|
||||
|
||||
// And attaching it twice must not double it up on the video.
|
||||
_video.Labels.ShouldHaveSingleItem();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task A_tag_and_a_collection_may_share_a_name()
|
||||
{
|
||||
var service = CreateService();
|
||||
|
||||
var tag = await service.AttachLabelAsync(_video.Id, "Марвел", LabelKind.Tag, Token);
|
||||
var collection = await service.AttachLabelAsync(_video.Id, "Марвел", LabelKind.Collection, Token);
|
||||
|
||||
collection.Id.ShouldNotBe(tag.Id);
|
||||
_video.Labels.Count.ShouldBe(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Detaching_leaves_the_label_itself_in_the_library()
|
||||
{
|
||||
var service = CreateService();
|
||||
var label = await service.AttachLabelAsync(_video.Id, "Комедия", LabelKind.Tag, Token);
|
||||
|
||||
await service.DetachLabelAsync(_video.Id, label.Id, Token);
|
||||
|
||||
_video.Labels.ShouldBeEmpty();
|
||||
|
||||
// Other videos may still use it, and re-adding must not make a second one.
|
||||
(await _labels.GetAllAsync(Token)).ShouldHaveSingleItem();
|
||||
}
|
||||
|
||||
private static CancellationToken Token => TestContext.Current.CancellationToken;
|
||||
|
||||
private LibraryService CreateService() => new(
|
||||
_videos,
|
||||
_labels,
|
||||
Substitute.For<IVideoFileScanner>(),
|
||||
Substitute.For<IMediaProbe>(),
|
||||
Substitute.For<IThumbnailGenerator>(),
|
||||
Substitute.For<IAnimatedPreviewGenerator>(),
|
||||
Substitute.For<IVideoPerceptualHasher>(),
|
||||
Substitute.For<IMetadataProvider>(),
|
||||
Options.Create(new LibraryOptions()),
|
||||
MetadataMonitor.Empty,
|
||||
NullLogger<LibraryService>.Instance);
|
||||
}
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NSubstitute;
|
||||
using PLib.Application.Abstractions;
|
||||
using PLib.Application.Library;
|
||||
using PLib.Domain.Videos;
|
||||
using Shouldly;
|
||||
|
||||
namespace PLib.Tests.Library;
|
||||
|
||||
public sealed class LabelTests
|
||||
{
|
||||
private readonly InMemoryVideoRepository _videos = new();
|
||||
private readonly InMemoryLabelRepository _labels = new();
|
||||
private readonly VideoItem _video = new(@"C:\videos\a.mp4", "a", 1_000, DateTimeOffset.UnixEpoch);
|
||||
|
||||
public LabelTests() => _videos.Seed(_video);
|
||||
|
||||
[Fact]
|
||||
public async Task A_name_used_for_the_first_time_creates_the_label()
|
||||
{
|
||||
var label = await CreateService().AttachLabelAsync(_video.Id, "Комедия", LabelKind.Tag, Token);
|
||||
|
||||
label.Name.ShouldBe("Комедия");
|
||||
_video.Labels.ShouldHaveSingleItem();
|
||||
(await _labels.GetAllAsync(Token)).ShouldHaveSingleItem();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task The_same_name_in_another_case_reuses_the_label_that_already_exists()
|
||||
{
|
||||
var service = CreateService();
|
||||
|
||||
var first = await service.AttachLabelAsync(_video.Id, "Комедия", LabelKind.Tag, Token);
|
||||
var second = await service.AttachLabelAsync(_video.Id, " комедия ", LabelKind.Tag, Token);
|
||||
|
||||
second.Id.ShouldBe(first.Id);
|
||||
(await _labels.GetAllAsync(Token)).ShouldHaveSingleItem();
|
||||
|
||||
// And attaching it twice must not double it up on the video.
|
||||
_video.Labels.ShouldHaveSingleItem();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task A_tag_and_a_collection_may_share_a_name()
|
||||
{
|
||||
var service = CreateService();
|
||||
|
||||
var tag = await service.AttachLabelAsync(_video.Id, "Марвел", LabelKind.Tag, Token);
|
||||
var collection = await service.AttachLabelAsync(_video.Id, "Марвел", LabelKind.Collection, Token);
|
||||
|
||||
collection.Id.ShouldNotBe(tag.Id);
|
||||
_video.Labels.Count.ShouldBe(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Detaching_leaves_the_label_itself_in_the_library()
|
||||
{
|
||||
var service = CreateService();
|
||||
var label = await service.AttachLabelAsync(_video.Id, "Комедия", LabelKind.Tag, Token);
|
||||
|
||||
await service.DetachLabelAsync(_video.Id, label.Id, Token);
|
||||
|
||||
_video.Labels.ShouldBeEmpty();
|
||||
|
||||
// Other videos may still use it, and re-adding must not make a second one.
|
||||
(await _labels.GetAllAsync(Token)).ShouldHaveSingleItem();
|
||||
}
|
||||
|
||||
private static CancellationToken Token => TestContext.Current.CancellationToken;
|
||||
|
||||
private LibraryService CreateService() => new(
|
||||
_videos,
|
||||
_labels,
|
||||
Substitute.For<IVideoFileScanner>(),
|
||||
Substitute.For<IMediaProbe>(),
|
||||
Substitute.For<IThumbnailGenerator>(),
|
||||
Substitute.For<IAnimatedPreviewGenerator>(),
|
||||
Substitute.For<IVideoPerceptualHasher>(),
|
||||
Substitute.For<IMetadataProvider>(),
|
||||
Substitute.For<IRemoteImageCache>(),
|
||||
Options.Create(new LibraryOptions()),
|
||||
MetadataMonitor.Empty,
|
||||
NullLogger<LibraryService>.Instance);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user