Skip to content

Commit 8db24c0

Browse files
committed
Adding disconnect and reconnect tests (#39)
1 parent 6f522b5 commit 8db24c0

File tree

9 files changed

+402
-112
lines changed

9 files changed

+402
-112
lines changed

Lib.AspNetCore.ServerSentEvents/IServerSentEventsClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public interface IServerSentEventsClient
3333
/// </summary>
3434
/// <remarks>
3535
/// This requires registering implementations of <see cref="IServerSentEventsClientIdProvider"/> and <see cref="IServerSentEventsNoReconnectClientsIdsStore"/>.
36+
/// </remarks>
3637
void Disconnect();
3738

3839
/// <summary>

Lib.AspNetCore.ServerSentEvents/ServerSentEventsClient.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,13 @@ public void Disconnect()
9595
throw new InvalidOperationException($"Disconnecting a {nameof(ServerSentEventsClient)} requires registering implementations of {nameof(IServerSentEventsClientIdProvider)} and {nameof(IServerSentEventsNoReconnectClientsIdsStore)}.");
9696
}
9797

98-
IsConnected = false;
9998
PreventReconnect = true;
10099

101-
_response.HttpContext.Abort();
100+
if (IsConnected)
101+
{
102+
IsConnected = false;
103+
_response.HttpContext.Abort();
104+
}
102105
}
103106

104107
/// <summary>

Lib.AspNetCore.ServerSentEvents/ServerSentEventsMiddleware.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public class ServerSentEventsMiddleware<TServerSentEventsService> where TServerS
3939
/// <param name="next">The next delegate in the pipeline.</param>
4040
/// <param name="policyProvider">The service which can provide an <see cref="AuthorizationPolicy" />.</param>
4141
/// <param name="serverSentEventsClientIdProvider">The provider of identifiers for <see cref="IServerSentEventsClient"/> instances.</param>
42+
/// <param name="serverSentEventsNoReconnectClientsIdsStore">The store which keeps identifiers of <see cref="IServerSentEventsClient"/> which shouldn't be allowed to reconnect.</param>
4243
/// <param name="serverSentEventsService">The service which provides operations over Server-Sent Events protocol.</param>
4344
/// <param name="serverSentEventsOptions"></param>
4445
/// <param name="loggerFactory">The logger factory.</param>

Test.AspNetCore.ServerSentEvents/Middleware/AuthorizationTests.cs

Lines changed: 47 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
using System.Threading;
2-
using System.Threading.Tasks;
1+
using System.Threading.Tasks;
32
using Microsoft.AspNetCore.Http;
43
using Microsoft.AspNetCore.Authentication;
54
using Microsoft.AspNetCore.Authorization;
65
using Microsoft.AspNetCore.Authorization.Policy;
7-
using Microsoft.Extensions.Options;
8-
using Microsoft.Extensions.DependencyInjection;
9-
using Microsoft.Extensions.Logging.Abstractions;
106
using Moq;
117
using Xunit;
128
using Lib.AspNetCore.ServerSentEvents;
@@ -35,37 +31,6 @@ private IAuthorizationPolicyProvider PrepareAuthorizationPolicyProvider()
3531
return policyProviderMock.Object;
3632
}
3733

