package nl.hsac.fitnesse.fixture.slim; import nl.hsac.fitnesse.fixture.util.JsonPathHelper; import org.apache.commons.lang3.StringUtils; import org.apache.http.entity.ContentType; import org.json.JSONObject; import java.util.List; /** * Fixture to make Http calls and interpret the result as JSON. */ public class JsonHttpTest extends HttpTest { public static final String JSON_CONTENT_TYPE = ContentType.APPLICATION_JSON.toString(); public boolean postValuesAsJsonTo(String serviceUrl) { return postToImpl(jsonEncodeCurrentValues(), serviceUrl, getContentTypeForJson()); } public boolean putValuesAsJsonTo(String serviceUrl) { return putToImpl(jsonEncodeCurrentValues(), serviceUrl, getContentTypeForJson()); } protected String jsonEncodeCurrentValues() { return new JSONObject(getCurrentValues()).toString(); } protected String getContentTypeForJson() { // for methods that post JSON we change the default content type to be application/json String contentType; if (isExplicitContentTypeSet()) { contentType = getContentType(); } else { contentType = JSON_CONTENT_TYPE; } return contentType; } @Override protected String formatValue(String value) { String formatted = super.formatValue(value); if (value != null && value.trim().startsWith("{")) { formatted = getEnvironment().getHtmlForJson(value); } return formatted; } public Object jsonPath(String path) { String responseString = getResponseBody(); String jsonPath = getPathExpr(path); return getPathHelper().getJsonPath(responseString, jsonPath); } public int jsonPathCount(String path) { List<Object> all = getAllMatches(path); return all.size(); } protected List<Object> getAllMatches(String path) { String responseString = getResponseBody(); String jsonPath = getPathExpr(path); return getPathHelper().getAllJsonPath(responseString, jsonPath); } protected String getResponseBody() { String responseString = getResponse().getResponse(); if (StringUtils.isEmpty(responseString)) { throw new SlimFixtureException(false, "No response body available"); } return responseString; } /** * Gets a HTML list with all matches to the supplied JsonPath. * @param expr expression to evaluate. * @return list containing all results of expression evaluation against last response received, null if there were no matches. * @throws RuntimeException if no valid response was available or Json Path could not be evaluated. */ public String allJsonPathMatches(String expr) { String result = null; List<Object> allJsonPath = getAllMatches(expr); if (allJsonPath != null && !allJsonPath.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append("<div><ul>"); for (Object match : allJsonPath) { sb.append("<li>"); sb.append(match); sb.append("</li>"); } sb.append("</ul></div>"); result = sb.toString(); } return result; } /** * Update a value in a the response by supplied jsonPath * @param path the jsonPath to locate the key whose value needs changing * @param value the new value to set */ public void setJsonPathTo(String path, String value) { String jsonStr = getResponseBody(); String jsonPath = getPathExpr(path); String newResponse = getPathHelper().updateJsonPathWithValue(jsonStr, jsonPath, value); getResponse().setResponse(newResponse); } public boolean repeatUntilJsonPathIs(final String jsonPath, final Object expectedValue) { RepeatCompletion completion; if (expectedValue == null) { completion = new RepeatLastCall() { @Override public boolean isFinished() { return jsonPath(jsonPath) == null; } }; } else { completion = new RepeatLastCall() { @Override public boolean isFinished() { Object actual = jsonPath(jsonPath); return compareActualToExpected(expectedValue, actual); } }; } return repeatUntil(completion); } protected String getPathExpr(String path) { String jsonPath = path; if (!path.startsWith("$")) { if (path.startsWith("[") || path.startsWith(".")) { jsonPath = "$" + path; } else { jsonPath = "$." + path; } } return jsonPath; } @Override protected String urlEncode(String str) { String strNoSpaces = str.replace(" ", "+"); return super.urlEncode(strNoSpaces); } protected JsonPathHelper getPathHelper() { return getEnvironment().getJsonPathHelper(); } }