@ -6,21 +6,21 @@ using Shouldly;
using Volo.Abp.Security.Claims ;
using Xunit ;
namespace Volo.Abp.OperationRateLimit ;
namespace Volo.Abp.OperationRateLimiting ;
public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public class OperationRateLimiting Checker_Tests : OperationRateLimiting TestBase
{
private readonly IOperationRateLimitChecker _ checker ;
private readonly IOperationRateLimiting Checker _ checker ;
public OperationRateLimitChecker_Tests ( )
public OperationRateLimiting Checker_Tests ( )
{
_ checker = GetRequiredService < IOperationRateLimitChecker > ( ) ;
_ checker = GetRequiredService < IOperationRateLimiting Checker > ( ) ;
}
[Fact]
public async Task Should_Allow_Within_Limit ( )
{
var context = new OperationRateLimitContext { Parameter = "test@example.com" } ;
var context = new OperationRateLimiting Context { Parameter = "test@example.com" } ;
// Should not throw for 3 requests (max is 3)
await _ checker . CheckAsync ( "TestSimple" , context ) ;
@ -32,13 +32,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Reject_When_Exceeded ( )
{
var param = $"exceed-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
var exception = await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
var exception = await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestSimple" , context ) ;
} ) ;
@ -46,14 +46,14 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
exception . PolicyName . ShouldBe ( "TestSimple" ) ;
exception . Result . IsAllowed . ShouldBeFalse ( ) ;
exception . HttpStatusCode . ShouldBe ( 4 2 9 ) ;
exception . Code . ShouldBe ( AbpOperationRateLimitErrorCodes . ExceedLimit ) ;
exception . Code . ShouldBe ( AbpOperationRateLimiting ErrorCodes . ExceedLimit ) ;
}
[Fact]
public async Task Should_Return_Correct_RemainingCount ( )
{
var param = $"remaining-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
var status = await _ checker . GetStatusAsync ( "TestSimple" , context ) ;
status . IsAllowed . ShouldBeTrue ( ) ;
@ -73,13 +73,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Return_Correct_RetryAfter ( )
{
var param = $"retry-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
var exception = await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
var exception = await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestSimple" , context ) ;
} ) ;
@ -100,8 +100,8 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var context = new OperationRateLimitContext { Parameter = $"composite-{Guid.NewGuid()}" } ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
var context = new OperationRateLimiting Context { Parameter = $"composite-{Guid.NewGuid()}" } ;
// Should pass: both rules within limits
await checker . CheckAsync ( "TestComposite" , context ) ;
@ -123,16 +123,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
var param = $"composite-reject-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
await checker . CheckAsync ( "TestComposite" , context ) ;
await checker . CheckAsync ( "TestComposite" , context ) ;
await checker . CheckAsync ( "TestComposite" , context ) ;
// 4th request: Rule1 (max 3 per hour by parameter) should fail
var exception = await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
var exception = await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await checker . CheckAsync ( "TestComposite" , context ) ;
} ) ;
@ -146,14 +146,14 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Reset_Counter ( )
{
var param = $"reset-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
// Should be at limit
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestSimple" , context ) ;
} ) ;
@ -169,12 +169,12 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Use_Custom_ErrorCode ( )
{
var param = $"custom-error-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
await _ checker . CheckAsync ( "TestCustomErrorCode" , context ) ;
await _ checker . CheckAsync ( "TestCustomErrorCode" , context ) ;
var exception = await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
var exception = await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestCustomErrorCode" , context ) ;
} ) ;
@ -194,7 +194,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
[Fact]
public async Task Should_Skip_When_Disabled ( )
{
var options = GetRequiredService < Microsoft . Extensions . Options . IOptions < AbpOperationRateLimitOptions > > ( ) ;
var options = GetRequiredService < Microsoft . Extensions . Options . IOptions < AbpOperationRateLimiting Options > > ( ) ;
var originalValue = options . Value . IsEnabled ;
try
@ -202,7 +202,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
options . Value . IsEnabled = false ;
var param = $"disabled-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
// Should pass unlimited times
for ( var i = 0 ; i < 1 0 0 ; i + + )
@ -220,7 +220,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Work_With_IsAllowedAsync ( )
{
var param = $"is-allowed-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
// IsAllowedAsync does not consume quota
( await _ checker . IsAllowedAsync ( "TestSimple" , context ) ) . ShouldBeTrue ( ) ;
@ -245,8 +245,8 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
var param1 = $"param1-{Guid.NewGuid()}" ;
var param2 = $"param2-{Guid.NewGuid()}" ;
var context1 = new OperationRateLimitContext { Parameter = param1 } ;
var context2 = new OperationRateLimitContext { Parameter = param2 } ;
var context1 = new OperationRateLimiting Context { Parameter = param1 } ;
var context2 = new OperationRateLimiting Context { Parameter = param2 } ;
// Consume all for param1
await _ checker . CheckAsync ( "TestSimple" , context1 ) ;
@ -262,7 +262,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Support_ExtraProperties_In_Exception_Data ( )
{
var param = $"extra-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext
var context = new OperationRateLimiting Context
{
Parameter = param ,
ExtraProperties =
@ -276,7 +276,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
await _ checker . CheckAsync ( "TestSimple" , context ) ;
await _ checker . CheckAsync ( "TestSimple" , context ) ;
var exception = await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
var exception = await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestSimple" , context ) ;
} ) ;
@ -291,13 +291,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Partition_By_Email_Via_Parameter ( )
{
var email = $"email-param-{Guid.NewGuid()}@example.com" ;
var context = new OperationRateLimitContext { Parameter = email } ;
var context = new OperationRateLimiting Context { Parameter = email } ;
await _ checker . CheckAsync ( "TestEmailBased" , context ) ;
await _ checker . CheckAsync ( "TestEmailBased" , context ) ;
await _ checker . CheckAsync ( "TestEmailBased" , context ) ;
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestEmailBased" , context ) ;
} ) ;
@ -315,16 +315,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
// No Parameter set, should fall back to ICurrentUser.Email
var context = new OperationRateLimitContext ( ) ;
var context = new OperationRateLimiting Context ( ) ;
await checker . CheckAsync ( "TestEmailBased" , context ) ;
await checker . CheckAsync ( "TestEmailBased" , context ) ;
await checker . CheckAsync ( "TestEmailBased" , context ) ;
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await checker . CheckAsync ( "TestEmailBased" , context ) ;
} ) ;
@ -336,13 +336,13 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Partition_By_PhoneNumber_Via_Parameter ( )
{
var phone = $"phone-param-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = phone } ;
var context = new OperationRateLimiting Context { Parameter = phone } ;
await _ checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
await _ checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
await _ checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
} ) ;
@ -360,16 +360,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
// No Parameter set, should fall back to ICurrentUser.PhoneNumber
var context = new OperationRateLimitContext ( ) ;
var context = new OperationRateLimiting Context ( ) ;
await checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
await checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
await checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await checker . CheckAsync ( "TestPhoneNumberBased" , context ) ;
} ) ;
@ -381,7 +381,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Throw_When_Email_Not_Available ( )
{
// No Parameter and no authenticated user
var context = new OperationRateLimitContext ( ) ;
var context = new OperationRateLimiting Context ( ) ;
await Assert . ThrowsAsync < AbpException > ( async ( ) = >
{
@ -403,16 +403,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
var param = $"no-waste-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
// 2 successful requests (Rule1: 2/5, Rule2: 2/2)
await checker . CheckAsync ( "TestCompositeRule2First" , context ) ;
await checker . CheckAsync ( "TestCompositeRule2First" , context ) ;
// 3rd request: Rule2 blocks (2/2 at max)
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await checker . CheckAsync ( "TestCompositeRule2First" , context ) ;
} ) ;
@ -442,7 +442,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
// TestCompositeParamIp: Rule1 (Parameter, 5/hour), Rule2 (ClientIp, 3/hour)
// IP limit (3) is lower, should trigger first
var param = $"param-ip-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
// 3 successful requests
await _ checker . CheckAsync ( "TestCompositeParamIp" , context ) ;
@ -450,7 +450,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
await _ checker . CheckAsync ( "TestCompositeParamIp" , context ) ;
// 4th: IP rule blocks (3/3)
var exception = await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
var exception = await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestCompositeParamIp" , context ) ;
} ) ;
@ -475,8 +475,8 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
// but share the same Rule2 (IP) counter
var param1 = $"share-ip-1-{Guid.NewGuid()}" ;
var param2 = $"share-ip-2-{Guid.NewGuid()}" ;
var context1 = new OperationRateLimitContext { Parameter = param1 } ;
var context2 = new OperationRateLimitContext { Parameter = param2 } ;
var context1 = new OperationRateLimiting Context { Parameter = param1 } ;
var context2 = new OperationRateLimiting Context { Parameter = param2 } ;
// 2 requests with param1
await _ checker . CheckAsync ( "TestCompositeParamIp" , context1 ) ;
@ -486,7 +486,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
await _ checker . CheckAsync ( "TestCompositeParamIp" , context2 ) ;
// 4th request with param2: IP rule blocks (3/3 from combined)
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestCompositeParamIp" , context2 ) ;
} ) ;
@ -516,9 +516,9 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
var param = $"triple-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
// 3 successful requests
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
@ -526,7 +526,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
// 4th: IP rule blocks (3/3)
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
} ) ;
@ -559,9 +559,9 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
var param = $"triple-nowaste-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
// 3 successful requests (all rules increment to 3)
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
@ -571,7 +571,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
// Attempt 3 more blocked requests
for ( var i = 0 ; i < 3 ; i + + )
{
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
} ) ;
@ -599,16 +599,16 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
using ( principalAccessor . Change ( claimsPrincipal ) )
{
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimitChecker > ( ) ;
var checker = scope . ServiceProvider . GetRequiredService < IOperationRateLimiting Checker > ( ) ;
var param = $"triple-reset-{Guid.NewGuid()}" ;
var context = new OperationRateLimitContext { Parameter = param } ;
var context = new OperationRateLimiting Context { Parameter = param } ;
// Exhaust IP limit
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await checker . CheckAsync ( "TestCompositeTriple" , context ) ;
} ) ;
@ -633,7 +633,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
public async Task Should_Throw_When_PhoneNumber_Not_Available ( )
{
// No Parameter and no authenticated user
var context = new OperationRateLimitContext ( ) ;
var context = new OperationRateLimiting Context ( ) ;
await Assert . ThrowsAsync < AbpException > ( async ( ) = >
{
@ -644,9 +644,9 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
[Fact]
public async Task Should_Deny_First_Request_When_MaxCount_Is_Zero ( )
{
var context = new OperationRateLimitContext { Parameter = $"ban-{Guid.NewGuid()}" } ;
var context = new OperationRateLimiting Context { Parameter = $"ban-{Guid.NewGuid()}" } ;
var exception = await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
var exception = await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestBanPolicy" , context ) ;
} ) ;
@ -659,7 +659,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
[Fact]
public async Task Should_IsAllowed_Return_False_When_MaxCount_Is_Zero ( )
{
var context = new OperationRateLimitContext { Parameter = $"ban-allowed-{Guid.NewGuid()}" } ;
var context = new OperationRateLimiting Context { Parameter = $"ban-allowed-{Guid.NewGuid()}" } ;
var allowed = await _ checker . IsAllowedAsync ( "TestBanPolicy" , context ) ;
allowed . ShouldBeFalse ( ) ;
@ -668,7 +668,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
[Fact]
public async Task Should_GetStatus_Show_Not_Allowed_When_MaxCount_Is_Zero ( )
{
var context = new OperationRateLimitContext { Parameter = $"ban-status-{Guid.NewGuid()}" } ;
var context = new OperationRateLimiting Context { Parameter = $"ban-status-{Guid.NewGuid()}" } ;
var status = await _ checker . GetStatusAsync ( "TestBanPolicy" , context ) ;
status . IsAllowed . ShouldBeFalse ( ) ;
@ -684,14 +684,14 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
var param1 = $"op1-{Guid.NewGuid()}" ;
var param2 = $"op2-{Guid.NewGuid()}" ;
var ctx1 = new OperationRateLimitContext { Parameter = param1 } ;
var ctx2 = new OperationRateLimitContext { Parameter = param2 } ;
var ctx1 = new OperationRateLimiting Context { Parameter = param1 } ;
var ctx2 = new OperationRateLimiting Context { Parameter = param2 } ;
// Exhaust param1's quota (max=2)
await _ checker . CheckAsync ( "TestCustomResolver" , ctx1 ) ;
await _ checker . CheckAsync ( "TestCustomResolver" , ctx1 ) ;
await Assert . ThrowsAsync < AbpOperationRateLimitException > ( async ( ) = >
await Assert . ThrowsAsync < AbpOperationRateLimiting Exception > ( async ( ) = >
{
await _ checker . CheckAsync ( "TestCustomResolver" , ctx1 ) ;
} ) ;
@ -704,7 +704,7 @@ public class OperationRateLimitChecker_Tests : OperationRateLimitTestBase
[Fact]
public void Should_Throw_When_Policy_Has_Duplicate_Rules ( )
{
var options = new AbpOperationRateLimitOptions ( ) ;
var options = new AbpOperationRateLimiting Options ( ) ;
Assert . Throws < AbpException > ( ( ) = >
{