using TeleWave.Application.Broadcast.Bumpers; using TeleWave.Application.Programming.Templates; using TeleWave.Application.Programming.Templates.Junctions; using TeleWave.Domain.Broadcast; using TeleWave.Domain.Programming; using Xunit; namespace TeleWave.Application.Tests.Programming; /// /// Валидаторы стыков и заставок. Проверяют границы, за которыми настройка перестаёт что-либо /// значить в эфире: врезка длиннее суток, допуск от часа шире самого часа, семь строк в кадре. /// public class JunctionBumperValidatorTests { private static JunctionElementInput Element( int amount = 1, int choiceWeight = 1, string? choiceKey = null, JunctionConditions? conditions = null ) => new( JunctionElementKind.Ad, Guid.NewGuid(), null, null, JunctionAmountMode.Count, amount, IsRequired: false, choiceKey, choiceWeight, conditions ); private static bool Valid(JunctionElementInput input) => new UpdateJunctionElementCommandValidator() .Validate(new UpdateJunctionElementCommand(Guid.NewGuid(), Guid.NewGuid(), input)) .IsValid; [Fact] public void Element_AcceptsUsualSettings() { var conditions = new JunctionConditions( MinMinutesBetween: 30, Chance: 40, NearHourMinutes: 2 ); Assert.True( Valid(Element(amount: 3, choiceWeight: 5, choiceKey: "fork", conditions: conditions)) ); // Условий может не быть вовсе — тогда проверять нечего. Assert.True(Valid(Element())); } [Theory] [InlineData(0)] // ноль врезок — это отсутствие врезки, а не настройка [InlineData(24 * 60 + 1)] // длиннее вещательных суток public void Element_RejectsAmountOutOfRange(int amount) { Assert.False(Valid(Element(amount))); } [Theory] [InlineData(-1)] [InlineData(1001)] public void Element_RejectsWeightOutOfRange(int weight) { Assert.False(Valid(Element(choiceWeight: weight))); } [Theory] [InlineData(101)] // вероятность выше ста [InlineData(-1)] public void Element_RejectsChanceOutOfRange(int chance) { Assert.False(Valid(Element(conditions: new JunctionConditions(Chance: chance)))); } [Fact] public void Element_RejectsNearHourWiderThanHalfHour() { // Допуск в 31 минуту покрывает час целиком — это уже не привязка к :00. Assert.False(Valid(Element(conditions: new JunctionConditions(NearHourMinutes: 31)))); Assert.False(Valid(Element(conditions: new JunctionConditions(NearHourMinutes: -1)))); } [Fact] public void Junction_ChecksNameAndCap() { var validator = new UpdateJunctionCommandValidator(); var id = Guid.NewGuid(); Assert.True( validator.Validate(new UpdateJunctionCommand(id, "Рекламный шов", 120)).IsValid ); // Потолок можно не задавать — тогда стык ограничен только якорем. Assert.True(validator.Validate(new UpdateJunctionCommand(id, "Шов", null)).IsValid); Assert.False(validator.Validate(new UpdateJunctionCommand(id, " ", 120)).IsValid); Assert.False(validator.Validate(new UpdateJunctionCommand(id, "Шов", 0)).IsValid); Assert.False( validator.Validate(new UpdateJunctionCommand(id, "Шов", 24 * 60 * 60 + 1)).IsValid ); Assert.False( new CreateJunctionCommandValidator().Validate(new CreateJunctionCommand("")).IsValid ); } private static bool ValidVariant(int weight, params string[] lines) => new UpdateBumperVariantCommandValidator() .Validate( new UpdateBumperVariantCommand( Guid.NewGuid(), Guid.NewGuid(), new BumperVariantInput( "Подблок", BumperTrigger.Both, BumperBackground.Template, weight, [ .. lines.Select(text => new BumperLineDto( BumperLineStyle.Title, BumperLineColor.Text, text )), ] ) ) ) .IsValid; [Fact] public void Variant_AcceptsUpToSixLines() { Assert.True(ValidVariant(1, "СЕЙЧАС", "{now.title}")); Assert.True(ValidVariant(0, "1", "2", "3", "4", "5", "6")); } [Fact] public void Variant_RejectsSeventhLine() { // Больше шести строк в кадр не помещается ни при каком размере шрифта. Assert.False(ValidVariant(1, "1", "2", "3", "4", "5", "6", "7")); } [Fact] public void Variant_RejectsEmptyLineAndBadWeight() { Assert.False(ValidVariant(1, " ")); Assert.False(ValidVariant(1001, "СЕЙЧАС")); Assert.False(ValidVariant(-1, "СЕЙЧАС")); } }