Table of Contents

Class RateLimitingTests

Namespace
ProjectTemplate.Web.Tests
Assembly
ProjectTemplate.Web.Tests.dll

Provides integration tests for the application rate limiting configuration and policies.

public sealed class RateLimitingTests
Inheritance
RateLimitingTests
Inherited Members

Methods

DisabledRateLimiting_DoesNotRejectRepeatedRequests()

Verifies that repeated requests are allowed when application rate limiting is disabled.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 206)]
public Task DisabledRateLimiting_DoesNotRejectRepeatedRequests()

Returns

Task

A task that represents the asynchronous test operation.

GetAddressPartitionKey_IPv4MappedAddress_UsesIPv4Address()

Verifies that IPv4-mapped IPv6 addresses are partitioned by IPv4 address rather than collapsed into one IPv6 prefix, since a dual-stack listener reports every IPv4 client in that form.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 573)]
public void GetAddressPartitionKey_IPv4MappedAddress_UsesIPv4Address()

GetAddressPartitionKey_IPv6AddressesInDifferentSlash64_UseDifferentPartitions()

Verifies that IPv6 clients in different /64 networks receive different partitions.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 530)]
public void GetAddressPartitionKey_IPv6AddressesInDifferentSlash64_UseDifferentPartitions()

GetAddressPartitionKey_IPv6AddressesInSameSlash64_ShareOnePartition()

Verifies that IPv6 clients within one /64 share a partition so rotating addresses cannot bypass the limiter.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 513)]
public void GetAddressPartitionKey_IPv6AddressesInSameSlash64_ShareOnePartition()

GetAddressPartitionKey_NonByteAlignedPrefix_MasksPartialByte()

Verifies that a prefix length that is not a multiple of eight masks the partial byte correctly.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 546)]
public void GetAddressPartitionKey_NonByteAlignedPrefix_MasksPartialByte()

GetAddressPartitionKey_PrefixLength128_UsesFullAddress()

Verifies that a prefix length of 128 keeps the full IPv6 address.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 559)]
public void GetAddressPartitionKey_PrefixLength128_UsesFullAddress()

GetClientPartitionKey_IPv6RemoteAddress_UsesConfiguredPrefix()

Verifies that client partitioning applies the configured IPv6 prefix length to the remote address.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 590)]
public void GetClientPartitionKey_IPv6RemoteAddress_UsesConfiguredPrefix()

GetClientPartitionKey_ReturnsRemoteIpAddress_WhenAvailable()

Verifies that client rate limiting uses the resolved remote IP address when available.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 273)]
public void GetClientPartitionKey_ReturnsRemoteIpAddress_WhenAvailable()

GetClientPartitionKey_ThrottlesFallbackWarning_AndReportsSuppressedCount()

Verifies that the fallback warning is written at most once per throttle interval and reports suppressed occurrences.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 388)]
public void GetClientPartitionKey_ThrottlesFallbackWarning_AndReportsSuppressedCount()

GetClientPartitionKey_UsesConfiguredSharedFallbackKey()

Verifies that unresolved client IP addresses share the configured fallback partition key.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 330)]
public void GetClientPartitionKey_UsesConfiguredSharedFallbackKey()

GetClientPartitionKey_UsesPerRequestFallback_WhenExplicitlyConfigured()

Verifies that unresolved client IP addresses only receive per-request fallback partitions when explicitly configured.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 359)]
public void GetClientPartitionKey_UsesPerRequestFallback_WhenExplicitlyConfigured()

GetClientPartitionKey_UsesSharedFallback_WhenRemoteIpAddressIsUnavailableByDefault()

Verifies that unresolved client IP addresses share one fallback partition by default so they remain rate limited.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 304)]
public void GetClientPartitionKey_UsesSharedFallback_WhenRemoteIpAddressIsUnavailableByDefault()

GetConcurrencyPartitionKey_Default_CombinesEndpointAndClient()

Verifies that the concurrency policy partitions by endpoint and client by default.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 609)]
public void GetConcurrencyPartitionKey_Default_CombinesEndpointAndClient()

GetConcurrencyPartitionKey_PartitionByClientDisabled_UsesEndpointOnly()

Verifies that disabling client partitioning restores one shared permit pool per endpoint.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 627)]
public void GetConcurrencyPartitionKey_PartitionByClientDisabled_UsesEndpointOnly()

GlobalFixedWindowLimiter_ReturnsTooManyRequests_WhenPermitLimitIsExceeded()

