Implement BumperEndpoints and remove deprecated bumper-related functionality
Added new BumperEndpoints to the API for managing bumper templates and variants, enhancing the channel management capabilities. Removed outdated bumper-related commands and handlers from the application, streamlining the codebase and improving maintainability. Updated ChannelEndpoints to reflect these changes and ensure proper routing for the new endpoints.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using NSubstitute;
|
||||
using TeleWave.Application.Broadcast;
|
||||
using TeleWave.Application.Broadcast.Bumpers;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Streaming;
|
||||
@@ -16,8 +15,8 @@ namespace TeleWave.Application.Tests.Broadcast;
|
||||
|
||||
/// <summary>
|
||||
/// Превью ТВ-заставки: рендерится каждый подблок блока, длительность выравнивается по длине
|
||||
/// сегмента HLS, а названия «из/в» берутся из групп этого канала — иначе превью показывало бы
|
||||
/// случайные шоу из библиотеки.
|
||||
/// сегмента HLS, а плейсхолдеры подставляются образцами выбранного канала — блок общий, но
|
||||
/// смотреть на него надо глазами конкретного канала.
|
||||
/// </summary>
|
||||
public class BumperPreviewTests
|
||||
{
|
||||
@@ -38,49 +37,49 @@ public class BumperPreviewTests
|
||||
Options.Create(new StreamingOptions { SegmentSeconds = 5 })
|
||||
);
|
||||
|
||||
private static BumperTemplate NewTemplate()
|
||||
{
|
||||
var template = BumperTemplate.Create("Блок", "Текст 1");
|
||||
template
|
||||
.Variants[0]
|
||||
.SetLines([
|
||||
BumperLine.Create(0, BumperLineStyle.Label, BumperLineColor.Accent, "СЕЙЧАС"),
|
||||
BumperLine.Create(1, BumperLineStyle.Title, BumperLineColor.Text, "{now.title}"),
|
||||
BumperLine.Create(2, BumperLineStyle.Label, BumperLineColor.Accent, "ДАЛЕЕ"),
|
||||
BumperLine.Create(3, BumperLineStyle.Title, BumperLineColor.Text, "{next.title}"),
|
||||
]);
|
||||
return template;
|
||||
}
|
||||
|
||||
private static IReadOnlyList<BumperRenderSpec> Specs(IBumperRenderer renderer) =>
|
||||
renderer
|
||||
.ReceivedCalls()
|
||||
.Select(c => c.GetArguments()[1])
|
||||
.OfType<BumperRenderSpec>()
|
||||
.ToList();
|
||||
|
||||
[Fact]
|
||||
public async Task Render_UnknownChannel_ReturnsNotFound()
|
||||
public async Task Render_UnknownTemplate_ReturnsNotFound()
|
||||
{
|
||||
var fixture = new TestDb();
|
||||
await using var db = fixture.New();
|
||||
|
||||
var result = await Handler(db)
|
||||
.Handle(
|
||||
new RenderBumperPreviewCommand(Guid.NewGuid(), Guid.NewGuid()),
|
||||
CancellationToken.None
|
||||
);
|
||||
.Handle(new RenderBumperPreviewCommand(Guid.NewGuid(), null), CancellationToken.None);
|
||||
|
||||
Assert.Equal(ChannelErrors.NotFound, result.Error);
|
||||
Assert.Equal(BumperErrors.TemplateNotFound, result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Render_UnknownTemplate_ReturnsBumperTemplateNotFound()
|
||||
public async Task Render_DrawsEveryVariant_WithChannelSamplesAndAlignedDuration()
|
||||
{
|
||||
var fixture = new TestDb();
|
||||
var channel = Channel.Create("Первый", "one", T0);
|
||||
await using (var seed = fixture.New())
|
||||
{
|
||||
seed.Channels.Add(channel);
|
||||
await seed.SaveChangesAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
await using var db = fixture.New();
|
||||
var result = await Handler(db)
|
||||
.Handle(
|
||||
new RenderBumperPreviewCommand(channel.Id, Guid.NewGuid()),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
Assert.Equal(ChannelErrors.BumperTemplateNotFound, result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Render_DrawsEveryVariant_WithChannelShowNamesAndAlignedDuration()
|
||||
{
|
||||
var fixture = new TestDb();
|
||||
var channel = Channel.Create("Первый", "one", T0);
|
||||
var template = channel.BumperTemplates[0];
|
||||
var template = NewTemplate();
|
||||
var second = template.AddVariant("Второй подблок");
|
||||
second.SetLines([
|
||||
BumperLine.Create(0, BumperLineStyle.Title, BumperLineColor.Text, "{channel}"),
|
||||
]);
|
||||
|
||||
// Шоу канала: слот сетки ссылается на группу, в группе — шоу.
|
||||
var show = Show.Create("Наше шоу", ShowKind.Series);
|
||||
@@ -105,6 +104,7 @@ public class BumperPreviewTests
|
||||
await using (var seed = fixture.New())
|
||||
{
|
||||
seed.Channels.Add(channel);
|
||||
seed.BumperTemplates.Add(template);
|
||||
seed.Shows.Add(show);
|
||||
seed.Groups.Add(group);
|
||||
seed.ScheduleTemplates.Add(grid);
|
||||
@@ -115,7 +115,7 @@ public class BumperPreviewTests
|
||||
await using var db = fixture.New();
|
||||
var result = await Handler(db, renderer)
|
||||
.Handle(
|
||||
new RenderBumperPreviewCommand(channel.Id, template.Id),
|
||||
new RenderBumperPreviewCommand(template.Id, channel.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
@@ -136,32 +136,28 @@ public class BumperPreviewTests
|
||||
Arg.Any<CancellationToken>()
|
||||
);
|
||||
|
||||
var specs = renderer
|
||||
.ReceivedCalls()
|
||||
.Select(c => c.GetArguments()[1])
|
||||
.OfType<BumperRenderSpec>()
|
||||
.ToList();
|
||||
var specs = Specs(renderer);
|
||||
// Своего звука у блока нет: 8 секунд по умолчанию, выровненные вверх до сегмента в 5 сек.
|
||||
Assert.All(specs, s => Assert.Equal(10, s.DurationSeconds));
|
||||
Assert.All(specs, s => Assert.Equal("Наше шоу", s.NowTitle));
|
||||
// Второго шоу у канала нет — подставляется заглушка.
|
||||
Assert.All(specs, s => Assert.Equal("Второе шоу", s.NextTitle));
|
||||
Assert.All(specs, s => Assert.Null(s.BackgroundFile));
|
||||
Assert.All(specs, s => Assert.Null(s.PosterFile));
|
||||
|
||||
var nowNext = specs.First(s => s.Lines.Count == 4);
|
||||
Assert.Equal("Наше шоу", nowNext.Lines[1].Text);
|
||||
|
||||
var channelLine = specs.First(s => s.Lines.Count == 1);
|
||||
Assert.Equal("Первый", channelLine.Lines[0].Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Render_WithBackgroundImage_ResolvesPathFromRegistry()
|
||||
{
|
||||
var fixture = new TestDb();
|
||||
var channel = Channel.Create("Первый", "one", T0);
|
||||
var template = channel.BumperTemplates[0];
|
||||
var template = NewTemplate();
|
||||
var image = Image.Create(ImageCategory.BumperBackground, ".png", "bg.png");
|
||||
template.SetBackgroundImage(image.Id);
|
||||
|
||||
await using (var seed = fixture.New())
|
||||
{
|
||||
seed.Channels.Add(channel);
|
||||
seed.BumperTemplates.Add(template);
|
||||
seed.Images.Add(image);
|
||||
await seed.SaveChangesAsync(CancellationToken.None);
|
||||
}
|
||||
@@ -172,19 +168,40 @@ public class BumperPreviewTests
|
||||
|
||||
await using var db = fixture.New();
|
||||
var result = await Handler(db, renderer, imageStore: imageStore)
|
||||
.Handle(
|
||||
new RenderBumperPreviewCommand(channel.Id, template.Id),
|
||||
CancellationToken.None
|
||||
);
|
||||
.Handle(new RenderBumperPreviewCommand(template.Id, null), CancellationToken.None);
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
var spec = renderer
|
||||
.ReceivedCalls()
|
||||
.Select(c => c.GetArguments()[1])
|
||||
.OfType<BumperRenderSpec>()
|
||||
.First();
|
||||
var spec = Specs(renderer).First();
|
||||
Assert.Equal("/data/images/bg.png", spec.BackgroundFile);
|
||||
// Шоу у канала нет — обе подписи заглушечные.
|
||||
Assert.Equal("Первое шоу", spec.NowTitle);
|
||||
// Канала нет — образцы заглушечные, но кадр всё равно собирается.
|
||||
Assert.Equal("Первое шоу", spec.Lines[1].Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Render_DropsLinesThatResolveToNothing()
|
||||
{
|
||||
var fixture = new TestDb();
|
||||
var template = BumperTemplate.Create("Блок", "Текст 1");
|
||||
template
|
||||
.Variants[0]
|
||||
.SetLines([
|
||||
BumperLine.Create(0, BumperLineStyle.Label, BumperLineColor.Accent, "{next.genre}"),
|
||||
BumperLine.Create(1, BumperLineStyle.Title, BumperLineColor.Text, "{next.title}"),
|
||||
]);
|
||||
|
||||
await using (var seed = fixture.New())
|
||||
{
|
||||
seed.BumperTemplates.Add(template);
|
||||
await seed.SaveChangesAsync(CancellationToken.None);
|
||||
}
|
||||
|
||||
var renderer = Substitute.For<IBumperRenderer>();
|
||||
await using var db = fixture.New();
|
||||
await Handler(db, renderer)
|
||||
.Handle(new RenderBumperPreviewCommand(template.Id, null), CancellationToken.None);
|
||||
|
||||
// Жанра у образца нет — строка схлопнулась, а не оставила дыру в кадре.
|
||||
var spec = Specs(renderer).First();
|
||||
Assert.Single(spec.Lines);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user