aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorWizardOfYendor1 <WizardOfYendor1@users.noreply.github.com>2026-07-17 12:02:09 -0400
committerWizardOfYendor1 <WizardOfYendor1@users.noreply.github.com>2026-07-17 14:59:46 -0400
commit0c7428f13675d1b63234cdc3ef5c748eb998e8e9 (patch)
tree091ebbf37dd8057fce2ab87a661a8e3889f9be0e /tests
parent97e666c56639c5b1f846e684dee391c3b62c0ac9 (diff)
Added verbose, rambling, log warning to help users with config issues (hoping to reduce false issues reports).
Also added a test to exercise it, which is perhaps silly but convenient.
Diffstat (limited to 'tests')
-rw-r--r--tests/Jellyfin.Networking.Tests/NetworkParseTests.cs89
1 files changed, 89 insertions, 0 deletions
diff --git a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs
index 5f7a0efe8a..d8cb9e1ac6 100644
--- a/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs
+++ b/tests/Jellyfin.Networking.Tests/NetworkParseTests.cs
@@ -562,6 +562,95 @@ namespace Jellyfin.Networking.Tests
Assert.Null(port);
}
+ [Theory]
+ // Full-URL override with a different public path: warn about the Live TV fallback.
+ [InlineData("all=https://media.example.com", "/jellyfin", true)]
+ // Full-URL override that ends with the base URL (with and without a trailing slash): no warning.
+ [InlineData("all=https://media.example.com/jellyfin", "/jellyfin", false)]
+ [InlineData("all=https://media.example.com/jellyfin/", "/jellyfin", false)]
+ [InlineData("all=https://media.example.com/media/jellyfin", "/jellyfin", false)]
+ [InlineData("all=https://media.example.com/cool%20server", "/cool server", false)]
+ // A similar segment or a path following the base URL is a different public API base.
+ [InlineData("all=https://media.example.com/jellyfinx", "/jellyfin", true)]
+ [InlineData("all=https://media.example.com/jellyfin/media", "/jellyfin", true)]
+ // No base URL configured: there is no path to compare.
+ [InlineData("all=https://media.example.com", "", false)]
+ // Bare host overrides get the base URL appended when the API URL is built: no warning.
+ [InlineData("all=media.example.com", "/jellyfin", false)]
+ [InlineData("internal=http-proxy.lan:8097", "/jellyfin", false)]
+ // Keyword overrides go through the same check as "all".
+ [InlineData("internal=http://10.0.0.5:8096", "/jellyfin", true)]
+ public void InitializeOverrides_FullUrlPublicPathDiffersFromBaseUrl_LogsWarning(string publishedServers, string baseUrl, bool expectWarning)
+ {
+ var conf = new NetworkConfiguration
+ {
+ LocalNetworkSubnets = new[] { "192.168.1.0/24" },
+ LocalNetworkAddresses = new[] { "eth16" },
+ EnableIPv4 = true,
+ PublishedServerUriBySubnet = new[] { publishedServers },
+ BaseUrl = baseUrl
+ };
+
+ var logger = new Mock<ILogger<NetworkManager>>();
+ NetworkManager.MockNetworkSettings = "192.168.1.208/24,-16,eth16";
+ var startupConf = new Mock<IConfiguration>();
+ using var nm = new NetworkManager(NetworkParseTests.GetMockConfig(conf), startupConf.Object, logger.Object);
+ NetworkManager.MockNetworkSettings = string.Empty;
+
+ VerifyBaseUrlWarning(logger, expectWarning ? Times.AtLeastOnce() : Times.Never());
+ }
+
+ /// <summary>
+ /// The JELLYFIN_PublishedServerUrl environment variable / --published-server-url option takes the
+ /// startup-configuration branch of <c>InitializeOverrides</c> and must funnel through the same
+ /// base URL check as the dashboard overrides.
+ /// </summary>
+ [Fact]
+ public void InitializeOverrides_StartupPublishedServerUrlPathDiffersFromBaseUrl_LogsWarningWithoutCredentials()
+ {
+ var conf = new NetworkConfiguration
+ {
+ LocalNetworkSubnets = new[] { "192.168.1.0/24" },
+ LocalNetworkAddresses = new[] { "eth16" },
+ EnableIPv4 = true,
+ BaseUrl = "/jellyfin"
+ };
+
+ var logger = new Mock<ILogger<NetworkManager>>();
+ var startupConf = new Mock<IConfiguration>();
+ startupConf.Setup(x => x[MediaBrowser.Controller.Extensions.ConfigurationExtensions.AddressOverrideKey]).Returns("https://user:password@media.example.com?access_token=secret#fragment");
+
+ NetworkManager.MockNetworkSettings = "192.168.1.208/24,-16,eth16";
+ using var nm = new NetworkManager(NetworkParseTests.GetMockConfig(conf), startupConf.Object, logger.Object);
+ NetworkManager.MockNetworkSettings = string.Empty;
+
+ VerifyBaseUrlWarning(logger, Times.AtLeastOnce());
+ logger.Verify(
+ l => l.Log(
+ LogLevel.Warning,
+ It.IsAny<EventId>(),
+ It.Is<It.IsAnyType>((state, _) => state.ToString()!.Contains("user", StringComparison.Ordinal)
+ || state.ToString()!.Contains("password", StringComparison.Ordinal)
+ || state.ToString()!.Contains("access_token", StringComparison.Ordinal)
+ || state.ToString()!.Contains("secret", StringComparison.Ordinal)
+ || state.ToString()!.Contains("fragment", StringComparison.Ordinal)),
+ It.IsAny<Exception?>(),
+ It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
+ Times.Never());
+ }
+
+ private static void VerifyBaseUrlWarning(Mock<ILogger<NetworkManager>> logger, Times times)
+ {
+ logger.Verify(
+ l => l.Log(
+ LogLevel.Warning,
+ It.IsAny<EventId>(),
+ It.Is<It.IsAnyType>((state, _) => state.ToString()!.Contains("Jellyfin will append this base URL when generating Live TV client URLs", StringComparison.Ordinal)),
+ It.IsAny<Exception?>(),
+ It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
+ times);
+ }
+
/// <summary>
/// <see cref="NetworkManager.GetBindAddress(HttpRequest, out int?)"/> is the piece of request-host
/// normalization that a request-host-aware smart API URL policy relies on: it resolves the bind address