feat(api): add channel state endpoint contract

This commit is contained in:
2026-07-02 19:29:59 +02:00
parent 1891498563
commit 7c1a1d5672
5 changed files with 50 additions and 0 deletions
@@ -0,0 +1,5 @@
using ErsatzTV.Core.Api.Channels;
namespace ErsatzTV.Application.Channels;
public record GetChannelStatesForApi : IRequest<List<ChannelStateResponseModel>>;
@@ -0,0 +1,6 @@
namespace ErsatzTV.Core.Api.Channels;
public record ChannelNowPlayingResponseModel(
string Title,
DateTimeOffset StartUtc,
DateTimeOffset FinishUtc);
@@ -0,0 +1,7 @@
namespace ErsatzTV.Core.Api.Channels;
public record ChannelStateResponseModel(
int ChannelId,
string ChannelNumber,
bool OnAir,
ChannelNowPlayingResponseModel NowPlaying);
@@ -6,6 +6,7 @@ using ErsatzTV.Application.Playouts;
using ErsatzTV.Controllers.Api; using ErsatzTV.Controllers.Api;
using ErsatzTV.Controllers.Api.Requests; using ErsatzTV.Controllers.Api.Requests;
using ErsatzTV.Core; using ErsatzTV.Core;
using ErsatzTV.Core.Api.Channels;
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Errors; using ErsatzTV.Core.Errors;
using LanguageExt; using LanguageExt;
@@ -34,6 +35,25 @@ public class ChannelControllerTests
_controller = new ChannelController(writer, _mediator); _controller = new ChannelController(writer, _mediator);
} }
[Test]
public async Task GetState_Should_Return_200_With_Channel_State()
{
var state = new ChannelStateResponseModel(
7,
"7.1",
true,
new ChannelNowPlayingResponseModel(
"Retro Cartoons",
new DateTimeOffset(2026, 7, 2, 17, 0, 0, TimeSpan.Zero),
new DateTimeOffset(2026, 7, 2, 17, 30, 0, TimeSpan.Zero)));
_mediator.Send(Arg.Any<GetChannelStatesForApi>(), Arg.Any<CancellationToken>())
.Returns([state]);
IActionResult result = await _controller.GetState(CancellationToken.None);
result.ShouldBeOfType<OkObjectResult>().Value.ShouldBe(new List<ChannelStateResponseModel> { state });
}
[Test] [Test]
public async Task Create_Should_Return_201_With_Location_And_Body() public async Task Create_Should_Return_201_With_Location_And_Body()
{ {
@@ -21,6 +21,18 @@ public class ChannelController(ChannelWriter<IBackgroundServiceRequest> workerCh
[EndpointGroupName("general")] [EndpointGroupName("general")]
public async Task<List<ChannelResponseModel>> GetAll() => await mediator.Send(new GetAllChannelsForApi()); public async Task<List<ChannelResponseModel>> GetAll() => await mediator.Send(new GetAllChannelsForApi());
[HttpGet("/api/channels/state")]
[Tags("Channels")]
[EndpointSummary("Get channel runtime state")]
[EndpointGroupName("general")]
[ProducesResponseType(typeof(List<ChannelStateResponseModel>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetState(CancellationToken cancellationToken)
{
List<ChannelStateResponseModel> result =
await mediator.Send(new GetChannelStatesForApi(), cancellationToken);
return new OkObjectResult(result);
}
[HttpGet("/api/channels/{id:int}", Name = "GetChannelById")] [HttpGet("/api/channels/{id:int}", Name = "GetChannelById")]
[Tags("Channels")] [Tags("Channels")]
[EndpointSummary("Get a channel by id")] [EndpointSummary("Get a channel by id")]