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.reactive.server;
018
019import java.util.function.Consumer;
020
021import org.hamcrest.Matcher;
022import org.hamcrest.MatcherAssert;
023
024import org.springframework.http.HttpStatus;
025import org.springframework.test.util.AssertionErrors;
026
027/**
028 * Assertions on the response status.
029 *
030 * @author Rossen Stoyanchev
031 * @since 5.0
032 * @see WebTestClient.ResponseSpec#expectStatus()
033 */
034public class StatusAssertions {
035
036        private final ExchangeResult exchangeResult;
037
038        private final WebTestClient.ResponseSpec responseSpec;
039
040
041        StatusAssertions(ExchangeResult result, WebTestClient.ResponseSpec spec) {
042                this.exchangeResult = result;
043                this.responseSpec = spec;
044        }
045
046
047        /**
048         * Assert the response status as an {@link HttpStatus}.
049         */
050        public WebTestClient.ResponseSpec isEqualTo(HttpStatus status) {
051                return isEqualTo(status.value());
052        }
053
054        /**
055         * Assert the response status as an integer.
056         */
057        public WebTestClient.ResponseSpec isEqualTo(int status) {
058                int actual = this.exchangeResult.getRawStatusCode();
059                this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.assertEquals("Status", status, actual));
060                return this.responseSpec;
061        }
062
063        /**
064         * Assert the response status code is {@code HttpStatus.OK} (200).
065         */
066        public WebTestClient.ResponseSpec isOk() {
067                return assertStatusAndReturn(HttpStatus.OK);
068        }
069
070        /**
071         * Assert the response status code is {@code HttpStatus.CREATED} (201).
072         */
073        public WebTestClient.ResponseSpec isCreated() {
074                HttpStatus expected = HttpStatus.CREATED;
075                return assertStatusAndReturn(expected);
076        }
077
078        /**
079         * Assert the response status code is {@code HttpStatus.ACCEPTED} (202).
080         */
081        public WebTestClient.ResponseSpec isAccepted() {
082                return assertStatusAndReturn(HttpStatus.ACCEPTED);
083        }
084
085        /**
086         * Assert the response status code is {@code HttpStatus.NO_CONTENT} (204).
087         */
088        public WebTestClient.ResponseSpec isNoContent() {
089                return assertStatusAndReturn(HttpStatus.NO_CONTENT);
090        }
091
092        /**
093         * Assert the response status code is {@code HttpStatus.FOUND} (302).
094         */
095        public WebTestClient.ResponseSpec isFound() {
096                return assertStatusAndReturn(HttpStatus.FOUND);
097        }
098
099        /**
100         * Assert the response status code is {@code HttpStatus.SEE_OTHER} (303).
101         */
102        public WebTestClient.ResponseSpec isSeeOther() {
103                return assertStatusAndReturn(HttpStatus.SEE_OTHER);
104        }
105
106        /**
107         * Assert the response status code is {@code HttpStatus.NOT_MODIFIED} (304).
108         */
109        public WebTestClient.ResponseSpec isNotModified() {
110                return assertStatusAndReturn(HttpStatus.NOT_MODIFIED);
111        }
112
113        /**
114         * Assert the response status code is {@code HttpStatus.TEMPORARY_REDIRECT} (307).
115         */
116        public WebTestClient.ResponseSpec isTemporaryRedirect() {
117                return assertStatusAndReturn(HttpStatus.TEMPORARY_REDIRECT);
118        }
119
120        /**
121         * Assert the response status code is {@code HttpStatus.PERMANENT_REDIRECT} (308).
122         */
123        public WebTestClient.ResponseSpec isPermanentRedirect() {
124                return assertStatusAndReturn(HttpStatus.PERMANENT_REDIRECT);
125        }
126
127        /**
128         * Assert the response status code is {@code HttpStatus.BAD_REQUEST} (400).
129         */
130        public WebTestClient.ResponseSpec isBadRequest() {
131                return assertStatusAndReturn(HttpStatus.BAD_REQUEST);
132        }
133
134        /**
135         * Assert the response status code is {@code HttpStatus.UNAUTHORIZED} (401).
136         */
137        public WebTestClient.ResponseSpec isUnauthorized() {
138                return assertStatusAndReturn(HttpStatus.UNAUTHORIZED);
139        }
140
141        /**
142         * Assert the response status code is {@code HttpStatus.FORBIDDEN} (403).
143         * @since 5.0.2
144         */
145        public WebTestClient.ResponseSpec isForbidden() {
146                return assertStatusAndReturn(HttpStatus.FORBIDDEN);
147        }
148
149        /**
150         * Assert the response status code is {@code HttpStatus.NOT_FOUND} (404).
151         */
152        public WebTestClient.ResponseSpec isNotFound() {
153                return assertStatusAndReturn(HttpStatus.NOT_FOUND);
154        }
155
156        /**
157         * Assert the response error message.
158         */
159        public WebTestClient.ResponseSpec reasonEquals(String reason) {
160                String actual = this.exchangeResult.getStatus().getReasonPhrase();
161                String message = "Response status reason";
162                this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.assertEquals(message, reason, actual));
163                return this.responseSpec;
164        }
165
166        /**
167         * Assert the response status code is in the 1xx range.
168         */
169        public WebTestClient.ResponseSpec is1xxInformational() {
170                return assertSeriesAndReturn(HttpStatus.Series.INFORMATIONAL);
171        }
172
173        /**
174         * Assert the response status code is in the 2xx range.
175         */
176        public WebTestClient.ResponseSpec is2xxSuccessful() {
177                return assertSeriesAndReturn(HttpStatus.Series.SUCCESSFUL);
178        }
179
180        /**
181         * Assert the response status code is in the 3xx range.
182         */
183        public WebTestClient.ResponseSpec is3xxRedirection() {
184                return assertSeriesAndReturn(HttpStatus.Series.REDIRECTION);
185        }
186
187        /**
188         * Assert the response status code is in the 4xx range.
189         */
190        public WebTestClient.ResponseSpec is4xxClientError() {
191                return assertSeriesAndReturn(HttpStatus.Series.CLIENT_ERROR);
192        }
193
194        /**
195         * Assert the response status code is in the 5xx range.
196         */
197        public WebTestClient.ResponseSpec is5xxServerError() {
198                HttpStatus.Series expected = HttpStatus.Series.SERVER_ERROR;
199                return assertSeriesAndReturn(expected);
200        }
201
202        /**
203         * Match the response status value with a Hamcrest matcher.
204         * @param matcher the matcher to use
205         * @since 5.1
206         */
207        public WebTestClient.ResponseSpec value(Matcher<Integer> matcher) {
208                int value = this.exchangeResult.getStatus().value();
209                this.exchangeResult.assertWithDiagnostics(() -> MatcherAssert.assertThat("Response status", value, matcher));
210                return this.responseSpec;
211        }
212
213        /**
214         * Consume the response status value as an integer.
215         * @param consumer the consumer to use
216         * @since 5.1
217         */
218        public WebTestClient.ResponseSpec value(Consumer<Integer> consumer) {
219                int value = this.exchangeResult.getStatus().value();
220                this.exchangeResult.assertWithDiagnostics(() -> consumer.accept(value));
221                return this.responseSpec;
222        }
223
224
225        private WebTestClient.ResponseSpec assertStatusAndReturn(HttpStatus expected) {
226                HttpStatus actual = this.exchangeResult.getStatus();
227                this.exchangeResult.assertWithDiagnostics(() -> AssertionErrors.assertEquals("Status", expected, actual));
228                return this.responseSpec;
229        }
230
231        private WebTestClient.ResponseSpec assertSeriesAndReturn(HttpStatus.Series expected) {
232                HttpStatus status = this.exchangeResult.getStatus();
233                this.exchangeResult.assertWithDiagnostics(() -> {
234                        String message = "Range for response status value " + status;
235                        AssertionErrors.assertEquals(message, expected, status.series());
236                });
237                return this.responseSpec;
238        }
239
240}