using TeleWave.Application.Library.GetShowUsage;
using TeleWave.Application.Programming.Groups;
using TeleWave.Application.Tests.Support;
using TeleWave.Domain.Broadcast;
using TeleWave.Domain.Library;
using TeleWave.Domain.Programming;
using Xunit;
namespace TeleWave.Application.Tests.Library;
///
/// «Где используется» для шоу: удаление отбивается ошибкой «используется», и без этого списка
/// непонятно, кем именно.
///
public class ShowUsageTests
{
[Fact]
public async Task ReportsExplicitGroupMembership()
{
var fixture = new TestDb();
var show = Show.Create("Шоу", ShowKind.Series);
var group = Group.Create("Явная");
group.AddElement(GroupElementKind.Show, show.Id);
await using (var seed = fixture.New())
{
seed.Shows.Add(show);
seed.Groups.Add(group);
await seed.SaveChangesAsync(CancellationToken.None);
}
var usage = await GetAsync(fixture, show.Id);
var reference = Assert.Single(usage.Groups);
Assert.Equal("Явная", reference.Name);
Assert.False(reference.ViaRule);
}
[Fact]
public async Task ReportsMembershipByRule()
{
// У динамической группы шоу входит без своей позиции — для «можно ли удалять» это то же самое.
var fixture = new TestDb();
var genre = Genre.Create("Мультфильм", "animation");
var show = Show.Create("Шоу", ShowKind.Series);
show.SetGenres([genre.Id]);
var group = Group.Create("По правилу");
group.SetFilter(new GroupFilter(GenreIds: [genre.Id]).ToJson());
group.SetMode(GroupMode.Dynamic);
await using (var seed = fixture.New())
{
seed.Genres.Add(genre);
seed.Shows.Add(show);
seed.Groups.Add(group);
await seed.SaveChangesAsync(CancellationToken.None);
}
var usage = await GetAsync(fixture, show.Id);
Assert.True(Assert.Single(usage.Groups).ViaRule);
}
[Fact]
public async Task ReportsCollectionsAndGroupsReachedThroughThem()
{
// В группу шоу попадает и через франшизу, целиком — это тоже использование.
var fixture = new TestDb();
var show = Show.Create("Часть", ShowKind.Single);
var collection = Collection.Create("Франшиза");
collection.AddShow(show.Id);
var group = Group.Create("С франшизой");
group.AddElement(GroupElementKind.Collection, collection.Id);
await using (var seed = fixture.New())
{
seed.Shows.Add(show);
seed.Collections.Add(collection);
seed.Groups.Add(group);
await seed.SaveChangesAsync(CancellationToken.None);
}
var usage = await GetAsync(fixture, show.Id);
Assert.Equal("Франшиза", Assert.Single(usage.Collections).Name);
Assert.Equal("С франшизой", Assert.Single(usage.Groups).Name);
}
[Fact]
public async Task ReportsChannelsWithScheduledEntries()
{
var fixture = new TestDb();
var show = Show.Create("Шоу", ShowKind.Series);
var channel = Channel.Create("Первый", "one", DateTimeOffset.UtcNow);
var start = new DateTimeOffset(2026, 3, 1, 12, 0, 0, TimeSpan.Zero);
await using (var seed = fixture.New())
{
seed.Shows.Add(show);
seed.Channels.Add(channel);
seed.ScheduleEntries.Add(
ScheduleEntry.Program(
channel.Id,
Guid.NewGuid(),
start,
start.AddMinutes(30),
show.Id,
0
)
);
await seed.SaveChangesAsync(CancellationToken.None);
}
var usage = await GetAsync(fixture, show.Id);
Assert.Equal("Первый", Assert.Single(usage.Channels).Name);
}
[Fact]
public async Task UnknownShow_ReturnsNotFound()
{
var fixture = new TestDb();
await using var db = fixture.New();
var result = await new GetShowUsageQueryHandler(db, GroupServices.Dynamic(db)).Handle(
new GetShowUsageQuery(Guid.NewGuid()),
CancellationToken.None
);
Assert.False(result.IsSuccess);
}
private static async Task GetAsync(TestDb fixture, Guid showId)
{
await using var db = fixture.New();
var result = await new GetShowUsageQueryHandler(db, GroupServices.Dynamic(db)).Handle(
new GetShowUsageQuery(showId),
CancellationToken.None
);
Assert.True(result.IsSuccess);
return result.Value;
}
}