package au.com.dius.pact.consumer.dsl; import au.com.dius.pact.consumer.ConsumerPactBuilder; import au.com.dius.pact.model.Consumer; import au.com.dius.pact.model.OptionalBody; import au.com.dius.pact.model.PactReader; import au.com.dius.pact.model.Provider; import com.mifmif.common.regex.Generex; import org.apache.http.entity.ContentType; import org.json.JSONObject; import org.w3c.dom.Document; import javax.xml.transform.TransformerException; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; public class PactDslRequestWithPath { private static final String CONTENT_TYPE = "Content-Type"; private final ConsumerPactBuilder consumerPactBuilder; Consumer consumer; Provider provider; String state; String description; String path = "/"; String requestMethod = "GET"; Map<String, String> requestHeaders = new HashMap<>(); Map<String, List<String>> query = new HashMap<>(); OptionalBody requestBody = OptionalBody.missing(); Map<String, Map<String, Object>> requestMatchers = new HashMap<>(); public PactDslRequestWithPath(ConsumerPactBuilder consumerPactBuilder, String consumerName, String providerName, String state, String description, String path, String requestMethod, Map<String, String> requestHeaders, Map<String, List<String>> query, OptionalBody requestBody, Map<String, Map<String, Object>> requestMatchers) { this.consumerPactBuilder = consumerPactBuilder; this.requestMatchers = requestMatchers; this.consumer = new Consumer(consumerName); this.provider = new Provider(providerName); this.state = state; this.description = description; this.path = path; this.requestMethod = requestMethod; this.requestHeaders = requestHeaders; this.query = query; this.requestBody = requestBody; this.requestMatchers = requestMatchers; } public PactDslRequestWithPath(ConsumerPactBuilder consumerPactBuilder, PactDslRequestWithPath existing, String description) { this.consumerPactBuilder = consumerPactBuilder; this.consumer = existing.consumer; this.provider = existing.provider; this.state = existing.state; this.description = description; } /** * The HTTP method for the request * * @param method Valid HTTP method */ public PactDslRequestWithPath method(String method) { requestMethod = method; return this; } /** * Headers to be included in the request * * @param firstHeaderName The name of the first header * @param firstHeaderValue The value of the first header * @param headerNameValuePairs Additional headers in name-value pairs. */ public PactDslRequestWithPath headers(String firstHeaderName, String firstHeaderValue, String... headerNameValuePairs) { if (headerNameValuePairs.length % 2 != 0) { throw new IllegalArgumentException("Pair key value should be provided, but there is one key without value."); } requestHeaders.put(firstHeaderName, firstHeaderValue); for (int i = 0; i < headerNameValuePairs.length; i+=2) { requestHeaders.put(headerNameValuePairs[i], headerNameValuePairs[i+1]); } return this; } /** * Headers to be included in the request * * @param headers Key-value pairs */ public PactDslRequestWithPath headers(Map<String, String> headers) { requestHeaders.putAll(headers); return this; } /** * The query string for the request * * @param query query string */ public PactDslRequestWithPath query(String query) { this.query = PactReader.queryStringToMap(query, false); return this; } /** * The body of the request * * @param body Request body in string form */ public PactDslRequestWithPath body(String body) { requestBody = OptionalBody.body(body); return this; } /** * The body of the request * * @param body Request body in string form */ public PactDslRequestWithPath body(String body, String mimeType) { requestBody = OptionalBody.body(body); requestHeaders.put(CONTENT_TYPE, mimeType); return this; } /** * The body of the request * * @param body Request body in string form */ public PactDslRequestWithPath body(String body, ContentType mimeType) { return body(body, mimeType.toString()); } /** * The body of the request * * @param body Request body in Java Functional Interface Supplier that must return a string */ public PactDslRequestWithPath body(Supplier<String> body) { requestBody = OptionalBody.body(body.get()); return this; } /** * The body of the request * * @param body Request body in Java Functional Interface Supplier that must return a string */ public PactDslRequestWithPath body(Supplier<String> body, String mimeType) { requestBody = OptionalBody.body(body.get()); requestHeaders.put(CONTENT_TYPE, mimeType); return this; } /** * The body of the request * * @param body Request body in Java Functional Interface Supplier that must return a string */ public PactDslRequestWithPath 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 PactDslRequestWithPath 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 PactDslRequestWithPath 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 PactDslRequestWithPath bodyWithSingleQuotes(String body, ContentType mimeType) { if (body != null) { body = QuoteUtil.convert(body); } return body(body, mimeType); } /** * The body of the request * * @param body Request body in JSON form */ public PactDslRequestWithPath body(JSONObject body) { requestBody = OptionalBody.body(body.toString()); if (!requestHeaders.containsKey(CONTENT_TYPE)) { requestHeaders.put(CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); } return this; } /** * The body of the request * * @param body Built using the Pact body DSL */ public PactDslRequestWithPath body(DslPart body) { DslPart parent = body.close(); for (String matcherName : parent.matchers.keySet()) { requestMatchers.put("$.body" + matcherName, parent.matchers.get(matcherName)); } requestBody = OptionalBody.body(parent.toString()); if (!requestHeaders.containsKey(CONTENT_TYPE)) { requestHeaders.put(CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); } return this; } /** * The body of the request * * @param body XML Document */ public PactDslRequestWithPath body(Document body) throws TransformerException { requestBody = OptionalBody.body(ConsumerPactBuilder.xmlToString(body)); if (!requestHeaders.containsKey(CONTENT_TYPE)) { requestHeaders.put(CONTENT_TYPE, ContentType.APPLICATION_XML.toString()); } return this; } /** * The path of the request * * @param path string path */ public PactDslRequestWithPath path(String path) { this.path = path; return this; } /** * The path of the request. This will generate a random path to use when generating requests * * @param pathRegex string path regular expression to match with */ public PactDslRequestWithPath matchPath(String pathRegex) { return matchPath(pathRegex, new Generex(pathRegex).random()); } /** * The path of the request * * @param path string path to use when generating requests * @param pathRegex regular expression to use to match paths */ public PactDslRequestWithPath matchPath(String pathRegex, String path) { HashMap<String, Object> matcher = new HashMap<String, Object>(); matcher.put("regex", pathRegex); requestMatchers.put("$.path", matcher); this.path = path; return this; } /** * Match a request header. A random example header value will be generated from the provided regular expression. * * @param header Header to match * @param regex Regular expression to match */ public PactDslRequestWithPath matchHeader(String header, String regex) { return matchHeader(header, regex, new Generex(regex).random()); } /** * Match a request header. * * @param header Header to match * @param regex Regular expression to match * @param headerExample Example value to use */ public PactDslRequestWithPath matchHeader(String header, String regex, String headerExample) { HashMap<String, Object> matcher = new HashMap<String, Object>(); matcher.put("regex", regex); requestMatchers.put("$.headers." + header, matcher); requestHeaders.put(header, headerExample); return this; } /** * Define the response to return */ public PactDslResponse willRespondWith() { return new PactDslResponse(consumerPactBuilder, this); } /** * Match a query parameter with a regex. A random query parameter value will be generated from the regex. * @param parameter Query parameter * @param regex Regular expression to match with */ public PactDslRequestWithPath matchQuery(String parameter, String regex) { return matchQuery(parameter, regex, new Generex(regex).random()); } /** * Match a query parameter with a regex. * @param parameter Query parameter * @param regex Regular expression to match with * @param example Example value to use for the query parameter */ public PactDslRequestWithPath matchQuery(String parameter, String regex, String example) { HashMap<String, Object> matcher = new HashMap<String, Object>(); matcher.put("regex", regex); requestMatchers.put("$.query." + parameter + ".*", matcher); query.put(parameter, Arrays.asList(example)); return this; } }