using System.Threading.Channels; using ErsatzTV.Application; using ErsatzTV.Application.Maintenance; using ErsatzTV.Controllers.Api; using ErsatzTV.Core; using LanguageExt; using MediatR; using Microsoft.AspNetCore.Mvc; using NSubstitute; using NUnit.Framework; using Shouldly; using static LanguageExt.Prelude; namespace ErsatzTV.Tests.Controllers; [TestFixture] public class MaintenanceControllerTests { private MaintenanceController _controller = null!; private IMediator _mediator = null!; private Channel _workerChannel = null!; [SetUp] public void SetUp() { _mediator = Substitute.For(); _workerChannel = Channel.CreateUnbounded(); _controller = new MaintenanceController(_mediator, _workerChannel.Writer); } [Test] public async Task EmptyTrash_Should_Return_200_On_Success() { _mediator.Send(Arg.Any()) .Returns(Right(unit)); IActionResult result = await _controller.EmptyTrash(); result.ShouldBeOfType(); await _mediator.Received(1).Send(Arg.Any()); } [Test] public async Task EmptyTrash_Should_Return_422_ProblemDetails_On_Error() { _mediator.Send(Arg.Any()) .Returns(Left(BaseError.New("Failed to empty trash"))); IActionResult result = await _controller.EmptyTrash(); var unprocessable = result.ShouldBeOfType(); var problem = unprocessable.Value.ShouldBeOfType(); problem.Status.ShouldBe(422); problem.Detail.ShouldBe("Failed to empty trash"); } [Test] public async Task CleanArtwork_Should_Return_202_And_Enqueue_DeleteOrphanedArtwork() { IActionResult result = await _controller.CleanArtwork(CancellationToken.None); result.ShouldBeOfType(); _workerChannel.Reader.TryRead(out IBackgroundServiceRequest? enqueued).ShouldBeTrue(); enqueued.ShouldBeOfType(); } }