Migrated to default WireMock helper methods; fixes gh-540

This commit is contained in:
Marcin Grzejszczak
2018-08-24 15:10:55 +02:00
parent a0bc2eb1c4
commit debea6edfd
15 changed files with 827 additions and 162 deletions

View File

@@ -69,7 +69,7 @@ abstract class MethodBodyBuilder {
private static final Closure GET_SERVER_VALUE = { it instanceof DslProperty ? it.serverValue : it }
private static final String FROM_REQUEST_PREFIX = "request."
private static final String FROM_REQUEST_BODY = "body"
private static final String FROM_REQUEST_BODY = "escapejsonbody"
private static final String FROM_REQUEST_PATH = "path"
protected final ContractVerifierConfigProperties configProperties
@@ -422,11 +422,15 @@ abstract class MethodBodyBuilder {
String entryAsString = (String) entry
if (templateProcessor.containsTemplateEntry(entryAsString) &&
!templateProcessor.containsJsonPathTemplateEntry(entryAsString)) {
String justEntry = entryAsString - contractTemplate.openingTemplate() -
// TODO: HANDLEBARS LEAKING VIA request.
String justEntry = entryAsString - contractTemplate.escapedOpeningTemplate() -
contractTemplate.openingTemplate() -
contractTemplate.escapedClosingTemplate() -
contractTemplate.closingTemplate() - FROM_REQUEST_PREFIX
if (justEntry == FROM_REQUEST_BODY) {
// the body should be transformed by standard mechanism
return entry
return contractTemplate.escapedOpeningTemplate() + FROM_REQUEST_PREFIX +
"escapedBody" + contractTemplate.escapedClosingTemplate()
}
try {
Object result = new PropertyUtilsBean().getProperty(templateModel, justEntry)
@@ -451,6 +455,8 @@ abstract class MethodBodyBuilder {
Object object = parsedRequestBody.read(jsonPathEntry)
if (!(object instanceof String)) {
return method
.replace('"' + contractTemplate.escapedOpeningTemplate(), contractTemplate.escapedOpeningTemplate())
.replace(contractTemplate.escapedClosingTemplate() + '"', contractTemplate.escapedClosingTemplate())
.replace('"' + contractTemplate.openingTemplate(), contractTemplate.openingTemplate())
.replace(contractTemplate.closingTemplate() + '"', contractTemplate.closingTemplate())
}

View File

@@ -41,14 +41,14 @@ class TestSideRequestTemplateModel {
final Map<String, List<String>> headers
/**
* Escaped request body that can be put into test
* Request body as it would be sent to the controller
*/
final String body
/**
* Request body as it would be sent to the controller
* Escaped request body that can be put into test
*/
final String rawBody
final String escapedBody
static TestSideRequestTemplateModel from(final Request request) {
String url = MapConverter.getTestSideValues(request.url ?: request.urlPath)
@@ -65,9 +65,9 @@ class TestSideRequestTemplateModel {
}?.collectEntries {
[(it.key): it.value.collect { MapConverter.getTestSideValues(it) }]
})
String body = trimmedAndEscapedBody(request.body)
String rawBody = getBodyAsRawJson(request.body)
return new TestSideRequestTemplateModel(fullUrl, query, paths, headers, body, rawBody)
String escapedBody = trimmedAndEscapedBody(request.body)
String body = getBodyAsRawJson(request.body)
return new TestSideRequestTemplateModel(fullUrl, query, paths, headers, body, escapedBody)
}
private static List<String> buildPathsFromUrl(String url) {
@@ -86,6 +86,9 @@ class TestSideRequestTemplateModel {
private static String getBodyAsRawJson(Object body) {
Object bodyValue = extractServerValueFromBody(body)
if (bodyValue instanceof GString || bodyValue instanceof String) {
return bodyValue.toString()
}
return bodyValue != null ? new JsonOutput().toJson(bodyValue) : bodyValue
}

View File

@@ -34,7 +34,7 @@ class HandlebarsEscapeHelper implements Helper<Map<String, Object>> {
}
private Object returnObjectForTest(Object model) {
return ((TestSideRequestTemplateModel) model).rawBody
return ((TestSideRequestTemplateModel) model).escapedBody
}
}

View File

@@ -1,5 +1,7 @@
package org.springframework.cloud.contract.verifier.builder.handlebars
import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers
import org.apache.commons.text.StringEscapeUtils
import wiremock.com.github.jknack.handlebars.Helper
import wiremock.com.github.jknack.handlebars.Options
import com.github.tomakehurst.wiremock.extension.responsetemplating.RequestTemplateModel
@@ -15,21 +17,41 @@ import org.springframework.cloud.contract.verifier.builder.TestSideRequestTempla
* @since 1.1.0
*/
@CompileStatic
class HandlebarsJsonPathHelper implements Helper<Map<String, Object>> {
class HandlebarsJsonPathHelper implements Helper<Object> {
public static final String NAME = "jsonpath"
public static final String REQUEST_MODEL_NAME = "request"
@Override
Object apply(Map<String, Object> context, Options options) throws IOException {
String jsonPath = options.param(0)
Object model = context.get(REQUEST_MODEL_NAME)
if (model instanceof TestSideRequestTemplateModel) {
return returnObjectForTest(model, jsonPath)
} else if (model instanceof RequestTemplateModel) {
return returnObjectForStub(model, jsonPath)
Object apply(Object context, Options options) throws IOException {
if (context instanceof Map<String, Object>) {
// legacy
Map<String, Object> oldContext = (Map<String, Object>) context
String jsonPath = options.param(0)
Object model = oldContext.get(REQUEST_MODEL_NAME)
if (model instanceof TestSideRequestTemplateModel) {
return returnObjectForTest(model, jsonPath)
} else if (model instanceof RequestTemplateModel) {
return returnObjectForStub(model, jsonPath)
}
throw new IllegalArgumentException("Unsupported model")
} else if (context instanceof String) {
Object value = WireMockHelpers.jsonPath.apply(context, options)
if (testSideModel(options)) {
return processTestResponseValue(value)
}
return value
}
throw new IllegalArgumentException("Unsupported model")
throw new IllegalArgumentException("Unsupported context")
}
private boolean testSideModel(Options options) {
Object model = options.context.model()
if (!(model instanceof Map)) {
return false
}
Map map = (Map) model
return map.values().any { it instanceof TestSideRequestTemplateModel }
}
private Object returnObjectForStub(Object model, String jsonPath) {
@@ -37,10 +59,14 @@ class HandlebarsJsonPathHelper implements Helper<Map<String, Object>> {
return documentContext.read(jsonPath)
}
private Object returnObjectForTest(Object model, String jsonPath) {
String body = removeSurroundingQuotes(((TestSideRequestTemplateModel) model).rawBody).replace('\\"', '"')
private Object returnObjectForTest(TestSideRequestTemplateModel model, String jsonPath) {
String body = removeSurroundingQuotes(model.escapedBody).replace('\\"', '"')
DocumentContext documentContext = JsonPath.parse(body)
Object value = documentContext.read(jsonPath)
return processTestResponseValue(value)
}
private Object processTestResponseValue(Object value) {
if (value instanceof Long) {
return String.valueOf(value) + "L"
}

View File

@@ -117,7 +117,7 @@ abstract class BaseWireMockStubStrategy {
return processEntriesForTemplating(transformedMap, context)
}
private Object processEntriesForTemplating(transformedMap, DocumentContext context) {
private Object processEntriesForTemplating(Object transformedMap, DocumentContext context) {
return transformValues(transformedMap, {
if (it instanceof String && processor.containsJsonPathTemplateEntry(it)) {
String jsonPath = processor.jsonPathFromTemplateEntry(it)
@@ -129,7 +129,8 @@ abstract class BaseWireMockStubStrategy {
return it
}
return "${WRAPPER}${it}${WRAPPER}"
} else if (it instanceof String && processor.containsTemplateEntry(it) && template.body() == it) {
} else if (it instanceof String && processor.containsTemplateEntry(it) &&
template.escapedBody() == it) {
return template.escapedBody()
}
return it

View File

@@ -1,16 +1,19 @@
package org.springframework.cloud.contract.verifier.template
import wiremock.com.github.jknack.handlebars.Handlebars
import wiremock.com.github.jknack.handlebars.Template
import groovy.transform.CompileStatic
import org.springframework.cloud.contract.spec.ContractTemplate
import org.springframework.cloud.contract.spec.internal.HandlebarsContractTemplate
import org.springframework.cloud.contract.spec.internal.Request
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsJsonPathHelper
import org.springframework.cloud.contract.verifier.builder.TestSideRequestTemplateModel
import java.util.regex.Matcher
import java.util.regex.Pattern
import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.WireMockHelpers
import groovy.transform.CompileStatic
import wiremock.com.github.jknack.handlebars.Handlebars
import wiremock.com.github.jknack.handlebars.Template
import org.springframework.cloud.contract.spec.ContractTemplate
import org.springframework.cloud.contract.spec.internal.CompositeContractTemplate
import org.springframework.cloud.contract.spec.internal.Request
import org.springframework.cloud.contract.verifier.builder.TestSideRequestTemplateModel
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsJsonPathHelper
/**
* Default Handlebars template processor
*
@@ -20,10 +23,17 @@ import java.util.regex.Pattern
@CompileStatic
class HandlebarsTemplateProcessor implements TemplateProcessor, ContractTemplate {
private static final Pattern JSON_PATH_PATTERN = Pattern.compile("^.*\\{\\{\\{jsonpath this '(.*)'}}}.*\$")
private static final Pattern ESCAPED_LEGACY_JSON_PATH_PATTERN = Pattern.compile("^.*\\{\\{\\{jsonpath this '(.*)'}}}.*\$")
private static final Pattern ESCAPED_JSON_PATH_PATTERN = Pattern.compile("^.*\\{\\{\\{jsonPath request.body '(.*)'}}}.*\$")
private static final Pattern LEGACY_JSON_PATH_PATTERN = Pattern.compile("^.*\\{\\{jsonpath this '(.*)'}}.*\$")
private static final Pattern JSON_PATH_PATTERN = Pattern.compile("^.*\\{\\{jsonPath request.body '(.*)'}}.*\$")
private static final List<Pattern> PATTERNS = [ESCAPED_LEGACY_JSON_PATH_PATTERN,
ESCAPED_JSON_PATH_PATTERN, LEGACY_JSON_PATH_PATTERN, JSON_PATH_PATTERN]
private static final String LEGACY_JSON_PATH_TEMPLATE_NAME = HandlebarsJsonPathHelper.NAME
private static final String JSON_PATH_TEMPLATE_NAME = WireMockHelpers.jsonPath.name()
@Delegate
private final ContractTemplate contractTemplate = new HandlebarsContractTemplate()
private final ContractTemplate contractTemplate = new CompositeContractTemplate()
@Override
String transform(Request request, String testContents) {
@@ -35,12 +45,16 @@ class HandlebarsTemplateProcessor implements TemplateProcessor, ContractTemplate
@Override
boolean containsTemplateEntry(String line) {
return line.matches('^.*\\{\\{\\{.*}}}.*$')
return (line.contains(contractTemplate.openingTemplate()) && line.contains(contractTemplate.closingTemplate())) ||
(line.contains(contractTemplate.escapedOpeningTemplate()) && line.contains(contractTemplate.escapedClosingTemplate()))
}
@Override
boolean containsJsonPathTemplateEntry(String line) {
return line.contains(openingTemplate() + HandlebarsJsonPathHelper.NAME)
return line.contains(openingTemplate() + LEGACY_JSON_PATH_TEMPLATE_NAME) ||
line.contains(openingTemplate() + JSON_PATH_TEMPLATE_NAME) ||
line.contains(escapedOpeningTemplate() + LEGACY_JSON_PATH_TEMPLATE_NAME) ||
line.contains(escapedOpeningTemplate() + JSON_PATH_TEMPLATE_NAME)
}
@Override
@@ -48,11 +62,13 @@ class HandlebarsTemplateProcessor implements TemplateProcessor, ContractTemplate
if (!containsJsonPathTemplateEntry(line)) {
return ""
}
Matcher matcher = JSON_PATH_PATTERN.matcher(line)
if (!matcher.matches()) {
return ""
for (Pattern pattern : PATTERNS) {
Matcher matcher = pattern.matcher(line)
if (matcher.matches()) {
return matcher.group(1)
}
}
return matcher.group(1)
return ""
}
private String templatedResponseBody(Map< String, TestSideRequestTemplateModel> model, Template bodyTemplate) {
@@ -71,6 +87,12 @@ class HandlebarsTemplateProcessor implements TemplateProcessor, ContractTemplate
try {
Handlebars handlebars = new Handlebars()
handlebars.registerHelper(HandlebarsJsonPathHelper.NAME, new HandlebarsJsonPathHelper())
handlebars.registerHelper(WireMockHelpers.jsonPath.name(), new HandlebarsJsonPathHelper())
WireMockHelpers.values()
.findAll { it != WireMockHelpers.jsonPath}
.each { WireMockHelpers helper ->
handlebars.registerHelper(helper.name(), helper)
}
return handlebars.compileInline(content)
} catch (IOException e) {
throw new RuntimeException(e)

View File

@@ -26,14 +26,14 @@ interface TemplateProcessor {
/**
* Returns {@code true} if the current line contains template related entry for json path processing.
* E.g. for Handlebars if a line contains {{{jsonpath ...}}} then
* E.g. for Handlebars if a line contains {{{jsonpath ...}}} or {{{jsonPath ...}}} then
* it's considered to contain template related entry for json path processing
*/
boolean containsJsonPathTemplateEntry(String line)
/**
* Returns the json path entry from the current line that contains template related entry for json path processing.
* E.g. for Handlebars if a line contains {{{jsonpath this '$.a.b.c'}}} then
* E.g. for Handlebars if a line contains {{{jsonpath this '$.a.b.c'}}} or {{{jsonPath request.body ...}}} then
* the te method would return {@code $.a.b.c}. Returns empty string if there's no matching
* json path entry
*/

View File

@@ -1515,8 +1515,7 @@ World.'''"""
method "GET"
urlPath('/auth/oauth/check_token') {
queryParameters {
parameter 'token':
value(
parameter 'token': value(
consumer(regex('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')),
producer('6973b31d-7140-402a-bca6-1cdb954e03a7')
)
@@ -1551,8 +1550,7 @@ World.'''"""
method "GET"
urlPath('/auth/oauth/check_token') {
queryParameters {
parameter 'token':
value(
parameter 'token': value(
consumer(regex('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')),
producer('6973b31d-7140-402a-bca6-1cdb954e03a7')
)
@@ -2594,7 +2592,17 @@ DocumentContext parsedJson = JsonPath.parse(json);
fullBody: fromRequest().body(),
responseFoo: fromRequest().body('$.foo'),
responseBaz: fromRequest().body('$.baz'),
responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla"
responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla",
rawUrl: fromRequest().rawUrl(),
rawPath: fromRequest().rawPath(),
rawPathIndex: fromRequest().rawPath(1),
rawParam: fromRequest().rawQuery("foo"),
rawParamIndex: fromRequest().rawQuery("foo", 1),
rawAuthorization: fromRequest().rawHeader("Authorization"),
rawAuthorization2: fromRequest().rawHeader("Authorization", 1),
rawResponseFoo: fromRequest().rawBody('$.foo'),
rawResponseBaz: fromRequest().rawBody('$.baz'),
rawResponseBaz2: "Bla bla ${fromRequest().rawBody('$.foo')} bla bla"
)
}
}
@@ -2608,6 +2616,7 @@ DocumentContext parsedJson = JsonPath.parse(json);
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
then:
!test.contains('''DslProperty''')
!test.contains('''ERROR: ''')
test.contains('''assertThatJson(parsedJson).field("['url']").isEqualTo("/api/v1/xxxx?foo=bar&foo=bar2")''')
test.contains('''assertThatJson(parsedJson).field("['path']").isEqualTo("/api/v1/xxxx")''')
test.contains('''assertThatJson(parsedJson).field("['pathIndex']").isEqualTo("v1")''')
@@ -2619,6 +2628,16 @@ DocumentContext parsedJson = JsonPath.parse(json);
test.contains('''assertThatJson(parsedJson).field("['responseBaz']").isEqualTo(5)''')
test.contains('''assertThatJson(parsedJson).field("['responseBaz2']").isEqualTo("Bla bla bar bla bla")''')
test.contains('''assertThatJson(parsedJson).field("['param']").isEqualTo("bar")''')
test.contains('''assertThatJson(parsedJson).field("['rawUrl']").isEqualTo("/api/v1/xxxx?foo=bar&foo=bar2")''')
test.contains('''assertThatJson(parsedJson).field("['rawPath']").isEqualTo("/api/v1/xxxx")''')
test.contains('''assertThatJson(parsedJson).field("['rawPathIndex']").isEqualTo("v1")''')
test.contains('''assertThatJson(parsedJson).field("['rawParamIndex']").isEqualTo("bar2")''')
test.contains('''assertThatJson(parsedJson).field("['rawResponseFoo']").isEqualTo("bar")''')
test.contains('''assertThatJson(parsedJson).field("['rawAuthorization']").isEqualTo("secret")''')
test.contains('''assertThatJson(parsedJson).field("['rawAuthorization2']").isEqualTo("secret2")''')
test.contains('''assertThatJson(parsedJson).field("['rawResponseBaz']").isEqualTo(5)''')
test.contains('''assertThatJson(parsedJson).field("['rawResponseBaz2']").isEqualTo("Bla bla bar bla bla")''')
test.contains('''assertThatJson(parsedJson).field("['rawParam']").isEqualTo("bar")''')
responseAssertion(test)
where:
methodBuilderName | methodBuilder | responseAssertion

View File

@@ -1736,7 +1736,73 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
}
@Issue('#237')
def "should generate a stub with response template"() {
def "should work with legacy mappings"() {
given:
def oldJsonMapping = '''
{
"request" : {
"urlPath" : "/api/v1/xxxx",
"method" : "POST",
"headers" : {
"Authorization" : {
"equalTo" : "secret2"
}
},
"cookies" : {
"foo" : {
"equalTo" : "bar"
}
},
"queryParameters" : {
"foo" : {
"equalTo" : "bar2"
}
},
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.['baz'] == 5)]"
}, {
"matchesJsonPath" : "$[?(@.['foo'] == 'bar')]"
} ]
},
"response" : {
"status" : 200,
"body" : "{\\"authorization\\":\\"{{{request.headers.Authorization.[0]}}}\\",\\"path\\":\\"{{{request.path}}}\\",\\"responseBaz\\":{{{jsonpath this '$.baz'}}} ,\\"param\\":\\"{{{request.query.foo.[0]}}}\\",\\"pathIndex\\":\\"{{{request.path.[1]}}}\\",\\"responseBaz2\\":\\"Bla bla {{{jsonpath this '$.foo'}}} bla bla\\",\\"responseFoo\\":\\"{{{jsonpath this '$.foo'}}}\\",\\"authorization2\\":\\"{{{request.headers.Authorization.[1]}}}\\",\\"fullBody\\":\\"{{{escapejsonbody}}}\\",\\"url\\":\\"{{{request.url}}}\\",\\"paramIndex\\":\\"{{{request.query.foo.[1]}}}\\"}",
"headers" : {
"Authorization" : "{{{request.headers.Authorization.[0]}}};foo"
},
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''
and:
int port = SocketUtils.findAvailableTcpPort()
WireMockServer server = new WireMockServer(config().port(port))
server.start()
and:
server.addStubMapping(WireMockStubMapping.buildFrom(oldJsonMapping))
when:
ResponseEntity<String> entity = call(port)
then:
entity.headers.find { it.key == "Authorization" && it.value.contains("secret;foo") }
AssertionUtil.assertThatJsonsAreEqual(('''
{
"url" : "/api/v1/xxxx?foo=bar&foo=bar2",
"param" : "bar",
"paramIndex" : "bar2",
"authorization" : "secret",
"authorization2" : "secret2",
"fullBody" : "{\\"foo\\":\\"bar\\",\\"baz\\":5}",
"responseFoo" : "bar",
"responseBaz" : 5,
"responseBaz2" : "Bla bla bar bla bla"
}
'''), entity.body)
cleanup:
server?.shutdown()
}
@Issue('#540')
def "should generate a stub with standard WireMock request template"() {
given:
org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make {
request {
@@ -1772,7 +1838,17 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
fullBody: fromRequest().body(),
responseFoo: fromRequest().body('$.foo'),
responseBaz: fromRequest().body('$.baz'),
responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla"
responseBaz2: "Bla bla ${fromRequest().body('$.foo')} bla bla",
rawUrl: fromRequest().rawUrl(),
rawPath: fromRequest().rawPath(),
rawPathIndex: fromRequest().rawPath(1),
rawParam: fromRequest().rawQuery("foo"),
rawParamIndex: fromRequest().rawQuery("foo", 1),
rawAuthorization: fromRequest().rawHeader("Authorization"),
rawAuthorization2: fromRequest().rawHeader("Authorization", 1),
rawResponseFoo: fromRequest().rawBody('$.foo'),
rawResponseBaz: fromRequest().rawBody('$.baz'),
rawResponseBaz2: "Bla bla ${fromRequest().rawBody('$.foo')} bla bla"
)
}
}
@@ -1807,7 +1883,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"authorization\\":\\"{{{request.headers.Authorization.[0]}}}\\",\\"path\\":\\"{{{request.path}}}\\",\\"responseBaz\\":{{{jsonpath this '$.baz'}}} ,\\"param\\":\\"{{{request.query.foo.[0]}}}\\",\\"pathIndex\\":\\"{{{request.path.[1]}}}\\",\\"responseBaz2\\":\\"Bla bla {{{jsonpath this '$.foo'}}} bla bla\\",\\"responseFoo\\":\\"{{{jsonpath this '$.foo'}}}\\",\\"authorization2\\":\\"{{{request.headers.Authorization.[1]}}}\\",\\"fullBody\\":\\"{{{escapejsonbody}}}\\",\\"url\\":\\"{{{request.url}}}\\",\\"paramIndex\\":\\"{{{request.query.foo.[1]}}}\\"}",
"body" : "{\\"rawAuthorization2\\":\\"{{request.headers.Authorization.[1]}}\\",\\"responseBaz\\":{{{jsonPath request.body '$.baz'}}} ,\\"pathIndex\\":\\"{{{request.path.[1]}}}\\",\\"rawAuthorization\\":\\"{{request.headers.Authorization.[0]}}\\",\\"authorization2\\":\\"{{{request.headers.Authorization.[1]}}}\\",\\"rawParam\\":\\"{{request.query.foo.[0]}}\\",\\"url\\":\\"{{{request.url}}}\\",\\"paramIndex\\":\\"{{{request.query.foo.[1]}}}\\",\\"authorization\\":\\"{{{request.headers.Authorization.[0]}}}\\",\\"path\\":\\"{{{request.path}}}\\",\\"rawUrl\\":\\"{{request.url}}\\",\\"rawPath\\":\\"{{request.path}}\\",\\"rawResponseBaz2\\":\\"Bla bla {{jsonPath request.body '$.foo'}} bla bla\\",\\"param\\":\\"{{{request.query.foo.[0]}}}\\",\\"rawResponseBaz\\":{{jsonPath request.body '$.baz'}} ,\\"responseBaz2\\":\\"Bla bla {{{jsonPath request.body '$.foo'}}} bla bla\\",\\"rawResponseFoo\\":\\"{{jsonPath request.body '$.foo'}}\\",\\"responseFoo\\":\\"{{{jsonPath request.body '$.foo'}}}\\",\\"rawPathIndex\\":\\"{{request.path.[1]}}\\",\\"fullBody\\":\\"{{{escapejsonbody}}}\\",\\"rawParamIndex\\":\\"{{request.query.foo.[1]}}\\"}",
"headers" : {
"Authorization" : "{{{request.headers.Authorization.[0]}}};foo"
},
@@ -1827,16 +1903,28 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
entity.headers.find { it.key == "Authorization" && it.value.contains("secret;foo") }
and:
AssertionUtil.assertThatJsonsAreEqual(('''
{
"url" : "/api/v1/xxxx?foo=bar&foo=bar2",
"param" : "bar",
"paramIndex" : "bar2",
"authorization" : "secret",
"authorization2" : "secret2",
"fullBody" : "{\\"foo\\":\\"bar\\",\\"baz\\":5}",
"responseFoo" : "bar",
"responseBaz" : 5,
"responseBaz2" : "Bla bla bar bla bla"
{
"rawAuthorization2":"secret2",
"responseBaz":5,
"pathIndex":"v1",
"rawAuthorization":"secret",
"authorization2":"secret2",
"rawParam":"bar",
"url":"/api/v1/xxxx?foo=bar&foo=bar2",
"paramIndex":"bar2",
"authorization":"secret",
"path":"/api/v1/xxxx",
"rawUrl":"/api/v1/xxxx?foo&#x3D;bar&amp;foo&#x3D;bar2",
"rawPath":"/api/v1/xxxx",
"rawResponseBaz2":"Bla bla bar bla bla",
"param":"bar",
"rawResponseBaz":5,
"responseBaz2":"Bla bla bar bla bla",
"rawResponseFoo":"bar",
"responseFoo":"bar",
"rawPathIndex":"v1",
"fullBody":"{\\"foo\\":\\"bar\\",\\"baz\\":5}",
"rawParamIndex":"bar2"
}
'''), entity.body)
cleanup: