Skip to content

Commit 19864d4

Browse files
committed
Added test scenarios for cookies and sessions
1 parent 38dcbce commit 19864d4

File tree

8 files changed

+346
-234
lines changed

8 files changed

+346
-234
lines changed

ManagedCode.Orleans.Identity.Tests/AuthenticationIntegrationTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Shouldly;
1212
using Xunit;
1313
using Xunit.Abstractions;
14+
using LoginRequest = ManagedCode.Orleans.Identity.Tests.Cookies.LoginRequest;
1415

1516
namespace ManagedCode.Orleans.Identity.Tests;
1617

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
using System.Net;
2+
using System.Net.Http.Json;
3+
using ManagedCode.Orleans.Identity.Tests.Cluster;
4+
using ManagedCode.Orleans.Identity.Tests.Constants;
5+
using Shouldly;
6+
using Xunit;
7+
using Xunit.Abstractions;
8+
9+
namespace ManagedCode.Orleans.Identity.Tests.Cookies;
10+
11+
[Collection(nameof(TestClusterApplication))]
12+
public class CookieAuthTests(TestClusterApplication testApp, ITestOutputHelper outputHelper)
13+
: IClassFixture<TestClusterApplication>
14+
{
15+
private readonly ITestOutputHelper _outputHelper = outputHelper;
16+
17+
#region Cookie Authentication - Basic Tests
18+
19+
[Fact]
20+
public async Task CookieAuth_WhenUserAuthenticated_ShouldAccessProtectedEndpoint()
21+
{
22+
// Arrange
23+
var client = testApp.CreateClient();
24+
await LoginWithCookie(client, "testuser");
25+
26+
// Act
27+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_DEFAULT_ROUTE);
28+
var content = await response.Content.ReadAsStringAsync();
29+
30+
// Assert
31+
response.IsSuccessStatusCode.ShouldBeTrue();
32+
content.ShouldContain("Hello, testuser!");
33+
}
34+
35+
[Fact]
36+
public async Task CookieAuth_WhenUserNotAuthenticated_ShouldReturnUnauthorized()
37+
{
38+
// Arrange
39+
var client = testApp.CreateClient();
40+
41+
// Act
42+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_DEFAULT_ROUTE);
43+
44+
// Assert
45+
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
46+
}
47+
48+
#endregion
49+
50+
#region Cookie Authentication - Role-based Tests
51+
52+
[Fact]
53+
public async Task CookieAuth_WhenUserIsAdmin_ShouldAccessAdminEndpoint()
54+
{
55+
// Arrange
56+
var client = testApp.CreateClient();
57+
await LoginWithCookie(client, "admin");
58+
59+
// Act
60+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_BAN);
61+
var content = await response.Content.ReadAsStringAsync();
62+
63+
// Assert
64+
response.IsSuccessStatusCode.ShouldBeTrue();
65+
content.ShouldContain("User admin is banned");
66+
}
67+
68+
[Fact]
69+
public async Task CookieAuth_WhenUserIsNotAdmin_ShouldReturnForbidden()
70+
{
71+
// Arrange
72+
var client = testApp.CreateClient();
73+
await LoginWithCookie(client, "user");
74+
75+
// Act
76+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_BAN);
77+
78+
// Assert
79+
response.StatusCode.ShouldBe(HttpStatusCode.Forbidden);
80+
}
81+
82+
[Fact]
83+
public async Task CookieAuth_WhenUserIsModerator_ShouldAccessModeratorEndpoint()
84+
{
85+
// Arrange
86+
var client = testApp.CreateClient();
87+
await LoginWithCookie(client, "moderator");
88+
89+
// Act
90+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_MODIFY);
91+
var content = await response.Content.ReadAsStringAsync();
92+
93+
// Assert
94+
response.IsSuccessStatusCode.ShouldBeTrue();
95+
content.ShouldContain("User moderator has been modified");
96+
}
97+
98+
[Fact]
99+
public async Task CookieAuth_WhenUserIsNotModerator_ShouldReturnForbidden()
100+
{
101+
// Arrange
102+
var client = testApp.CreateClient();
103+
await LoginWithCookie(client, "user");
104+
105+
// Act
106+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_MODIFY);
107+
108+
// Assert
109+
response.StatusCode.ShouldBe(HttpStatusCode.Forbidden);
110+
}
111+
112+
#endregion
113+
114+
#region Cookie Authentication - Public Endpoint Tests
115+
116+
[Fact]
117+
public async Task CookieAuth_WhenUserNotAuthenticated_ShouldAccessPublicEndpoint()
118+
{
119+
// Arrange
120+
var client = testApp.CreateClient();
121+
122+
// Act
123+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_PUBLIC_INFO);
124+
var content = await response.Content.ReadAsStringAsync();
125+
126+
// Assert
127+
response.IsSuccessStatusCode.ShouldBeTrue();
128+
content.ShouldContain("This is public information");
129+
}
130+
131+
#endregion
132+
133+
#region Cookie Authentication - Logout Tests
134+
135+
[Fact]
136+
public async Task CookieAuth_WhenUserLogsOut_ShouldNotAccessProtectedEndpoint()
137+
{
138+
// Arrange
139+
var client = testApp.CreateClient();
140+
await LoginWithCookie(client, "testuser");
141+
142+
// Verify user is authenticated
143+
var authResponse = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_DEFAULT_ROUTE);
144+
authResponse.IsSuccessStatusCode.ShouldBeTrue();
145+
146+
// Act - Logout
147+
var logoutResponse = await client.PostAsync("/auth/logout", null);
148+
logoutResponse.IsSuccessStatusCode.ShouldBeTrue();
149+
150+
// Act - Try to access protected endpoint
151+
var response = await client.GetAsync(TestControllerRoutes.USER_CONTROLLER_DEFAULT_ROUTE);
152+
153+
// Assert
154+
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
155+
}
156+
157+
#endregion
158+
159+
#region Helper Methods
160+
161+
private async Task LoginWithCookie(HttpClient client, string username)
162+
{
163+
var loginRequest = new LoginRequest { Username = username };
164+
var response = await client.PostAsJsonAsync("/auth/login-cookie", loginRequest);
165+
166+
response.IsSuccessStatusCode.ShouldBeTrue();
167+
}
168+
169+
#endregion
170+
}
171+
172+
public class LoginRequest
173+
{
174+
public string Username { get; set; } = string.Empty;
175+
}

