using System; using System.IO; using System.Linq; using Paca.Browser.Scripts; using Paca.Browser.Tabs; using Xunit; namespace Paca.Tests.Browser; public class ChromeUserScriptManagerTests { [Fact] public void UserScript_Parser_Extracts_Metadata() { var content = @"// ==UserScript== // @name Ad Skipper // @match *://*.youtube.com/* // @run-at document-end // ==/UserScript== console.log('Ad Skipper Initialized');"; var script = UserScriptParser.Parse(content); Assert.NotNull(script); Assert.Equal("Ad Skipper", script.Name); Assert.Equal("*://*.youtube.com/*", script.MatchPattern); Assert.Equal("document-end", script.RunAt); Assert.Contains("console.log('Ad Skipper Initialized');", script.Code); Assert.True(script.IsEnabled); } [Theory] [InlineData("*://*.example.com/*", "https://sub.example.com/path", true)] [InlineData("*://*.example.com/*", "http://example.com/", true)] [InlineData("*://*.example.com/*", "https://other.com/path", false)] [InlineData("https://youtube.com/*", "https://youtube.com/watch?v=1", true)] [InlineData("https://youtube.com/*", "http://youtube.com/watch?v=1", false)] [InlineData("", "https://anything.org/test", true)] public void UserScript_Pattern_Matching_Works(string pattern, string url, bool expected) { var isMatch = UserScriptPatternMatcher.IsMatch(pattern, url); Assert.Equal(expected, isMatch); } [Fact] public void UserScriptManager_Registry_And_Filtering() { var mgr = new UserScriptManager(); var script1 = new UserScript("id1", "YT Script", "*://*.youtube.com/*", "document-idle", "alert(1);", true); var script2 = new UserScript("id2", "YT Start Script", "*://*.youtube.com/*", "document-start", "alert(2);", true); var script3 = new UserScript("id3", "Disabled Script", "*://*.youtube.com/*", "document-idle", "alert(3);", false); var script4 = new UserScript("id4", "Other Site", "https://example.com/*", "document-idle", "alert(4);", true); mgr.Add(script1); mgr.Add(script2); mgr.Add(script3); mgr.Add(script4); var ytIdle = mgr.GetScriptsForUrl("https://www.youtube.com/watch?v=abc", "document-idle"); Assert.Single(ytIdle); Assert.Equal("id1", ytIdle[0].Id); var ytStart = mgr.GetScriptsForUrl("https://www.youtube.com/watch?v=abc", "document-start"); Assert.Single(ytStart); Assert.Equal("id2", ytStart[0].Id); // Toggle script 1 to disabled mgr.Toggle("id1", false); var ytIdleAfter = mgr.GetScriptsForUrl("https://www.youtube.com/watch?v=abc", "document-idle"); Assert.Empty(ytIdleAfter); } [Fact] public void UserScriptManager_File_Persistence() { var tempFile = Path.Combine(Path.GetTempPath(), "paca_script_test_" + Guid.NewGuid().ToString("N") + ".json"); try { var mgr1 = new UserScriptManager(); mgr1.Add(new UserScript("s1", "Persistent Script", "*://*.naver.com/*", "document-idle", "console.log('hi');", true)); mgr1.Save(tempFile); var mgr2 = new UserScriptManager(); mgr2.Load(tempFile); Assert.Single(mgr2.Scripts); Assert.Equal("Persistent Script", mgr2.Scripts[0].Name); Assert.Equal("*://*.naver.com/*", mgr2.Scripts[0].MatchPattern); } finally { if (File.Exists(tempFile)) File.Delete(tempFile); } } [Fact] public void OmniboxActionEvaluator_Matches_Extensions() { var actionsKr = OmniboxActionEvaluator.GetMatchingActions("확장 프로그램"); Assert.Contains(actionsKr, a => a.ActionId == "action:extensions"); var actionsEn = OmniboxActionEvaluator.GetMatchingActions("userscripts"); Assert.Contains(actionsEn, a => a.ActionId == "action:extensions"); var action = OmniboxActionEvaluator.AllActions.FirstOrDefault(a => a.ActionId == "action:extensions"); Assert.NotNull(action); Assert.Contains("확장 프로그램", action.DisplayTitle); } }