using System.Reflection; using ErsatzTV.Application.Health; using ErsatzTV.Controllers.Api; using ErsatzTV.Core.Api.Health; using MediatR; using Microsoft.AspNetCore.Mvc.Routing; using NSubstitute; using NUnit.Framework; using Shouldly; namespace ErsatzTV.Tests.Controllers; [TestFixture] public class HealthControllerTests { private IMediator _mediator = null!; private HealthController _controller = null!; [SetUp] public void SetUp() { _mediator = Substitute.For(); _controller = new HealthController(_mediator); } [Test] public void Controller_Should_Expose_Idiomatic_Rest_Route() { MethodInfo action = typeof(HealthController).GetMethod(nameof(HealthController.GetAll)) ?? throw new AssertionException("Missing action GetAll"); HttpMethodAttribute attribute = action.GetCustomAttributes(inherit: true).Single(); attribute.HttpMethods.ShouldContain("GET"); attribute.Template.ShouldBe("/api/v1/health"); attribute.Name.ShouldBe("GetHealthChecks"); } [Test] public async Task GetAll_Should_Return_Results_From_Mediator() { var expected = new List { new("Check One", "pass", "all good", null, null, null), new( "Check Two", "fail", "broken", "broken", "https://example.com", new HealthCheckRemediationResponseModel("ExternalDoc", "https://example.com")) }; _mediator.Send(Arg.Any(), Arg.Any()) .Returns(expected); List result = await _controller.GetAll(false, CancellationToken.None); result.ShouldBe(expected); } [Test] public async Task GetAll_Should_Return_Empty_List_When_None_Exist() { _mediator.Send(Arg.Any(), Arg.Any()) .Returns([]); List result = await _controller.GetAll(false, CancellationToken.None); result.ShouldBeEmpty(); } [Test] public async Task GetAll_Should_Forward_Refresh_Flag_To_Query() { _mediator.Send(Arg.Any(), Arg.Any()) .Returns([]); await _controller.GetAll(true, CancellationToken.None); await _mediator.Received(1).Send( Arg.Is(q => q.Refresh), Arg.Any()); } }