All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.hsac.fitnesse.fixture.slim.HttpTest Maven / Gradle / Ivy

There is a newer version: 5.3.17
Show newest version
package nl.hsac.fitnesse.fixture.slim;

import fit.exception.FitFailureException;
import freemarker.template.Template;
import nl.hsac.fitnesse.fixture.util.BinaryHttpResponse;
import nl.hsac.fitnesse.fixture.util.HttpResponse;
import nl.hsac.fitnesse.fixture.util.NonValidResponseReceivedException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.CookieStore;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.cookie.BasicClientCookie;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
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 String downloadBase = new File(filesDir, "downloads").getPath() + "/";
    private final Map headerValues = new LinkedHashMap<>();
    private boolean stopTestOnException = true;
    private boolean storeCookies = false;
    private HttpResponse response = createResponse();
    private String template;
    private boolean explicitContentTypeSet = false;
    private String contentType = DEFAULT_POST_CONTENT_TYPE;
    private String lastUrl = null;
    private String lastMethod = null;
    private boolean throwExceptionOnHttpRequestFailure = false;

    public void setThrowExceptionOnHttpRequestFailure(boolean throwException) {
        throwExceptionOnHttpRequestFailure = throwException;
    }

    public boolean getThrowExceptionOnHttpRequestFailure() {
        return throwExceptionOnHttpRequestFailure;
    }

    /**
     * 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;
    }

    /**
     * Enables content compression support in the current environment (i.e. for the entire test run)
     * @deprecated use {@link HttpClientSetup} to configure http client
     */
    @Deprecated
    public void enableCompression() {
        getEnvironment().enableHttpClientCompression();
    }

    /**
     * Disables content compression support in the current environment (i.e. for the entire test run)
     * @deprecated use {@link HttpClientSetup} to configure http client
     */
    @Deprecated
    public void disableCompression() {
        getEnvironment().disableHttpClientCompression();
    }

    /**
     * Disables SSL certificate verification in the current environment (i.e. for the entire test run)
     * @deprecated use {@link HttpClientSetup} to configure http client
     */
    @Deprecated
    public void disableSSLVerification() {
        getEnvironment().disableHttpClientSSLVerification();
    }

    /**
     * Enables SSL certificate verification in the current environment (i.e. for the entire test run)
     * @deprecated use {@link HttpClientSetup} to configure http client
     */
    @Deprecated
    public void enableSSLVerification() {
        getEnvironment().enableHttpClientSSLVerification();
    }

    /**
     * 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();
    }

    /**
     * Adds all values in the supplied map to the current header values.
     *
     * @param map to obtain values from.
     */
    public void copyHeaderValuesFrom(Map map) {
        getMapHelper().copyValuesFromTo(map, headerValues);
    }

    /**
     * Allows subclasses access to the header values.
     *
     * @return header values.
     */
    protected Map getHeaderValues() {
        return headerValues;
    }

    //// 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

    protected String createFileFromBase64(String baseName, String base64Content) {
        Base64Fixture base64Fixture = getBase64Fixture();
        return base64Fixture.createFrom(baseName, base64Content);
    }

    /**
     * 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) {
        return postTemplateTo(serviceUrl, getContentType());
    }

    /**
     * Sends HTTP POST template with current values to service endpoint.
     *
     * @param serviceUrl   service endpoint to send request to.
     * @param aContentType content type to use for post.
     * @return true if call could be made and response did not indicate error.
     */
    public boolean postTemplateTo(String serviceUrl, String aContentType) {
        return sendTemplateTo(serviceUrl, aContentType, "POST");
    }

    /**
     * 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 HTTP DELETE body to service endpoint.
     *
     * @param body       content to delete
     * @param serviceUrl service endpoint to send body to.
     * @return true if call could be made and response did not indicate error.
     */
    public boolean deleteWith(String serviceUrl, String body) {
        String cleanedBody = cleanupBody(body);
        return deleteToImpl(cleanedBody, serviceUrl);
    }

    /**
     * Sends a file by HTTP POST body to service endpoint.
     *
     * @param fileName   fileName 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 postFileTo(String fileName, String serviceUrl) {
        return postFileToImpl(fileName, serviceUrl);
    }

    /**
     * Sends a file by HTTP POST body to service endpoint with specific partname.
     *
     * @param fileName   fileName to post
     * @param partName   partName for file
     * @param serviceUrl service endpoint to send body to.
     * @return true if call could be made and response did not indicate error.
     */
    public boolean postFileAsTo(String fileName, String partName, String serviceUrl) {
        return postFileAsToImpl(partName, fileName, 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) {
        return sendToImpl(body, serviceUrl, getContentType(), "POST");
    }

    protected boolean deleteToImpl(String body, String serviceUrl) {
        return sendToImpl(body, serviceUrl, getContentType(), "DELETE");
    }

    protected boolean patchWithImpl(String body, String serviceUrl) {
        return sendToImpl(body, serviceUrl, getContentType(), "PATCH");
    }

    protected boolean sendToImpl(String body, String serviceUrl, String aContentType, String method) {
        boolean result;
        resetResponse();
        response.setRequest(body);
        String url = getUrl(serviceUrl);
        try {
            storeLastCall(method, serviceUrl);
            switch (method) {
                case "POST":
                    getEnvironment().doHttpPost(url, response, headerValues, aContentType);
                    break;
                case "PUT":
                    getEnvironment().doHttpPut(url, response, headerValues, aContentType);
                    break;
                case "DELETE":
                    getEnvironment().doDelete(url, response, headerValues, aContentType);
                    break;
                case "PATCH":
                    getEnvironment().doHttpPatch(url, response, headerValues, aContentType);
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported method: " + method);
            }
        } catch (Throwable t) {
            handleCallException("Unable to get response from " + method + " to: " + url, t);
        }
        result = postProcessResponse();
        return result;
    }

    protected boolean postFileToImpl(String fileName, String serviceUrl) {
        return postFileAsToImpl("file", fileName, serviceUrl);
    }

    protected boolean postFileAsToImpl(String partName, String fileName, String serviceUrl) {
        return sendFileImpl(partName, fileName, serviceUrl, "POST");
    }

    /**
     * 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) {
        return sendTemplateTo(serviceUrl, getContentType(), "PUT");
    }

    /**
     * Sends HTTP DELETE 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 deleteWithTemplate(String serviceUrl) {
        return sendTemplateTo(serviceUrl, getContentType(), "DELETE");
    }

    /**
     * Sends HTTP PATCH 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 patchWithTemplate(String serviceUrl) {
        return sendTemplateTo(serviceUrl, getContentType(), "PATCH");
    }

    /**
     * Sends HTTP method call template with current values to service endpoint.
     *
     * @param serviceUrl   service endpoint to send request to.
     * @param aContentType content type to use for post.
     * @param method       HTTP method to use
     * @return true if call could be made and response did not indicate error.
     */
    public boolean sendTemplateTo(String serviceUrl, String aContentType, String method) {
        boolean result;
        resetResponse();
        if (template == null) {
            throw new StopTestException("No template available to use in " + method);
        } else {
            String url = getUrl(serviceUrl);
            try {
                storeLastCall(method, serviceUrl);
                switch (method) {
                    case "POST":
                        getEnvironment().doHttpPost(url, template, getCurrentValues(), response, headerValues, aContentType);
                        break;
                    case "PUT":
                        getEnvironment().doHttpPut(url, template, getCurrentValues(), response, headerValues, aContentType);
                        break;
                    case "DELETE":
                        getEnvironment().doDelete(url, template, getCurrentValues(), response, headerValues, aContentType);
                        break;
                    case "PATCH":
                        getEnvironment().doHttpPatch(url, template, getCurrentValues(), response, headerValues, aContentType);
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported method: " + method);
                }
            } catch (Throwable t) {
                handleCallException("Unable to get response from " + method + " 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);
    }

    public boolean patchWith(String serviceUrl, String body) {
        String cleanedBody = cleanupBody(body);
        return patchWithImpl(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) {
        return sendToImpl(body, serviceUrl, getContentType(), "PUT");
    }

    /**
     * Sends a file by HTTP PUT body to service endpoint.
     *
     * @param fileName   fileName 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 putFileTo(String fileName, String serviceUrl) {
        return putFileToImpl(fileName, serviceUrl);
    }

    /**
     * Sends a file by HTTP PUT body to service endpoint.
     *
     * @param fileName   fileName to post
     * @param partName   partName for file
     * @param serviceUrl service endpoint to send body to.
     * @return true if call could be made and response did not indicate error.
     */
    public boolean putFileAsTo(String fileName, String partName, String serviceUrl) {
        return putFileAsToImpl(partName, fileName, serviceUrl);
    }

    protected boolean putFileToImpl(String fileName, String serviceUrl) {
        return putFileAsToImpl("file", fileName, serviceUrl);
    }

    protected boolean putFileAsToImpl(String partName, String fileName, String serviceUrl) {
        return sendFileImpl(partName, fileName, serviceUrl, "PUT");
    }

    protected boolean sendFileImpl(String partName, String fileName, String serviceUrl, String method) {
        boolean result;
        resetResponse();
        String url = getUrl(serviceUrl);

        String filePath = getFilePathFromWikiUrl(fileName);
        File file = new File(filePath);
        if (!file.exists()) {
            throw new StopTestException(false, "File " + filePath + " not found.");
        }

        try {
            response.setRequest(fileName);
            storeLastCall(method + "_FILE", serviceUrl);
            switch (method) {
                case "POST":
                    getEnvironment().doHttpFilePost(url, response, headerValues, partName, file);
                    break;
                case "PUT":
                    getEnvironment().doHttpFilePut(url, response, headerValues, partName, file);
                    break;
            }
        } catch (Throwable t) {
            handleCallException("Unable to get response from " + method + " 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) {
        return getImpl(serviceUrl, true);
    }

    /**
     * Sends HTTP GET to service endpoint to retrieve content, not following a redirect if sent.
     *
     * @param serviceUrl service endpoint to get content from.
     * @return true if call could be made and response did not indicate error.
     */
    public boolean getFromNoRedirect(String serviceUrl) {
        return getImpl(serviceUrl, false);
    }

    protected boolean getImpl(String serviceUrl, boolean followRedirect) {
        boolean result;
        resetResponse();
        String url = createUrlWithParams(serviceUrl);
        try {
            String method;
            if (followRedirect) {
                method = "GET";
            } else {
                method = "GET_NO_REDIRECT";
            }
            storeLastCall(method, serviceUrl);
            getEnvironment().doGet(url, response, headerValues, followRedirect);
        } catch (Throwable t) {
            handleCallException("Unable to GET response from: " + url, t);
        }
        result = postProcessResponse();
        return result;
    }

    /**
     * Downloads binary content from specified url.
     *
     * @param serviceUrl url to download from
     * @return link to downloaded file
     */
    public String getFileFrom(String serviceUrl) {
        resetResponse();

        BinaryHttpResponse resp = createBinaryResponse(response);
        String url = createUrlWithParams(serviceUrl);
        getEnvironment().doGet(url, resp, headerValues);
        return processBinaryResponse(resp);
    }

    /**
     * Downloads binary content from specified url.
     *
     * @param serviceUrl url to download from
     * @return link to downloaded file
     */
    public String postValuesAndGetFileFrom(String serviceUrl) {
        resetResponse();
        String body = urlEncodeCurrentValues();
        response.setRequest(body);

        BinaryHttpResponse resp = createBinaryResponse(response);
        String url = getUrl(serviceUrl);
        getEnvironment().doHttpPost(url, resp, headerValues, getContentType());
        return processBinaryResponse(resp);
    }

    protected BinaryHttpResponse createBinaryResponse(HttpResponse aResponse) {
        BinaryHttpResponse resp = new BinaryHttpResponse();
        resp.setCookieStore(aResponse.getCookieStore());
        resp.setRequest(aResponse.getRequest());
        return resp;
    }

    protected String processBinaryResponse(BinaryHttpResponse resp) {
        response.cloneValues(resp);

        byte[] content = resp.getResponseContent();
        if (content == null) {
            content = resp.getResponse().getBytes(StandardCharsets.UTF_8);
        }
        String fileName = resp.getFileName();
        if (StringUtils.isEmpty(fileName)) {
            fileName = "download";
        }
        return createFile(downloadBase, fileName, content);
    }

    /**
     * Sends HTTP HEAD to service endpoint.
     *
     * @param serviceUrl service endpoint to delete.
     * @return true if call could be made and response did not indicate error.
     */
    public boolean headFrom(String serviceUrl) {
        boolean result;
        resetResponse();
        String url = createUrlWithParams(serviceUrl);
        try {
            storeLastCall("HEAD", serviceUrl);
            getEnvironment().doHead(url, response, headerValues);
        } catch (Throwable t) {
            handleCallException("Unable to HEAD: " + 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 {
            storeLastCall("DELETE", serviceUrl);
            getEnvironment().doDelete(url, response, headerValues);
        } catch (Throwable t) {
            handleCallException("Unable to DELETE: " + url, t);
        }
        result = postProcessResponse();
        return result;
    }

    protected void handleCallException(String msg, Throwable t) {
        if (stopTestOnException()) {
            throw new StopTestException(msg, t);
        } else {
            logger.warn(msg);
            if (logger.isDebugEnabled()) {
                logger.debug(msg, t);
            }
        }
    }

    protected void resetResponse() {
        CookieStore cookieStore = null;
        if (storeCookies) {
            cookieStore = getResponse().getCookieStore();
            if (cookieStore == null) {
                cookieStore = new BasicCookieStore();
            }
        }
        response = createResponse();
        if (storeCookies) {
            response.setCookieStore(cookieStore);
        }
    }

    protected String createUrlWithParams(String serviceUrl) {
        String baseUrl = getUrl(serviceUrl);
        if (!getCurrentValues().isEmpty()) {
            if (baseUrl.contains("?") && !baseUrl.endsWith("?")) {
                baseUrl += "&";
            }
            if (!baseUrl.contains("?")) {
                baseUrl += "?";
            }
            baseUrl += urlEncodeCurrentValuesForQueryString();
        }
        return baseUrl;
    }

    protected String urlEncodeCurrentValuesForQueryString() {
        // in request BODY a '+' should be used for application/x-www-form-urlencoded
        // but in query string one should use '%20'
        return urlEncodeCurrentValues().replace("+", "%20");
    }

    protected String urlEncodeCurrentValues() {
        StringBuilder sb = new StringBuilder();
        addUrlEncodedKeyValues(sb, "", getCurrentValues());
        return sb.toString();
    }

    private void addUrlEncodedKeyValues(StringBuilder sb, String prefix, Map map) {
        for (Map.Entry entry : map.entrySet()) {
            String key = prefix + entry.getKey();
            Object value = entry.getValue();
            if (value instanceof List) {
                List values = (List) value;
                for (Object v : values) {
                    addEncodedKeyValue(sb, key, v);
                }
            } else if (value instanceof Map) {
                addUrlEncodedKeyValues(sb, key + ".", (Map) value);
            } else {
                addEncodedKeyValue(sb, key, value);
            }
        }
    }

    private void addEncodedKeyValue(StringBuilder sb, String key, Object value) {
        if (sb.length() != 0) {
            sb.append("&");
        }
        sb.append(urlEncode(key));
        if (value != null) {
            sb.append("=");
            sb.append(urlEncode(value.toString()));
        }
    }

    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() {
        try {
            response.validResponse();
        } catch (FitFailureException | NonValidResponseReceivedException e) {
            if (throwExceptionOnHttpRequestFailure) {
                throw new SlimFixtureException(false, e.getMessage());
            } else {
                return false;
            }
        }
        return true;
    }

    /**
     * @return request sent last time.
     */
    public String request() {
        return safeFormatValue(response.getRequest());
    }

    /**
     * @return actual headers sent (these will contain the headers explicitly set and some implicit).
     */
    public Map requestHeaders() {
        return response.getRequestHeaders();
    }

    /**
     * @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 response time in ms for call to service. */ public long responseTime() { return getResponse().getResponseTime(); } /** * @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 (may be a list if the saame header name was sent multiple times * (e.g. Set-Cookie). */ public Object responseHeader(String headerName) { return responseHeaders().get(headerName); } public void setStoreCookies(boolean storeCookies) { this.storeCookies = storeCookies; } /** * Adds all current Selenium cookies to this fixture's cookie store. * This will also ensure this class will store cookies (otherwise copying the cookies has no purpose). */ public void copyBrowserCookies() { setStoreCookies(true); getEnvironment().addSeleniumCookies(getResponse()); } /** * @return name->value of cookies in the cookie store. */ public Map cookieValues() { Map result = null; CookieStore cookies = getResponse().getCookieStore(); if (cookies != null) { result = new LinkedHashMap<>(); for (Cookie cookie : cookies.getCookies()) { result.put(cookie.getName(), cookie.getValue()); } } return result; } /** * @param cookieName name of cookie. * @return value of cookie in the cookie store. */ public String cookieValue(String cookieName) { String result = null; Cookie cookie = getCookie(cookieName); if (cookie != null) { result = cookie.getValue(); } return result; } /** * @param cookieName name of cookie. * @return domain of cookie in the cookie store. */ public String cookieDomain(String cookieName) { String result = null; Cookie cookie = getCookie(cookieName); if (cookie != null) { result = cookie.getDomain(); } return result; } /** * @param cookieName name of cookie. * @return path of cookie in the cookie store. */ public String cookiePath(String cookieName) { String result = null; Cookie cookie = getCookie(cookieName); if (cookie != null) { result = cookie.getPath(); } return result; } /** * @param cookieName name of cookie. * @return whether cookie in the cookie store is persistent. */ public Boolean cookieIsPersistent(String cookieName) { Boolean result = null; Cookie cookie = getCookie(cookieName); if (cookie != null) { result = cookie.isPersistent(); } return result; } /** * @param cookieName name of cookie. * @return whether cookie in the cookie store requires a secure connection. */ public Boolean cookieIsSecure(String cookieName) { Boolean result = null; Cookie cookie = getCookie(cookieName); if (cookie != null) { result = cookie.isSecure(); } return result; } /** * @param cookieName name of cookie. * @return whether cookie in the cookie store is http-only (not accessible to Javascript). */ public Boolean cookieIsHttpOnly(String cookieName) { return cookieAttribute(cookieName, "httponly") != null; } /** * @param cookieName name of cookie. * @param attributeName name of attribute. * @return value of attribute for cookie. */ public String cookieAttribute(String cookieName, String attributeName) { String result = null; Cookie cookie = getCookie(cookieName); if (cookie instanceof BasicClientCookie) { result = ((BasicClientCookie) cookie).getAttribute(attributeName.toLowerCase(Locale.ENGLISH)); } return result; } private Cookie getCookie(String cookieName) { return getResponse().getCookieNamed(cookieName); } /** * Removes all cookies from the cookie store. */ public void clearCookies() { getResponse().getCookieStore().clear(); } protected HttpResponse getResponse() { return response; } protected HttpResponse createResponse() { return new HttpResponse(); } public String getContentType() { return contentType; } public void setContentType(String aContentType) { explicitContentTypeSet = true; contentType = aContentType; } public void setBasicAuthorizationHeaderForUserAndPassword(String user, String password) { String credential = user + ":" + password; try { String base64credential = Base64.getEncoder().encodeToString(credential.getBytes("ISO-8859-1")); setValueForHeader("Basic " + base64credential, "Authorization"); } catch (UnsupportedEncodingException e) { throw new SlimFixtureException("ISO-8859-1 encoding unavailable!", e); } } public boolean isExplicitContentTypeSet() { return explicitContentTypeSet; } public void setStopTestOnException(boolean stopTestOnException) { this.stopTestOnException = stopTestOnException; } public boolean stopTestOnException() { return stopTestOnException; } // Polling public boolean repeatUntilResponseStatusIs(final int expectedStatus) { return repeatUntil( new RepeatLastCall() { @Override public boolean isFinished() { return responseStatus() == expectedStatus; } }); } public boolean repeatUntilResponseIs(final String expectedResponse) { return repeatUntil(createResponseIsCompletion(expectedResponse)); } public boolean repeatUntilResponseIsNot(final String expectedResponse) { return repeatUntilNot(createResponseIsCompletion(expectedResponse)); } protected RepeatCompletion createResponseIsCompletion(final String expectedResponse) { RepeatCompletion completion; if (expectedResponse == null) { completion = new RepeatLastCall() { @Override public boolean isFinished() { return response() == null; } }; } else { String cleanedExpected = cleanupValue(expectedResponse); completion = new RepeatLastCall() { @Override public boolean isFinished() { Object actual = response(); return compareActualToExpected(cleanedExpected, actual); } }; } return completion; } public boolean repeatUntilHeaderIs(final String header, final Object expectedValue) { RepeatCompletion completion; if (expectedValue == null) { completion = new RepeatLastCall() { @Override public boolean isFinished() { return responseHeader(header) == null; } }; } else { Object cleanedExpected = cleanupValue(expectedValue); completion = new RepeatLastCall() { @Override public boolean isFinished() { Object actual = responseHeader(header); return compareActualToExpected(cleanedExpected, actual); } }; } return repeatUntil(completion); } protected void repeatLastCall() { if (lastMethod == null) { throw new SlimFixtureException(false, "First make a call before trying to repeat one."); } switch (lastMethod) { case "GET": getImpl(lastUrl, true); break; case "HEAD": headFrom(lastUrl); break; case "POST": postToImpl(response.getRequest(), lastUrl); break; case "PUT": putToImpl(response.getRequest(), lastUrl); break; case "PATCH": patchWithImpl(response.getRequest(), lastUrl); break; case "DELETE": if (lastUrl.equals(response.getRequest())) { delete(lastUrl); } else { deleteToImpl(response.getRequest(), lastUrl); } break; case "GET_NO_REDIRECT": getImpl(lastUrl, false); break; case "POST_FILE": postFileToImpl(response.getRequest(), lastUrl); break; case "PUT_FILE": putFileToImpl(response.getRequest(), lastUrl); break; default: throw new SlimFixtureException(false, "Repeat of method: " + lastMethod + " not configured."); } } protected void storeLastCall(String method, String url) { lastMethod = method; lastUrl = url; } protected abstract class RepeatLastCall implements RepeatCompletion { @Override public void repeat() { repeatLastCall(); } } // Polling }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy