Skip to content

Commit eb5655d

Browse files
refactor(Core.Application.BenchmarkTests): add benchmark tests for authorization behavior
1 parent 3f877ea commit eb5655d

File tree

5 files changed

+194
-0
lines changed

5 files changed

+194
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<Optimize>true</Optimize>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
13+
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<ProjectReference Include="..\..\Core.Application\Core.Application.csproj" />
18+
</ItemGroup>
19+
20+
</Project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using BenchmarkDotNet.Attributes;
2+
using MediatR;
3+
using NArchitecture.Core.Application.Pipelines.Authorization;
4+
using NArchitecture.Core.Security.Constants;
5+
6+
namespace Core.Application.BenchmarkTests.Pipelines.Authorization;
7+
8+
[MemoryDiagnoser(true)]
9+
public class AuthorizationBehaviorBenchmark
10+
{
11+
public class ExampleRequestType : IRequest<ExampleResponseType>, ISecuredRequest
12+
{
13+
public IEnumerable<string> IdentityRoles { get; set; }
14+
private const string _requiredRoleClaims = "Test";
15+
public ReadOnlySpan<char> RequiredRoleClaims => _requiredRoleClaims.AsSpan();
16+
17+
public class ExampleRequestTypeHandler : IRequestHandler<ExampleRequestType, ExampleResponseType>
18+
{
19+
public Task<ExampleResponseType?> Handle(ExampleRequestType request, CancellationToken cancellationToken)
20+
{
21+
return Task.FromResult(default(ExampleResponseType));
22+
}
23+
}
24+
}
25+
26+
public class ExampleResponseType { }
27+
28+
[Benchmark]
29+
public async Task<ExampleResponseType?> BenchmarkAuthorizationBehavior()
30+
{
31+
ExampleRequestType request = new() { IdentityRoles = [GeneralOperationClaims.Admin] };
32+
33+
AuthorizationBehavior<ExampleRequestType, ExampleResponseType> authorizationBehavior =
34+
new AuthorizationBehavior<ExampleRequestType, ExampleResponseType>();
35+
return await authorizationBehavior.Handle(
36+
request,
37+
() => Task.FromResult(default(ExampleResponseType)),
38+
CancellationToken.None
39+
);
40+
}
41+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using BenchmarkDotNet.Running;
2+
using Core.Application.BenchmarkTests.Pipelines.Authorization;
3+
4+
BenchmarkRunner.Run<AuthorizationBehaviorBenchmark>();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<IsTestProject>true</IsTestProject>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="coverlet.collector" Version="6.0.0" />
14+
<PackageReference Include="MediatR" Version="12.2.0" />
15+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
16+
<PackageReference Include="Moq" Version="4.20.70" />
17+
<PackageReference Include="xunit" Version="2.5.3" />
18+
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<ProjectReference Include="..\..\..\Core.Application\Core.Application.csproj" />
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<Using Include="Xunit" />
27+
</ItemGroup>
28+
29+
</Project>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System.Security.Authentication;
2+
using MediatR;
3+
using Moq;
4+
using NArchitecture.Core.Application.Pipelines.Authorization;
5+
using NArchitecture.Core.CrossCuttingConcerns.Exception.Types;
6+
7+
namespace NArchitecture.Core.Application.Tests.Pipelines.Authorization;
8+
9+
public class AuthorizationBehaviorTests
10+
{
11+
[Fact]
12+
public async Task Handle_ValidRequest_ReturnsResponse()
13+
{
14+
// Arrange
15+
var request = new ValidSecuredRequest();
16+
request.IdentityRoles = ["admin", "user"];
17+
var next = Mock.Of<RequestHandlerDelegate<int>>();
18+
19+
// Act
20+
_ = await new AuthorizationBehavior<ValidSecuredRequest, int>().Handle(request, next, CancellationToken.None);
21+
22+
// Assert
23+
Assert.True(true);
24+
}
25+
26+
public class ValidSecuredRequest : IRequest<int>, ISecuredRequest
27+
{
28+
public IEnumerable<string> IdentityRoles { get; set; }
29+
public ReadOnlySpan<char> RequiredRoleClaims => "".AsSpan();
30+
}
31+
32+
[Fact]
33+
public async Task Handle_InvalidRequest_ThrowsAuthorizationException()
34+
{
35+
// Arrange
36+
var request = new InvalidSecuredRequest();
37+
var next = Mock.Of<RequestHandlerDelegate<int>>();
38+
39+
// Act and Assert
40+
await Assert.ThrowsAsync<AuthenticationException>(
41+
() => new AuthorizationBehavior<InvalidSecuredRequest, int>().Handle(request, next, CancellationToken.None)
42+
);
43+
}
44+
45+
public class InvalidSecuredRequest : IRequest<int>, ISecuredRequest
46+
{
47+
public IEnumerable<string> IdentityRoles { get; set; }
48+
public ReadOnlySpan<char> RequiredRoleClaims => "".AsSpan();
49+
}
50+
51+
[Fact]
52+
public async Task Handle_InvalidRequest_WithRequiredRoleClaims_ThrowsAuthorizationException()
53+
{
54+
// Arrange
55+
var request = new SecuredRequestWithRequiredRoleClaims();
56+
request.IdentityRoles = new[] { "user" };
57+
var next = Mock.Of<RequestHandlerDelegate<int>>();
58+
59+
// Act and Assert
60+
await Assert.ThrowsAsync<AuthorizationException>(
61+
() =>
62+
new AuthorizationBehavior<SecuredRequestWithRequiredRoleClaims, int>().Handle(
63+
request,
64+
next,
65+
CancellationToken.None
66+
)
67+
);
68+
}
69+
70+
public class SecuredRequestWithRequiredRoleClaims : IRequest<int>, ISecuredRequest
71+
{
72+
public IEnumerable<string> IdentityRoles { get; set; }
73+
public ReadOnlySpan<char> RequiredRoleClaims => "admin".AsSpan();
74+
}
75+
76+
[Fact]
77+
public async Task Handle_ValidRequest_WithRequiredRoleClaims_ReturnsResponse()
78+
{
79+
// Arrange
80+
var request = new SecuredRequestWithoutRequiredRoleClaims();
81+
request.IdentityRoles = new[] { "user", "admin" };
82+
var next = Mock.Of<RequestHandlerDelegate<int>>();
83+
84+
// Act
85+
_ = await new AuthorizationBehavior<SecuredRequestWithoutRequiredRoleClaims, int>().Handle(
86+
request,
87+
next,
88+
CancellationToken.None
89+
);
90+
91+
// Assert
92+
Assert.True(true);
93+
}
94+
95+
public class SecuredRequestWithoutRequiredRoleClaims : IRequest<int>, ISecuredRequest
96+
{
97+
public IEnumerable<string> IdentityRoles { get; set; }
98+
public ReadOnlySpan<char> RequiredRoleClaims => "admin".AsSpan();
99+
}
100+
}

0 commit comments

Comments
 (0)