@@ -37,8 +37,12 @@ public ErrorHandlingTests(ITestOutputHelper testOutputHelper) : base(testOutputH
3737 [ Theory ]
3838 [ Priority ( 2 ) ]
3939 [ Category ( "P2Tests" ) ]
40- [ MemberData ( nameof ( RejectedCookies ) ) ]
41- public async Task RejectedCookie ( string relativePath , string name , string value , Action < TestResponse > validate )
40+ [ InlineData ( "/" , "__Controller::TempData" , "Message=You successfully uploaded z̡̜͍̈̍̐̃̊͋́a̜̣͍̬̞̝͉̽ͧ͗l̸̖͕̤̠̹̘͖̃̌ͤg͓̝͓̰̀ͪo͈͌ 1.0.0." , 400 , false ) ]
41+ [ InlineData ( "/" , "__Controller::TempData" , "Message=<script>alert(1)</script>" , 400 , false ) ]
42+ [ InlineData ( "/" , "__Controller::TempData" , "<script>alert(1)</script>" , 400 , false ) ]
43+ [ InlineData ( "/packages" , "nugetab" , "<script>alert(1)</script>" , 400 , true ) ]
44+ [ InlineData ( "/packages" , "nugetab" , "z̡̜͍̈̍̐̃̊͋́a̜̣͍̬̞̝͉̽ͧ͗l̸̖͕̤̠̹̘͖̃̌ͤg͓̝͓̰̀ͪo͈͌" , 400 , false ) ]
45+ public async Task RejectedCookie ( string relativePath , string name , string value , int statusCode , bool pretty )
4246 {
4347 // Arrange
4448 _httpClientHandler . UseCookies = false ;
@@ -51,23 +55,17 @@ public async Task RejectedCookie(string relativePath, string name, string value,
5155 var response = await GetTestResponseAsync ( relativePath , request ) ;
5256
5357 // Assert
54- validate ( response ) ;
58+ if ( pretty )
59+ {
60+ Validator . PrettyHtml ( ( HttpStatusCode ) statusCode ) ( response ) ;
61+ }
62+ else
63+ {
64+ Validator . SimpleHtml ( ( HttpStatusCode ) statusCode ) ( response ) ;
65+ }
5566 }
5667 }
5768
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-
7169 /// <summary>
7270 /// Verify the behavior when a URL with restricted characters is used.
7371 /// </summary>
@@ -85,9 +83,7 @@ public async Task RejectedUrl(string relativePath)
8583 var response = await GetTestResponseAsync ( relativePath ) ;
8684
8785 // Assert
88- // Since the HTTP client is configured to not follow redirects, the response we get back is not the
89- // error page itself but instead a redirect to an error page.
90- Validator . Redirect ( "400" ) ( response ) ;
86+ Validator . SimpleHtml ( HttpStatusCode . BadRequest ) ( response ) ;
9187 }
9288
9389 /// <summary>
@@ -96,17 +92,49 @@ public async Task RejectedUrl(string relativePath)
9692 [ Theory ]
9793 [ Priority ( 2 ) ]
9894 [ Category ( "P2Tests" ) ]
99- [ InlineData ( "/api/does-not-exist" ) ]
100- [ InlineData ( "/pages/does-not-exist" ) ]
101- [ InlineData ( "/api/v2/curated-feed/microsoftdotnet/DoesNotExist()" ) ]
102- [ InlineData ( "/does-not-exist" ) ]
103- public async Task PageThatDoesNotExist ( string relativePath )
95+ [ InlineData ( "/api/does-not-exist" , true ) ]
96+ [ InlineData ( "/pages/does-not-exist" , true ) ]
97+ [ InlineData ( "/api/v2/curated-feed/microsoftdotnet/DoesNotExist()" , true ) ]
98+ [ InlineData ( "/does-not-exist" , true ) ]
99+ [ InlineData ( "/packages/package--cannot--exist" , true ) ]
100+ [ InlineData ( "/packages/BaseTestPackage/invalid-version/Manage" , true ) ]
101+ // The following behave poorly. See: https://github.com/NuGet/NuGetGallery/issues/7959
102+ [ InlineData ( "/packages/BaseTestPackage/invalid-version" , false ) ]
103+ [ InlineData ( "/packages/BaseTestPackage/1.0.0/Mismanage" , false ) ]
104+ public async Task PageThatDoesNotExist ( string relativePath , bool pretty )
104105 {
105106 // Arrange & Act
106107 var response = await GetTestResponseAsync ( relativePath ) ;
107108
108109 // Assert
109- Validator . PrettyHtml ( HttpStatusCode . NotFound ) ( response ) ;
110+ if ( pretty )
111+ {
112+ Validator . PrettyHtml ( HttpStatusCode . NotFound ) ( response ) ;
113+ }
114+ else
115+ {
116+ Validator . SimpleHtml ( HttpStatusCode . NotFound ) ( response ) ;
117+ }
118+ }
119+
120+ /// <summary>
121+ /// Verify a matched route but a mismatched HTTP method.
122+ /// </summary>
123+ [ Theory ]
124+ [ Priority ( 2 ) ]
125+ [ Category ( "P2Tests" ) ]
126+ [ InlineData ( "DELETE" , "/api/v2" , 405 ) ]
127+ // The following have non-ideal behavior.
128+ [ InlineData ( "DELETE" , "/api/status" , 500 ) ]
129+ [ InlineData ( "GET" , "/packages/manage/reflow" , 404 ) ]
130+ [ InlineData ( "POST" , "/packages/BaseTestPackage/1.0.0/License" , 404 ) ]
131+ public async Task UnsupportedMethod ( string httpMethod , string relativePath , int statusCode )
132+ {
133+ // Arrange & Act
134+ var response = await GetTestResponseAsync ( new HttpMethod ( httpMethod ) , relativePath ) ;
135+
136+ // Assert
137+ Assert . Equal ( ( HttpStatusCode ) statusCode , response . StatusCode ) ;
110138 }
111139
112140 [ Fact ]
@@ -136,8 +164,7 @@ public async Task ErrorInErrorPageWithoutPath()
136164 var response = await GetTestResponseAsync ( "/Errors/500" , cookies ) ;
137165
138166 // Assert
139- Validator . Redirect ( "500" ) ( response ) ;
140- Assert . Equal ( "/Errors/500?aspxerrorpath=/Errors/500" , response . LocationHeader ) ;
167+ Validator . SimpleHtml ( HttpStatusCode . InternalServerError ) ;
141168 }
142169
143170 /// <summary>
@@ -244,14 +271,14 @@ public static IEnumerable<object[]> AllTestData
244271 { SER ( EndpointType . OData , SimulatedErrorType . Result500 ) , Validator . Empty ( HttpStatusCode . InternalServerError , SimulatedErrorType . Result500 ) } ,
245272 { SER ( EndpointType . OData , SimulatedErrorType . Result503 ) , Validator . Empty ( HttpStatusCode . ServiceUnavailable , SimulatedErrorType . Result503 ) } ,
246273 { SER ( EndpointType . OData , SimulatedErrorType . UserSafeException ) , Validator . Xml ( ) } ,
247- { SER ( EndpointType . Pages , SimulatedErrorType . HttpException400 ) , Validator . Redirect ( "400" ) } ,
248- { SER ( EndpointType . Pages , SimulatedErrorType . HttpException404 ) , Validator . Redirect ( "404" ) } ,
249- { SER ( EndpointType . Pages , SimulatedErrorType . HttpException503 ) , Validator . Redirect ( "500" ) } ,
274+ { SER ( EndpointType . Pages , SimulatedErrorType . HttpException400 ) , Validator . SimpleHtml ( HttpStatusCode . BadRequest ) } ,
275+ { SER ( EndpointType . Pages , SimulatedErrorType . HttpException404 ) , Validator . SimpleHtml ( HttpStatusCode . NotFound ) } ,
276+ { SER ( EndpointType . Pages , SimulatedErrorType . HttpException503 ) , Validator . SimpleHtml ( HttpStatusCode . InternalServerError ) } ,
250277 { SER ( EndpointType . Pages , SimulatedErrorType . ReadOnlyMode ) , Validator . PrettyHtml ( HttpStatusCode . ServiceUnavailable ) } ,
251278 { SER ( EndpointType . Pages , SimulatedErrorType . Result400 ) , Validator . SimpleHtml ( HttpStatusCode . BadRequest , SimulatedErrorType . Result400 ) } ,
252279 { SER ( EndpointType . Pages , SimulatedErrorType . Result404 ) , Validator . PrettyHtml ( HttpStatusCode . NotFound ) } ,
253280 { SER ( EndpointType . Pages , SimulatedErrorType . Result503 ) , Validator . SimpleHtml ( HttpStatusCode . ServiceUnavailable , SimulatedErrorType . Result503 ) } ,
254- { SER ( EndpointType . Pages , SimulatedErrorType . ExceptionInInlineErrorPage ) , Validator . Redirect ( "500" ) } ,
281+ { SER ( EndpointType . Pages , SimulatedErrorType . ExceptionInInlineErrorPage ) , Validator . SimpleHtml ( HttpStatusCode . InternalServerError ) } ,
255282 } ;
256283
257284 /// <summary>
@@ -284,7 +311,22 @@ private async Task<TestResponse> GetTestResponseAsync(SimulatedErrorRequest erro
284311
285312 private async Task < TestResponse > GetTestResponseAsync ( string relativePath , IReadOnlyDictionary < string , string > cookies )
286313 {
287- using ( var request = new HttpRequestMessage ( HttpMethod . Get , GetRequestUri ( relativePath ) ) )
314+ return await GetTestResponseAsync ( HttpMethod . Get , relativePath , cookies ) ;
315+ }
316+
317+ private async Task < TestResponse > GetTestResponseAsync ( string relativePath )
318+ {
319+ return await GetTestResponseAsync ( HttpMethod . Get , relativePath ) ;
320+ }
321+
322+ private async Task < TestResponse > GetTestResponseAsync ( HttpMethod method , string relativePath )
323+ {
324+ return await GetTestResponseAsync ( method , relativePath , new Dictionary < string , string > ( ) ) ;
325+ }
326+
327+ private async Task < TestResponse > GetTestResponseAsync ( HttpMethod method , string relativePath , IReadOnlyDictionary < string , string > cookies )
328+ {
329+ using ( var request = new HttpRequestMessage ( method , GetRequestUri ( relativePath ) ) )
288330 {
289331 foreach ( var cookie in cookies )
290332 {
@@ -295,11 +337,6 @@ private async Task<TestResponse> GetTestResponseAsync(string relativePath, IRead
295337 }
296338 }
297339
298- private async Task < TestResponse > GetTestResponseAsync ( string relativePath )
299- {
300- return await GetTestResponseAsync ( relativePath , new Dictionary < string , string > ( ) ) ;
301- }
302-
303340 private Uri GetRequestUri ( string relativePath )
304341 {
305342 return new Uri ( new Uri ( UrlHelper . BaseUrl ) , relativePath ) ;
0 commit comments