test(core/browser/platform): 26 extreme RED/GREEN TDD cycles and full regression hardening (3,235 PASS)
This commit is contained in:
parent
bcd242691f
commit
8677853822
100 changed files with 4814 additions and 333 deletions
144
tests/Paca.Tests/Core/SpeedAndBitrateScheduleExtremeRedTests.cs
Normal file
144
tests/Paca.Tests/Core/SpeedAndBitrateScheduleExtremeRedTests.cs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Paca.Core;
|
||||
using Xunit;
|
||||
|
||||
namespace Paca.Tests.Core;
|
||||
|
||||
public class SpeedAndBitrateScheduleExtremeRedTests
|
||||
{
|
||||
private const string SampleInput = "C:\\Media\\input.mp4";
|
||||
private const string SampleOutput = "C:\\Media\\output.mp4";
|
||||
|
||||
// ==========================================
|
||||
// 1. MediaPlaybackSpeedPitchEngine
|
||||
// ==========================================
|
||||
|
||||
[Fact]
|
||||
public void MediaPlaybackSpeedPitchEngine_BuildCommandLine_SameInputAndOutput_ThrowsInvalidOperationException()
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
MediaPlaybackSpeedPitchEngine.BuildSpeedCommandLine(SampleInput, SampleInput, 1.5));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, SampleOutput)]
|
||||
[InlineData(SampleInput, null)]
|
||||
[InlineData("", SampleOutput)]
|
||||
[InlineData(SampleInput, " ")]
|
||||
public void MediaPlaybackSpeedPitchEngine_BuildCommandLine_NullOrWhitespacePaths_ThrowsArgumentException(string? inPath, string? outPath)
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
MediaPlaybackSpeedPitchEngine.BuildSpeedCommandLine(inPath!, outPath!, 1.5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MediaPlaybackSpeedPitchEngine_BuildCommandLine_PathsWithQuotes_EscapedOrStripped()
|
||||
{
|
||||
string maliciousIn = "C:\\Media\\in\"put.mp4";
|
||||
string maliciousOut = "C:\\Media\\out\"put.mp4";
|
||||
|
||||
var cmd = MediaPlaybackSpeedPitchEngine.BuildSpeedCommandLine(maliciousIn, maliciousOut, 2.0);
|
||||
Assert.NotNull(cmd);
|
||||
Assert.DoesNotContain("in\"put", cmd);
|
||||
Assert.DoesNotContain("out\"put", cmd);
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 2. MediaBitrateEstimator
|
||||
// ==========================================
|
||||
|
||||
[Fact]
|
||||
public void MediaBitrateEstimator_BuildTwoPassCommands_SameInputAndOutput_ThrowsInvalidOperationException()
|
||||
{
|
||||
var plan = new BitrateEstimationResult(true, 2500, 128, 50_000_000);
|
||||
Assert.Throws<InvalidOperationException>(() =>
|
||||
MediaBitrateEstimator.BuildTwoPassCommands(SampleInput, SampleInput, plan));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, SampleOutput)]
|
||||
[InlineData(SampleInput, null)]
|
||||
[InlineData("", SampleOutput)]
|
||||
[InlineData(SampleInput, " ")]
|
||||
public void MediaBitrateEstimator_BuildTwoPassCommands_NullOrWhitespacePaths_ThrowsArgumentException(string? inPath, string? outPath)
|
||||
{
|
||||
var plan = new BitrateEstimationResult(true, 2500, 128, 50_000_000);
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
MediaBitrateEstimator.BuildTwoPassCommands(inPath!, outPath!, plan));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MediaBitrateEstimator_BuildTwoPassCommands_PathsWithQuotes_EscapedOrStripped()
|
||||
{
|
||||
var plan = new BitrateEstimationResult(true, 2500, 128, 50_000_000);
|
||||
string maliciousIn = "C:\\Media\\in\"put.mp4";
|
||||
string maliciousOut = "C:\\Media\\out\"put.mp4";
|
||||
|
||||
var (p1, p2) = MediaBitrateEstimator.BuildTwoPassCommands(maliciousIn, maliciousOut, plan);
|
||||
Assert.NotNull(p1);
|
||||
Assert.NotNull(p2);
|
||||
Assert.DoesNotContain("in\"put", p1);
|
||||
Assert.DoesNotContain("out\"put", p2);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(-1024)]
|
||||
public void MediaBitrateEstimator_CalculateBitrate_ZeroOrNegativeTarget_ReturnsNotPossible(long badTarget)
|
||||
{
|
||||
var result = MediaBitrateEstimator.CalculateBitrate(60.0, badTarget);
|
||||
Assert.NotNull(result);
|
||||
Assert.False(result.IsPossible);
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 3. BandwidthScheduleProfileEngine
|
||||
// ==========================================
|
||||
|
||||
[Fact]
|
||||
public void BandwidthScheduleProfileEngine_GetActiveProfile_NullConfig_ReturnsSafeDefault()
|
||||
{
|
||||
var profile = BandwidthScheduleProfileEngine.GetActiveProfile(DateTime.UtcNow, null!);
|
||||
Assert.NotNull(profile);
|
||||
Assert.Equal("Default", profile.ProfileName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BandwidthScheduleProfileEngine_GetActiveProfile_ConfigWithNullRules_SkipsNullRulesSafely()
|
||||
{
|
||||
var config = new BandwidthScheduleConfig
|
||||
{
|
||||
IsEnabled = true,
|
||||
DefaultProfile = new BandwidthProfile("Default", 0, 4),
|
||||
Rules = new List<BandwidthTimeRule>
|
||||
{
|
||||
null!,
|
||||
new(TimeSpan.FromHours(1), TimeSpan.FromHours(2), null!)
|
||||
}
|
||||
};
|
||||
|
||||
var ex = Record.Exception(() => BandwidthScheduleProfileEngine.GetActiveProfile(DateTime.UtcNow, config));
|
||||
Assert.Null(ex);
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 4. HlsManifestValidator
|
||||
// ==========================================
|
||||
|
||||
[Fact]
|
||||
public void HlsManifestValidator_Analyze_NullManifest_ReturnsSafeEmptyResult()
|
||||
{
|
||||
var result = HlsManifestValidator.Analyze(null!);
|
||||
Assert.NotNull(result);
|
||||
Assert.False(result.IsMasterPlaylist);
|
||||
Assert.Equal(0, result.SegmentCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HlsManifestValidator_StripAdBlocks_NullManifest_ReturnsEmptyString()
|
||||
{
|
||||
var stripped = HlsManifestValidator.StripAdBlocks(null!);
|
||||
Assert.NotNull(stripped);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue