1 /*
2 * Copyright 2005-2012 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.springframework.ws.test.server;
18
19 import java.io.IOException;
20 import java.util.Locale;
21 import java.util.Map;
22 import javax.xml.namespace.QName;
23 import javax.xml.transform.Source;
24
25 import org.springframework.core.io.Resource;
26 import org.springframework.util.Assert;
27 import org.springframework.ws.FaultAwareWebServiceMessage;
28 import org.springframework.ws.WebServiceMessage;
29 import org.springframework.ws.soap.SoapVersion;
30 import org.springframework.ws.test.support.matcher.PayloadDiffMatcher;
31 import org.springframework.ws.test.support.matcher.SchemaValidatingMatcher;
32 import org.springframework.ws.test.support.matcher.SoapEnvelopeDiffMatcher;
33 import org.springframework.ws.test.support.matcher.SoapHeaderMatcher;
34 import org.springframework.xml.transform.ResourceSource;
35
36 import static org.springframework.ws.test.support.AssertionErrors.fail;
37
38 /**
39 * Factory methods for {@link ResponseMatcher} classes. Typically used to provide input for {@link
40 * ResponseActions#andExpect(ResponseMatcher)}.
41 *
42 * @author Arjen Poutsma
43 * @since 2.0
44 */
45 public abstract class ResponseMatchers {
46
47 private ResponseMatchers() {
48 }
49
50 // Payload
51
52 /**
53 * Expects the given {@link Source} XML payload.
54 *
55 * @param payload the XML payload
56 * @return the response matcher
57 */
58 public static ResponseMatcher payload(Source payload) {
59 return new WebServiceMessageMatcherAdapter(new PayloadDiffMatcher(payload));
60 }
61
62 /**
63 * Expects the given {@link Resource} XML payload.
64 *
65 * @param payload the XML payload
66 * @return the response matcher
67 */
68 public static ResponseMatcher payload(Resource payload) throws IOException {
69 return payload(new ResourceSource(payload));
70 }
71
72 /**
73 * Expects the payload to validate against the given XSD schema(s).
74 *
75 * @param schema the schema
76 * @param furtherSchemas further schemas, if necessary
77 * @return the response matcher
78 */
79 public static ResponseMatcher validPayload(Resource schema, Resource... furtherSchemas) throws IOException {
80 return new WebServiceMessageMatcherAdapter(new SchemaValidatingMatcher(schema, furtherSchemas));
81 }
82
83 /**
84 * Expects the given XPath expression to (not) exist or be evaluated to a value.
85 *
86 * @param xpathExpression the XPath expression
87 * @return the XPath expectations, to be further configured
88 */
89 public static ResponseXPathExpectations xpath(String xpathExpression) {
90 return new XPathExpectationsHelperAdapter(xpathExpression, null);
91 }
92
93 /**
94 * Expects the given XPath expression to (not) exist or be evaluated to a value.
95 *
96 * @param xpathExpression the XPath expression
97 * @param namespaceMapping the namespaces
98 * @return the XPath expectations, to be further configured
99 */
100 public static ResponseXPathExpectations xpath(String xpathExpression, Map<String, String> namespaceMapping) {
101 return new XPathExpectationsHelperAdapter(xpathExpression, namespaceMapping);
102 }
103
104 // SOAP
105
106 /**
107 * Expects the given {@link Source} XML SOAP envelope.
108 *
109 * @param soapEnvelope the XML SOAP envelope
110 * @return the response matcher
111 * @since 2.1.1
112 */
113 public static ResponseMatcher soapEnvelope(Source soapEnvelope) {
114 return new WebServiceMessageMatcherAdapter(new SoapEnvelopeDiffMatcher(soapEnvelope));
115 }
116
117 /**
118 * Expects the given {@link Resource} XML SOAP envelope.
119 *
120 * @param soapEnvelope the XML SOAP envelope
121 * @return the response matcher
122 * @since 2.1.1
123 */
124 public static ResponseMatcher soapEnvelope(Resource soapEnvelope) throws IOException {
125 return soapEnvelope(new ResourceSource(soapEnvelope));
126 }
127
128 /**
129 * Expects the given SOAP header in the outgoing message.
130 *
131 * @param soapHeaderName the qualified name of the SOAP header to expect
132 * @return the request matcher
133 */
134 public static ResponseMatcher soapHeader(QName soapHeaderName) {
135 Assert.notNull(soapHeaderName, "'soapHeaderName' must not be null");
136 return new WebServiceMessageMatcherAdapter(new SoapHeaderMatcher(soapHeaderName));
137 }
138
139 /**
140 * Expects the response <strong>not</strong> to contain a SOAP fault.
141 *
142 * @return the response matcher
143 */
144 public static ResponseMatcher noFault() {
145 return new ResponseMatcher() {
146 public void match(WebServiceMessage request, WebServiceMessage response)
147 throws IOException, AssertionError {
148 if (response instanceof FaultAwareWebServiceMessage) {
149 FaultAwareWebServiceMessage faultMessage = (FaultAwareWebServiceMessage) response;
150 if (faultMessage.hasFault()) {
151 fail("Response has a SOAP Fault: \"" + faultMessage.getFaultReason() + "\"");
152 }
153 }
154 }
155
156 };
157 }
158
159 /**
160 * Expects a {@code MustUnderstand} fault.
161 *
162 * @see org.springframework.ws.soap.SoapBody#addMustUnderstandFault(String, Locale)
163 */
164 public static ResponseMatcher mustUnderstandFault() {
165 return mustUnderstandFault(null);
166 }
167
168 /**
169 * Expects a {@code MustUnderstand} fault with a particular fault string or reason.
170 *
171 * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
172 * reason text will not be verified
173 * @see org.springframework.ws.soap.SoapBody#addMustUnderstandFault(String, Locale)
174 */
175 public static ResponseMatcher mustUnderstandFault(String faultStringOrReason) {
176 return new SoapFaultResponseMatcher(faultStringOrReason) {
177 @Override
178 protected QName getExpectedFaultCode(SoapVersion version) {
179 return version.getMustUnderstandFaultName();
180 }
181 };
182 }
183
184 /**
185 * Expects a {@code Client} (SOAP 1.1) or {@code Sender} (SOAP 1.2) fault.
186 *
187 * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
188 */
189 public static ResponseMatcher clientOrSenderFault() {
190 return clientOrSenderFault(null);
191 }
192
193 /**
194 * Expects a {@code Client} (SOAP 1.1) or {@code Sender} (SOAP 1.2) fault with a particular fault string or reason.
195 *
196 * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
197 * reason text will not be verified
198 * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
199 */
200 public static ResponseMatcher clientOrSenderFault(String faultStringOrReason) {
201 return new SoapFaultResponseMatcher(faultStringOrReason) {
202 @Override
203 protected QName getExpectedFaultCode(SoapVersion version) {
204 return version.getClientOrSenderFaultName();
205 }
206 };
207 }
208
209 /**
210 * Expects a {@code Server} (SOAP 1.1) or {@code Receiver} (SOAP 1.2) fault.
211 *
212 * @see org.springframework.ws.soap.SoapBody#addServerOrReceiverFault(String, java.util.Locale)
213 */
214 public static ResponseMatcher serverOrReceiverFault() {
215 return serverOrReceiverFault(null);
216 }
217
218 /**
219 * Expects a {@code Server} (SOAP 1.1) or {@code Receiver} (SOAP 1.2) fault with a particular fault string or reason.
220 *
221 * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
222 * reason text will not be verified
223 * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
224 */
225 public static ResponseMatcher serverOrReceiverFault(String faultStringOrReason) {
226 return new SoapFaultResponseMatcher(faultStringOrReason) {
227 @Override
228 protected QName getExpectedFaultCode(SoapVersion version) {
229 return version.getServerOrReceiverFaultName();
230 }
231 };
232 }
233
234 /**
235 * Expects a {@code VersionMismatch} fault.
236 *
237 * @see org.springframework.ws.soap.SoapBody#addVersionMismatchFault(String, java.util.Locale)
238 */
239 public static ResponseMatcher versionMismatchFault() {
240 return versionMismatchFault(null);
241 }
242
243 /**
244 * Expects a {@code VersionMismatch} fault with a particular fault string or reason.
245 *
246 * @param faultStringOrReason the SOAP 1.1 fault string or SOAP 1.2 reason text. If {@code null} the fault string or
247 * reason text will not be verified
248 * @see org.springframework.ws.soap.SoapBody#addClientOrSenderFault(String, Locale)
249 */
250 public static ResponseMatcher versionMismatchFault(String faultStringOrReason) {
251 return new SoapFaultResponseMatcher(faultStringOrReason) {
252 @Override
253 protected QName getExpectedFaultCode(SoapVersion version) {
254 return version.getVersionMismatchFaultName();
255 }
256 };
257 }
258
259 }