using ZB.MOM.WW.Auth.ApiKeys; namespace ZB.MOM.WW.Auth.ApiKeys.Tests; public class ApiKeySecretGeneratorTests { [Fact] public void NewSecret_ReturnsNonEmpty() { var secret = ApiKeySecretGenerator.NewSecret(); Assert.NotEmpty(secret); } [Fact] public void NewSecret_TwoCallsDiffer() { var first = ApiKeySecretGenerator.NewSecret(); var second = ApiKeySecretGenerator.NewSecret(); Assert.NotEqual(first, second); } [Fact] public void NewSecret_DecodesToThirtyTwoBytes() { var secret = ApiKeySecretGenerator.NewSecret(); // Restore URL-safe base64 to standard before decoding string standard = secret.Replace('-', '+').Replace('_', '/'); // Add padding if needed int pad = standard.Length % 4; if (pad == 2) standard += "=="; else if (pad == 3) standard += "="; byte[] bytes = Convert.FromBase64String(standard); Assert.Equal(32, bytes.Length); } [Fact] public void NewSecret_IsUrlSafe_NoPlus() { // Run many iterations to make collisions with '+' unlikely to be missed for (int i = 0; i < 200; i++) { Assert.DoesNotContain('+', ApiKeySecretGenerator.NewSecret()); } } [Fact] public void NewSecret_IsUrlSafe_NoSlash() { for (int i = 0; i < 200; i++) { Assert.DoesNotContain('/', ApiKeySecretGenerator.NewSecret()); } } [Fact] public void NewSecret_IsUrlSafe_NoPaddingEquals() { for (int i = 0; i < 200; i++) { Assert.DoesNotContain('=', ApiKeySecretGenerator.NewSecret()); } } }