using TeleWave.Application.Library.ListShows; using TeleWave.Application.Tests.Support; using TeleWave.Domain.Library; using TeleWave.Domain.Media; using Xunit; namespace TeleWave.Application.Tests.Library; /// /// Список библиотеки: он же считает сезоны (номера в модели не хранятся — только в именах файлов) /// и подставляет названия жанров, поэтому проверяем именно сводку, а не факт выборки. /// public class ListShowsTests { private sealed record Seeded(TestDb Db, Guid ActionGenreId, Guid DramaGenreId, Guid SeriesId); private static async Task SeedAsync() { var fixture = new TestDb(); var action = Genre.Create("Боевик", "action"); var drama = Genre.Create("Драма", "drama"); var series = Show.Create("Сериал", ShowKind.Series); series.SetGenres([action.Id, drama.Id], action.Id); series.SetPosterImage(Guid.NewGuid()); var assets = new[] { MediaAsset.Register("Serial.S01E01.mkv", ".mkv", MediaSource.Upload), MediaAsset.Register("Serial.S01E02.mkv", ".mkv", MediaSource.Upload), MediaAsset.Register("Serial.S02E01.mkv", ".mkv", MediaSource.Upload), // Имя без метки сезона: серия считается, сезон — нет. MediaAsset.Register("Serial-bonus.mkv", ".mkv", MediaSource.Upload), }; foreach (var asset in assets) series.AddEpisode(asset.Id); var film = Show.Create("Автофильм", ShowKind.Single); var bumper = Show.Create("Ролик", ShowKind.Interstitial); await using var seed = fixture.New(); seed.Genres.AddRange(action, drama); seed.MediaAssets.AddRange(assets); seed.Shows.AddRange(series, film, bumper); await seed.SaveChangesAsync(CancellationToken.None); return new Seeded(fixture, action.Id, drama.Id, series.Id); } [Fact] public async Task List_ReturnsContentSortedByName_WithoutInterstitials() { var seeded = await SeedAsync(); await using var db = seeded.Db.New(); var shows = await new ListShowsQueryHandler(db).Handle( new ListShowsQuery(), CancellationToken.None ); // Ролики-врезки живут на своей странице и в общей библиотеке только мешали бы. Assert.Equal(["Автофильм", "Сериал"], shows.Select(s => s.Name).ToArray()); } [Fact] public async Task List_CountsEpisodesAndDistinctSeasons() { var seeded = await SeedAsync(); await using var db = seeded.Db.New(); var shows = await new ListShowsQueryHandler(db).Handle( new ListShowsQuery(), CancellationToken.None ); var series = shows.Single(s => s.Id == seeded.SeriesId); Assert.Equal(4, series.EpisodeCount); Assert.Equal(2, series.SeasonCount); Assert.True(series.HasPoster); Assert.Equal("Боевик", series.PrimaryGenre); Assert.Equal(["Драма"], series.OtherGenres.ToArray()); } [Fact] public async Task List_ByGenre_KeepsOnlyShowsWithIt() { var seeded = await SeedAsync(); await using var db = seeded.Db.New(); var byDrama = await new ListShowsQueryHandler(db).Handle( new ListShowsQuery(seeded.DramaGenreId), CancellationToken.None ); var byUnknown = await new ListShowsQueryHandler(db).Handle( new ListShowsQuery(Guid.NewGuid()), CancellationToken.None ); // Жанр ищется среди всех, а не только основного. Assert.Equal(seeded.SeriesId, Assert.Single(byDrama).Id); Assert.Empty(byUnknown); } [Fact] public async Task List_Interstitials_ReturnsOnlyThem() { var seeded = await SeedAsync(); await using var db = seeded.Db.New(); var shows = await new ListShowsQueryHandler(db).Handle( new ListShowsQuery(Interstitials: true), CancellationToken.None ); var only = Assert.Single(shows); Assert.Equal("Ролик", only.Name); Assert.Equal(ShowKind.Interstitial, only.Kind); Assert.Equal(0, only.SeasonCount); Assert.Null(only.PrimaryGenre); Assert.False(only.HasPoster); } }