package au.com.dius.pact.consumer.dsl; import au.com.dius.pact.consumer.ConsumerPactBuilder; import au.com.dius.pact.model.OptionalBody; import au.com.dius.pact.model.Pact; import au.com.dius.pact.model.PactFragment; import au.com.dius.pact.model.PactReader; import au.com.dius.pact.model.Request; import au.com.dius.pact.model.RequestResponseInteraction; import au.com.dius.pact.model.RequestResponsePact; import au.com.dius.pact.model.Response; import com.mifmif.common.regex.Generex; import org.apache.http.entity.ContentType; import org.json.JSONObject; import org.w3c.dom.Document; import scala.collection.JavaConversions$; import javax.xml.transform.TransformerException; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; public class PactDslResponse { private static final String CONTENT_TYPE = "Content-Type"; private final ConsumerPactBuilder consumerPactBuilder; private PactDslRequestWithPath request; private int responseStatus = 200; private Map<String, String> responseHeaders = new HashMap<String, String>(); private OptionalBody responseBody = OptionalBody.missing(); private Map<String, Map<String, Object>> responseMatchers = new HashMap<String, Map<String, Object>>(); public PactDslResponse(ConsumerPactBuilder consumerPactBuilder, PactDslRequestWithPath request) { this.consumerPactBuilder = consumerPactBuilder; this.request = request; } /** * Response status code * * @param status HTTP status code */ public PactDslResponse status(int status) { this.responseStatus = status; return this; } /** * Response headers to return * * @param headers key-value pairs of headers */ public PactDslResponse headers(Map<String, String> headers) { this.responseHeaders.putAll(headers); return this; } /** * Response body to return * * @param body Response body in string form */ public PactDslResponse body(String body) { this.responseBody = OptionalBody.body(body); return this; } /** * Response body to return * * @param body body in string form */ public PactDslResponse body(String body, String mimeType) { responseBody = OptionalBody.body(body); responseHeaders.put(CONTENT_TYPE, mimeType); return this; } /** * Response body to return * * @param body body in string form */ public PactDslResponse body(String body, ContentType mimeType) { return body(body, mimeType.toString()); } /** * The body of the request * * @param body Response body in Java Functional Interface Supplier that must return a string */ public PactDslResponse body(Supplier<String> body) { responseBody = OptionalBody.body(body.get()); return this; } /** * The body of the request * * @param body Response body in Java Functional Interface Supplier that must return a string */ public PactDslResponse body(Supplier<String> body, String mimeType) { responseBody = OptionalBody.body(body.get()); responseHeaders.put(CONTENT_TYPE, mimeType); return this; } /** * The body of the request * * @param body Response body in Java Functional Interface Supplier that must return a string */ public PactDslResponse body(Supplier<String> body, ContentType mimeType) { return body(body, mimeType.toString()); } /** * The body of the request with possible single quotes as delimiters * and using {@link QuoteUtil} to convert single quotes to double quotes if required. * * @param body Request body in string form */ public PactDslResponse bodyWithSingleQuotes(String body) { if (body != null) { body = QuoteUtil.convert(body); } return body(body); } /** * The body of the request with possible single quotes as delimiters * and using {@link QuoteUtil} to convert single quotes to double quotes if required. * * @param body Request body in string form */ public PactDslResponse bodyWithSingleQuotes(String body, String mimeType) { if (body != null) { body = QuoteUtil.convert(body); } return body(body, mimeType); } /** * The body of the request with possible single quotes as delimiters * and using {@link QuoteUtil} to convert single quotes to double quotes if required. * * @param body Request body in string form */ public PactDslResponse bodyWithSingleQuotes(String body, ContentType mimeType) { return body(body, mimeType.toString()); } /** * Response body to return * * @param body Response body in JSON form */ public PactDslResponse body(JSONObject body) { this.responseBody = OptionalBody.body(body.toString()); if (!responseHeaders.containsKey(CONTENT_TYPE)) { responseHeaders.put(CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); } return this; } /** * Response body to return * * @param body Response body built using the Pact body DSL */ public PactDslResponse body(DslPart body) { DslPart parent = body.close(); if (parent instanceof PactDslJsonRootValue) { ((PactDslJsonRootValue)parent).setEncodeJson(true); } for (String matcherName : parent.matchers.keySet()) { responseMatchers.put("$.body" + matcherName, parent.matchers.get(matcherName)); } if (parent.getBody() != null) { responseBody = OptionalBody.body(parent.getBody().toString()); } else { responseBody = OptionalBody.nullBody(); } if (!responseHeaders.containsKey(CONTENT_TYPE)) { responseHeaders.put(CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); } return this; } /** * Response body to return * * @param body Response body as an XML Document */ public PactDslResponse body(Document body) throws TransformerException { responseBody = OptionalBody.body(ConsumerPactBuilder.xmlToString(body)); if (!responseHeaders.containsKey(CONTENT_TYPE)) { responseHeaders.put(CONTENT_TYPE, ContentType.APPLICATION_XML.toString()); } return this; } /** * Match a response header. A random example header value will be generated from the provided regular expression. * * @param header Header to match * @param regexp Regular expression to match */ public PactDslResponse matchHeader(String header, String regexp) { return matchHeader(header, regexp, new Generex(regexp).random()); } /** * Match a response header. * * @param header Header to match * @param regexp Regular expression to match * @param headerExample Example value to use */ public PactDslResponse matchHeader(String header, String regexp, String headerExample) { HashMap<String, Object> matcher = new HashMap<String, Object>(); matcher.put("regex", regexp); responseMatchers.put("$.headers." + header, matcher); responseHeaders.put(header, headerExample); return this; } private void addInteraction() { consumerPactBuilder.getInteractions().add(new RequestResponseInteraction( request.description, request.state, new Request(request.requestMethod, request.path, request.query, request.requestHeaders, request.requestBody, request.requestMatchers), new Response(responseStatus, responseHeaders, responseBody, responseMatchers) )); } /** * Terminates the DSL and builds a pact fragment to represent the interactions * * @deprecated Use toPact instead */ public PactFragment toFragment() { addInteraction(); return new PactFragment( request.consumer, request.provider, JavaConversions$.MODULE$.asScalaBuffer(consumerPactBuilder.getInteractions()).toSeq()); } /** * Terminates the DSL and builds a pact to represent the interactions */ public RequestResponsePact toPact() { addInteraction(); return new RequestResponsePact(request.provider, request.consumer, consumerPactBuilder.getInteractions()); } /** * Description of the request that is expected to be received * * @param description request description */ public PactDslRequestWithPath uponReceiving(String description) { addInteraction(); return new PactDslRequestWithPath(consumerPactBuilder, request, description); } public PactDslWithState given(String state) { addInteraction(); return new PactDslWithState(consumerPactBuilder, request.consumer.getName(), request.provider.getName(), state); } }