@@ -15,15 +15,18 @@ namespace NuGetGallery.FunctionalTests.ErrorHandling
1515{
1616 public class ErrorHandlingTests : GalleryTestBase , IDisposable
1717 {
18+ private readonly CookieContainer _cookieContainer ;
1819 private readonly HttpClientHandler _httpClientHandler ;
1920 private readonly HttpClient _httpClient ;
2021
2122 public ErrorHandlingTests ( ITestOutputHelper testOutputHelper ) : base ( testOutputHelper )
2223 {
24+ _cookieContainer = new CookieContainer ( ) ;
2325 _httpClientHandler = new HttpClientHandler
2426 {
2527 AllowAutoRedirect = false ,
26- UseCookies = false ,
28+ UseCookies = true ,
29+ CookieContainer = _cookieContainer ,
2730 } ;
2831 _httpClient = new HttpClient ( _httpClientHandler ) ;
2932 }
@@ -34,11 +37,11 @@ public ErrorHandlingTests(ITestOutputHelper testOutputHelper) : base(testOutputH
3437 [ Theory ]
3538 [ Priority ( 2 ) ]
3639 [ Category ( "P2Tests" ) ]
37- [ InlineData ( "__Controller::TempData" , "Message=You successfully uploaded z̡̜͍̈̍̐̃̊͋́a̜̣͍̬̞̝͉̽ͧ͗l̸̖͕̤̠̹̘͖̃̌ͤg͓̝͓̰̀ͪo͈͌ 1.0.0." ) ]
38- public async Task RejectedCookie ( string name , string value )
40+ [ MemberData ( nameof ( RejectedCookies ) ) ]
41+ public async Task RejectedCookie ( string relativePath , string name , string value , Action < TestResponse > validate )
3942 {
4043 // Arrange
41- var relativePath = $ "/packages/ { Constants . TestPackageId } " ;
44+ _httpClientHandler . UseCookies = false ;
4245 var requestUri = GetRequestUri ( relativePath ) ;
4346 using ( var request = new HttpRequestMessage ( HttpMethod . Get , requestUri ) )
4447 {
@@ -48,10 +51,23 @@ public async Task RejectedCookie(string name, string value)
4851 var response = await GetTestResponseAsync ( relativePath , request ) ;
4952
5053 // Assert
51- Validator . SimpleHtml ( HttpStatusCode . BadRequest ) ( response ) ;
54+ validate ( response ) ;
5255 }
5356 }
5457
58+ public static IEnumerable < object [ ] > RejectedCookies => new [ ]
59+ {
60+ new object [ ] { $ "/packages/{ Constants . TestPackageId } ", "__Controller::TempData" , "Message=You successfully uploaded z̡̜͍̈̍̐̃̊͋́a̜̣͍̬̞̝͉̽ͧ͗l̸̖͕̤̠̹̘͖̃̌ͤg͓̝͓̰̀ͪo͈͌ 1.0.0." , Validator . SimpleHtml ( HttpStatusCode . BadRequest ) } ,
61+
62+ new object [ ] { $ "/packages/{ Constants . TestPackageId } ", "__Controller::TempData" , "Message=<script>alert(1)</script>" , Validator . Redirect ( "500" ) } ,
63+
64+ new object [ ] { $ "/packages/{ Constants . TestPackageId } ", "__Controller::TempData" , "<script>alert(1)</script>" , Validator . Redirect ( "500" ) } ,
65+
66+ new object [ ] { "/packages" , "nugetab" , "<script>alert(1)</script>" , Validator . PrettyInternalServerError ( ) } ,
67+
68+ new object [ ] { "/packages" , "nugetab" , "z̡̜͍̈̍̐̃̊͋́a̜̣͍̬̞̝͉̽ͧ͗l̸̖͕̤̠̹̘͖̃̌ͤg͓̝͓̰̀ͪo͈͌" , Validator . SimpleHtml ( HttpStatusCode . BadRequest ) } ,
69+ } ;
70+
5571 /// <summary>
5672 /// Verify the behavior when a URL with restricted characters is used.
5773 /// </summary>
@@ -93,6 +109,60 @@ public async Task PageThatDoesNotExist(string relativePath)
93109 Validator . PrettyHtml ( HttpStatusCode . NotFound ) ( response ) ;
94110 }
95111
112+ [ Fact ]
113+ [ Priority ( 2 ) ]
114+ [ Category ( "P2Tests" ) ]
115+ public async Task DefaultErrorPageBehavior ( )
116+ {
117+ // Arrange & Act
118+ var response = await GetTestResponseAsync ( "/Errors/500" ) ;
119+
120+ // Assert
121+ Validator . PrettyInternalServerError ( ) ( response ) ;
122+ }
123+
124+ /// <summary>
125+ /// Verify behavior when the pretty HTTP 500 page fails itself.
126+ /// </summary>
127+ [ Fact ]
128+ [ Priority ( 2 ) ]
129+ [ Category ( "P2Tests" ) ]
130+ public async Task ErrorInErrorPageWithoutPath ( )
131+ {
132+ // Arrange
133+ var cookies = new SimulatedErrorRequest ( EndpointType . Pages , SimulatedErrorType . ExceptionInDedicatedErrorPage ) . GetCookies ( ) ;
134+
135+ // Act
136+ var response = await GetTestResponseAsync ( "/Errors/500" , cookies ) ;
137+
138+ // Assert
139+ Validator . Redirect ( "500" ) ( response ) ;
140+ Assert . Equal ( "/Errors/500?aspxerrorpath=/Errors/500" , response . LocationHeader ) ;
141+ }
142+
143+ /// <summary>
144+ /// Verify behavior when the pretty HTTP 500 page fails itself.
145+ /// </summary>
146+ [ Fact ]
147+ [ Priority ( 2 ) ]
148+ [ Category ( "P2Tests" ) ]
149+ public async Task ErrorInErrorPageWithPathToSelf ( )
150+ {
151+ // Arrange
152+ var cookies = new SimulatedErrorRequest ( EndpointType . Pages , SimulatedErrorType . ExceptionInDedicatedErrorPage ) . GetCookies ( ) ;
153+
154+ // Act
155+ var response = await GetTestResponseAsync ( "/Errors/500?aspxerrorpath=/Errors/500" , cookies ) ;
156+
157+ // Assert
158+ Validator . SimpleHtml ( HttpStatusCode . InternalServerError ) ( response ) ;
159+ Assert . Contains (
160+ "An exception occurred while processing your request. " +
161+ "Additionally, another exception occurred while executing the custom error page for the first exception. " +
162+ "The request has been terminated." ,
163+ response . Content ) ;
164+ }
165+
96166 /// <summary>
97167 /// Simulate cases where application code throws different sorts of exceptions.
98168 /// </summary>
@@ -106,7 +176,7 @@ public async Task SimulateError(EndpointType endpointType, SimulatedErrorType si
106176 var request = new SimulatedErrorRequest ( endpointType , simulatedErrorType ) ;
107177
108178 // Act
109- var response = await GetTestResponseAsync ( request . GetRelativePath ( ) ) ;
179+ var response = await GetTestResponseAsync ( request ) ;
110180
111181 // Assert
112182 if ( ! ExpectedSimulatedErrorResponses . TryGetValue ( request , out var validator ) )
@@ -153,7 +223,13 @@ public static IEnumerable<object[]> AllTestData
153223 { SER ( EndpointType . Api , SimulatedErrorType . Result404 ) , Validator . PrettyHtml ( HttpStatusCode . NotFound ) } ,
154224 { SER ( EndpointType . Api , SimulatedErrorType . Result503 ) , Validator . SimpleHtml ( HttpStatusCode . ServiceUnavailable , SimulatedErrorType . Result503 ) } ,
155225 { SER ( EndpointType . Api , SimulatedErrorType . UserSafeException ) , Validator . SimpleHtml ( HttpStatusCode . InternalServerError , SimulatedErrorType . UserSafeException ) } ,
226+ { SER ( EndpointType . Api , SimulatedErrorType . ExceptionInView ) , Validator . SimpleHtml ( HttpStatusCode . InternalServerError , SimulatedErrorType . ExceptionInView ) } ,
227+ { SER ( EndpointType . Api , SimulatedErrorType . ExceptionInInlineErrorPage ) , Validator . SimpleHtml ( HttpStatusCode . InternalServerError , SimulatedErrorType . ExceptionInInlineErrorPage ) } ,
228+ { SER ( EndpointType . Api , SimulatedErrorType . ExceptionInDedicatedErrorPage ) , Validator . SimpleHtml ( HttpStatusCode . InternalServerError , SimulatedErrorType . ExceptionInDedicatedErrorPage ) } ,
156229 { SER ( EndpointType . OData , SimulatedErrorType . Exception ) , Validator . Xml ( ) } ,
230+ { SER ( EndpointType . OData , SimulatedErrorType . ExceptionInView ) , Validator . Xml ( ) } ,
231+ { SER ( EndpointType . OData , SimulatedErrorType . ExceptionInInlineErrorPage ) , Validator . Xml ( ) } ,
232+ { SER ( EndpointType . OData , SimulatedErrorType . ExceptionInDedicatedErrorPage ) , Validator . Xml ( ) } ,
157233 { SER ( EndpointType . OData , SimulatedErrorType . HttpException400 ) , Validator . Xml ( ) } ,
158234 { SER ( EndpointType . OData , SimulatedErrorType . HttpException404 ) , Validator . Xml ( ) } ,
159235 { SER ( EndpointType . OData , SimulatedErrorType . HttpException500 ) , Validator . Xml ( ) } ,
@@ -175,6 +251,7 @@ public static IEnumerable<object[]> AllTestData
175251 { SER ( EndpointType . Pages , SimulatedErrorType . Result400 ) , Validator . SimpleHtml ( HttpStatusCode . BadRequest , SimulatedErrorType . Result400 ) } ,
176252 { SER ( EndpointType . Pages , SimulatedErrorType . Result404 ) , Validator . PrettyHtml ( HttpStatusCode . NotFound ) } ,
177253 { SER ( EndpointType . Pages , SimulatedErrorType . Result503 ) , Validator . SimpleHtml ( HttpStatusCode . ServiceUnavailable , SimulatedErrorType . Result503 ) } ,
254+ { SER ( EndpointType . Pages , SimulatedErrorType . ExceptionInInlineErrorPage ) , Validator . Redirect ( "500" ) } ,
178255 } ;
179256
180257 /// <summary>
@@ -198,14 +275,31 @@ private async Task<TestResponse> GetTestResponseAsync(string relativePath, HttpR
198275 }
199276 }
200277
201- private async Task < TestResponse > GetTestResponseAsync ( string relativePath )
278+ private async Task < TestResponse > GetTestResponseAsync ( SimulatedErrorRequest errorRequest )
279+ {
280+ return await GetTestResponseAsync (
281+ errorRequest . GetRelativePath ( ) ,
282+ errorRequest . GetCookies ( ) ) ;
283+ }
284+
285+ private async Task < TestResponse > GetTestResponseAsync ( string relativePath , IReadOnlyDictionary < string , string > cookies )
202286 {
203287 using ( var request = new HttpRequestMessage ( HttpMethod . Get , GetRequestUri ( relativePath ) ) )
204288 {
289+ foreach ( var cookie in cookies )
290+ {
291+ _cookieContainer . Add ( new Uri ( UrlHelper . BaseUrl ) , new Cookie { Name = cookie . Key , Value = cookie . Value } ) ;
292+ }
293+
205294 return await GetTestResponseAsync ( relativePath , request ) ;
206295 }
207296 }
208297
298+ private async Task < TestResponse > GetTestResponseAsync ( string relativePath )
299+ {
300+ return await GetTestResponseAsync ( relativePath , new Dictionary < string , string > ( ) ) ;
301+ }
302+
209303 private Uri GetRequestUri ( string relativePath )
210304 {
211305 return new Uri ( new Uri ( UrlHelper . BaseUrl ) , relativePath ) ;
0 commit comments