Updated the DeleteShowCommand and its handler to include an optional parameter for media deletion, allowing users to remove associated media files when deleting a show. Refactored related components and API calls to accommodate this new feature, ensuring a seamless user experience. Additionally, updated localization strings to reflect the new functionality and adjusted tests to verify the correct behavior of the deletion process with and without media.
173 lines
5.9 KiB
C#
173 lines
5.9 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using NSubstitute;
|
|
using TeleWave.Application.Broadcast;
|
|
using TeleWave.Application.Broadcast.Bumpers;
|
|
using TeleWave.Application.Broadcast.GetChannel;
|
|
using TeleWave.Application.Broadcast.GetSchedule;
|
|
using TeleWave.Application.Broadcast.ListChannels;
|
|
using TeleWave.Application.Common.Interfaces;
|
|
using TeleWave.Application.Library.DeleteShow;
|
|
using TeleWave.Application.Library.GetShow;
|
|
using TeleWave.Application.Media;
|
|
using TeleWave.Application.Programming.Groups;
|
|
using TeleWave.Application.Tests.Support;
|
|
using TeleWave.Domain.Broadcast;
|
|
using TeleWave.Domain.Library;
|
|
using TeleWave.Domain.Media;
|
|
using Xunit;
|
|
|
|
namespace TeleWave.Application.Tests.Broadcast;
|
|
|
|
public class QueryHandlersTests
|
|
{
|
|
private static readonly DateTimeOffset T0 = new(2026, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
|
|
|
private static GroupMembershipCleaner GroupCleaner(IAppDbContext db) =>
|
|
new(db, GroupServices.Stats(db));
|
|
|
|
private static ShowMediaEraser Eraser(IAppDbContext db) =>
|
|
new(db, Substitute.For<IMediaStorage>());
|
|
|
|
[Fact]
|
|
public async Task GetChannel_UnknownId_ReturnsNotFound()
|
|
{
|
|
var fixture = new TestDb();
|
|
await using var db = fixture.New();
|
|
var result = await new GetChannelQueryHandler(db).Handle(
|
|
new GetChannelQuery(Guid.NewGuid()),
|
|
CancellationToken.None
|
|
);
|
|
Assert.False(result.IsSuccess);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ListChannels_ReturnsSummaries()
|
|
{
|
|
var fixture = new TestDb();
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.Channels.Add(Channel.Create("A", "a", T0));
|
|
seed.Channels.Add(Channel.Create("B", "b", T0));
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
await using var db = fixture.New();
|
|
var result = await new ListChannelsQueryHandler(db).Handle(
|
|
new ListChannelsQuery(),
|
|
CancellationToken.None
|
|
);
|
|
Assert.Equal(2, result.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetChannelSchedule_ReturnsEntriesWithBumperLabel()
|
|
{
|
|
var fixture = new TestDb();
|
|
var channel = Channel.Create("c", "c", T0);
|
|
var show = Show.Create("Show A", ShowKind.Series);
|
|
var bumperTemplate = BumperTemplate.Create("Блок", "Текст 1");
|
|
var variant = bumperTemplate.Variants[0];
|
|
var asset = MediaAsset.Register("Show.A.S01E01.mkv", ".mkv", MediaSource.Upload);
|
|
var bumperAsset = MediaAsset.RegisterGenerated("Блок: СЕЙЧАС / Show A");
|
|
// Метка в расписании берётся из кэша заставки — там лежит ровно тот текст, что играл.
|
|
var cache = BumperAsset.Create(
|
|
bumperTemplate.Id,
|
|
variant.Id,
|
|
"sig",
|
|
"""[{"style":"Label","color":"Accent","text":"СЕЙЧАС"},{"style":"Title","color":"Text","text":"Show A"}]""",
|
|
null,
|
|
bumperAsset.Id
|
|
);
|
|
var program = ScheduleEntry.Program(
|
|
channel.Id,
|
|
asset.Id,
|
|
T0,
|
|
T0.AddMinutes(20),
|
|
show.Id,
|
|
0
|
|
);
|
|
var bumper = ScheduleEntry.Bumper(
|
|
channel.Id,
|
|
bumperAsset.Id,
|
|
T0.AddMinutes(20),
|
|
T0.AddMinutes(20).AddSeconds(8),
|
|
show.Id,
|
|
variant.Id
|
|
);
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.Shows.Add(show);
|
|
seed.Channels.Add(channel);
|
|
seed.BumperTemplates.Add(bumperTemplate);
|
|
seed.MediaAssets.Add(asset);
|
|
seed.MediaAssets.Add(bumperAsset);
|
|
seed.BumperAssets.Add(cache);
|
|
seed.ScheduleEntries.Add(program);
|
|
seed.ScheduleEntries.Add(bumper);
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
await using var db = fixture.New();
|
|
var result = await new GetChannelScheduleQueryHandler(db).Handle(
|
|
new GetChannelScheduleQuery(channel.Id, T0.AddMinutes(-5), T0.AddHours(1)),
|
|
CancellationToken.None
|
|
);
|
|
|
|
Assert.True(result.IsSuccess);
|
|
Assert.Equal(2, result.Value.Count);
|
|
var bumperDto = result.Value.Single(e => e.Kind == ScheduleEntryKind.Bumper);
|
|
Assert.Equal("Текст 1", bumperDto.BumperName);
|
|
Assert.Equal("СЕЙЧАС · Show A", bumperDto.BumperText);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetShow_ReturnsDtoOrNotFound()
|
|
{
|
|
var fixture = new TestDb();
|
|
var show = Show.Create("A", ShowKind.Series);
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.Shows.Add(show);
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
await using var db = fixture.New();
|
|
var ok = await new GetShowQueryHandler(db).Handle(
|
|
new GetShowQuery(show.Id),
|
|
CancellationToken.None
|
|
);
|
|
Assert.True(ok.IsSuccess);
|
|
|
|
var missing = await new GetShowQueryHandler(db).Handle(
|
|
new GetShowQuery(Guid.NewGuid()),
|
|
CancellationToken.None
|
|
);
|
|
Assert.False(missing.IsSuccess);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteShow_RemovesOrNotFound()
|
|
{
|
|
var fixture = new TestDb();
|
|
var show = Show.Create("A", ShowKind.Series);
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.Shows.Add(show);
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
await using var db = fixture.New();
|
|
var missing = await new DeleteShowCommandHandler(db, GroupCleaner(db), Eraser(db)).Handle(
|
|
new DeleteShowCommand(Guid.NewGuid()),
|
|
CancellationToken.None
|
|
);
|
|
Assert.False(missing.IsSuccess);
|
|
|
|
var ok = await new DeleteShowCommandHandler(db, GroupCleaner(db), Eraser(db)).Handle(
|
|
new DeleteShowCommand(show.Id),
|
|
CancellationToken.None
|
|
);
|
|
Assert.True(ok.IsSuccess);
|
|
}
|
|
}
|