Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (push) Skipped
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (push) Skipped
Build ErsatzTV Image / CI toolchain image resolves (push) Successful in 9s
Build ErsatzTV Image / Delimiter ban (release path) (push) Successful in 25s
Build ErsatzTV Image / Build & test (.NET) (push) Successful in 8m40s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (push) Successful in 6m18s
Build ErsatzTV Image / Functional E2E (curl + UI contracts) (push) Successful in 6m12s
Build ErsatzTV Image / Build & push image (amd64) (push) Successful in 4m13s
probe742/combined-newest SECOND
Co-authored-by: Timothy <timothy@noreply.gitea.tblindustries.be>
93 lines
3.0 KiB
C#
93 lines
3.0 KiB
C#
using ErsatzTV.Application.Channels;
|
|
using ErsatzTV.Core;
|
|
using ErsatzTV.Core.Domain;
|
|
using ErsatzTV.Core.Graphics;
|
|
using ErsatzTV.FFmpeg.State;
|
|
using ErsatzTV.Infrastructure.Data;
|
|
using ErsatzTV.Tests.Support;
|
|
using LanguageExt;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using NUnit.Framework;
|
|
using Shouldly;
|
|
|
|
namespace ErsatzTV.Tests.Application.Channels;
|
|
|
|
/// <summary>
|
|
/// #732: the On Now / Next overlay is a default rather than an opt-in, so a channel created after
|
|
/// that decision gets the built-in element without the operator toggling anything.
|
|
/// </summary>
|
|
[TestFixture]
|
|
public class CreateChannelDefaultGraphicsElementTests : ChannelHandlerTestBase
|
|
{
|
|
private CreateChannelHandler MakeHandler() => new(Worker, Db.Factory, SearchTargets, RemoteLogoCacher);
|
|
|
|
private async Task<int> SeedBuiltInElement()
|
|
{
|
|
await using TvContext context = Db.CreateContext();
|
|
var element = new GraphicsElement
|
|
{
|
|
Path = $"/templates/text/{GraphicsElementDefaults.OnNowNextFileName}",
|
|
Kind = GraphicsElementKind.Text
|
|
};
|
|
|
|
context.GraphicsElements.Add(element);
|
|
await context.SaveChangesAsync();
|
|
return element.Id;
|
|
}
|
|
|
|
private async Task<List<int>> AttachedElementIds(int channelId)
|
|
{
|
|
await using TvContext context = Db.CreateContext();
|
|
Channel reloaded = await context.Channels
|
|
.Include(c => c.ChannelGraphicsElements)
|
|
.SingleAsync(c => c.Id == channelId);
|
|
|
|
return reloaded.ChannelGraphicsElements.Select(x => x.GraphicsElementId).ToList();
|
|
}
|
|
|
|
[Test]
|
|
public async Task Attaches_The_Built_In_Element_To_A_New_Channel()
|
|
{
|
|
await SeedFFmpegProfile();
|
|
int elementId = await SeedBuiltInElement();
|
|
|
|
Either<BaseError, CreateChannelResult> result =
|
|
await MakeHandler().Handle(MakeCreate(), CancellationToken.None);
|
|
|
|
result.IsRight.ShouldBeTrue();
|
|
int channelId = result.RightToSeq().Head().ChannelId;
|
|
|
|
(await AttachedElementIds(channelId)).ShouldBe([elementId]);
|
|
}
|
|
|
|
[Test]
|
|
public async Task Leaves_An_Hls_Direct_Channel_Alone_Because_Nothing_Can_Render_There()
|
|
{
|
|
await SeedFFmpegProfile();
|
|
await SeedBuiltInElement();
|
|
|
|
Either<BaseError, CreateChannelResult> result = await MakeHandler().Handle(
|
|
MakeCreate(streamingMode: StreamingMode.HttpLiveStreamingDirect),
|
|
CancellationToken.None);
|
|
|
|
result.IsRight.ShouldBeTrue();
|
|
int channelId = result.RightToSeq().Head().ChannelId;
|
|
|
|
(await AttachedElementIds(channelId)).ShouldBeEmpty();
|
|
}
|
|
|
|
[Test]
|
|
public async Task Creates_The_Channel_Even_When_The_Built_In_Element_Does_Not_Exist()
|
|
{
|
|
await SeedFFmpegProfile();
|
|
|
|
Either<BaseError, CreateChannelResult> result =
|
|
await MakeHandler().Handle(MakeCreate(), CancellationToken.None);
|
|
|
|
result.IsRight.ShouldBeTrue();
|
|
int channelId = result.RightToSeq().Head().ChannelId;
|
|
|
|
(await AttachedElementIds(channelId)).ShouldBeEmpty();
|
|
}
|
|
}
|