using Microsoft.Extensions.Configuration; using ZB.MOM.WW.Configuration; namespace ZB.MOM.WW.Configuration.Tests; /// /// Pins the exact failure-message wording produced by the shared Checks seam through its /// public front-ends ( for raw port values, /// for host:port endpoints). Covers Configuration-002 (consistent quoting) and Configuration-003 /// (strict, culture-invariant port parsing). /// public sealed class ChecksWordingTests { private static IConfiguration Config(string key, string? value) => new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { [key] = value }) .Build(); private static string PortFailure(string? rawValue) { var pf = ConfigPreflight.For(Config("X:Port", rawValue)).RequirePort("X:Port"); return Assert.Single(pf.Failures); } // Configuration-002: range failure and parse failure must quote the offending value the same way. [Fact] public void PortValue_range_failure_quotes_the_value() { Assert.Equal("X:Port must be between 1 and 65535 (was '0')", PortFailure("0")); } [Fact] public void PortValue_high_range_failure_quotes_the_value() { Assert.Equal("X:Port must be between 1 and 65535 (was '70000')", PortFailure("70000")); } [Fact] public void PortValue_parse_failure_quotes_the_value() { Assert.Equal("X:Port must be between 1 and 65535 (was 'notaport')", PortFailure("notaport")); } [Fact] public void PortValue_null_failure_renders_null() { Assert.Equal("X:Port must be between 1 and 65535 (was 'null')", PortFailure(null)); } // Configuration-003: strict, culture-invariant parsing rejects sign and surrounding whitespace. [Theory] [InlineData("+5000")] [InlineData(" 5000")] [InlineData("5000 ")] [InlineData(" 5000 ")] [InlineData("-1")] public void PortValue_rejects_loose_inputs(string raw) { var pf = ConfigPreflight.For(Config("X:Port", raw)).RequirePort("X:Port"); Assert.False(pf.IsValid); Assert.Equal($"X:Port must be between 1 and 65535 (was '{raw}')", Assert.Single(pf.Failures)); } [Fact] public void PortValue_accepts_plain_in_range_port() { var pf = ConfigPreflight.For(Config("X:Port", "5000")).RequirePort("X:Port"); Assert.True(pf.IsValid); } [Theory] [InlineData("host:+5000")] [InlineData("host: 5000")] [InlineData("host:5000 ")] public void HostPort_rejects_loose_port_inputs(string value) { var b = new ValidationBuilder(); b.HostPort(value, "X:Endpoint"); Assert.False(b.IsValid); Assert.Equal($"X:Endpoint must be 'host:port' with port 1-65535 (was '{value}')", Assert.Single(b.Failures)); } [Fact] public void HostPort_accepts_plain_endpoint() { var b = new ValidationBuilder(); b.HostPort("host:5000", "X:Endpoint"); Assert.True(b.IsValid); } }