131 lines
4.9 KiB
C#
131 lines
4.9 KiB
C#
using System.Threading.Channels;
|
|
using ErsatzTV.Application;
|
|
using ErsatzTV.Application.Playouts;
|
|
using ErsatzTV.Core;
|
|
using ErsatzTV.Core.Domain;
|
|
using ErsatzTV.Core.Scheduling;
|
|
using ErsatzTV.Infrastructure.Data;
|
|
using ErsatzTV.Tests.Support;
|
|
using LanguageExt;
|
|
using MediatR;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using NSubstitute;
|
|
using NUnit.Framework;
|
|
using Shouldly;
|
|
using Testably.Abstractions.Testing;
|
|
using Unit = LanguageExt.Unit;
|
|
using Channel = System.Threading.Channels.Channel;
|
|
|
|
namespace ErsatzTV.Tests.Integration;
|
|
|
|
[TestFixture]
|
|
public class PlayoutLifecycleIntegrationTests
|
|
{
|
|
private InMemoryTvContext _db = null!;
|
|
private Channel<IBackgroundServiceRequest> _worker = null!;
|
|
|
|
[SetUp]
|
|
public async Task SetUp()
|
|
{
|
|
_db = await InMemoryTvContext.CreateAsync();
|
|
_worker = Channel.CreateUnbounded<IBackgroundServiceRequest>();
|
|
}
|
|
|
|
[TearDown]
|
|
public async Task TearDown() => await _db.DisposeAsync();
|
|
|
|
[Test]
|
|
public async Task CreateClassic_Should_Link_Channel_And_Schedule_And_Enqueue_Build()
|
|
{
|
|
(int channelId, int scheduleId) = await SeedChannelAndSchedule();
|
|
var handler = new CreateClassicPlayoutHandler(_worker.Writer, _db.Factory);
|
|
|
|
Either<BaseError, CreatePlayoutResponse> result =
|
|
await handler.Handle(new CreateClassicPlayout(channelId, scheduleId), CancellationToken.None);
|
|
|
|
CreatePlayoutResponse response = result.Match(
|
|
Right: r => r,
|
|
Left: error => throw new AssertionException(error.Value));
|
|
|
|
await using TvContext context = _db.CreateContext();
|
|
Playout playout = await context.Playouts.SingleAsync();
|
|
playout.Id.ShouldBe(response.PlayoutId);
|
|
playout.ChannelId.ShouldBe(channelId);
|
|
playout.ProgramScheduleId.ShouldBe(scheduleId);
|
|
playout.ScheduleKind.ShouldBe(PlayoutScheduleKind.Classic);
|
|
|
|
IBackgroundServiceRequest backgroundRequest = await _worker.Reader.ReadAsync();
|
|
backgroundRequest.ShouldBeOfType<BuildPlayout>().PlayoutId.ShouldBe(playout.Id);
|
|
}
|
|
|
|
[Test]
|
|
public async Task Delete_Should_Remove_Playout_Without_Deleting_Channel_Or_Schedule()
|
|
{
|
|
(int channelId, int scheduleId) = await SeedChannelAndSchedule();
|
|
var createHandler = new CreateClassicPlayoutHandler(_worker.Writer, _db.Factory);
|
|
int playoutId = (await createHandler.Handle(new CreateClassicPlayout(channelId, scheduleId), CancellationToken.None))
|
|
.Match(Right: r => r.PlayoutId, Left: error => throw new AssertionException(error.Value));
|
|
var deleteHandler = new DeletePlayoutHandler(
|
|
_worker.Writer,
|
|
_db.Factory,
|
|
new MockFileSystem(),
|
|
Substitute.For<IMediator>());
|
|
|
|
Either<BaseError, Unit> result = await deleteHandler.Handle(new DeletePlayout(playoutId), CancellationToken.None);
|
|
|
|
result.IsRight.ShouldBeTrue();
|
|
await using TvContext context = _db.CreateContext();
|
|
(await context.Playouts.CountAsync()).ShouldBe(0);
|
|
(await context.Channels.CountAsync(c => c.Id == channelId)).ShouldBe(1);
|
|
(await context.ProgramSchedules.CountAsync(ps => ps.Id == scheduleId)).ShouldBe(1);
|
|
}
|
|
|
|
private async Task<(int ChannelId, int ScheduleId)> SeedChannelAndSchedule()
|
|
{
|
|
await using TvContext context = _db.CreateContext();
|
|
var channel = new ErsatzTV.Core.Domain.Channel(Guid.NewGuid())
|
|
{
|
|
Number = "101",
|
|
SortNumber = 101,
|
|
Name = "Lifecycle",
|
|
Group = string.Empty,
|
|
Categories = string.Empty,
|
|
StreamingMode = StreamingMode.HttpLiveStreamingSegmenter,
|
|
Playouts = [],
|
|
Artwork = [],
|
|
StreamSelector = string.Empty,
|
|
PreferredAudioLanguageCode = string.Empty,
|
|
PreferredAudioTitle = string.Empty,
|
|
PreferredSubtitleLanguageCode = string.Empty,
|
|
MusicVideoCreditsTemplate = string.Empty,
|
|
PlayoutSource = ChannelPlayoutSource.Generated,
|
|
PlayoutMode = ChannelPlayoutMode.Continuous,
|
|
IsEnabled = true,
|
|
ShowInEpg = true
|
|
};
|
|
var schedule = new ProgramSchedule
|
|
{
|
|
Name = "Lifecycle",
|
|
Items =
|
|
[
|
|
new ProgramScheduleItemOne
|
|
{
|
|
Index = 0,
|
|
CollectionType = CollectionType.SearchQuery,
|
|
SearchQuery = "news",
|
|
PlaybackOrder = PlaybackOrder.Shuffle,
|
|
GuideMode = GuideMode.Normal,
|
|
Watermarks = [],
|
|
GraphicsElements = []
|
|
}
|
|
],
|
|
Playouts = [],
|
|
ProgramScheduleAlternates = []
|
|
};
|
|
context.Channels.Add(channel);
|
|
context.ProgramSchedules.Add(schedule);
|
|
await context.SaveChangesAsync();
|
|
return (channel.Id, schedule.Id);
|
|
}
|
|
}
|