nl.hsac.fitnesse.fixture.slim.HttpTest Maven / Gradle / Ivy
package nl.hsac.fitnesse.fixture.slim;
import freemarker.template.Template;
import nl.hsac.fitnesse.fixture.util.HttpResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Fixture to make HTTP requests using Slim scripts and/or scenarios.
*/
public class HttpTest extends SlimFixtureWithMap {
/** Default content type for posts and puts. */
public final static String DEFAULT_POST_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=UTF-8";
private final Map headerValues = new LinkedHashMap();
private HttpResponse response = createResponse();
private String template;
private String contentType = DEFAULT_POST_CONTENT_TYPE;
/**
* Sets template to use.
* @param aTemplate name of template file (relative to 'templates' directory on classpath)
* @return true if template could be found.
*/
public boolean template(String aTemplate) {
boolean result = false;
Template t = getEnvironment().getTemplate(aTemplate);
if (t != null) {
template = aTemplate;
result = true;
}
return result;
}
/**
* Stores value to be passed as headers.
* @param value value to be passed.
* @param name name to use this value for.
*/
public void setValueForHeader(Object value, String name) {
getMapHelper().setValueForIn(value, name, headerValues);
}
/**
* Clears a header value previously set.
* @param name value to remove.
* @return true if value was present.
*/
public boolean clearHeaderValue(String name) {
String cleanName = cleanupValue(name);
boolean result = headerValues.containsKey(cleanName);
headerValues.remove(cleanName);
return result;
}
/**
* Clears all header values previously set.
*/
public void clearHeaderValues() {
headerValues.clear();
}
//// methods to support usage in dynamic decision tables
/**
* Called before next row is executed. (Clears all current and header values.)
*/
@Override
public void reset() {
clearValues();
clearHeaderValues();
}
private static final Pattern HEADER_KEY_PATTERN = Pattern.compile("header:\\s*(\\.+)");
/**
* Sets a value.
* @param key (possibly nested) key to set value for.
* @param value value to be stored.
*/
public void set(String key, Object value) {
Matcher m = HEADER_KEY_PATTERN.matcher(key);
if (m.matches()) {
String headerKey = m.group(1);
setValueForHeader(value, headerKey);
} else {
super.set(key, value);
}
}
//// end: methods to support usage in dynamic decision tables
/**
* Sends HTTP POST template with current values to service endpoint.
* @param serviceUrl service endpoint to send request to.
* @return true if call could be made and response did not indicate error.
*/
public boolean postTemplateTo(String serviceUrl) {
boolean result;
resetResponse();
if (template == null) {
throw new StopTestException("No template available to use in post");
} else {
String url = getUrl(serviceUrl);
try {
getEnvironment().doHttpPost(url, template, getCurrentValues(), response, headerValues, getContentType());
} catch (Throwable t) {
throw new StopTestException("Unable to get response from POST to: " + url, t);
}
result = postProcessResponse();
}
return result;
}
/**
* Sends HTTP POST body to service endpoint.
* @param body content to post
* @param serviceUrl service endpoint to send body to.
* @return true if call could be made and response did not indicate error.
*/
public boolean postTo(String body, String serviceUrl) {
String cleanedBody = cleanupBody(body);
return postToImpl(cleanedBody, serviceUrl);
}
/**
* Sends all values (url encoded) using post.
* @param serviceUrl service endpoint to send values to.
* @return true if call could be made and response did not indicate error.
*/
public boolean postValuesTo(String serviceUrl) {
String body = urlEncodeCurrentValues();
return postToImpl(body, serviceUrl);
}
protected boolean postToImpl(String body, String serviceUrl) {
boolean result;
resetResponse();
response.setRequest(body);
String url = getUrl(serviceUrl);
try {
getEnvironment().doHttpPost(url, response, headerValues, getContentType());
} catch (Throwable t) {
throw new StopTestException("Unable to get response from POST to: " + url, t);
}
result = postProcessResponse();
return result;
}
/**
* Sends HTTP PUT template with current values to service endpoint.
* @param serviceUrl service endpoint to send request to.
* @return true if call could be made and response did not indicate error.
*/
public boolean putTemplateTo(String serviceUrl) {
boolean result;
resetResponse();
if (template == null) {
throw new StopTestException("No template available to use in put");
} else {
String url = getUrl(serviceUrl);
try {
getEnvironment().doHttpPut(url, template, getCurrentValues(), response, headerValues, getContentType());
} catch (Throwable t) {
throw new StopTestException("Unable to get response from PUT to: " + url, t);
}
result = postProcessResponse();
}
return result;
}
/**
* Sends HTTP PUT body to service endpoint.
* @param body content to put
* @param serviceUrl service endpoint to send body to.
* @return true if call could be made and response did not indicate error.
*/
public boolean putTo(String body, String serviceUrl) {
String cleanedBody = cleanupBody(body);
return putToImpl(cleanedBody, serviceUrl);
}
/**
* Sends all values (url encoded) using put.
* @param serviceUrl service endpoint to send values to.
* @return true if call could be made and response did not indicate error.
*/
public boolean putValuesTo(String serviceUrl) {
String body = urlEncodeCurrentValues();
return putToImpl(body, serviceUrl);
}
protected boolean putToImpl(String body, String serviceUrl) {
boolean result;
resetResponse();
response.setRequest(body);
String url = getUrl(serviceUrl);
try {
getEnvironment().doHttpPut(url, response, headerValues, getContentType());
} catch (Throwable t) {
throw new StopTestException("Unable to get response from PUT to: " + url, t);
}
result = postProcessResponse();
return result;
}
protected String cleanupBody(String body) {
return getEnvironment().getHtmlCleaner().cleanupPreFormatted(body);
}
/**
* Sends HTTP GET to service endpoint to retrieve content.
* @param serviceUrl service endpoint to get content from.
* @return true if call could be made and response did not indicate error.
*/
public boolean getFrom(String serviceUrl) {
boolean result;
resetResponse();
String url = createUrlWithParams(serviceUrl);
try {
getEnvironment().doGet(url, response, headerValues);
} catch (Throwable t) {
throw new StopTestException("Unable to GET response from: " + url, t);
}
result = postProcessResponse();
return result;
}
/**
* Sends HTTP DELETE to service endpoint.
* @param serviceUrl service endpoint to delete.
* @return true if call could be made and response did not indicate error.
*/
public boolean delete(String serviceUrl) {
boolean result;
resetResponse();
String url = createUrlWithParams(serviceUrl);
try {
getEnvironment().doDelete(url, response, headerValues);
} catch (Throwable t) {
throw new StopTestException("Unable to DELETE: " + url, t);
}
result = postProcessResponse();
return result;
}
protected void resetResponse() {
response = createResponse();
}
String createUrlWithParams(String serviceUrl) {
String baseUrl = getUrl(serviceUrl);
if (!getCurrentValues().isEmpty()) {
if (baseUrl.contains("?") && !baseUrl.endsWith("?")) {
baseUrl += "&";
}
if (!baseUrl.contains("?")) {
baseUrl += "?";
}
baseUrl += urlEncodeCurrentValues();
}
return baseUrl;
}
protected String urlEncodeCurrentValues() {
boolean isFirst = true;
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : getCurrentValues().entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof List) {
List values = (List) value;
for (Object v : values) {
addEncodedKeyValue(sb, isFirst, key, v);
isFirst = false;
}
} else {
addEncodedKeyValue(sb, isFirst, key, value);
isFirst = false;
}
}
return sb.toString();
}
private boolean addEncodedKeyValue(StringBuilder sb, boolean isFirst, String key, Object value) {
if (!isFirst) {
sb.append("&");
}
sb.append(urlEncode(key));
if (value != null) {
sb.append("=");
sb.append(urlEncode(value.toString()));
}
return isFirst;
}
protected String urlEncode(String str) {
try {
return URLEncoder.encode(str, "utf-8");
} catch (UnsupportedEncodingException e) {
throw new Error(e);
}
}
/**
* Performs any post processing directly after retrieving response.
* @return true if all is well, false otherwise.
*/
protected boolean postProcessResponse() {
return responseIsValid();
}
/**
* @return true if response does not indicate an error.
*/
public boolean responseIsValid() {
boolean result;
try {
response.validResponse();
result = true;
} catch (RuntimeException e) {
result = false;
}
return result;
}
/**
* @return request sent last time.
*/
public String request() {
return safeFormatValue(response.getRequest());
}
/**
* @return response received last time postTo(), delete() or getFrom() was called.
*/
public String response() {
return safeFormatValue(response.getResponse());
}
/**
* Internal method to format a value, which will just return the 'raw' value if there is a problem formatting.
* @param value value to format
* @return formatted value
*/
protected final String safeFormatValue(String value) {
String result;
try {
result = formatValue(value);
} catch (Exception e) {
result = value;
}
return result;
}
/**
* Method that will take care of formatting a value, which may be overridden in subclasses.
* This implementation just returns value.
* @param value value to format
* @return formatted value
*/
protected String formatValue(String value) {
return value;
}
/**
* @return HTML response received last time postTo() or get() was called.
*/
public String htmlResponse() {
String content = response.getResponse();
content = "" + content + "";
return content;
}
/**
* @return http status received in response to last request.
*/
public int responseStatus() {
return response.getStatusCode();
}
/**
* @return headers received with response to last request.
*/
public Map responseHeaders() {
return response.getResponseHeaders();
}
/**
* @param headerName name of response header.
* @return value of header in last response.
*/
public String responseHeader(String headerName) {
return responseHeaders().get(headerName);
}
protected HttpResponse getResponse() {
return response;
}
protected HttpResponse createResponse() {
return new HttpResponse();
}
public String getContentType() {
return contentType;
}
public void setContentType(String aContentType) {
contentType = aContentType;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy