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(), Substitute.For(), Substitute.For(), Substitute.For(), Substitute.For(), Substitute.For(), Options.Create(new LibraryOptions()), MetadataMonitor.Empty, NullLogger.Instance); }