ManagedCode.Orleans.Identity.Tests/JwtGrainFilterTests.cs renamed to ManagedCode.Orleans.Identity.Tests/Jwt/JwtGrainFilterTests.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
using System.Net;
22
using System.Net.Http.Headers;
33
using System.Net.Http.Json;
4-
using System.Text;
5-
using System.Text.Json;
6-
using Shouldly;
74
using ManagedCode.Orleans.Identity.Tests.Cluster;
85
using ManagedCode.Orleans.Identity.Tests.Constants;
96
using ManagedCode.Orleans.Identity.Tests.TestApp.Controllers;
107
using ManagedCode.Orleans.Identity.Tests.TestApp.Services;
11-
using Microsoft.Extensions.DependencyInjection;
8+
using Shouldly;
129
using Xunit;
1310
using Xunit.Abstractions;
11+
using LoginRequest = ManagedCode.Orleans.Identity.Tests.Cookies.LoginRequest;
1412

15-
namespace ManagedCode.Orleans.Identity.Tests;
13+
namespace ManagedCode.Orleans.Identity.Tests.Jwt;
1614

1715
[Collection(nameof(TestClusterApplication))]
1816
public class JwtGrainFilterTests

ManagedCode.Orleans.Identity.Tests/JwtSignalRTests.cs renamed to ManagedCode.Orleans.Identity.Tests/Jwt/JwtSignalRTests.cs

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
using System.Net;
21
using System.Net.Http.Json;
3-
using Shouldly;
2+
using ManagedCode.Orleans.Identity.Tests.Cluster;
3+
using ManagedCode.Orleans.Identity.Tests.TestApp.Models;
44
using Microsoft.AspNetCore.SignalR;
55
using Microsoft.AspNetCore.SignalR.Client;
6-
using ManagedCode.Orleans.Identity.Tests.Cluster;
6+
using Shouldly;
77
using Xunit;
88
using Xunit.Abstractions;
99