38-
private ServerSentEventsMiddleware<ServerSentEventsService> PrepareServerSentEventsMiddleware(ServerSentEventsAuthorization authorization = null)
39-
{
40-
return new ServerSentEventsMiddleware<ServerSentEventsService>
41-
(
42-
NOOP_REQUEST_DELEGATE,
43-
PrepareAuthorizationPolicyProvider(),
44-
new NewGuidServerSentEventsClientIdProvider(),
45-
new NoOpServerSentEventsNoReconnectClientsIdsStore(),
46-
Mock.Of<TestServerSentEventsService>(),
47-
Options.Create(new ServerSentEventsOptions { Authorization = authorization }),
48-
NullLoggerFactory.Instance
49-
);
50-
}
51-
52-
private HttpContext PrepareHttpContext(Mock<IAuthenticationService> authenticationServiceMock = null)
53-
{
54-
HttpContext context = new DefaultHttpContext();
55-
56-
context.Request.Headers.Append(ACCEPT_HTTP_HEADER, SSE_CONTENT_TYPE);
57-
context.RequestAborted = new CancellationToken(true);
58-
59-
authenticationServiceMock = authenticationServiceMock ?? new Mock<IAuthenticationService>();
60-
61-
ServiceCollection serviceCollection = new ServiceCollection();
62-
serviceCollection.AddSingleton(authenticationServiceMock.Object);
63-
64-
context.RequestServices = serviceCollection.BuildServiceProvider();
65-
66-
return context;
67-
}
68-
6934
private Mock<IPolicyEvaluator> PreparePolicyEvaluatorMock(HttpContext context, AuthenticateResult authenticateResult = null, PolicyAuthorizationResult policyAuthorizationResult = null)
7035
{
7136
authenticateResult = authenticateResult ?? DEFAULT_AUTHENTICATE_RESULT;
@@ -83,8 +48,8 @@ private Mock<IPolicyEvaluator> PreparePolicyEvaluatorMock(HttpContext context, A
8348
[Fact]
8449
public async Task Invoke_SseRequest_NoAuthorization_DoesNotCallAuthenticateAsync()
8550
{
86-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware();
87-
HttpContext context = PrepareHttpContext();
51+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(authorizationPolicyProvider: PrepareAuthorizationPolicyProvider());
52+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext();
8853
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context);
8954

9055
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -95,8 +60,8 @@ public async Task Invoke_SseRequest_NoAuthorization_DoesNotCallAuthenticateAsync
9560
[Fact]
9661
public async Task Invoke_SseRequest_NoAuthorization_DoesNotCallAuthorizeAsync()
9762
{
98-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware();
99-
HttpContext context = PrepareHttpContext();
63+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(authorizationPolicyProvider: PrepareAuthorizationPolicyProvider());
64+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext();
10065
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context);
10166

10267
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -107,8 +72,11 @@ public async Task Invoke_SseRequest_NoAuthorization_DoesNotCallAuthorizeAsync()
10772
[Fact]
10873
public async Task Invoke_SseRequest_Authorization_CallsAuthenticateAsync()
10974
{
110-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(ServerSentEventsAuthorization.Default);
111-
HttpContext context = PrepareHttpContext();
75+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
76+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
77+
options: new ServerSentEventsOptions { Authorization = ServerSentEventsAuthorization.Default });
78+
79+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext();
11280
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context);
11381

11482
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -119,8 +87,11 @@ public async Task Invoke_SseRequest_Authorization_CallsAuthenticateAsync()
11987
[Fact]
12088
public async Task Invoke_SseRequest_Authorization_CallsAuthorizeAsync()
12189
{
122-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(ServerSentEventsAuthorization.Default);
123-
HttpContext context = PrepareHttpContext();
90+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
91+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
92+
options: new ServerSentEventsOptions { Authorization = ServerSentEventsAuthorization.Default });
93+
94+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext();
12495
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context);
12596

12697
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -131,10 +102,13 @@ public async Task Invoke_SseRequest_Authorization_CallsAuthorizeAsync()
131102
[Fact]
132103
public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultSuccess_DoesNotCallChallengeAsync()
133104
{
134-
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
105+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
106+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
107+
options: new ServerSentEventsOptions { Authorization = ServerSentEventsAuthorization.Default });
135108

136-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(ServerSentEventsAuthorization.Default);
137-
HttpContext context = PrepareHttpContext(authenticationServiceMock);
109+
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
110+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext(authenticationService: authenticationServiceMock.Object);
111+
138112
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context, policyAuthorizationResult: PolicyAuthorizationResult.Success());
139113

140114
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -145,10 +119,13 @@ public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultSucce
145119
[Fact]
146120
public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultSuccess_DoesNotCallForbidAsync()
147121
{
122+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
123+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
124+
options: new ServerSentEventsOptions { Authorization = ServerSentEventsAuthorization.Default });
125+
148126
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
127+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext(authenticationService: authenticationServiceMock.Object);
149128

