001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.rest.client.assertion; 018 019import org.apache.juneau.rest.client.*; 020 021/** 022 * A fluent assertion class for validating {@link RestResponse} instances. 023 * 024 * <p> 025 * Provides assertion methods for HTTP status code, response headers, and body content. 026 * All assertion methods return {@code this} for chaining, and throw {@link AssertionError} 027 * on failure. 028 * 029 * <p> 030 * Obtain instances via {@link RestResponse#assertThat()}. 031 * 032 * <p class='bjava'> 033 * <jk>try</jk> (RestResponse <jv>resp</jv> = client.get(<js>"/api/users"</js>).run()) { 034 * <jv>resp</jv>.assertThat() 035 * .statusCode(200) 036 * .header(<js>"Content-Type"</js>).contains(<js>"application/json"</js>) 037 * .body().contains(<js>"alice"</js>); 038 * } 039 * </p> 040 * 041 * <h5 class='section'>See Also:</h5><ul> 042 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a> 043 * </ul> 044 * 045 * @since 9.2.1 046 */ 047@SuppressWarnings({ 048 "resource" // Eclipse resource analysis: response is borrowed for assertions; caller closes it 049}) 050public final class ResponseAssertion { 051 052 private final RestResponse response; 053 054 /** 055 * Constructor. 056 * 057 * @param response The response to assert on. Must not be <jk>null</jk>. 058 */ 059 public ResponseAssertion(RestResponse response) { 060 this.response = response; 061 } 062 063 /** 064 * Asserts that the response status code equals the expected value. 065 * 066 * @param expected The expected status code. 067 * @return This object (for chaining). 068 * @throws AssertionError If the status code does not match. 069 */ 070 public ResponseAssertion statusCode(int expected) { 071 var actual = response.getStatusCode(); 072 if (actual != expected) 073 throw new AssertionError("Expected status code " + expected + " but got " + actual); 074 return this; 075 } 076 077 /** 078 * Asserts that the response status code is in the 2xx (success) range. 079 * 080 * @return This object (for chaining). 081 * @throws AssertionError If the status code is not in 200–299. 082 */ 083 public ResponseAssertion isOk() { 084 var sc = response.getStatusCode(); 085 if (sc < 200 || sc > 299) 086 throw new AssertionError("Expected 2xx status but got " + sc); 087 return this; 088 } 089 090 /** 091 * Asserts that the response status code is in the 4xx (client error) range. 092 * 093 * @return This object (for chaining). 094 * @throws AssertionError If the status code is not in 400–499. 095 */ 096 public ResponseAssertion isClientError() { 097 var sc = response.getStatusCode(); 098 if (sc < 400 || sc > 499) 099 throw new AssertionError("Expected 4xx status but got " + sc); 100 return this; 101 } 102 103 /** 104 * Asserts that the response status code is in the 5xx (server error) range. 105 * 106 * @return This object (for chaining). 107 * @throws AssertionError If the status code is not in 500–599. 108 */ 109 public ResponseAssertion isServerError() { 110 var sc = response.getStatusCode(); 111 if (sc < 500 || sc > 599) 112 throw new AssertionError("Expected 5xx status but got " + sc); 113 return this; 114 } 115 116 /** 117 * Returns a fluent header assertion for the named response header. 118 * 119 * @param name The header name (case-insensitive). Must not be <jk>null</jk>. 120 * @return A new header assertion. Never <jk>null</jk>. 121 */ 122 public ResponseHeaderAssertion header(String name) { 123 return new ResponseHeaderAssertion(name, response, this); 124 } 125 126 /** 127 * Returns a fluent body assertion. 128 * 129 * @return A new body assertion. Never <jk>null</jk>. 130 */ 131 public ResponseBodyAssertion body() { 132 return new ResponseBodyAssertion(response, this); 133 } 134 135 /** 136 * Returns the underlying response (for further access after assertions). 137 * 138 * @return The response. Never <jk>null</jk>. 139 */ 140 public RestResponse and() { 141 return response; 142 } 143}