using System; using System.Collections.Generic; using Paca.Browser; using Paca.Browser.Content; using Xunit; namespace Paca.Tests.Browser; public class BrowserContentAndRoutingExtremeRedTests { // ========================================== // 1. ChromeInternalUrlRouter // ========================================== [Theory] [InlineData("chrome://settings?category=privacy", ChromeInternalAction.Settings)] [InlineData("chrome://downloads?q=paca", ChromeInternalAction.Downloads)] [InlineData("chrome://history#search", ChromeInternalAction.History)] [InlineData("chrome:///settings", ChromeInternalAction.Settings)] [InlineData("paca://extensions?id=123", ChromeInternalAction.Extensions)] [InlineData("chrome://settings/content?site=example.com", ChromeInternalAction.SiteSettings)] [InlineData("chrome://clear-browsing-data?time=all", ChromeInternalAction.ClearBrowsingData)] public void ChromeInternalUrlRouter_Route_WithQueryOrFragment_ResolvesActionCorrectly(string url, ChromeInternalAction expected) { var action = ChromeInternalUrlRouter.Route(url); Assert.Equal(expected, action); } // ========================================== // 2. DualSubtitleEngine // ========================================== [Theory] [InlineData(double.NaN)] [InlineData(double.NegativeInfinity)] [InlineData(double.PositiveInfinity)] [InlineData(-1.0)] public void DualSubtitleEngine_GetDualCues_InvalidTimestamp_ReturnsNull(double timestamp) { var engine = new DualSubtitleEngine(); var cues = engine.GetDualCues(timestamp); Assert.Null(cues); } [Fact] public void DualSubtitleEngine_RegisterAudioTrack_NullOrDuplicate_HandledSafely() { var engine = new DualSubtitleEngine(); engine.RegisterAudioTrack(null!); Assert.Empty(engine.AudioTracks); var track1 = new AudioTrackInfo(1, "ko", "한국어", true); var track1Duplicate = new AudioTrackInfo(1, "ko-alt", "한국어 더빙", false); engine.RegisterAudioTrack(track1); engine.RegisterAudioTrack(track1Duplicate); Assert.Single(engine.AudioTracks); Assert.Equal(1, engine.SelectedAudioTrackId); } // ========================================== // 3. LiveCaptionEngine // ========================================== [Theory] [InlineData(double.NaN)] [InlineData(-10.0)] public void LiveCaptionEngine_GetActiveCue_InvalidTimestamp_ReturnsNull(double timestamp) { var engine = new LiveCaptionEngine(); var cue = engine.GetActiveCue(timestamp); Assert.Null(cue); } // ========================================== // 4. MhtmlWebArchivePackager // ========================================== [Fact] public void MhtmlWebArchivePackager_Package_NullRequest_ThrowsArgumentNullException() { var packager = new MhtmlWebArchivePackager(); Assert.Throws(() => packager.Package(null!)); } [Fact] public void MhtmlWebArchivePackager_Package_NullResourcesOrData_PackagesWithoutCrashing() { var packager = new MhtmlWebArchivePackager(); var req = new WebArchivePackageRequest( Url: "https://example.com", Title: "Test Page", HtmlContent: "Hello", Resources: new List { new("https://example.com/null.png", "image/png", null!), null! } ); var mhtml = packager.Package(req); Assert.NotNull(mhtml); Assert.Contains("Hello", mhtml); } }