using System; using System.Security.Cryptography; using System.Text; using GB5Shared.Auth.Jwt; using Xunit; namespace GB5SharedTests; /// /// Covers GB5Shared.Auth.Jwt.RefreshTokenHelper — extracted verbatim from what DXPJwtService and /// ClientJwtService each used to hand-roll identically. /// public class RefreshTokenHelperTests { [Fact] public void Test_GenerateRefreshToken_ProducesUrlSafeToken_AndMatchingHash() { var (raw, hash) = RefreshTokenHelper.GenerateRefreshToken(); Assert.DoesNotContain("+", raw); Assert.DoesNotContain("/", raw); Assert.DoesNotContain("=", raw); Assert.Equal(RefreshTokenHelper.HashRefreshToken(raw), hash); } [Fact] public void Test_GenerateRefreshToken_TwoCalls_ProduceDifferentTokens() { var (raw1, _) = RefreshTokenHelper.GenerateRefreshToken(); var (raw2, _) = RefreshTokenHelper.GenerateRefreshToken(); Assert.NotEqual(raw1, raw2); } [Fact] public void Test_HashRefreshToken_MatchesSha256OfRawToken() { var hash = RefreshTokenHelper.HashRefreshToken("some-raw-token"); var expected = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes("some-raw-token"))); Assert.Equal(expected, hash); } [Fact] public void Test_HashRefreshToken_IsDeterministic_SameInputSameHash() { var hash1 = RefreshTokenHelper.HashRefreshToken("same-input"); var hash2 = RefreshTokenHelper.HashRefreshToken("same-input"); Assert.Equal(hash1, hash2); } }