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