10-
namespace ManagedCode.Orleans.Identity.Tests;
10+
namespace ManagedCode.Orleans.Identity.Tests.Jwt;
1111

1212
[Collection(nameof(TestClusterApplication))]
1313
public class JwtSignalRTests
@@ -26,19 +26,22 @@ private async Task<string> GetJwtToken(string username)
2626
var client = _testApp.CreateClient();
2727
var loginRequest = new { Username = username };
2828
var response = await client.PostAsJsonAsync("/auth/login", loginRequest);
29-
29+
3030
response.IsSuccessStatusCode.ShouldBeTrue();
3131
var result = await response.Content.ReadFromJsonAsync<LoginResponse>();
3232
return result!.Token;
3333
}
3434

35-
private async Task<HubConnection> CreateSignalRConnection(string token)
35+
private async Task<HubConnection> CreateSignalRConnection(string? token = null)
3636
{
3737
var connection = _testApp.CreateSignalRClient("TestAuthorizeHub", builder =>
3838
{
3939
builder.WithUrl($"{_testApp.Server.BaseAddress}TestAuthorizeHub", options =>
4040
{
41-
options.AccessTokenProvider = () => Task.FromResult<string?>(token);
41+
if (!string.IsNullOrEmpty(token))
42+
{
43+
options.AccessTokenProvider = () => Task.FromResult<string?>(token);
44+
}
4245
});
4346
});
4447

@@ -89,6 +92,27 @@ public async Task SignalR_GetPublicInfo_WhenAuthenticated_ShouldReturnPublicInfo
8992
await connection.DisposeAsync();
9093
}
9194
}
95+
96+
[Fact]
97+
public async Task SignalR_GetPublicInfo_WhenNotAuthenticated_ShouldReturnPublicInfo()
98+
{
99+
// Arrange
100+
var connection = await CreateSignalRConnection();
101+
102+
try
103+
{
104+
// Act
105+
var result = await connection.InvokeAsync<string>("GetPublicInfo");
106+
107+
// Assert
108+
result.ShouldNotBeNullOrEmpty();
109+
result.ShouldContain("public information");
110+
}
111+
finally
112+
{
113+
await connection.DisposeAsync();
114+
}
115+
}
92116

93117
[Fact]
94118
public async Task SignalR_GetAdminInfo_WhenAdmin_ShouldReturnSuccess()
@@ -123,9 +147,9 @@ public async Task SignalR_GetAdminInfo_WhenNotAdmin_ShouldThrowException()
123147
try
124148
{
125149
// Act & Assert
126-
var exception = await Assert.ThrowsAsync<HubException>(() =>
150+
var exception = await Assert.ThrowsAsync<HubException>(() =>
127151
connection.InvokeAsync<string>("GetAdminInfo"));
128-
152+
129153
exception.Message.ShouldContain("Failed to invoke 'GetAdminInfo' because user is unauthorized");
130154
}
131155
finally
@@ -143,9 +167,9 @@ public async Task SignalR_ConnectWithoutToken_ShouldFail()
143167
.Build();
144168

145169
// Act & Assert
146-
var exception = await Assert.ThrowsAsync<HttpRequestException>(() =>
170+
var exception = await Assert.ThrowsAsync<HttpRequestException>(() =>
147171
connection.StartAsync());
148-
172+
149173
await connection.DisposeAsync();
150174
}
151-
}
175+
}

0 commit comments

Comments
 (0)