using ErsatzTV.Application.Channels; using ErsatzTV.Core; using ErsatzTV.Core.Errors; using ErsatzTV.Infrastructure.Data; using ErsatzTV.Tests.Support; using LanguageExt; using Microsoft.EntityFrameworkCore; using NUnit.Framework; using Shouldly; namespace ErsatzTV.Tests.Application.Channels; [TestFixture] public class UpdateChannelNumbersHandlerTests : ChannelHandlerTestBase { private UpdateChannelNumbersHandler MakeHandler() => new(Db.Factory, Worker); [Test] public async Task Should_Renumber_All_Channels() { await SeedChannel(1, "5"); await SeedChannel(2, "6"); Option result = await MakeHandler().Handle( new UpdateChannelNumbers( [ new ChannelSortViewModel { Id = 1, Number = "10" }, new ChannelSortViewModel { Id = 2, Number = "11.1" } ]), CancellationToken.None); result.IsNone.ShouldBeTrue(); await using TvContext context = Db.CreateContext(); var channels = await context.Channels .OrderBy(c => c.Id) .Select(c => new { c.Number, c.SortNumber }) .ToListAsync(); channels[0].Number.ShouldBe("10"); channels[0].SortNumber.ShouldBe(10); channels[1].Number.ShouldBe("11.1"); channels[1].SortNumber.ShouldBe(11.1); } [Test] public async Task Should_Return_NotFound_And_Not_Renumber_When_Any_Channel_Is_Missing() { await SeedChannel(1, "5"); Option result = await MakeHandler().Handle( new UpdateChannelNumbers( [ new ChannelSortViewModel { Id = 1, Number = "10" }, new ChannelSortViewModel { Id = 99, Number = "11" } ]), CancellationToken.None); BaseError error = ErrorOf(result); error.ShouldBeOfType(); await using TvContext context = Db.CreateContext(); string number = await context.Channels.Where(c => c.Id == 1).Select(c => c.Number).SingleAsync(); number.ShouldBe("5"); } [Test] public async Task Should_Reject_Duplicate_Numbers_And_Not_Renumber() { await SeedChannel(1, "5"); await SeedChannel(2, "6"); Option result = await MakeHandler().Handle( new UpdateChannelNumbers( [ new ChannelSortViewModel { Id = 1, Number = "10" }, new ChannelSortViewModel { Id = 2, Number = "10" } ]), CancellationToken.None); BaseError error = ErrorOf(result); error.ShouldNotBeOfType(); error.Value.ShouldContain("unique"); await using TvContext context = Db.CreateContext(); List numbers = await context.Channels.OrderBy(c => c.Id).Select(c => c.Number).ToListAsync(); numbers.ShouldBe(["5", "6"]); } [Test] public async Task Should_Reject_Invalid_Number_And_Not_Renumber() { await SeedChannel(1, "5"); Option result = await MakeHandler().Handle( new UpdateChannelNumbers([new ChannelSortViewModel { Id = 1, Number = "10.123" }]), CancellationToken.None); BaseError error = ErrorOf(result); error.ShouldNotBeOfType(); error.Value.ShouldContain("Invalid channel number"); await using TvContext context = Db.CreateContext(); string number = await context.Channels.Where(c => c.Id == 1).Select(c => c.Number).SingleAsync(); number.ShouldBe("5"); } private static BaseError ErrorOf(Option result) => result.Match( Some: error => error, None: () => throw new AssertionException("Expected an error")); }