Refactored the GridPlanner class to optimize slot management during grid generation, ensuring more efficient handling of slots. Updated the GenerateGridDialog component to improve its layout and usability, enhancing the overall user experience when interacting with slot lists. These changes contribute to better functionality and accessibility in grid management.
118 lines
4.6 KiB
C#
118 lines
4.6 KiB
C#
using TeleWave.Application.Programming.Groups;
|
|
using TeleWave.Application.Programming.Groups.FindGroupCandidates;
|
|
using TeleWave.Application.Tests.Support;
|
|
using TeleWave.Domain.Library;
|
|
using TeleWave.Domain.Media;
|
|
using TeleWave.Domain.Programming;
|
|
using Xunit;
|
|
|
|
namespace TeleWave.Application.Tests.Programming;
|
|
|
|
/// <summary>
|
|
/// Подбор позиций по правилу набора: то, что редактор группы показывает кнопкой «Подобрать».
|
|
/// Важна не только выборка, но и отметка «уже в группе» — по ней видно, что добавлять нечего.
|
|
/// </summary>
|
|
public class FindGroupCandidatesTests
|
|
{
|
|
private static (Show Show, MediaAsset Asset) Playable(string name, int minutes)
|
|
{
|
|
var asset = MediaAsset.Register($"{name}.mkv", ".mkv", MediaSource.Upload);
|
|
asset.MarkProcessing();
|
|
asset.MarkReady(
|
|
new MediaReadyInfo(
|
|
TimeSpan.FromMinutes(minutes),
|
|
6,
|
|
minutes * 10,
|
|
1920,
|
|
1080,
|
|
"h264",
|
|
"aac",
|
|
$"assets/{name}"
|
|
)
|
|
);
|
|
var show = Show.Create(name, ShowKind.Single);
|
|
show.AddEpisode(asset.Id);
|
|
return (show, asset);
|
|
}
|
|
|
|
private static async Task<TeleWave.Application.Common.Models.Result<
|
|
IReadOnlyList<GroupCandidateDto>
|
|
>> FindAsync(TestDb fixture, FindGroupCandidatesQuery query)
|
|
{
|
|
await using var db = fixture.New();
|
|
return await new FindGroupCandidatesQueryHandler(
|
|
db,
|
|
new GroupFilterMatcher(db),
|
|
new GroupElementResolver(db)
|
|
).Handle(query, CancellationToken.None);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task MarksWhatIsAlreadyInGroup_AndFiltersByUnitDuration()
|
|
{
|
|
var fixture = new TestDb();
|
|
var shortFilm = Playable("Короткий", 20);
|
|
var longFilm = Playable("Длинный", 120);
|
|
var inside = Playable("Уже внутри", 100);
|
|
|
|
var group = Group.Create("Кино");
|
|
group.SetFilter(new GroupFilter(UnitMinutesMin: 60).ToJson());
|
|
group.AddElement(GroupElementKind.Show, inside.Show.Id);
|
|
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.MediaAssets.AddRange(shortFilm.Asset, longFilm.Asset, inside.Asset);
|
|
seed.Shows.AddRange(shortFilm.Show, longFilm.Show, inside.Show);
|
|
seed.Groups.Add(group);
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
var result = await FindAsync(fixture, new FindGroupCandidatesQuery(group.Id));
|
|
|
|
Assert.True(result.IsSuccess);
|
|
// Короткий отсечён по длине единицы: правило меряет саму серию, а не сумму по шоу.
|
|
Assert.Equal(["Длинный", "Уже внутри"], result.Value.Select(c => c.ElementName));
|
|
Assert.False(result.Value.Single(c => c.ElementName == "Длинный").AlreadyInGroup);
|
|
Assert.True(result.Value.Single(c => c.ElementName == "Уже внутри").AlreadyInGroup);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UsesFilterFromQuery_WhenGivenExplicitly()
|
|
{
|
|
var fixture = new TestDb();
|
|
var film = Playable("Кино", 100);
|
|
// У группы своего правила нет — редактор крутит фильтр до сохранения.
|
|
var group = Group.Create("Черновик");
|
|
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.MediaAssets.Add(film.Asset);
|
|
seed.Shows.Add(film.Show);
|
|
seed.Groups.Add(group);
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
var withFilter = await FindAsync(
|
|
fixture,
|
|
new FindGroupCandidatesQuery(group.Id, new GroupFilter(ShowKinds: [ShowKind.Single]))
|
|
);
|
|
var withoutFilter = await FindAsync(fixture, new FindGroupCandidatesQuery(group.Id));
|
|
|
|
Assert.Single(withFilter.Value);
|
|
// Без правила подбирать не из чего — и это отказ, а не пустой список.
|
|
Assert.False(withoutFilter.IsSuccess);
|
|
Assert.Equal(GroupErrors.FilterNotSet, withoutFilter.Error);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Fails_WhenGroupIsGone()
|
|
{
|
|
var fixture = new TestDb();
|
|
|
|
var result = await FindAsync(fixture, new FindGroupCandidatesQuery(Guid.NewGuid()));
|
|
|
|
Assert.False(result.IsSuccess);
|
|
Assert.Equal(GroupErrors.NotFound, result.Error);
|
|
}
|
|
}
|