feat(api): enrich channel list response

This commit is contained in:
2026-07-02 18:56:05 +02:00
parent 97b6c4bee7
commit 32c0d6a6d3
6 changed files with 116 additions and 3 deletions
+6 -1
View File
@@ -42,10 +42,15 @@ internal static class Mapper
new( new(
channel.Id, channel.Id,
channel.Number, channel.Number,
channel.SortNumber,
channel.Name, channel.Name,
channel.Group,
channel.Categories,
channel.FFmpegProfile.Name, channel.FFmpegProfile.Name,
channel.PreferredAudioLanguageCode, channel.PreferredAudioLanguageCode,
GetStreamingMode(channel)); GetStreamingMode(channel),
channel.IsEnabled,
channel.ShowInEpg);
internal static ResolutionViewModel ProjectToViewModel(Resolution resolution) => internal static ResolutionViewModel ProjectToViewModel(Resolution resolution) =>
new(resolution.Height, resolution.Width); new(resolution.Height, resolution.Width);
@@ -5,8 +5,13 @@ namespace ErsatzTV.Core.Api.Channels;
public record ChannelResponseModel( public record ChannelResponseModel(
int Id, int Id,
string Number, string Number,
double SortNumber,
string Name, string Name,
string Group,
string Categories,
[property: JsonProperty("ffmpegProfile")] [property: JsonProperty("ffmpegProfile")]
string FFmpegProfile, string FFmpegProfile,
string Language, string Language,
string StreamingMode); string StreamingMode,
bool IsEnabled,
bool ShowInEpg);
@@ -0,0 +1,53 @@
using ErsatzTV.Application.Channels;
using ErsatzTV.Core;
using ErsatzTV.Core.Api.Channels;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Repositories;
using NSubstitute;
using NUnit.Framework;
using Shouldly;
namespace ErsatzTV.Tests.Application.Channels;
[TestFixture]
public class GetAllChannelsForApiHandlerTests
{
[Test]
public async Task Should_Project_Management_Table_Fields()
{
IChannelRepository repository = Substitute.For<IChannelRepository>();
repository.GetAll(Arg.Any<CancellationToken>())
.Returns([
new Channel(Guid.NewGuid())
{
Id = 7,
Number = "7.1",
SortNumber = 7.1,
Name = "Retro Cartoons",
Group = "Kids",
Categories = "animation",
FFmpegProfile = new FFmpegProfile { Name = "HLS 720p" },
PreferredAudioLanguageCode = "eng",
StreamingMode = StreamingMode.HttpLiveStreamingSegmenter,
IsEnabled = false,
ShowInEpg = false
}
]);
var handler = new GetAllChannelsForApiHandler(repository);
List<ChannelResponseModel> result = await handler.Handle(new GetAllChannelsForApi(), CancellationToken.None);
ChannelResponseModel channel = result.ShouldHaveSingleItem();
channel.Id.ShouldBe(7);
channel.Number.ShouldBe("7.1");
channel.SortNumber.ShouldBe(7.1);
channel.Name.ShouldBe("Retro Cartoons");
channel.Group.ShouldBe("Kids");
channel.Categories.ShouldBe("animation");
channel.FFmpegProfile.ShouldBe("HLS 720p");
channel.Language.ShouldBe("eng");
channel.StreamingMode.ShouldBe("HLS Segmenter");
channel.IsEnabled.ShouldBeFalse();
channel.ShowInEpg.ShouldBeFalse();
}
}
@@ -23,6 +23,24 @@ public class OpenApiErrorResponseContractTests
.ShouldContain("One"); .ShouldContain("One");
} }
[Test]
public void Static_OpenApi_Should_Document_Channel_List_Management_Fields()
{
using JsonDocument document = JsonDocument.Parse(File.ReadAllText(FindOpenApiDocument()));
JsonElement schema = document.RootElement
.GetProperty("components")
.GetProperty("schemas")
.GetProperty("ChannelResponseModel")
.GetProperty("properties");
schema.TryGetProperty("group", out _).ShouldBeTrue();
schema.TryGetProperty("isEnabled", out _).ShouldBeTrue();
schema.TryGetProperty("showInEpg", out _).ShouldBeTrue();
schema.TryGetProperty("sortNumber", out _).ShouldBeTrue();
schema.TryGetProperty("categories", out _).ShouldBeTrue();
}
[TestCase("/api/channels/{id}", "get", "404")] [TestCase("/api/channels/{id}", "get", "404")]
[TestCase("/api/channels", "post", "404")] [TestCase("/api/channels", "post", "404")]
[TestCase("/api/channels", "post", "422")] [TestCase("/api/channels", "post", "422")]
+28 -1
View File
@@ -3092,10 +3092,15 @@
"required": [ "required": [
"id", "id",
"number", "number",
"sortNumber",
"name", "name",
"group",
"categories",
"fFmpegProfile", "fFmpegProfile",
"language", "language",
"streamingMode" "streamingMode",
"isEnabled",
"showInEpg"
], ],
"type": "object", "type": "object",
"properties": { "properties": {
@@ -3109,12 +3114,28 @@
"string" "string"
] ]
}, },
"sortNumber": {
"type": "number",
"format": "double"
},
"name": { "name": {
"type": [ "type": [
"null", "null",
"string" "string"
] ]
}, },
"group": {
"type": [
"null",
"string"
]
},
"categories": {
"type": [
"null",
"string"
]
},
"fFmpegProfile": { "fFmpegProfile": {
"type": [ "type": [
"null", "null",
@@ -3132,6 +3153,12 @@
"null", "null",
"string" "string"
] ]
},
"isEnabled": {
"type": "boolean"
},
"showInEpg": {
"type": "boolean"
} }
} }
}, },
+5
View File
@@ -29,10 +29,15 @@ export interface components {
"ChannelResponseModel": { "ChannelResponseModel": {
"id": number; "id": number;
"number": null | string; "number": null | string;
"sortNumber": number;
"name": null | string; "name": null | string;
"group": null | string;
"categories": null | string;
"fFmpegProfile": null | string; "fFmpegProfile": null | string;
"language": null | string; "language": null | string;
"streamingMode": null | string; "streamingMode": null | string;
"isEnabled": boolean;
"showInEpg": boolean;
}; };
"ChannelSongVideoMode": "Default" | "WithProgress"; "ChannelSongVideoMode": "Default" | "WithProgress";
"ChannelStreamSelectorMode": "Default" | "Custom" | "Troubleshooting"; "ChannelStreamSelectorMode": "Default" | "Custom" | "Troubleshooting";