001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.servlet.result; 018 019import org.hamcrest.Matcher; 020 021import org.springframework.http.HttpStatus; 022import org.springframework.test.web.servlet.MvcResult; 023import org.springframework.test.web.servlet.ResultMatcher; 024 025import static org.hamcrest.MatcherAssert.*; 026import static org.springframework.test.util.AssertionErrors.*; 027 028/** 029 * Factory for assertions on the response status. 030 * 031 * <p>An instance of this class is typically accessed via 032 * {@link MockMvcResultMatchers#status}. 033 * 034 * @author Keesun Baik 035 * @author Rossen Stoyanchev 036 * @author Sebastien Deleuze 037 * @author Brian Clozel 038 * @since 3.2 039 */ 040public class StatusResultMatchers { 041 042 /** 043 * Protected constructor. 044 * Use {@link MockMvcResultMatchers#status()}. 045 */ 046 protected StatusResultMatchers() { 047 } 048 049 050 /** 051 * Assert the response status code with the given Hamcrest {@link Matcher}. 052 */ 053 public ResultMatcher is(final Matcher<Integer> matcher) { 054 return new ResultMatcher() { 055 @Override 056 public void match(MvcResult result) throws Exception { 057 assertThat("Response status", result.getResponse().getStatus(), matcher); 058 } 059 }; 060 } 061 062 /** 063 * Assert the response status code is equal to an integer value. 064 */ 065 public ResultMatcher is(final int status) { 066 return new ResultMatcher() { 067 @Override 068 public void match(MvcResult result) throws Exception { 069 assertEquals("Response status", status, result.getResponse().getStatus()); 070 } 071 }; 072 } 073 074 /** 075 * Assert the response status code is in the 1xx range. 076 */ 077 public ResultMatcher is1xxInformational() { 078 return new ResultMatcher() { 079 @Override 080 public void match(MvcResult result) throws Exception { 081 assertEquals("Range for response status value " + result.getResponse().getStatus(), 082 HttpStatus.Series.INFORMATIONAL, getHttpStatusSeries(result)); 083 } 084 }; 085 } 086 087 /** 088 * Assert the response status code is in the 2xx range. 089 */ 090 public ResultMatcher is2xxSuccessful() { 091 return new ResultMatcher() { 092 @Override 093 public void match(MvcResult result) throws Exception { 094 assertEquals("Range for response status value " + result.getResponse().getStatus(), 095 HttpStatus.Series.SUCCESSFUL, getHttpStatusSeries(result)); 096 } 097 }; 098 } 099 100 /** 101 * Assert the response status code is in the 3xx range. 102 */ 103 public ResultMatcher is3xxRedirection() { 104 return new ResultMatcher() { 105 @Override 106 public void match(MvcResult result) throws Exception { 107 assertEquals("Range for response status value " + result.getResponse().getStatus(), 108 HttpStatus.Series.REDIRECTION, getHttpStatusSeries(result)); 109 } 110 }; 111 } 112 113 /** 114 * Assert the response status code is in the 4xx range. 115 */ 116 public ResultMatcher is4xxClientError() { 117 return new ResultMatcher() { 118 @Override 119 public void match(MvcResult result) throws Exception { 120 assertEquals("Range for response status value " + result.getResponse().getStatus(), 121 HttpStatus.Series.CLIENT_ERROR, getHttpStatusSeries(result)); 122 } 123 }; 124 } 125 126 /** 127 * Assert the response status code is in the 5xx range. 128 */ 129 public ResultMatcher is5xxServerError() { 130 return new ResultMatcher() { 131 @Override 132 public void match(MvcResult result) throws Exception { 133 assertEquals("Range for response status value " + result.getResponse().getStatus(), 134 HttpStatus.Series.SERVER_ERROR, getHttpStatusSeries(result)); 135 } 136 }; 137 } 138 139 private HttpStatus.Series getHttpStatusSeries(MvcResult result) { 140 int statusValue = result.getResponse().getStatus(); 141 HttpStatus status = HttpStatus.valueOf(statusValue); 142 return status.series(); 143 } 144 145 /** 146 * Assert the Servlet response error message with the given Hamcrest {@link Matcher}. 147 */ 148 public ResultMatcher reason(final Matcher<? super String> matcher) { 149 return new ResultMatcher() { 150 @Override 151 public void match(MvcResult result) throws Exception { 152 assertThat("Response status reason", result.getResponse().getErrorMessage(), matcher); 153 } 154 }; 155 } 156 157 /** 158 * Assert the Servlet response error message. 159 */ 160 public ResultMatcher reason(final String reason) { 161 return new ResultMatcher() { 162 @Override 163 public void match(MvcResult result) throws Exception { 164 assertEquals("Response status reason", reason, result.getResponse().getErrorMessage()); 165 } 166 }; 167 } 168 169 /** 170 * Assert the response status code is {@code HttpStatus.CONTINUE} (100). 171 */ 172 public ResultMatcher isContinue() { 173 return matcher(HttpStatus.CONTINUE); 174 } 175 176 /** 177 * Assert the response status code is {@code HttpStatus.SWITCHING_PROTOCOLS} (101). 178 */ 179 public ResultMatcher isSwitchingProtocols() { 180 return matcher(HttpStatus.SWITCHING_PROTOCOLS); 181 } 182 183 /** 184 * Assert the response status code is {@code HttpStatus.PROCESSING} (102). 185 */ 186 public ResultMatcher isProcessing() { 187 return matcher(HttpStatus.PROCESSING); 188 } 189 190 /** 191 * Assert the response status code is {@code HttpStatus.CHECKPOINT} (103). 192 */ 193 public ResultMatcher isCheckpoint() { 194 return matcher(HttpStatus.valueOf(103)); 195 } 196 197 /** 198 * Assert the response status code is {@code HttpStatus.OK} (200). 199 */ 200 public ResultMatcher isOk() { 201 return matcher(HttpStatus.OK); 202 } 203 204 /** 205 * Assert the response status code is {@code HttpStatus.CREATED} (201). 206 */ 207 public ResultMatcher isCreated() { 208 return matcher(HttpStatus.CREATED); 209 } 210 211 /** 212 * Assert the response status code is {@code HttpStatus.ACCEPTED} (202). 213 */ 214 public ResultMatcher isAccepted() { 215 return matcher(HttpStatus.ACCEPTED); 216 } 217 218 /** 219 * Assert the response status code is {@code HttpStatus.NON_AUTHORITATIVE_INFORMATION} (203). 220 */ 221 public ResultMatcher isNonAuthoritativeInformation() { 222 return matcher(HttpStatus.NON_AUTHORITATIVE_INFORMATION); 223 } 224 225 /** 226 * Assert the response status code is {@code HttpStatus.NO_CONTENT} (204). 227 */ 228 public ResultMatcher isNoContent() { 229 return matcher(HttpStatus.NO_CONTENT); 230 } 231 232 /** 233 * Assert the response status code is {@code HttpStatus.RESET_CONTENT} (205). 234 */ 235 public ResultMatcher isResetContent() { 236 return matcher(HttpStatus.RESET_CONTENT); 237 } 238 239 /** 240 * Assert the response status code is {@code HttpStatus.PARTIAL_CONTENT} (206). 241 */ 242 public ResultMatcher isPartialContent() { 243 return matcher(HttpStatus.PARTIAL_CONTENT); 244 } 245 246 /** 247 * Assert the response status code is {@code HttpStatus.MULTI_STATUS} (207). 248 */ 249 public ResultMatcher isMultiStatus() { 250 return matcher(HttpStatus.MULTI_STATUS); 251 } 252 253 /** 254 * Assert the response status code is {@code HttpStatus.ALREADY_REPORTED} (208). 255 */ 256 public ResultMatcher isAlreadyReported() { 257 return matcher(HttpStatus.ALREADY_REPORTED); 258 } 259 260 /** 261 * Assert the response status code is {@code HttpStatus.IM_USED} (226). 262 */ 263 public ResultMatcher isImUsed() { 264 return matcher(HttpStatus.IM_USED); 265 } 266 267 /** 268 * Assert the response status code is {@code HttpStatus.MULTIPLE_CHOICES} (300). 269 */ 270 public ResultMatcher isMultipleChoices() { 271 return matcher(HttpStatus.MULTIPLE_CHOICES); 272 } 273 274 /** 275 * Assert the response status code is {@code HttpStatus.MOVED_PERMANENTLY} (301). 276 */ 277 public ResultMatcher isMovedPermanently() { 278 return matcher(HttpStatus.MOVED_PERMANENTLY); 279 } 280 281 /** 282 * Assert the response status code is {@code HttpStatus.FOUND} (302). 283 */ 284 public ResultMatcher isFound() { 285 return matcher(HttpStatus.FOUND); 286 } 287 288 /** 289 * Assert the response status code is {@code HttpStatus.MOVED_TEMPORARILY} (302). 290 * @see #isFound() 291 * @deprecated in favor of {@link #isFound()} 292 */ 293 @Deprecated 294 public ResultMatcher isMovedTemporarily() { 295 return matcher(HttpStatus.MOVED_TEMPORARILY); 296 } 297 298 /** 299 * Assert the response status code is {@code HttpStatus.SEE_OTHER} (303). 300 */ 301 public ResultMatcher isSeeOther() { 302 return matcher(HttpStatus.SEE_OTHER); 303 } 304 305 /** 306 * Assert the response status code is {@code HttpStatus.NOT_MODIFIED} (304). 307 */ 308 public ResultMatcher isNotModified() { 309 return matcher(HttpStatus.NOT_MODIFIED); 310 } 311 312 /** 313 * Assert the response status code is {@code HttpStatus.USE_PROXY} (305). 314 * @deprecated matching the deprecation of {@code HttpStatus.USE_PROXY} 315 */ 316 @Deprecated 317 public ResultMatcher isUseProxy() { 318 return matcher(HttpStatus.USE_PROXY); 319 } 320 321 /** 322 * Assert the response status code is {@code HttpStatus.TEMPORARY_REDIRECT} (307). 323 */ 324 public ResultMatcher isTemporaryRedirect() { 325 return matcher(HttpStatus.TEMPORARY_REDIRECT); 326 } 327 328 /** 329 * Assert the response status code is {@code HttpStatus.PERMANENT_REDIRECT} (308). 330 */ 331 public ResultMatcher isPermanentRedirect() { 332 return matcher(HttpStatus.valueOf(308)); 333 } 334 335 /** 336 * Assert the response status code is {@code HttpStatus.BAD_REQUEST} (400). 337 */ 338 public ResultMatcher isBadRequest() { 339 return matcher(HttpStatus.BAD_REQUEST); 340 } 341 342 /** 343 * Assert the response status code is {@code HttpStatus.UNAUTHORIZED} (401). 344 */ 345 public ResultMatcher isUnauthorized() { 346 return matcher(HttpStatus.UNAUTHORIZED); 347 } 348 349 /** 350 * Assert the response status code is {@code HttpStatus.PAYMENT_REQUIRED} (402). 351 */ 352 public ResultMatcher isPaymentRequired() { 353 return matcher(HttpStatus.PAYMENT_REQUIRED); 354 } 355 356 /** 357 * Assert the response status code is {@code HttpStatus.FORBIDDEN} (403). 358 */ 359 public ResultMatcher isForbidden() { 360 return matcher(HttpStatus.FORBIDDEN); 361 } 362 363 /** 364 * Assert the response status code is {@code HttpStatus.NOT_FOUND} (404). 365 */ 366 public ResultMatcher isNotFound() { 367 return matcher(HttpStatus.NOT_FOUND); 368 } 369 370 /** 371 * Assert the response status code is {@code HttpStatus.METHOD_NOT_ALLOWED} (405). 372 */ 373 public ResultMatcher isMethodNotAllowed() { 374 return matcher(HttpStatus.METHOD_NOT_ALLOWED); 375 } 376 377 /** 378 * Assert the response status code is {@code HttpStatus.NOT_ACCEPTABLE} (406). 379 */ 380 public ResultMatcher isNotAcceptable() { 381 return matcher(HttpStatus.NOT_ACCEPTABLE); 382 } 383 384 /** 385 * Assert the response status code is {@code HttpStatus.PROXY_AUTHENTICATION_REQUIRED} (407). 386 */ 387 public ResultMatcher isProxyAuthenticationRequired() { 388 return matcher(HttpStatus.PROXY_AUTHENTICATION_REQUIRED); 389 } 390 391 /** 392 * Assert the response status code is {@code HttpStatus.REQUEST_TIMEOUT} (408). 393 */ 394 public ResultMatcher isRequestTimeout() { 395 return matcher(HttpStatus.REQUEST_TIMEOUT); 396 } 397 398 /** 399 * Assert the response status code is {@code HttpStatus.CONFLICT} (409). 400 */ 401 public ResultMatcher isConflict() { 402 return matcher(HttpStatus.CONFLICT); 403 } 404 405 /** 406 * Assert the response status code is {@code HttpStatus.GONE} (410). 407 */ 408 public ResultMatcher isGone() { 409 return matcher(HttpStatus.GONE); 410 } 411 412 /** 413 * Assert the response status code is {@code HttpStatus.LENGTH_REQUIRED} (411). 414 */ 415 public ResultMatcher isLengthRequired() { 416 return matcher(HttpStatus.LENGTH_REQUIRED); 417 } 418 419 /** 420 * Assert the response status code is {@code HttpStatus.PRECONDITION_FAILED} (412). 421 */ 422 public ResultMatcher isPreconditionFailed() { 423 return matcher(HttpStatus.PRECONDITION_FAILED); 424 } 425 426 /** 427 * Assert the response status code is {@code HttpStatus.PAYLOAD_TOO_LARGE} (413). 428 * @since 4.1 429 */ 430 public ResultMatcher isPayloadTooLarge() { 431 return matcher(HttpStatus.PAYLOAD_TOO_LARGE); 432 } 433 434 /** 435 * Assert the response status code is {@code HttpStatus.REQUEST_ENTITY_TOO_LARGE} (413). 436 * @deprecated matching the deprecation of {@code HttpStatus.REQUEST_ENTITY_TOO_LARGE} 437 * @see #isPayloadTooLarge() 438 */ 439 @Deprecated 440 public ResultMatcher isRequestEntityTooLarge() { 441 return matcher(HttpStatus.REQUEST_ENTITY_TOO_LARGE); 442 } 443 444 /** 445 * Assert the response status code is {@code HttpStatus.REQUEST_URI_TOO_LONG} (414). 446 * @since 4.1 447 */ 448 public ResultMatcher isUriTooLong() { 449 return matcher(HttpStatus.URI_TOO_LONG); 450 } 451 452 /** 453 * Assert the response status code is {@code HttpStatus.REQUEST_URI_TOO_LONG} (414). 454 * @deprecated matching the deprecation of {@code HttpStatus.REQUEST_URI_TOO_LONG} 455 * @see #isUriTooLong() 456 */ 457 @Deprecated 458 public ResultMatcher isRequestUriTooLong() { 459 return matcher(HttpStatus.REQUEST_URI_TOO_LONG); 460 } 461 462 /** 463 * Assert the response status code is {@code HttpStatus.UNSUPPORTED_MEDIA_TYPE} (415). 464 */ 465 public ResultMatcher isUnsupportedMediaType() { 466 return matcher(HttpStatus.UNSUPPORTED_MEDIA_TYPE); 467 } 468 469 /** 470 * Assert the response status code is {@code HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE} (416). 471 */ 472 public ResultMatcher isRequestedRangeNotSatisfiable() { 473 return matcher(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE); 474 } 475 476 /** 477 * Assert the response status code is {@code HttpStatus.EXPECTATION_FAILED} (417). 478 */ 479 public ResultMatcher isExpectationFailed() { 480 return matcher(HttpStatus.EXPECTATION_FAILED); 481 } 482 483 /** 484 * Assert the response status code is {@code HttpStatus.I_AM_A_TEAPOT} (418). 485 */ 486 public ResultMatcher isIAmATeapot() { 487 return matcher(HttpStatus.valueOf(418)); 488 } 489 490 /** 491 * Assert the response status code is {@code HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE} (419). 492 * @deprecated matching the deprecation of {@code HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE} 493 */ 494 @Deprecated 495 public ResultMatcher isInsufficientSpaceOnResource() { 496 return matcher(HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE); 497 } 498 499 /** 500 * Assert the response status code is {@code HttpStatus.METHOD_FAILURE} (420). 501 * @deprecated matching the deprecation of {@code HttpStatus.METHOD_FAILURE} 502 */ 503 @Deprecated 504 public ResultMatcher isMethodFailure() { 505 return matcher(HttpStatus.METHOD_FAILURE); 506 } 507 508 /** 509 * Assert the response status code is {@code HttpStatus.DESTINATION_LOCKED} (421). 510 * @deprecated matching the deprecation of {@code HttpStatus.DESTINATION_LOCKED} 511 */ 512 @Deprecated 513 public ResultMatcher isDestinationLocked() { 514 return matcher(HttpStatus.DESTINATION_LOCKED); 515 } 516 517 /** 518 * Assert the response status code is {@code HttpStatus.UNPROCESSABLE_ENTITY} (422). 519 */ 520 public ResultMatcher isUnprocessableEntity() { 521 return matcher(HttpStatus.UNPROCESSABLE_ENTITY); 522 } 523 524 /** 525 * Assert the response status code is {@code HttpStatus.LOCKED} (423). 526 */ 527 public ResultMatcher isLocked() { 528 return matcher(HttpStatus.LOCKED); 529 } 530 531 /** 532 * Assert the response status code is {@code HttpStatus.FAILED_DEPENDENCY} (424). 533 */ 534 public ResultMatcher isFailedDependency() { 535 return matcher(HttpStatus.FAILED_DEPENDENCY); 536 } 537 538 /** 539 * Assert the response status code is {@code HttpStatus.UPGRADE_REQUIRED} (426). 540 */ 541 public ResultMatcher isUpgradeRequired() { 542 return matcher(HttpStatus.UPGRADE_REQUIRED); 543 } 544 545 /** 546 * Assert the response status code is {@code HttpStatus.PRECONDITION_REQUIRED} (428). 547 */ 548 public ResultMatcher isPreconditionRequired() { 549 return matcher(HttpStatus.valueOf(428)); 550 } 551 552 /** 553 * Assert the response status code is {@code HttpStatus.TOO_MANY_REQUESTS} (429). 554 */ 555 public ResultMatcher isTooManyRequests() { 556 return matcher(HttpStatus.valueOf(429)); 557 } 558 559 /** 560 * Assert the response status code is {@code HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE} (431). 561 */ 562 public ResultMatcher isRequestHeaderFieldsTooLarge() { 563 return matcher(HttpStatus.valueOf(431)); 564 } 565 566 /** 567 * Assert the response status code is {@code HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS} (451). 568 * @since 4.3 569 */ 570 public ResultMatcher isUnavailableForLegalReasons() { 571 return matcher(HttpStatus.valueOf(451)); 572 } 573 574 /** 575 * Assert the response status code is {@code HttpStatus.INTERNAL_SERVER_ERROR} (500). 576 */ 577 public ResultMatcher isInternalServerError() { 578 return matcher(HttpStatus.INTERNAL_SERVER_ERROR); 579 } 580 581 /** 582 * Assert the response status code is {@code HttpStatus.NOT_IMPLEMENTED} (501). 583 */ 584 public ResultMatcher isNotImplemented() { 585 return matcher(HttpStatus.NOT_IMPLEMENTED); 586 } 587 588 /** 589 * Assert the response status code is {@code HttpStatus.BAD_GATEWAY} (502). 590 */ 591 public ResultMatcher isBadGateway() { 592 return matcher(HttpStatus.BAD_GATEWAY); 593 } 594 595 /** 596 * Assert the response status code is {@code HttpStatus.SERVICE_UNAVAILABLE} (503). 597 */ 598 public ResultMatcher isServiceUnavailable() { 599 return matcher(HttpStatus.SERVICE_UNAVAILABLE); 600 } 601 602 /** 603 * Assert the response status code is {@code HttpStatus.GATEWAY_TIMEOUT} (504). 604 */ 605 public ResultMatcher isGatewayTimeout() { 606 return matcher(HttpStatus.GATEWAY_TIMEOUT); 607 } 608 609 /** 610 * Assert the response status code is {@code HttpStatus.HTTP_VERSION_NOT_SUPPORTED} (505). 611 */ 612 public ResultMatcher isHttpVersionNotSupported() { 613 return matcher(HttpStatus.HTTP_VERSION_NOT_SUPPORTED); 614 } 615 616 /** 617 * Assert the response status code is {@code HttpStatus.VARIANT_ALSO_NEGOTIATES} (506). 618 */ 619 public ResultMatcher isVariantAlsoNegotiates() { 620 return matcher(HttpStatus.VARIANT_ALSO_NEGOTIATES); 621 } 622 623 /** 624 * Assert the response status code is {@code HttpStatus.INSUFFICIENT_STORAGE} (507). 625 */ 626 public ResultMatcher isInsufficientStorage() { 627 return matcher(HttpStatus.INSUFFICIENT_STORAGE); 628 } 629 630 /** 631 * Assert the response status code is {@code HttpStatus.LOOP_DETECTED} (508). 632 */ 633 public ResultMatcher isLoopDetected() { 634 return matcher(HttpStatus.LOOP_DETECTED); 635 } 636 637 /** 638 * Assert the response status code is {@code HttpStatus.BANDWIDTH_LIMIT_EXCEEDED} (509). 639 */ 640 public ResultMatcher isBandwidthLimitExceeded() { 641 return matcher(HttpStatus.valueOf(509)); 642 } 643 644 /** 645 * Assert the response status code is {@code HttpStatus.NOT_EXTENDED} (510). 646 */ 647 public ResultMatcher isNotExtended() { 648 return matcher(HttpStatus.NOT_EXTENDED); 649 } 650 651 /** 652 * Assert the response status code is {@code HttpStatus.NETWORK_AUTHENTICATION_REQUIRED} (511). 653 */ 654 public ResultMatcher isNetworkAuthenticationRequired() { 655 return matcher(HttpStatus.valueOf(511)); 656 } 657 658 /** 659 * Match the expected response status to that of the HttpServletResponse 660 */ 661 private ResultMatcher matcher(final HttpStatus status) { 662 return new ResultMatcher() { 663 @Override 664 public void match(MvcResult result) { 665 assertEquals("Status", status.value(), result.getResponse().getStatus()); 666 } 667 }; 668 } 669 670}