diff --git a/BrowseRouter/Model/UriFactory.cs b/BrowseRouter/Model/UriFactory.cs index f3fe14d..7ee572c 100644 --- a/BrowseRouter/Model/UriFactory.cs +++ b/BrowseRouter/Model/UriFactory.cs @@ -4,16 +4,11 @@ namespace BrowseRouter.Model; public static class UriFactory { - public static Uri Get(string url) + public static Uri? Get(string url) => url switch { - try - { - return new Uri(WebUtility.UrlDecode(url)); - } - catch (UriFormatException) - { - // Try to prepend https when given an incomplete URI e.g. "google.com" - return new Uri($"https://{url}"); - } - } + _ when Uri.TryCreate(url, UriKind.Absolute, out var uri) => uri, + _ when Uri.TryCreate($"https://{url}", UriKind.Absolute, out var uri) => uri, + _ when Uri.TryCreate(WebUtility.UrlDecode(url), UriKind.Absolute, out var uri) => uri, + _ => null, + }; } \ No newline at end of file diff --git a/BrowseRouter/Services/BrowserService.cs b/BrowseRouter/Services/BrowserService.cs index 9fdcc2a..d6e75f8 100644 --- a/BrowseRouter/Services/BrowserService.cs +++ b/BrowseRouter/Services/BrowserService.cs @@ -26,7 +26,14 @@ public async Task LaunchAsync(string rawUrl, string windowTitle) IEnumerable urlPreferences = config.GetUrlPreferences(ConfigType.Urls); IEnumerable sourcePreferences = config.GetUrlPreferences(ConfigType.Sources); - Uri uri = UriFactory.Get(url); + Uri? uri = UriFactory.Get(url); + + if (uri is null) + { + Log.Write($"Invalid URL: {url}"); + await notifier.NotifyAsync("Error", $"Invalid URL: {url}"); + return; + } UrlPreference? pref = null; if (sourcePreferences.TryGetPreference(windowTitle, out UrlPreference sourcePref)) diff --git a/BrowseRouter/config.ini b/BrowseRouter/config.ini index 046ef47..135529d 100644 --- a/BrowseRouter/config.ini +++ b/BrowseRouter/config.ini @@ -11,9 +11,9 @@ ff = %ProgramFiles%\Mozilla Firefox\firefox.exe chrome = %ProgramFiles%\Google\Chrome\Application\chrome.exe [urls] -*.google.com = chrome -*.visualstudio.com = edge -*.mozilla.org = ff +*google.com = chrome +*microsoft.com = edge +*mozilla.org = ff [sources] *Microsoft Teams* = edge diff --git a/BrowseRouter/config.json b/BrowseRouter/config.json index f47132f..d1fd3f0 100644 --- a/BrowseRouter/config.json +++ b/BrowseRouter/config.json @@ -8,9 +8,9 @@ "enabled": true }, "urls": { - "*.google.com": "chrome", - "*.visualstudio.com": "edge", - "*.mozilla.org": "ff" + "*google.com": "chrome", + "*microsoft.com": "edge", + "*mozilla.org": "ff" }, "browsers": { "edge": "%ProgramFiles(x86)%\\Microsoft\\Edge\\Application\\msedge.exe", diff --git a/Directory.Build.props b/Directory.Build.props index cb3972c..8952438 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,7 +5,7 @@ enable enable latest - 0.15.6 + 0.16.0 BrowseRouter EnduraByte LLC 2025 diff --git a/Tests/BrowseRouter.Tests/Model/ArgsTests/FormatMethod.cs b/Tests/BrowseRouter.Tests/Model/ArgsTests/FormatMethod.cs new file mode 100644 index 0000000..cd75cf5 --- /dev/null +++ b/Tests/BrowseRouter.Tests/Model/ArgsTests/FormatMethod.cs @@ -0,0 +1,14 @@ +using BrowseRouter.Model; + +namespace BrowseRouter.Tests.Model.ArgsTests; + +public class FormatMethod +{ + [Fact] + public void DoesNotDecodeQueryString() + { + string result = Args.Format("", new Uri("https://www.google.com/search?q=C%23+Rocks")); + + result.Should().NotContain("C# Rocks"); + } +} diff --git a/Tests/BrowseRouter.Tests/Model/UriFactoryTests.cs b/Tests/BrowseRouter.Tests/Model/UriFactoryTests.cs index 43376c7..1a1885c 100644 --- a/Tests/BrowseRouter.Tests/Model/UriFactoryTests.cs +++ b/Tests/BrowseRouter.Tests/Model/UriFactoryTests.cs @@ -8,26 +8,45 @@ public class GetMethod public void HandlesValidUrl() { string url = "https://www.example.com/path"; - var act = () => UriFactory.Get(url); + var uri = UriFactory.Get(url); - act.Should().NotThrow(); + uri?.AbsoluteUri.Should().Be("https://www.example.com/path"); } [Fact] - public void HandlesUrlWithoutHttps() + public void PrependsHttps_ForUrlWithoutScheme() { string url = "www.example.com/path"; - var act = () => UriFactory.Get(url); + var uri = UriFactory.Get(url); - act.Should().NotThrow(); + uri?.Scheme.Should().Be("https"); + uri?.AbsoluteUri.Should().Be("https://www.example.com/path"); } [Fact] - public void HandlesUrlEncodedUrl() + public void DecodesUrlEncodedUrl() { - string url = "https%3A%2F%2Fwww.example.com%2Fpath%2F"; - var act = () => UriFactory.Get(url); + string url = "https%3A%2F%2Fwww.example.com%2Fpath"; + var uri = UriFactory.Get(url); - act.Should().NotThrow(); + uri?.AbsoluteUri.Should().Be("https://www.example.com/path"); + } + + [Fact] + public void PreservesQueryParameters() + { + string url = "https://www.example.com/path?token=6Us%2btD%2btWmVr"; + var uri = UriFactory.Get(url); + + uri?.Query.Should().Be("?token=6Us%2btD%2btWmVr"); + } + + [Fact] + public void ReturnsNull_ForInvalidUrl() + { + string url = ""; + var uri = UriFactory.Get(url); + + uri.Should().BeNull(); } }