Closes #4
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
using FinalFactory.Rendezvous.Contracts;
|
||||
|
||||
namespace FinalFactory.Rendezvous.Tests.Contracts;
|
||||
|
||||
public sealed class ContractLimitTests
|
||||
{
|
||||
[Fact]
|
||||
public void ByteAndCollectionLimitsAcceptTheBoundaryOnly()
|
||||
{
|
||||
Assert.True(ContractValidation.IsHttpRequestSizeValid(ContractLimits.HttpRequestMaxBytes));
|
||||
Assert.False(ContractValidation.IsHttpRequestSizeValid(ContractLimits.HttpRequestMaxBytes + 1));
|
||||
Assert.True(ContractValidation.IsBrowserResponseSizeValid(ContractLimits.BrowserResponseMaxBytes));
|
||||
Assert.False(ContractValidation.IsBrowserResponseSizeValid(ContractLimits.BrowserResponseMaxBytes + 1));
|
||||
Assert.True(ContractValidation.IsPageSizeValid(ContractLimits.BrowserPageMaxItems));
|
||||
Assert.False(ContractValidation.IsPageSizeValid(ContractLimits.BrowserPageMaxItems + 1));
|
||||
Assert.False(ContractValidation.IsPageSizeValid(0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Utf8LimitsCountBytesInsteadOfCharacters()
|
||||
{
|
||||
string atLimit = new('é', ContractLimits.DisplayNameMaxBytes / 2);
|
||||
string overLimit = atLimit + "é";
|
||||
|
||||
Assert.True(ContractValidation.IsDisplayNameValid(atLimit));
|
||||
Assert.False(ContractValidation.IsDisplayNameValid(overLimit));
|
||||
Assert.True(ContractValidation.IsBuildVersionValid(
|
||||
new string('a', ContractLimits.BuildVersionMaxBytes)));
|
||||
Assert.False(ContractValidation.IsBuildVersionValid(
|
||||
new string('a', ContractLimits.BuildVersionMaxBytes + 1)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CapabilityLimitStaysBelowLiteNetLibTokenLimit()
|
||||
{
|
||||
Assert.True(ContractValidation.IsCapabilityValid(
|
||||
new string('a', ContractLimits.UdpCapabilityMaxCharacters - 1)));
|
||||
Assert.True(ContractValidation.IsCapabilityValid(
|
||||
new string('a', ContractLimits.UdpCapabilityMaxCharacters)));
|
||||
Assert.False(ContractValidation.IsCapabilityValid(
|
||||
new string('a', ContractLimits.UdpCapabilityMaxCharacters + 1)));
|
||||
Assert.False(ContractValidation.IsCapabilityValid("not+base64url"));
|
||||
Assert.True(
|
||||
ContractLimits.UdpCapabilityMaxCharacters
|
||||
< ContractLimits.LiteNetLibNatTokenMaxCharacters);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CapacityAndMetadataLimitsAreBounded()
|
||||
{
|
||||
Assert.True(ContractValidation.IsCapacityValid(new SessionCapacity
|
||||
{
|
||||
CurrentPlayers = ContractLimits.SessionCapacityMaxPlayers,
|
||||
MaximumPlayers = ContractLimits.SessionCapacityMaxPlayers,
|
||||
}));
|
||||
Assert.False(ContractValidation.IsCapacityValid(new SessionCapacity
|
||||
{
|
||||
CurrentPlayers = 0,
|
||||
MaximumPlayers = ContractLimits.SessionCapacityMaxPlayers + 1,
|
||||
}));
|
||||
|
||||
Dictionary<string, string> maximumKeys = Enumerable
|
||||
.Range(0, ContractLimits.MetadataMaxKeys)
|
||||
.ToDictionary(index => $"key-{index}", _ => "value", StringComparer.Ordinal);
|
||||
Dictionary<string, string> tooManyKeys = new(maximumKeys, StringComparer.Ordinal)
|
||||
{
|
||||
["overflow"] = "value",
|
||||
};
|
||||
|
||||
Assert.True(ContractValidation.IsMetadataValid(maximumKeys));
|
||||
Assert.False(ContractValidation.IsMetadataValid(tooManyKeys));
|
||||
Assert.False(ContractValidation.IsMetadataValid(new Dictionary<string, string>
|
||||
{
|
||||
[new string('k', ContractLimits.MetadataKeyMaxBytes + 1)] = "value",
|
||||
}));
|
||||
Assert.False(ContractValidation.IsMetadataValid(new Dictionary<string, string>
|
||||
{
|
||||
["key"] = new string('v', ContractLimits.MetadataValueMaxBytes + 1),
|
||||
}));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MetadataDocumentLimitAcceptsExactlyFourKibibytes()
|
||||
{
|
||||
Dictionary<string, string> atLimit = Enumerable
|
||||
.Range(0, ContractLimits.MetadataMaxKeys)
|
||||
.ToDictionary(index => $"k{index:00}", _ => string.Empty, StringComparer.Ordinal);
|
||||
for (int index = 0; index < 14; index++)
|
||||
{
|
||||
atLimit[$"k{index:00}"] = new string('v', ContractLimits.MetadataValueMaxBytes);
|
||||
}
|
||||
|
||||
atLimit["k14"] = new string('v', 223);
|
||||
Dictionary<string, string> overLimit = new(atLimit, StringComparer.Ordinal)
|
||||
{
|
||||
["k14"] = new string('v', 224),
|
||||
};
|
||||
|
||||
Assert.True(ContractValidation.IsMetadataValid(atLimit));
|
||||
Assert.False(ContractValidation.IsMetadataValid(overLimit));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EndpointValidationIsAddressFamilyAware()
|
||||
{
|
||||
Assert.True(ContractValidation.IsNetworkEndpointValid(new NetworkEndpoint
|
||||
{
|
||||
AddressFamily = AddressFamilyKind.Ipv4,
|
||||
Address = "192.0.2.10",
|
||||
Port = 9050,
|
||||
}));
|
||||
Assert.True(ContractValidation.IsNetworkEndpointValid(new NetworkEndpoint
|
||||
{
|
||||
AddressFamily = AddressFamilyKind.Ipv6,
|
||||
Address = "2001:db8::10",
|
||||
Port = 9050,
|
||||
}));
|
||||
Assert.False(ContractValidation.IsNetworkEndpointValid(new NetworkEndpoint
|
||||
{
|
||||
AddressFamily = AddressFamilyKind.Ipv4,
|
||||
Address = "2001:db8::10",
|
||||
Port = 9050,
|
||||
}));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScopeAndOpaqueTextBoundariesAreEnforced()
|
||||
{
|
||||
Assert.True(GameId.TryParse(new string('a', ContractLimits.GameIdMaxCharacters), out _));
|
||||
Assert.False(GameId.TryParse(
|
||||
new string('a', ContractLimits.GameIdMaxCharacters + 1),
|
||||
out _));
|
||||
Assert.True(ContractValidation.IsIdempotencyKeyValid(
|
||||
new string('i', ContractLimits.IdempotencyKeyMaxCharacters)));
|
||||
Assert.False(ContractValidation.IsIdempotencyKeyValid(
|
||||
new string('i', ContractLimits.IdempotencyKeyMaxCharacters + 1)));
|
||||
Assert.True(ContractValidation.IsCursorValid(null));
|
||||
Assert.False(ContractValidation.IsCursorValid("contains whitespace"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user