using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Library.Collections;
using TeleWave.Application.Library.Collections.FillCollectionPosters;
using TeleWave.Application.Tests.Support;
using TeleWave.Domain.Images;
using TeleWave.Domain.Library;
using Xunit;
namespace TeleWave.Application.Tests.Library;
///
/// Постер коллекции по её частям. Правило простое и объяснимое: обложка первой части — франшиза
/// узнаётся именно по ней, а коллекция без картинки теряется в списке.
///
public class CollectionPosterTests
{
private static Show WithPoster(string name, Guid? imageId)
{
var show = Show.Create(name, ShowKind.Single);
if (imageId is { } id)
show.ApplyMetadata("tmdb", name, null, 1990, id);
return show;
}
private static async Task FillAsync(TestDb fixture, params Guid[] ids)
{
await using var db = fixture.New();
var result = await new FillCollectionPostersCommandHandler(
db,
new CollectionPosterPicker(db)
).Handle(
new FillCollectionPostersCommand(ids.Length > 0 ? ids : null),
CancellationToken.None
);
Assert.True(result.IsSuccess);
await db.SaveChangesAsync(CancellationToken.None);
return result.Value;
}
[Fact]
public async Task TakesPosterOfTheFirstPart()
{
var fixture = new TestDb();
var poster = Image.Create(ImageCategory.ShowPoster, ".jpg", "Терминатор");
var second = Image.Create(ImageCategory.ShowPoster, ".jpg", "Терминатор 2");
var first = WithPoster("Терминатор", poster.Id);
var sequel = WithPoster("Терминатор 2", second.Id);
var collection = Collection.Create("Терминатор");
collection.AddShow(first.Id);
collection.AddShow(sequel.Id);
await using (var seed = fixture.New())
{
seed.Images.AddRange(poster, second);
seed.Shows.AddRange(first, sequel);
seed.Collections.Add(collection);
await seed.SaveChangesAsync(CancellationToken.None);
}
Assert.Equal(1, await FillAsync(fixture));
await using var db = fixture.New();
var stored = await db.Collections.SingleAsync(CancellationToken.None);
Assert.Equal(poster.Id, stored.PosterImageId);
}
[Fact]
public async Task SkipsFirstPartWithoutPoster()
{
// У первой части постера нет — берём следующую с обложкой, а не оставляем коллекцию пустой.
var fixture = new TestDb();
var poster = Image.Create(ImageCategory.ShowPoster, ".jpg", "Вторая часть");
var first = WithPoster("Первая часть", null);
var second = WithPoster("Вторая часть", poster.Id);
var collection = Collection.Create("Цикл");
collection.AddShow(first.Id);
collection.AddShow(second.Id);
await using (var seed = fixture.New())
{
seed.Images.Add(poster);
seed.Shows.AddRange(first, second);
seed.Collections.Add(collection);
await seed.SaveChangesAsync(CancellationToken.None);
}
Assert.Equal(1, await FillAsync(fixture));
await using var db = fixture.New();
Assert.Equal(
poster.Id,
(await db.Collections.SingleAsync(CancellationToken.None)).PosterImageId
);
}
[Fact]
public async Task KeepsPosterChosenByHand()
{
// Выбор человека автоматика не перебивает: он мог поставить кадр, а не обложку первой части.
var fixture = new TestDb();
var chosen = Image.Create(ImageCategory.ShowPoster, ".jpg", "Выбранный");
var showPoster = Image.Create(ImageCategory.ShowPoster, ".jpg", "Часть");
var show = WithPoster("Часть", showPoster.Id);
var collection = Collection.Create("Цикл");
collection.AddShow(show.Id);
collection.SetPosterImage(chosen.Id);
await using (var seed = fixture.New())
{
seed.Images.AddRange(chosen, showPoster);
seed.Shows.Add(show);
seed.Collections.Add(collection);
await seed.SaveChangesAsync(CancellationToken.None);
}
Assert.Equal(0, await FillAsync(fixture));
await using var db = fixture.New();
Assert.Equal(
chosen.Id,
(await db.Collections.SingleAsync(CancellationToken.None)).PosterImageId
);
}
[Fact]
public async Task LeavesCollectionWithoutPostersAlone()
{
// Ни у одной части нет обложки — ставить нечего, и это не ошибка.
var fixture = new TestDb();
var show = WithPoster("Часть", null);
var collection = Collection.Create("Цикл");
collection.AddShow(show.Id);
await using (var seed = fixture.New())
{
seed.Shows.Add(show);
seed.Collections.Add(collection);
await seed.SaveChangesAsync(CancellationToken.None);
}
Assert.Equal(0, await FillAsync(fixture));
await using var db = fixture.New();
Assert.Null((await db.Collections.SingleAsync(CancellationToken.None)).PosterImageId);
}
[Fact]
public async Task FillsOnlyRequestedCollections()
{
var fixture = new TestDb();
var poster = Image.Create(ImageCategory.ShowPoster, ".jpg", "Часть");
var show = WithPoster("Часть", poster.Id);
var wanted = Collection.Create("Нужная");
wanted.AddShow(show.Id);
var other = Collection.Create("Другая");
other.AddShow(show.Id);
await using (var seed = fixture.New())
{
seed.Images.Add(poster);
seed.Shows.Add(show);
seed.Collections.AddRange(wanted, other);
await seed.SaveChangesAsync(CancellationToken.None);
}
Assert.Equal(1, await FillAsync(fixture, wanted.Id));
await using var db = fixture.New();
Assert.NotNull((await db.Collections.SingleAsync(c => c.Id == wanted.Id)).PosterImageId);
Assert.Null((await db.Collections.SingleAsync(c => c.Id == other.Id)).PosterImageId);
}
}