save progress
This commit is contained in:
@@ -95,6 +95,96 @@ public sealed class ReplayTokenGeneratorTests
|
||||
Assert.False(generator.Verify(token, different));
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Generate_IgnoresAdditionalContextOrdering()
|
||||
{
|
||||
var cryptoHash = DefaultCryptoHash.CreateForTests();
|
||||
var timeProvider = new FixedTimeProvider(new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
||||
|
||||
var generator = new Sha256ReplayTokenGenerator(cryptoHash, timeProvider);
|
||||
|
||||
var requestA = new ReplayTokenRequest
|
||||
{
|
||||
InputHashes = new[] { "sha256:input" },
|
||||
AdditionalContext = new Dictionary<string, string>
|
||||
{
|
||||
["a"] = "1",
|
||||
["b"] = "2"
|
||||
}
|
||||
};
|
||||
|
||||
var requestB = new ReplayTokenRequest
|
||||
{
|
||||
InputHashes = new[] { "sha256:input" },
|
||||
AdditionalContext = new Dictionary<string, string>
|
||||
{
|
||||
["b"] = "2",
|
||||
["a"] = "1"
|
||||
}
|
||||
};
|
||||
|
||||
var tokenA = generator.Generate(requestA);
|
||||
var tokenB = generator.Generate(requestB);
|
||||
|
||||
Assert.Equal(tokenA.Value, tokenB.Value);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Generate_DuplicateAdditionalContextKeys_Throws()
|
||||
{
|
||||
var cryptoHash = DefaultCryptoHash.CreateForTests();
|
||||
var timeProvider = new FixedTimeProvider(new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
||||
|
||||
var generator = new Sha256ReplayTokenGenerator(cryptoHash, timeProvider);
|
||||
|
||||
var request = new ReplayTokenRequest
|
||||
{
|
||||
InputHashes = new[] { "sha256:input" },
|
||||
AdditionalContext = new Dictionary<string, string>
|
||||
{
|
||||
["key"] = "1",
|
||||
[" key "] = "2"
|
||||
}
|
||||
};
|
||||
|
||||
Assert.Throws<ArgumentException>(() => generator.Generate(request));
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void GenerateWithExpiration_UsesDistinctCanonicalVersion()
|
||||
{
|
||||
var cryptoHash = DefaultCryptoHash.CreateForTests();
|
||||
var timeProvider = new FixedTimeProvider(new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
||||
|
||||
var generator = new Sha256ReplayTokenGenerator(cryptoHash, timeProvider);
|
||||
var request = new ReplayTokenRequest { InputHashes = new[] { "sha256:input" } };
|
||||
|
||||
var v1Token = generator.Generate(request);
|
||||
var v2Token = generator.GenerateWithExpiration(request, TimeSpan.FromMinutes(5));
|
||||
|
||||
Assert.NotEqual(v1Token.Value, v2Token.Value);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
[InlineData(-1)]
|
||||
public void GenerateWithExpiration_NonPositiveExpiration_Throws(int seconds)
|
||||
{
|
||||
var cryptoHash = DefaultCryptoHash.CreateForTests();
|
||||
var timeProvider = new FixedTimeProvider(new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
||||
|
||||
var generator = new Sha256ReplayTokenGenerator(cryptoHash, timeProvider);
|
||||
var request = new ReplayTokenRequest { InputHashes = new[] { "sha256:input" } };
|
||||
|
||||
var expiration = TimeSpan.FromSeconds(seconds);
|
||||
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => generator.GenerateWithExpiration(request, expiration));
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ReplayToken_Parse_RoundTripsCanonical()
|
||||
|
||||
Reference in New Issue
Block a user