using TeleWave.Domain.Broadcast; using Xunit; namespace TeleWave.Domain.Tests.Broadcast; public class ChannelTests { private static readonly DateTimeOffset Epoch = new(2026, 1, 1, 0, 0, 0, TimeSpan.Zero); private static Channel NewChannel() => Channel.Create("News", "news", Epoch); [Fact] public void Create_SetsDefaults_AndSeedsDefaultBumperTemplate() { var channel = NewChannel(); Assert.NotEqual(Guid.Empty, channel.Id); Assert.Equal("News", channel.Name); Assert.Equal("news", channel.Slug); Assert.True(channel.IsEnabled); Assert.Equal(Epoch, channel.EpochUtc); Assert.False(channel.BumpersEnabled); Assert.Equal(BumperSelection.WeightedRandom, channel.BumperSelection); Assert.Equal(Channel.DefaultUtcOffsetMinutes, channel.UtcOffsetMinutes); Assert.Equal(Channel.DefaultDayStartTime, channel.DayStartTime); var template = Assert.Single(channel.BumperTemplates); Assert.True(template.IsDefault); Assert.Equal(0, template.Position); Assert.Single(template.Variants); // дефолтный подблок } [Fact] public void UpdateSettings_ChangesFields() { var channel = NewChannel(); var filler = Guid.NewGuid(); channel.UpdateSettings("N2", false, true, filler); Assert.Equal("N2", channel.Name); Assert.False(channel.IsEnabled); Assert.True(channel.BumpersEnabled); Assert.Equal(filler, channel.FillerAssetId); } [Fact] public void UpdateBumperSettings_ChangesFontAndSelection() { var channel = NewChannel(); channel.UpdateBumperSettings(BumperFont.Serif, BumperSelection.AlwaysFirst); Assert.Equal(BumperFont.Serif, channel.BumperFont); Assert.Equal(BumperSelection.AlwaysFirst, channel.BumperSelection); } [Theory] [InlineData(-1.0, 2.0, 0.0, 1.0)] [InlineData(0.4, 0.25, 0.4, 0.25)] public void UpdateViewerSettings_ClampsStrengths( double opacity, double filter, double expectedOpacity, double expectedFilter ) { var channel = NewChannel(); var logo = Guid.NewGuid(); channel.UpdateViewerSettings(logo, LogoCorner.BottomRight, opacity, true, filter); Assert.Equal(logo, channel.LogoImageId); Assert.Equal(LogoCorner.BottomRight, channel.LogoCorner); Assert.Equal(expectedOpacity, channel.LogoOpacity); Assert.True(channel.ShowClock); Assert.Equal(expectedFilter, channel.AnalogFilterStrength); } [Fact] public void NewChannel_HasViewerOverlaysOff() { // Канал без логотипа, часов и шума — законная конфигурация, а не недонастроенная. var channel = NewChannel(); Assert.Null(channel.LogoImageId); Assert.False(channel.ShowClock); Assert.Equal(0.0, channel.AnalogFilterStrength); } [Fact] public void AddBumperTemplate_AppendsWithNextPosition() { var channel = NewChannel(); var t1 = channel.AddBumperTemplate("Block 2"); var t2 = channel.AddBumperTemplate("Block 3"); Assert.Equal(1, t1.Position); Assert.Equal(2, t2.Position); Assert.False(t1.IsDefault); Assert.Equal(3, channel.BumperTemplates.Count); Assert.Equal(t1, channel.FindBumperTemplate(t1.Id)); Assert.Null(channel.FindBumperTemplate(Guid.NewGuid())); } [Fact] public void RemoveBumperTemplate_CannotRemoveDefault_CanRemoveOthers() { var channel = NewChannel(); var def = channel.BumperTemplates[0]; var extra = channel.AddBumperTemplate("Block 2"); Assert.False(channel.RemoveBumperTemplate(def.Id)); Assert.True(channel.RemoveBumperTemplate(extra.Id)); Assert.False(channel.RemoveBumperTemplate(Guid.NewGuid())); Assert.Single(channel.BumperTemplates); } [Fact] public void UpdateTimeSettings_ClampsOffsetAndDropsNonPositiveNumber() { var channel = NewChannel(); channel.UpdateTimeSettings(0, 99 * 60, new TimeOnly(5, 0)); // Номер 0 — не номер; смещение за пределами суток оторвало бы сетку от календаря. Assert.Null(channel.Number); Assert.Equal(14 * 60, channel.UtcOffsetMinutes); Assert.Equal(new TimeOnly(5, 0), channel.DayStartTime); } [Fact] public void SetTemplate_LinksAndUnlinks() { var channel = NewChannel(); var templateId = Guid.NewGuid(); channel.SetTemplate(templateId); Assert.Equal(templateId, channel.TemplateId); channel.SetTemplate(null); Assert.Null(channel.TemplateId); } }