Properly escapes query parameters; fixes gh-1441
This commit is contained in:
@@ -78,7 +78,15 @@ interface GroovyBodyParser extends BodyParser {
|
||||
|
||||
@Override
|
||||
default String quotedLongText(Object text) {
|
||||
return "'''" + groovyEscapedString(text) + "'''";
|
||||
String escapedString = groovyEscapedString(text);
|
||||
if (escapedString.startsWith("'")) {
|
||||
escapedString = "\\'" + escapedString.substring(1);
|
||||
}
|
||||
if (escapedString.endsWith("'")) {
|
||||
escapedString = escapedString.substring(0, escapedString.length() - 1)
|
||||
+ "\\'";
|
||||
}
|
||||
return "'''" + escapedString + "'''";
|
||||
}
|
||||
|
||||
default String groovyEscapedString(Object text) {
|
||||
|
||||
@@ -33,9 +33,13 @@ class JaxRsUrlPathWhen implements When, JaxRsAcceptor, QueryParamsResolver {
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
JaxRsUrlPathWhen(BlockBuilder blockBuilder, GeneratedClassMetaData metaData) {
|
||||
private final BodyParser bodyParser;
|
||||
|
||||
JaxRsUrlPathWhen(BlockBuilder blockBuilder, GeneratedClassMetaData metaData,
|
||||
BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = metaData;
|
||||
this.bodyParser = bodyParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,7 +76,8 @@ class JaxRsUrlPathWhen implements When, JaxRsAcceptor, QueryParamsResolver {
|
||||
.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
QueryParameter param = iterator.next();
|
||||
String text = ".queryParam(\"" + param.getName() + "\", \"" + resolveParamValue(param) + "\")";
|
||||
String text = ".queryParam(\"" + param.getName() + "\", "
|
||||
+ this.bodyParser.quotedShortText(resolveParamValue(param)) + ")";
|
||||
if (iterator.hasNext()) {
|
||||
this.blockBuilder.addLine(text);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,9 @@ class JaxRsWhen implements When, BodyMethodVisitor, JaxRsAcceptor {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
this.bodyParser = bodyParser;
|
||||
this.whens.addAll(Arrays.asList(new JaxRsUrlPathWhen(this.blockBuilder, this.generatedClassMetaData),
|
||||
this.whens.addAll(Arrays.asList(
|
||||
new JaxRsUrlPathWhen(this.blockBuilder, this.generatedClassMetaData,
|
||||
bodyParser),
|
||||
new JaxRsRequestWhen(this.blockBuilder, this.generatedClassMetaData),
|
||||
new JaxRsRequestHeadersWhen(this.blockBuilder, bodyParser),
|
||||
new JaxRsRequestCookiesWhen(this.blockBuilder, bodyParser),
|
||||
|
||||
@@ -632,7 +632,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
} | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")']
|
||||
}
|
||||
|
||||
def "should generate a call with an url path and query parameters with #methodBuilderName"() {
|
||||
def "should generate a call with an url path and query parameters with jaxrs"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
@@ -646,6 +646,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
parameter 'search': $(consumer(notMatching(~/^\/[0-9]{2}$/)), producer("55"))
|
||||
parameter 'age': $(consumer(notMatching("^\\w*\$")), producer("99"))
|
||||
parameter 'name': $(consumer(matching("Denis.*")), producer("Denis.Stepanov"))
|
||||
parameter 'nameWithDoubleQuote': '"quote"'
|
||||
parameter 'nameWithQuote': "'quote'"
|
||||
parameter 'email': "bob@email.com"
|
||||
parameter 'hello': $(consumer(matching("Denis.*")), producer(absent()))
|
||||
parameter 'hello': absent()
|
||||
@@ -666,14 +668,16 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
when:
|
||||
String test = singleTestGenerator(contractDsl)
|
||||
then:
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("limit", "10"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("offset", "20"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("filter", "email"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("sort", "name"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("search", "55"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("age", "99"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("name", "Denis.Stepanov"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("email", "bob@email.com"'''))
|
||||
test.contains('''queryParam("limit", "10"''')
|
||||
test.contains('''queryParam("offset", "20"''')
|
||||
test.contains('''queryParam("filter", "email"''')
|
||||
test.contains('''queryParam("sort", "name"''')
|
||||
test.contains('''queryParam("search", "55"''')
|
||||
test.contains('''queryParam("age", "99"''')
|
||||
test.contains('''queryParam("name", "Denis.Stepanov"''')
|
||||
test.contains('''queryParam("nameWithDoubleQuote", "\\"quote\\""''')
|
||||
test.contains('''queryParam("nameWithQuote", "'quote'"''')
|
||||
test.contains('''queryParam("email", "bob@email.com"''')
|
||||
test.contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""")
|
||||
test.contains("""assertThatJson(parsedJson).field("['property2']").isEqualTo("b")""")
|
||||
and:
|
||||
@@ -681,13 +685,69 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
SyntaxChecker.tryToCompile(methodBuilderName, test)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | modifyStringIfRequired
|
||||
"jaxrs-spock" | {
|
||||
properties.testFramework = TestFramework.SPOCK; properties.testMode = TestMode.JAXRSCLIENT
|
||||
} | { String paramString -> paramString }
|
||||
methodBuilderName | methodBuilder
|
||||
"jaxrs" | {
|
||||
properties.testFramework = TestFramework.JUNIT; properties.testMode = TestMode.JAXRSCLIENT
|
||||
} | { String paramString -> paramString.replace("'", "\"") }
|
||||
}
|
||||
}
|
||||
|
||||
def "should generate a call with an url path and query parameters with jaxrs-spock"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
urlPath('/users') {
|
||||
queryParameters {
|
||||
parameter 'limit': $(consumer(equalTo("20")), producer(equalTo("10")))
|
||||
parameter 'offset': $(consumer(containing("20")), producer(equalTo("20")))
|
||||
parameter 'filter': "email"
|
||||
parameter 'sort': equalTo("name")
|
||||
parameter 'search': $(consumer(notMatching(~/^\/[0-9]{2}$/)), producer("55"))
|
||||
parameter 'age': $(consumer(notMatching("^\\w*\$")), producer("99"))
|
||||
parameter 'name': $(consumer(matching("Denis.*")), producer("Denis.Stepanov"))
|
||||
parameter 'nameWithDoubleQuote': '"quote"'
|
||||
parameter 'nameWithQuote': "'quote'"
|
||||
parameter 'email': "bob@email.com"
|
||||
parameter 'hello': $(consumer(matching("Denis.*")), producer(absent()))
|
||||
parameter 'hello': absent()
|
||||
}
|
||||
}
|
||||
}
|
||||
response {
|
||||
status OK()
|
||||
body """
|
||||
{
|
||||
"property1": "a",
|
||||
"property2": "b"
|
||||
}
|
||||
"""
|
||||
}
|
||||
}
|
||||
methodBuilder()
|
||||
when:
|
||||
String test = singleTestGenerator(contractDsl)
|
||||
then:
|
||||
test.contains('''queryParam("limit", '10\'''')
|
||||
test.contains('''queryParam("offset", '20\'''')
|
||||
test.contains('''queryParam("filter", 'email\'''')
|
||||
test.contains('''queryParam("sort", 'name\'''')
|
||||
test.contains('''queryParam("search", '55\'''')
|
||||
test.contains('''queryParam("age", '99\'''')
|
||||
test.contains('''queryParam("name", 'Denis.Stepanov\'''')
|
||||
test.contains("""queryParam("nameWithDoubleQuote", '''"quote"'''""")
|
||||
test.contains("""queryParam("nameWithQuote", '''\\'quote\\''''""")
|
||||
test.contains('''queryParam("email", 'bob@email.com\'''')
|
||||
test.contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""")
|
||||
test.contains("""assertThatJson(parsedJson).field("['property2']").isEqualTo("b")""")
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
and:
|
||||
SyntaxChecker.tryToCompile(methodBuilderName, test)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"jaxrs-spock" | {
|
||||
properties.testFramework = TestFramework.SPOCK; properties.testMode = TestMode.JAXRSCLIENT
|
||||
}
|
||||
}
|
||||
|
||||
@Issue('#169')
|
||||
@@ -725,14 +785,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
when:
|
||||
String test = singleTestGenerator(contractDsl)
|
||||
then:
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("limit", "10"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("offset", "20"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("filter", "email"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("sort", "name"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("search", "55"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("age", "99"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("name", "Denis.Stepanov"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("email", "bob@email.com"'''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("limit", '10\''''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("offset", '20\''''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("filter", 'email\''''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("sort", 'name\''''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("search", '55\''''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("age", '99\''''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("name", 'Denis.Stepanov\''''))
|
||||
test.contains(modifyStringIfRequired.call('''queryParam("email", 'bob@email.com\''''))
|
||||
test.contains("""assertThatJson(parsedJson).field("['property1']").isEqualTo("a")""")
|
||||
test.contains("""assertThatJson(parsedJson).field("['property2']").isEqualTo("b")""")
|
||||
and:
|
||||
|
||||
@@ -1814,6 +1814,49 @@ response:
|
||||
}
|
||||
}
|
||||
|
||||
@Issue("#1441")
|
||||
def "should work with query parameters that need to be escaped [#methodBuilderName]"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'POST'
|
||||
urlPath("/rest/something") {
|
||||
queryParameters {
|
||||
parameter 'quote': equalTo("\"")
|
||||
}
|
||||
}
|
||||
}
|
||||
response {
|
||||
status OK()
|
||||
}
|
||||
}
|
||||
methodBuilder()
|
||||
when:
|
||||
String test = singleTestGenerator(contractDsl)
|
||||
then:
|
||||
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
|
||||
!test.contains('''.queryParam("quote",""")''')
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"spock" | {
|
||||
properties.testFramework = TestFramework.SPOCK
|
||||
}
|
||||
"mockmvc" | {
|
||||
properties.testMode = TestMode.MOCKMVC
|
||||
}
|
||||
"jaxrs-spock" | {
|
||||
properties.testFramework = TestFramework.SPOCK; properties.testMode = TestMode.JAXRSCLIENT
|
||||
}
|
||||
"jaxrs" | {
|
||||
properties.testFramework = TestFramework.JUNIT; properties.testMode = TestMode.JAXRSCLIENT
|
||||
}
|
||||
"testNG" | {
|
||||
properties.testFramework = TestFramework.TESTNG
|
||||
}
|
||||
}
|
||||
|
||||
@Issue("#1262")
|
||||
def "should work with the timeout flag for groovy [#methodBuilderName]"() {
|
||||
given:
|
||||
|
||||
Reference in New Issue
Block a user