using ErsatzTV.Application.Artworks; using ErsatzTV.Application.Channels; using ErsatzTV.Controllers.Api.Requests; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Scheduling; using NUnit.Framework; using Shouldly; namespace ErsatzTV.Tests.Controllers; [TestFixture] public class AutoTuneRequestsTests { [Test] public void ToCommand_Maps_Overrides_And_Sanitizes_A_Bad_Logo_Content_Type() { var request = new AutoTunedChannelRequest( AutoTuneAxis.TvGenre, "Comedy", "Comedy", "500", TemplateId: 11, // A hostile content type must not survive to the command (stored-XSS defense, #283) — // the request mirrors CreateChannelFromLineupRequest's Sanitized() call. Logo: new ArtworkContentTypeModel("iptv/logos/comedy.png", "text/html"), Advanced: new CreateChannelFromLineupAdvancedOptionsRequest( PlaybackOrder: PlaybackOrder.Chronological, FFmpegProfileId: 42)); AutoTuneChannelSelection command = request.ToCommand(); command.TemplateId.ShouldBe(11); command.Logo.Path.ShouldBe("iptv/logos/comedy.png"); command.Logo.ContentType.ShouldBe(string.Empty); // blanked command.Advanced.ShouldNotBeNull(); command.Advanced.PlaybackOrder.ShouldBe(PlaybackOrder.Chronological); command.Advanced.FFmpegProfileId.ShouldBe(42); } [Test] public void ToCommand_Without_Overrides_Leaves_Command_Fields_At_Defaults() { var request = new AutoTunedChannelRequest(AutoTuneAxis.TvShow, "The Office", "The Office", "500"); AutoTuneChannelSelection command = request.ToCommand(); command.TemplateId.ShouldBeNull(); command.Advanced.ShouldBeNull(); // An omitted logo maps to None (empty path), not null. command.Logo.ShouldBe(ArtworkContentTypeModel.None); } }