Update scheduling parameters and refactor channel endpoints: extend HorizonDays to 7 and RetentionDays to 90 in appsettings.json. Consolidate channel-related endpoint logic by removing obsolete files and enhancing the ShowEndpoints with audience and genre management capabilities. Improve error handling and streamline command handlers for channel operations.
build / backend (push) Successful in 7m40s
build / frontend (push) Failing after 39s
tests / backend-tests (push) Successful in 6m9s

This commit is contained in:
Leonid Pershin
2026-07-26 13:32:13 +03:00
parent c4ef954dea
commit 66040a8841
272 changed files with 27944 additions and 8699 deletions
@@ -0,0 +1,141 @@
using TeleWave.Domain.Programming;
using Xunit;
namespace TeleWave.Domain.Tests.Programming;
public class ScheduleTemplateTests
{
private static ScheduleTemplate NewTemplate() =>
ScheduleTemplate.Create(Guid.NewGuid(), "Основная");
[Fact]
public void Create_AddsBackgroundLayer()
{
var template = NewTemplate();
var background = Assert.Single(template.Layers);
Assert.True(background.IsBackground);
Assert.Equal(GridLayer.BackgroundPriority, background.Priority);
}
[Fact]
public void RemoveLayer_RefusesBackground()
{
var template = NewTemplate();
var background = template.Background!;
Assert.False(template.RemoveLayer(background.Id));
Assert.Single(template.Layers);
}
[Fact]
public void AddLayer_KeepsPriorityAboveBackground()
{
var template = NewTemplate();
var layer = template.AddLayer("Выходные", 0);
// Ноль занят фоном: слой с таким же приоритетом сделал бы выбор неоднозначным.
Assert.True(layer.Priority > GridLayer.BackgroundPriority);
}
[Fact]
public void BackgroundLayer_KeepsPriority_WhenUpdated()
{
var template = NewTemplate();
var background = template.Background!;
background.Update("Фон", 99, null, isEnabled: true);
Assert.Equal(GridLayer.BackgroundPriority, background.Priority);
}
[Fact]
public void MarkChanged_MakesPendingUntilApplied()
{
var template = NewTemplate();
Assert.False(template.HasPendingChanges);
template.MarkChanged();
Assert.True(template.HasPendingChanges);
template.MarkApplied();
Assert.False(template.HasPendingChanges);
}
}
public class GridLayerOverlapTests
{
private static GridLayer NewLayer() =>
ScheduleTemplate.Create(Guid.NewGuid(), "T").AddLayer("Базовая", 10);
[Fact]
public void HasOverlap_DetectsIntersectionOnSameDay()
{
var layer = NewLayer();
layer.AddSlot("Вечернее кино", new TimeOnly(20, 0), 90, weekday: 5);
Assert.True(layer.HasOverlap(5, new TimeOnly(21, 0), 30, null));
Assert.False(layer.HasOverlap(5, new TimeOnly(21, 30), 30, null));
}
[Fact]
public void HasOverlap_IgnoresOtherWeekdays()
{
var layer = NewLayer();
layer.AddSlot("Вечернее кино", new TimeOnly(20, 0), 90, weekday: 5);
Assert.False(layer.HasOverlap(3, new TimeOnly(20, 30), 30, null));
}
[Fact]
public void HasOverlap_EverydaySlotConflictsWithAnyDay()
{
var layer = NewLayer();
layer.AddSlot("Новости", new TimeOnly(18, 0), 30);
// Слот без дня недели идёт каждый день, поэтому конфликтует и с конкретным днём.
Assert.True(layer.HasOverlap(2, new TimeOnly(18, 15), 30, null));
}
[Fact]
public void HasOverlap_SkipsSlotBeingEdited()
{
var layer = NewLayer();
var slot = layer.AddSlot("Вечернее кино", new TimeOnly(20, 0), 90, weekday: 5);
Assert.False(layer.HasOverlap(5, new TimeOnly(20, 0), 120, slot.Id));
}
[Fact]
public void UpdateContent_ClearsFieldsForeignToSlotKind()
{
var layer = NewLayer();
var slot = layer.AddSlot("Кино", new TimeOnly(20, 0), 90);
slot.UpdateContent(
"Кино",
SlotKind.Content,
Guid.NewGuid(),
"{\"type\":\"sequential\"}",
null,
SlotBlockMode.Count,
1,
OverflowPolicy.ContinueNext
);
slot.UpdateContent(
"Конец вещания",
SlotKind.SignOff,
Guid.NewGuid(),
"{\"type\":\"sequential\"}",
null,
SlotBlockMode.FillSlot,
1,
OverflowPolicy.ContinueNext
);
// Иначе генератор прочитал бы настройки, оставшиеся от прежнего типа слота.
Assert.Null(slot.GroupId);
Assert.Null(slot.StrategyJson);
}
}