001: /*
002: * Copyright (c) 2002-2008 Gargoyle Software Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: * 2. Redistributions in binary form must reproduce the above copyright notice,
010: * this list of conditions and the following disclaimer in the documentation
011: * and/or other materials provided with the distribution.
012: * 3. The end-user documentation included with the redistribution, if any, must
013: * include the following acknowledgment:
014: *
015: * "This product includes software developed by Gargoyle Software Inc.
016: * (http://www.GargoyleSoftware.com/)."
017: *
018: * Alternately, this acknowledgment may appear in the software itself, if
019: * and wherever such third-party acknowledgments normally appear.
020: * 4. The name "Gargoyle Software" must not be used to endorse or promote
021: * products derived from this software without prior written permission.
022: * For written permission, please contact info@GargoyleSoftware.com.
023: * 5. Products derived from this software may not be called "HtmlUnit", nor may
024: * "HtmlUnit" appear in their name, without prior written permission of
025: * Gargoyle Software Inc.
026: *
027: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
028: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
029: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
030: * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
031: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
032: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
033: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
034: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
035: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
036: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
037: */
038: package com.gargoylesoftware.htmlunit;
039:
040: import java.io.IOException;
041: import java.net.URL;
042: import java.util.ArrayList;
043: import java.util.Collections;
044: import java.util.HashMap;
045: import java.util.List;
046: import java.util.Map;
047:
048: import org.apache.commons.httpclient.HttpState;
049: import org.apache.commons.httpclient.NameValuePair;
050: import org.apache.commons.logging.Log;
051: import org.apache.commons.logging.LogFactory;
052:
053: /**
054: * A fake WebConnection designed to mock out the actual http connections.
055: *
056: * @version $Revision: 2132 $
057: * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
058: * @author Noboru Sinohara
059: * @author Marc Guillemot
060: * @author Brad Clarke
061: * @author Ahmed Ashour
062: */
063: public class MockWebConnection extends WebConnectionImpl {
064: private final Map responseMap_ = new HashMap(10);
065: private WebResponseData defaultResponse_;
066:
067: private WebRequestSettings lastRequest_;
068: private HttpState httpState_ = new HttpState();
069:
070: /**
071: * Create an instance
072: *
073: * @param webClient The web client
074: */
075: public MockWebConnection(final WebClient webClient) {
076: super (webClient);
077: }
078:
079: /**
080: * Return the log that is being used for all scripting objects
081: * @return The log.
082: */
083: protected final Log getLog() {
084: return LogFactory.getLog(getClass());
085: }
086:
087: /**
088: * Submit a request and retrieve a response
089: *
090: * @param webRequestSettings Settings to make the request with
091: * @return See above
092: * @throws IOException (only for extending classes)
093: */
094: public WebResponse getResponse(
095: final WebRequestSettings webRequestSettings)
096: throws IOException {
097: final URL url = webRequestSettings.getURL();
098:
099: getLog().debug("Getting response for " + url.toExternalForm());
100:
101: lastRequest_ = webRequestSettings;
102:
103: WebResponseData response = (WebResponseData) responseMap_
104: .get(url.toExternalForm());
105: if (response == null) {
106: response = defaultResponse_;
107: if (response == null) {
108: throw new IllegalStateException(
109: "No response specified that can handle url ["
110: + url.toExternalForm() + "]");
111: }
112: }
113:
114: return new WebResponseImpl(response, webRequestSettings
115: .getCharset(), webRequestSettings.getURL(),
116: webRequestSettings.getSubmitMethod(), 0);
117: }
118:
119: /**
120: * Return the method that was used in the last call to submitRequest()
121: *
122: * @return See above
123: */
124: public SubmitMethod getLastMethod() {
125: return lastRequest_.getSubmitMethod();
126: }
127:
128: /**
129: * Return the parameters that were used in the last call to submitRequest()
130: *
131: * @return See above
132: */
133: public List getLastParameters() {
134: return lastRequest_.getRequestParameters();
135: }
136:
137: /**
138: * Set the response that will be returned when the specified url is requested.
139: * @param url The url that will return the given response
140: * @param content The content to return
141: * @param statusCode The status code to return
142: * @param statusMessage The status message to return
143: * @param contentType The content type to return
144: * @param responseHeaders A list of {@link KeyValuePair}s that will be returned as
145: * response headers.
146: */
147: public void setResponse(final URL url, final String content,
148: final int statusCode, final String statusMessage,
149: final String contentType, final List responseHeaders) {
150:
151: setResponse(url, TextUtil.stringToByteArray(content),
152: statusCode, statusMessage, contentType, responseHeaders);
153: }
154:
155: /**
156: * Set the response that will be returned when the specified url is requested.
157: * @param url The url that will return the given response
158: * @param content The content to return
159: * @param statusCode The status code to return
160: * @param statusMessage The status message to return
161: * @param contentType The content type to return
162: * @param responseHeaders A list of {@link KeyValuePair}s that will be returned as
163: * response headers.
164: */
165: public void setResponse(final URL url, final byte[] content,
166: final int statusCode, final String statusMessage,
167: final String contentType, final List responseHeaders) {
168:
169: final List compiledHeaders = new ArrayList(responseHeaders);
170: compiledHeaders.add(new NameValuePair("Content-Type",
171: contentType));
172: final WebResponseData responseEntry = new WebResponseData(
173: content, statusCode, statusMessage, compiledHeaders);
174: responseMap_.put(url.toExternalForm(), responseEntry);
175: }
176:
177: /**
178: * Convenience method that is the same as calling
179: * {@link #setResponse(URL,String,int,String,String,List)} with a status
180: * of "200 OK", a content type of "text/html" and no additional headers.
181: *
182: * @param url The url that will return the given response
183: * @param content The content to return
184: */
185: public void setResponse(final URL url, final String content) {
186: setResponse(url, content, 200, "OK", "text/html",
187: Collections.EMPTY_LIST);
188: }
189:
190: /**
191: * Convenience method that is the same as calling
192: * {@link #setResponse(URL,String,int,String,String,List)} with a status
193: * of "200 OK" and no additional headers.
194: *
195: * @param url The url that will return the given response
196: * @param content The content to return
197: * @param contentType The content type to return
198: */
199: public void setResponse(final URL url, final String content,
200: final String contentType) {
201: setResponse(url, content, 200, "OK", contentType,
202: Collections.EMPTY_LIST);
203: }
204:
205: /**
206: * Specify a generic html page that will be returned when the given url is specified.
207: * The page will contain only minimal html to satisfy the html parser but will contain
208: * the specified title so that tests can check for titleText.
209: *
210: * @param url The url that will return the given response
211: * @param title The title of the page
212: */
213: public void setResponseAsGenericHtml(final URL url,
214: final String title) {
215: final String content = "<html><head><title>" + title
216: + "</title></head><body></body></html>";
217: setResponse(url, content);
218: }
219:
220: /**
221: * Set the response that will be returned when a url is requested that does
222: * not have a specific content set for it.
223: *
224: * @param content The content to return
225: * @param statusCode The status code to return
226: * @param statusMessage The status message to return
227: * @param contentType The content type to return
228: */
229: public void setDefaultResponse(final String content,
230: final int statusCode, final String statusMessage,
231: final String contentType) {
232:
233: setDefaultResponse(TextUtil.stringToByteArray(content),
234: statusCode, statusMessage, contentType);
235: }
236:
237: /**
238: * Set the response that will be returned when a url is requested that does
239: * not have a specific content set for it.
240: *
241: * @param content The content to return
242: * @param statusCode The status code to return
243: * @param statusMessage The status message to return
244: * @param contentType The content type to return
245: */
246: public void setDefaultResponse(final byte[] content,
247: final int statusCode, final String statusMessage,
248: final String contentType) {
249:
250: final List compiledHeaders = new ArrayList();
251: compiledHeaders.add(new NameValuePair("Content-Type",
252: contentType));
253: final WebResponseData responseEntry = new WebResponseData(
254: content, statusCode, statusMessage, compiledHeaders);
255: defaultResponse_ = responseEntry;
256: }
257:
258: /**
259: * Set the response that will be returned when a url is requested that does
260: * not have a specific content set for it.
261: *
262: * @param content The content to return
263: */
264: public void setDefaultResponse(final String content) {
265: setDefaultResponse(content, 200, "OK", "text/html");
266: }
267:
268: /**
269: * Return the {@link HttpState}
270: * @return The state.
271: */
272: public HttpState getState() {
273: return httpState_;
274: }
275:
276: /**
277: * Return the additional headers that were used in the in the last call
278: * to {@link #getResponse(WebRequestSettings)}.
279: * @return See above
280: */
281: public Map getLastAdditionalHeaders() {
282: return lastRequest_.getAdditionalHeaders();
283: }
284:
285: /**
286: * Return the {@link WebRequestSettings} that was used in the in the last call
287: * to {@link #getResponse(WebRequestSettings)}.
288: * @return See above
289: */
290: public WebRequestSettings getLastWebRequestSettings() {
291: return lastRequest_;
292: }
293: }
|