releases/tests/Paca.Tests/Core/SubtitleAndNetworkResilienceExtremeRedTests.cs
Yun Chan 8677853822
Some checks failed
release / test (push) Failing after 14m5s
release / windows (push) Has been cancelled
release / android (push) Has been cancelled
release / linux (push) Has been cancelled
release / macos (push) Has been cancelled
test(core/browser/platform): 26 extreme RED/GREEN TDD cycles and full regression hardening (3,235 PASS)
2026-09-18 23:32:32 +09:00

111 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Paca.Core;
using Paca.Core.Net;
using Xunit;
namespace Paca.Tests.Core;
public class SubtitleAndNetworkResilienceExtremeRedTests
{
[Fact]
public void SubtitleBurnInEngine_InPlaceOverwrite_ThrowsArgumentException()
{
var ex = Assert.Throws<ArgumentException>(() =>
SubtitleBurnInEngine.BuildBurnInCommandLine("movie.mp4", "sub.srt", "movie.mp4"));
Assert.Contains("identical", ex.Message, StringComparison.OrdinalIgnoreCase);
}
[Theory]
[InlineData(null, "sub.srt", "out.mp4")]
[InlineData("", "sub.srt", "out.mp4")]
[InlineData("in.mp4", null, "out.mp4")]
[InlineData("in.mp4", "", "out.mp4")]
[InlineData("in.mp4", "sub.srt", null)]
[InlineData("in.mp4", "sub.srt", "")]
public void SubtitleBurnInEngine_NullOrEmptyPaths_ThrowsArgumentException(string? inVid, string? sub, string? outVid)
{
Assert.Throws<ArgumentException>(() =>
SubtitleBurnInEngine.BuildBurnInCommandLine(inVid!, sub!, outVid!));
}
[Fact]
public void SubtitleBurnInEngine_EscapePath_EscapesSquareBrackets()
{
var path = @"C:\Downloads\[SubsPlease] Video [1080p].srt";
var escaped = SubtitleBurnInEngine.EscapeSubtitlePathForFfmpeg(path);
Assert.Contains(@"\[", escaped);
Assert.Contains(@"\]", escaped);
}
[Fact]
public void SubtitleBurnInEngine_FontNameInjection_Sanitized()
{
var style = new SubtitleBurnInStyle
{
FontName = "Arial,Bold;drop=all",
FontSize = 24
};
var forceStyle = SubtitleBurnInEngine.BuildForceStyleString(style);
Assert.DoesNotContain("Arial,Bold", forceStyle);
Assert.DoesNotContain(";", forceStyle);
}
[Theory]
[InlineData(0)]
[InlineData(-5)]
public void SubtitleBurnInEngine_InvalidFontSize_ThrowsArgumentOutOfRangeException(int invalidSize)
{
var style = new SubtitleBurnInStyle { FontSize = invalidSize };
Assert.Throws<ArgumentOutOfRangeException>(() =>
SubtitleBurnInEngine.BuildForceStyleString(style));
}
[Theory]
[InlineData("https://i.4cdn.org/wsg/1234567.webm", 1200)]
[InlineData("http://is2.4chan.org/pol/src/123.jpg", 1200)]
[InlineData("i.4cdn.org:443", 1200)]
[InlineData("https://v.redd.it/xyz987/DASH_720.mp4", 800)]
[InlineData("reddit.com:80", 800)]
[InlineData("https://example.com/video.mp4", 200)]
public void HostRateLimiter_FullUrlAndPort_NormalizesAndRecognizesDomain(string input, int expectedInterval)
{
var interval = HostRateLimiter.GetDefaultIntervalMs(input);
Assert.Equal(expectedInterval, interval);
}
[Fact]
public async Task MultiCdnMeshDownloader_NullMirrorList_ReturnsFailureGracefully()
{
var downloader = new MultiCdnMeshDownloader();
var result = await downloader.RaceDownloadSegmentAsync(null!);
Assert.False(result.IsSuccess);
}
[Fact]
public async Task MultiCdnMeshDownloader_RelativeUri_DoesNotThrowInvalidOperationException()
{
var downloader = new MultiCdnMeshDownloader();
var mirrors = new List<Uri> { new("/relative/path/seg0.ts", UriKind.Relative) };
var ex = await Record.ExceptionAsync(() => downloader.RaceDownloadSegmentAsync(mirrors));
Assert.Null(ex);
}
[Fact]
public async Task MultiCdnMeshDownloader_NegativeStagger_DoesNotThrow()
{
var downloader = new MultiCdnMeshDownloader();
var mirrors = new List<Uri>
{
new("https://cdn1.example.com/seg0.ts"),
new("https://cdn2.example.com/seg0.ts")
};
var ex = await Record.ExceptionAsync(() => downloader.RaceDownloadSegmentAsync(mirrors, staggerDelayMs: -50));
Assert.Null(ex);
}
}