Implemented new API endpoints and frontend components for grid auto-building based on predefined profiles. Added functionality to list grid profiles, preview generated grids, and generate grids with specified parameters. Enhanced the TemplateEndpoints and related services to support these features, improving the user experience for channel scheduling. Localization updates were made to accommodate new features in both English and Russian.
133 lines
4.2 KiB
C#
133 lines
4.2 KiB
C#
using NSubstitute;
|
|
using TeleWave.Application.Common.Interfaces;
|
|
using TeleWave.Application.Media.Stats;
|
|
using TeleWave.Application.Tests.Support;
|
|
using TeleWave.Domain.Media;
|
|
using Xunit;
|
|
|
|
namespace TeleWave.Application.Tests.Media;
|
|
|
|
public class MediaStatsTests
|
|
{
|
|
private static MediaAsset Pending(string name) =>
|
|
MediaAsset.Register(name, ".mkv", MediaSource.Upload);
|
|
|
|
private static MediaAsset Processing(string name)
|
|
{
|
|
var a = Pending(name);
|
|
a.MarkProcessing();
|
|
return a;
|
|
}
|
|
|
|
private static MediaAsset Ready(string name)
|
|
{
|
|
var a = Pending(name);
|
|
a.MarkProcessing();
|
|
a.MarkReady(
|
|
new MediaReadyInfo(
|
|
TimeSpan.FromMinutes(20),
|
|
2,
|
|
600,
|
|
1920,
|
|
1080,
|
|
"h264",
|
|
"aac",
|
|
"assets/x"
|
|
)
|
|
);
|
|
return a;
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Stats_CountsQueuedAndProcessing_AndAveragesReady_ExcludingGenerated()
|
|
{
|
|
var fixture = new TestDb();
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.MediaAssets.AddRange(
|
|
Pending("a.mkv"),
|
|
Pending("b.mkv"),
|
|
Processing("c.mkv"),
|
|
Ready("d.mkv"),
|
|
MediaAsset.RegisterGenerated("Заставка") // Generated — не входит в статистику
|
|
);
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
await using var db = fixture.New();
|
|
var stats = await new GetMediaStatsQueryHandler(db, Limits(1)).Handle(
|
|
new GetMediaStatsQuery(),
|
|
CancellationToken.None
|
|
);
|
|
|
|
Assert.Equal(2, stats.Queued); // два Pending (Generated исключён)
|
|
Assert.Equal(1, stats.Processing);
|
|
Assert.NotNull(stats.AverageProcessingSeconds);
|
|
Assert.True(stats.AverageProcessingSeconds >= 0);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Estimate_ScalesWithQueueAndParallelism()
|
|
{
|
|
var fixture = new TestDb();
|
|
await using (var seed = fixture.New())
|
|
{
|
|
// Одна завершённая задаёт среднее, четыре ждут своей очереди.
|
|
seed.MediaAssets.AddRange(
|
|
Ready("done.mkv"),
|
|
Pending("a.mkv"),
|
|
Pending("b.mkv"),
|
|
Pending("c.mkv"),
|
|
Pending("d.mkv")
|
|
);
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
await using var db = fixture.New();
|
|
var single = await new GetMediaStatsQueryHandler(db, Limits(1)).Handle(
|
|
new GetMediaStatsQuery(),
|
|
CancellationToken.None
|
|
);
|
|
var parallel = await new GetMediaStatsQueryHandler(db, Limits(2)).Handle(
|
|
new GetMediaStatsQuery(),
|
|
CancellationToken.None
|
|
);
|
|
|
|
var average = single.AverageProcessingSeconds!.Value;
|
|
Assert.Equal(4 * average, single.EstimatedRemainingSeconds!.Value, 3);
|
|
// Два транскода одновременно — вдвое меньше ждать.
|
|
Assert.Equal(
|
|
single.EstimatedRemainingSeconds!.Value / 2,
|
|
parallel.EstimatedRemainingSeconds!.Value,
|
|
3
|
|
);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Estimate_IsAbsent_WhenQueueIsEmpty()
|
|
{
|
|
var fixture = new TestDb();
|
|
await using (var seed = fixture.New())
|
|
{
|
|
seed.MediaAssets.Add(Ready("done.mkv"));
|
|
await seed.SaveChangesAsync(CancellationToken.None);
|
|
}
|
|
|
|
await using var db = fixture.New();
|
|
var stats = await new GetMediaStatsQueryHandler(db, Limits(1)).Handle(
|
|
new GetMediaStatsQuery(),
|
|
CancellationToken.None
|
|
);
|
|
|
|
// Ждать нечего — оценки нет вовсе, а не «0 секунд».
|
|
Assert.Null(stats.EstimatedRemainingSeconds);
|
|
}
|
|
|
|
private static IMediaProcessingLimits Limits(int parallel)
|
|
{
|
|
var limits = Substitute.For<IMediaProcessingLimits>();
|
|
limits.MaxParallelTranscodes.Returns(parallel);
|
|
return limits;
|
|
}
|
|
}
|