Verifies that the global fixed-window limiter rejects requests after the configured permit limit is exceeded.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 29)]
public Task GlobalFixedWindowLimiter_ReturnsTooManyRequests_WhenPermitLimitIsExceeded()

Returns

Task

A task that represents the asynchronous test operation.

LogRejectedRequest_IncludesRemoteIpAddress_WhenRequestLoggingOptsIn()

Verifies that the rejection log entry includes the remote IP address only when request logging opts in.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 187)]
public void LogRejectedRequest_IncludesRemoteIpAddress_WhenRequestLoggingOptsIn()

LogRejectedRequest_OmitsRemoteIpAddress_ByDefault()

Verifies that the rejection log entry omits the remote IP address by default.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 167)]
public void LogRejectedRequest_OmitsRemoteIpAddress_ByDefault()

NamedConcurrencyPolicy_ReturnsTooManyRequests_WhenConcurrentLimitIsExceeded()

Verifies that the named concurrency policy rejects a second request while the configured permit is already in use.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 81)]
public Task NamedConcurrencyPolicy_ReturnsTooManyRequests_WhenConcurrentLimitIsExceeded()

Returns

Task

A task that represents the asynchronous test operation.

NamedFixedWindowPolicy_ReturnsTooManyRequests_WhenPermitLimitIsExceeded()

Verifies that the named fixed-window policy rejects endpoint requests after the configured permit limit is exceeded.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 55)]
public Task NamedFixedWindowPolicy_ReturnsTooManyRequests_WhenPermitLimitIsExceeded()

Returns

Task

A task that represents the asynchronous test operation.

RateLimitingFallbackWarningThrottle_NonPositiveInterval_Throws()

Verifies that the fallback warning throttle rejects a non-positive interval.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 423)]
public void RateLimitingFallbackWarningThrottle_NonPositiveInterval_Throws()

RateLimitingOptions_AreBoundFromConfiguration()

Verifies that application rate limiting options are bound from configuration into the options model.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 230)]
public void RateLimitingOptions_AreBoundFromConfiguration()

RateLimitingOptions_CodeDefault_UsesSharedUnknownClientPartition()

Verifies that the rate limiting options default to a shared fallback partition for unresolved clients.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 292)]
public void RateLimitingOptions_CodeDefault_UsesSharedUnknownClientPartition()

RateLimiting_EmptyUnknownClientPartitionKey_FailsStartup()

Verifies that startup validation fails when the unknown client fallback partition key is empty.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 433)]
public void RateLimiting_EmptyUnknownClientPartitionKey_FailsStartup()

RateLimiting_InvalidIPv6PartitionPrefixLength_FailsStartup(string)

Verifies that startup validation rejects an IPv6 partition prefix length outside 1 through 128.

[Theory("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 648)]
[InlineData(new object?[] { "0" })]
[InlineData(new object?[] { "129" })]
public void RateLimiting_InvalidIPv6PartitionPrefixLength_FailsStartup(string prefixLength)

Parameters

prefixLength string

The configured prefix length.

RateLimiting_NegativeQueueLimit_FailsStartup()

Verifies that startup validation fails when a rate-limiting queue limit is negative.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 473)]
public void RateLimiting_NegativeQueueLimit_FailsStartup()

RateLimiting_ZeroPermitLimit_FailsStartup()

Verifies that startup validation fails when a fixed-window permit limit is zero.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 453)]
public void RateLimiting_ZeroPermitLimit_FailsStartup()

RateLimiting_ZeroWindowSeconds_FailsStartup()

Verifies that startup validation fails when a fixed-window duration is zero seconds.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 493)]
public void RateLimiting_ZeroWindowSeconds_FailsStartup()

RejectedRequest_ApiShaped_ReturnsProblemDetails()

Verifies that API-shaped rejected requests return a Problem Details 429 response with the shared identifiers.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 114)]
public Task RejectedRequest_ApiShaped_ReturnsProblemDetails()

Returns

Task

A task that represents the asynchronous test operation.

RejectedRequest_BrowserShaped_ReturnsPlainTextWithoutRenderingErrorPage()

Verifies that browser-shaped rejected requests receive a short plain-text 429 response rather than a rendered error page.

[Fact("/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/tests/ProjectTemplate.Web.Tests/RateLimitingTests.cs", 146)]
public Task RejectedRequest_BrowserShaped_ReturnsPlainTextWithoutRenderingErrorPage()

Returns

Task

A task that represents the asynchronous test operation.