1- // Copyright (c) .NET Foundation. All rights reserved.
1+ // Copyright (c) .NET Foundation. All rights reserved.
22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
44using System ;
55using System . Threading . Tasks ;
6+ using Microsoft . AspNetCore . Authorization ;
7+ using Microsoft . AspNetCore . Cors . Infrastructure ;
68using Microsoft . AspNetCore . Http ;
79using Microsoft . AspNetCore . Http . Features ;
810using Microsoft . Extensions . Logging . Abstractions ;
11+ using Microsoft . Extensions . Options ;
12+ using Moq ;
913using Xunit ;
1014
1115namespace Microsoft . AspNetCore . Routing
1216{
1317 public class EndpointMiddlewareTest
1418 {
19+ private readonly IOptions < RouteOptions > RouteOptions = Options . Create ( new RouteOptions ( ) ) ;
20+
1521 [ Fact ]
1622 public async Task Invoke_NoFeature_NoOps ( )
1723 {
@@ -24,7 +30,7 @@ public async Task Invoke_NoFeature_NoOps()
2430 return Task . CompletedTask ;
2531 } ;
2632
27- var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , next ) ;
33+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , next , RouteOptions ) ;
2834
2935 // Act
3036 await middleware . Invoke ( httpContext ) ;
@@ -49,7 +55,7 @@ public async Task Invoke_NoEndpoint_NoOps()
4955 return Task . CompletedTask ;
5056 } ;
5157
52- var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , next ) ;
58+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , next , RouteOptions ) ;
5359
5460 // Act
5561 await middleware . Invoke ( httpContext ) ;
@@ -81,7 +87,7 @@ public async Task Invoke_WithEndpoint_InvokesDelegate()
8187 return Task . CompletedTask ;
8288 } ;
8389
84- var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , next ) ;
90+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , next , RouteOptions ) ;
8591
8692 // Act
8793 await middleware . Invoke ( httpContext ) ;
@@ -90,6 +96,146 @@ public async Task Invoke_WithEndpoint_InvokesDelegate()
9096 Assert . True ( invoked ) ;
9197 }
9298
99+ [ Fact ]
100+ public async Task Invoke_WithEndpoint_ThrowsIfAuthAttributesWereFound_ButAuthMiddlewareNotInvoked ( )
101+ {
102+ // Arrange
103+ var expected = "Endpoint Test contains authorization metadata, but a middleware was not found that supports authorization." +
104+ Environment . NewLine +
105+ "Configure your application startup by adding app.UseAuthorization() inside the call to Configure(..) in the application startup code." ;
106+ var httpContext = new DefaultHttpContext
107+ {
108+ RequestServices = new ServiceProvider ( )
109+ } ;
110+
111+ httpContext . Features . Set < IEndpointFeature > ( new EndpointSelectorContext ( )
112+ {
113+ Endpoint = new Endpoint ( _ => Task . CompletedTask , new EndpointMetadataCollection ( Mock . Of < IAuthorizeData > ( ) ) , "Test" ) ,
114+ } ) ;
115+
116+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , _ => Task . CompletedTask , RouteOptions ) ;
117+
118+ // Act & Assert
119+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( ( ) => middleware . Invoke ( httpContext ) ) ;
120+
121+ // Assert
122+ Assert . Equal ( expected , ex . Message ) ;
123+ }
124+
125+ [ Fact ]
126+ public async Task Invoke_WithEndpoint_WorksIfAuthAttributesWereFound_AndAuthMiddlewareInvoked ( )
127+ {
128+ // Arrange
129+ var httpContext = new DefaultHttpContext
130+ {
131+ RequestServices = new ServiceProvider ( )
132+ } ;
133+
134+ httpContext . Features . Set < IEndpointFeature > ( new EndpointSelectorContext ( )
135+ {
136+ Endpoint = new Endpoint ( _ => Task . CompletedTask , new EndpointMetadataCollection ( Mock . Of < IAuthorizeData > ( ) ) , "Test" ) ,
137+ } ) ;
138+
139+ httpContext . Items [ EndpointMiddleware . AuthorizationMiddlewareInvokedKey ] = true ;
140+
141+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , _ => Task . CompletedTask , RouteOptions ) ;
142+
143+ // Act & Assert
144+ await middleware . Invoke ( httpContext ) ;
145+
146+ // If we got this far, we can sound the everything's OK alarm.
147+ }
148+
149+ [ Fact ]
150+ public async Task Invoke_WithEndpoint_DoesNotThrowIfUnhandledAuthAttributesWereFound_ButSuppressedViaOptions ( )
151+ {
152+ // Arrange
153+ var httpContext = new DefaultHttpContext
154+ {
155+ RequestServices = new ServiceProvider ( )
156+ } ;
157+
158+ httpContext . Features . Set < IEndpointFeature > ( new EndpointSelectorContext ( )
159+ {
160+ Endpoint = new Endpoint ( _ => Task . CompletedTask , new EndpointMetadataCollection ( Mock . Of < IAuthorizeData > ( ) ) , "Test" ) ,
161+ } ) ;
162+ var routeOptions = Options . Create ( new RouteOptions { SuppressCheckForUnhandledSecurityMetadata = true } ) ;
163+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , _ => Task . CompletedTask , routeOptions ) ;
164+
165+ // Act & Assert
166+ await middleware . Invoke ( httpContext ) ;
167+ }
168+
169+ [ Fact ]
170+ public async Task Invoke_WithEndpoint_ThrowsIfCorsMetadataWasFound_ButCorsMiddlewareNotInvoked ( )
171+ {
172+ // Arrange
173+ var expected = "Endpoint Test contains CORS metadata, but a middleware was not found that supports CORS." +
174+ Environment . NewLine +
175+ "Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code." ;
176+ var httpContext = new DefaultHttpContext
177+ {
178+ RequestServices = new ServiceProvider ( )
179+ } ;
180+
181+ httpContext . Features . Set < IEndpointFeature > ( new EndpointSelectorContext ( )
182+ {
183+ Endpoint = new Endpoint ( _ => Task . CompletedTask , new EndpointMetadataCollection ( Mock . Of < ICorsMetadata > ( ) ) , "Test" ) ,
184+ } ) ;
185+
186+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , _ => Task . CompletedTask , RouteOptions ) ;
187+
188+ // Act & Assert
189+ var ex = await Assert . ThrowsAsync < InvalidOperationException > ( ( ) => middleware . Invoke ( httpContext ) ) ;
190+
191+ // Assert
192+ Assert . Equal ( expected , ex . Message ) ;
193+ }
194+
195+ [ Fact ]
196+ public async Task Invoke_WithEndpoint_WorksIfCorsMetadataWasFound_AndCorsMiddlewareInvoked ( )
197+ {
198+ // Arrange
199+ var httpContext = new DefaultHttpContext
200+ {
201+ RequestServices = new ServiceProvider ( )
202+ } ;
203+
204+ httpContext . Features . Set < IEndpointFeature > ( new EndpointSelectorContext ( )
205+ {
206+ Endpoint = new Endpoint ( _ => Task . CompletedTask , new EndpointMetadataCollection ( Mock . Of < ICorsMetadata > ( ) ) , "Test" ) ,
207+ } ) ;
208+
209+ httpContext . Items [ EndpointMiddleware . CorsMiddlewareInvokedKey ] = true ;
210+
211+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , _ => Task . CompletedTask , RouteOptions ) ;
212+
213+ // Act & Assert
214+ await middleware . Invoke ( httpContext ) ;
215+
216+ // If we got this far, we can sound the everything's OK alarm.
217+ }
218+
219+ [ Fact ]
220+ public async Task Invoke_WithEndpoint_DoesNotThrowIfUnhandledCorsAttributesWereFound_ButSuppressedViaOptions ( )
221+ {
222+ // Arrange
223+ var httpContext = new DefaultHttpContext
224+ {
225+ RequestServices = new ServiceProvider ( )
226+ } ;
227+
228+ httpContext . Features . Set < IEndpointFeature > ( new EndpointSelectorContext ( )
229+ {
230+ Endpoint = new Endpoint ( _ => Task . CompletedTask , new EndpointMetadataCollection ( Mock . Of < IAuthorizeData > ( ) ) , "Test" ) ,
231+ } ) ;
232+ var routeOptions = Options . Create ( new RouteOptions { SuppressCheckForUnhandledSecurityMetadata = true } ) ;
233+ var middleware = new EndpointMiddleware ( NullLogger < EndpointMiddleware > . Instance , _ => Task . CompletedTask , routeOptions ) ;
234+
235+ // Act & Assert
236+ await middleware . Invoke ( httpContext ) ;
237+ }
238+
93239 private class ServiceProvider : IServiceProvider
94240 {
95241 public object GetService ( Type serviceType )
0 commit comments