using ZB.MOM.WW.Secrets.Abstractions; using Xunit; namespace ZB.MOM.WW.Secrets.Tests; public class SecretNameTests { [Theory] [InlineData("sql/historiangw/historian-password", "sql/historiangw/historian-password")] [InlineData(" SQL/Foo ", "sql/foo")] // trimmed + lowercased public void Normalizes(string input, string expected) => Assert.Equal(expected, new SecretName(input).Value); [Theory] [InlineData("")] [InlineData(" ")] [InlineData("bad name with spaces")] [InlineData("../escape")] public void RejectsInvalid(string input) => Assert.Throws(() => new SecretName(input)); [Theory] [InlineData("/etc/passwd")] // rooted / absolute [InlineData("/")] // rooted (starts and ends with '/') [InlineData("sql//foo")] // empty path segment [InlineData("sql/foo/")] // trailing '/' public void RejectsRootedOrEmptySegment(string input) => Assert.Throws(() => new SecretName(input)); [Fact] public void AcceptsExactlyMaxLength_AndRejectsOneOver() { Assert.Equal(450, SecretName.MaxLength); Assert.Equal(450, new SecretName(new string('a', 450)).Value.Length); Assert.Throws(() => new SecretName(new string('a', 451))); // Length is measured after trim/lowercase normalization. Assert.Equal(450, new SecretName(" " + new string('A', 450) + " ").Value.Length); } [Fact] public void DefaultInstance_ThrowsOnValue() => Assert.Throws(() => _ = default(SecretName).Value); [Fact] public void ValidNestedName_RoundTrips() => Assert.Equal( "sql/historiangw/historian-password", new SecretName("sql/historiangw/historian-password").Value); }