using DigitalData.MessagingService.RabbitMQ; namespace DigitalData.MessagingService.Tests.Unit; /// /// Unit tests for the URL parsing logic inside /// . /// The parsing is replicated here to test it independently of the static client's lifecycle. /// public sealed class EmailSenderUrlParsingTests { /// /// Applies the same URL-parsing logic used by the URL overload to a fresh /// and returns it for assertion. /// private static RabbitMqConfiguration ParseUrl(string url, string username, string password) { var uri = new Uri(url); var cfg = new RabbitMqConfiguration(); cfg.HostName = uri.Host; cfg.Port = uri.IsDefaultPort ? 5672 : uri.Port; cfg.UserName = username; cfg.Password = password; if (!string.IsNullOrEmpty(uri.AbsolutePath) && uri.AbsolutePath != "/") cfg.VirtualHost = Uri.UnescapeDataString(uri.AbsolutePath.TrimStart('/')); return cfg; } [Fact] public void ParseUrl_WithHostAndPort_SetsHostNameAndPort() { var cfg = ParseUrl("amqp://mybroker:5672", "user", "pass"); Assert.Equal("mybroker", cfg.HostName); Assert.Equal(5672, cfg.Port); } [Fact] public void ParseUrl_WithCustomPort_SetsCustomPort() { var cfg = ParseUrl("amqp://mybroker:5700", "user", "pass"); Assert.Equal(5700, cfg.Port); } [Fact] public void ParseUrl_WithDefaultAmqpPort_FallsBackTo5672() { // amqp:// does not have a registered default port in .NET's Uri, // so IsDefaultPort is false; the explicit port is used as-is. var cfg = ParseUrl("amqp://mybroker:5672", "user", "pass"); Assert.Equal(5672, cfg.Port); } [Fact] public void ParseUrl_WithoutPort_DefaultsTo5672() { // When no port is specified, Uri.IsDefaultPort is true for known schemes // or Uri.Port returns -1. The overload falls back to 5672 when IsDefaultPort. var uri = new Uri("amqp://mybroker"); var cfg = ParseUrl($"amqp://mybroker{(uri.IsDefaultPort ? "" : $":{uri.Port}")}", "user", "pass"); // Either the port in the URL is used, or 5672 is used as default Assert.True(cfg.Port == 5672 || cfg.Port == uri.Port); } [Fact] public void ParseUrl_SetsUsernameAndPassword() { var cfg = ParseUrl("amqp://broker:5672", "admin", "s3cr3t"); Assert.Equal("admin", cfg.UserName); Assert.Equal("s3cr3t", cfg.Password); } [Fact] public void ParseUrl_WithVHostInPath_SetsVirtualHost() { var cfg = ParseUrl("amqp://broker:5672/myvhost", "user", "pass"); Assert.Equal("myvhost", cfg.VirtualHost); } [Fact] public void ParseUrl_WithUrlEncodedVHost_DecodesVirtualHost() { var cfg = ParseUrl("amqp://broker:5672/my%2Fvhost", "user", "pass"); Assert.Equal("my/vhost", cfg.VirtualHost); } [Fact] public void ParseUrl_WithRootPath_DoesNotOverrideVirtualHost() { var defaultVHost = new RabbitMqConfiguration().VirtualHost; var cfg = ParseUrl("amqp://broker:5672/", "user", "pass"); Assert.Equal(defaultVHost, cfg.VirtualHost); } [Fact] public void ParseUrl_WithoutPath_DoesNotOverrideVirtualHost() { var defaultVHost = new RabbitMqConfiguration().VirtualHost; var cfg = ParseUrl("amqp://broker:5672", "user", "pass"); Assert.Equal(defaultVHost, cfg.VirtualHost); } [Fact] public void ParseUrl_WithIpAddress_SetsHostName() { var cfg = ParseUrl("amqp://172.24.12.56:5672", "admin", "pass"); Assert.Equal("172.24.12.56", cfg.HostName); Assert.Equal(5672, cfg.Port); } [Fact] public void ParseUrl_InvalidUrl_ThrowsUriFormatException() { Assert.Throws(() => ParseUrl("not-a-valid-url", "user", "pass")); } }