150-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(ServerSentEventsAuthorization.Default);
151-
HttpContext context = PrepareHttpContext(authenticationServiceMock);
152129
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context, policyAuthorizationResult: PolicyAuthorizationResult.Success());
153130

154131
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -159,10 +136,13 @@ public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultSucce
159136
[Fact]
160137
public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultChallenge_CallsChallengeAsync()
161138
{
139+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
140+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
141+
options: new ServerSentEventsOptions { Authorization = ServerSentEventsAuthorization.Default });
142+
162143
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
144+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext(authenticationService: authenticationServiceMock.Object);
163145

164-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(ServerSentEventsAuthorization.Default);
165-
HttpContext context = PrepareHttpContext(authenticationServiceMock);
166146
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context, policyAuthorizationResult: PolicyAuthorizationResult.Challenge());
167147

168148
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -173,10 +153,13 @@ public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultChall
173153
[Fact]
174154
public async Task Invoke_SseRequest_AuthorizationWithSchemes_PolicyAuthorizationResultChallenge_CallsChallengeAsyncForEveryScheme()
175155
{
156+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
157+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
158+
options: new ServerSentEventsOptions { Authorization = new ServerSentEventsAuthorization { AuthenticationSchemes = "schema1,schema2" } });
159+
176160
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
161+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext(authenticationService: authenticationServiceMock.Object);
177162

178-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(new ServerSentEventsAuthorization { AuthenticationSchemes = "schema1,schema2" });
179-
HttpContext context = PrepareHttpContext(authenticationServiceMock);
180163
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context, policyAuthorizationResult: PolicyAuthorizationResult.Challenge());
181164

182165
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -188,10 +171,13 @@ public async Task Invoke_SseRequest_AuthorizationWithSchemes_PolicyAuthorization
188171
[Fact]
189172
public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultForbid_CallsForbidAsync()
190173
{
174+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
175+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
176+
options: new ServerSentEventsOptions { Authorization = ServerSentEventsAuthorization.Default });
177+
191178
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
179+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext(authenticationService: authenticationServiceMock.Object);
192180

193-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(ServerSentEventsAuthorization.Default);
194-
HttpContext context = PrepareHttpContext(authenticationServiceMock);
195181
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context, policyAuthorizationResult: PolicyAuthorizationResult.Forbid());
196182

197183
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);
@@ -202,10 +188,13 @@ public async Task Invoke_SseRequest_Authorization_PolicyAuthorizationResultForbi
202188
[Fact]
203189
public async Task Invoke_SseRequest_AuthorizationWithSchemes_PolicyAuthorizationResultForbid_CallsForbidAsyncForEveryScheme()
204190
{
205-
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
191+
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = SubjectUnderTestHelper.PrepareServerSentEventsMiddleware(
192+
authorizationPolicyProvider: PrepareAuthorizationPolicyProvider(),
193+
options: new ServerSentEventsOptions { Authorization = new ServerSentEventsAuthorization { AuthenticationSchemes = "schema1,schema2" } });
206194

207-
ServerSentEventsMiddleware<ServerSentEventsService> serverSentEventsMiddleware = PrepareServerSentEventsMiddleware(new ServerSentEventsAuthorization { AuthenticationSchemes = "schema1,schema2" });
208-
HttpContext context = PrepareHttpContext(authenticationServiceMock);
195+
Mock<IAuthenticationService> authenticationServiceMock = new Mock<IAuthenticationService>();
196+
HttpContext context = SubjectUnderTestHelper.PrepareHttpContext(authenticationService: authenticationServiceMock.Object);
197+
209198
Mock<IPolicyEvaluator> policyEvaluatorMock = PreparePolicyEvaluatorMock(context, policyAuthorizationResult: PolicyAuthorizationResult.Forbid());
210199

211200
await serverSentEventsMiddleware.Invoke(context, policyEvaluatorMock.Object);

0 commit comments

Comments
 (0)