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 java.util.concurrent.Callable; 020 021import javax.servlet.http.HttpServletRequest; 022import javax.servlet.http.HttpSession; 023 024import org.hamcrest.Matcher; 025 026import org.springframework.mock.web.MockHttpServletRequest; 027import org.springframework.test.web.servlet.ResultMatcher; 028import org.springframework.util.Assert; 029import org.springframework.web.context.request.async.DeferredResult; 030import org.springframework.web.context.request.async.WebAsyncTask; 031 032import static org.hamcrest.MatcherAssert.assertThat; 033import static org.springframework.test.util.AssertionErrors.assertEquals; 034import static org.springframework.test.util.AssertionErrors.assertFalse; 035import static org.springframework.test.util.AssertionErrors.assertNull; 036import static org.springframework.test.util.AssertionErrors.assertTrue; 037 038/** 039 * Factory for assertions on the request. 040 * 041 * <p>An instance of this class is typically accessed via 042 * {@link MockMvcResultMatchers#request}. 043 * 044 * @author Rossen Stoyanchev 045 * @author Sam Brannen 046 * @since 3.2 047 */ 048public class RequestResultMatchers { 049 050 /** 051 * Protected constructor. 052 * <p>Use {@link MockMvcResultMatchers#request()}. 053 */ 054 protected RequestResultMatchers() { 055 } 056 057 058 /** 059 * Assert whether asynchronous processing started, usually as a result of a 060 * controller method returning {@link Callable} or {@link DeferredResult}. 061 * <p>The test will await the completion of a {@code Callable} so that 062 * {@link #asyncResult(Matcher)} or {@link #asyncResult(Object)} can be used 063 * to assert the resulting value. 064 * <p>Neither a {@code Callable} nor a {@code DeferredResult} will complete 065 * processing all the way since a {@link MockHttpServletRequest} does not 066 * perform asynchronous dispatches. 067 * @see #asyncNotStarted() 068 */ 069 public ResultMatcher asyncStarted() { 070 return result -> assertAsyncStarted(result.getRequest()); 071 } 072 073 /** 074 * Assert that asynchronous processing was not started. 075 * @see #asyncStarted() 076 */ 077 public ResultMatcher asyncNotStarted() { 078 return result -> assertFalse("Async started", result.getRequest().isAsyncStarted()); 079 } 080 081 /** 082 * Assert the result from asynchronous processing with the given matcher. 083 * <p>This method can be used when a controller method returns {@link Callable} 084 * or {@link WebAsyncTask}. 085 */ 086 @SuppressWarnings("unchecked") 087 public <T> ResultMatcher asyncResult(Matcher<T> matcher) { 088 return result -> { 089 HttpServletRequest request = result.getRequest(); 090 assertAsyncStarted(request); 091 assertThat("Async result", (T) result.getAsyncResult(), matcher); 092 }; 093 } 094 095 /** 096 * Assert the result from asynchronous processing. 097 * <p>This method can be used when a controller method returns {@link Callable} 098 * or {@link WebAsyncTask}. The value matched is the value returned from the 099 * {@code Callable} or the exception raised. 100 */ 101 public ResultMatcher asyncResult(Object expectedResult) { 102 return result -> { 103 HttpServletRequest request = result.getRequest(); 104 assertAsyncStarted(request); 105 assertEquals("Async result", expectedResult, result.getAsyncResult()); 106 }; 107 } 108 109 /** 110 * Assert a request attribute value with the given Hamcrest {@link Matcher}. 111 */ 112 @SuppressWarnings("unchecked") 113 public <T> ResultMatcher attribute(String name, Matcher<T> matcher) { 114 return result -> { 115 T value = (T) result.getRequest().getAttribute(name); 116 assertThat("Request attribute '" + name + "'", value, matcher); 117 }; 118 } 119 120 /** 121 * Assert a request attribute value. 122 */ 123 public ResultMatcher attribute(String name, Object expectedValue) { 124 return result -> 125 assertEquals("Request attribute '" + name + "'", expectedValue, result.getRequest().getAttribute(name)); 126 } 127 128 /** 129 * Assert a session attribute value with the given Hamcrest {@link Matcher}. 130 */ 131 @SuppressWarnings("unchecked") 132 public <T> ResultMatcher sessionAttribute(String name, Matcher<T> matcher) { 133 return result -> { 134 HttpSession session = result.getRequest().getSession(); 135 Assert.state(session != null, "No HttpSession"); 136 T value = (T) session.getAttribute(name); 137 assertThat("Session attribute '" + name + "'", value, matcher); 138 }; 139 } 140 141 /** 142 * Assert a session attribute value. 143 */ 144 public ResultMatcher sessionAttribute(String name, Object value) { 145 return result -> { 146 HttpSession session = result.getRequest().getSession(); 147 Assert.state(session != null, "No HttpSession"); 148 assertEquals("Session attribute '" + name + "'", value, session.getAttribute(name)); 149 }; 150 } 151 152 /** 153 * Assert the given session attributes do not exist. 154 * @since 5.2.1 155 */ 156 public ResultMatcher sessionAttributeDoesNotExist(String... names) { 157 return result -> { 158 HttpSession session = result.getRequest().getSession(); 159 Assert.state(session != null, "No HttpSession"); 160 for (String name : names) { 161 assertNull("Session attribute '" + name + "' exists", session.getAttribute(name)); 162 } 163 }; 164 } 165 166 private static void assertAsyncStarted(HttpServletRequest request) { 167 assertTrue("Async not started", request.isAsyncStarted()); 168 } 169 170}