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(() => 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(() => 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(() => 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 { 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 { 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); } }