From 67019774e1b2f931e2c7d2c44b70e63145ae77ac Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 20 Mar 2018 21:08:24 +0100 Subject: [PATCH] Fixed missing conversion of messaging patterns to java without this change patterns were not escaped the way they should fixes gh-587 --- .../JUnitMessagingMethodBodyBuilder.groovy | 5 +- .../SpockMessagingMethodBodyBuilder.groovy | 6 +- .../MessagingMethodBodyBuilderSpec.groovy | 87 +++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy index ef464114dc..8d74842edb 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -30,6 +30,7 @@ import org.springframework.cloud.contract.verifier.util.MapConverter import java.util.regex.Pattern +import static groovy.json.StringEscapeUtils.escapeJava import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT /** @@ -221,9 +222,11 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { protected String createHeaderComparison(Pattern headerValue) { String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") - return "matches(\"$escapedHeader\");" + String escapedJavaHeader = escapeJava(escapedHeader) + return "matches(\"$escapedJavaHeader\");" } + private String patternText(Pattern value) { return "==~ java.util.regex.Pattern.compile('$value')" } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy index 123a72c760..d68ed46744 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy @@ -29,6 +29,9 @@ import org.springframework.cloud.contract.verifier.config.ContractVerifierConfig import org.springframework.cloud.contract.verifier.util.MapConverter import java.util.regex.Pattern + +import static org.apache.commons.text.StringEscapeUtils.escapeJava + /** * @author Jakub Kubrynski, codearte.io */ @@ -204,7 +207,8 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { } protected String convertHeaderComparison(Pattern headerValue) { - return "==~ java.util.regex.Pattern.compile('$headerValue')" + String converted = escapeJava(convertUnicodeEscapesIfRequired(headerValue.toString())) + return "==~ java.util.regex.Pattern.compile('$converted')" } // #273 - should escape $ for Groovy since it will try to make it a GString diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy index 7bd6ec17ab..688ca6eeeb 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy @@ -499,6 +499,50 @@ Contract.make { stripped(test) == stripped(expectedMsg) } + @Issue("587") + def "should generate tests with message headers containing regular expression with escapes for JUnit"() { + given: + def contractDsl = + org.springframework.cloud.contract.spec.Contract.make { + label 'trigger_event' + + input { + triggeredBy('requestIsCalled()') + } + + outputMessage { + sentTo 'topic.rateablequote' + headers { + header('processId', value(producer(regex(nonEmpty())), consumer('123'))) + } + body([ + eventId: value(producer(regex(nonEmpty())), consumer('1')) + ]) + } + } + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + String expectedMsg = + ''' + // when: + requestIsCalled(); + + // then: + ContractVerifierMessage response = contractVerifierMessaging.receive("topic.rateablequote"); + assertThat(response).isNotNull(); + assertThat(response.getHeader("processId")).isNotNull(); + assertThat(response.getHeader("processId").toString()).matches("[\\S\\s]+"); + // and: + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload())); + assertThatJson(parsedJson).field("['eventId']").matches("[\\S\\s]+"); +''' + stripped(test) == stripped(expectedMsg) + } + @Issue("336") def "should generate tests with message headers containing regular expression for Spock"() { given: @@ -542,6 +586,49 @@ Contract.make { stripped(test) == stripped(expectedMsg) } + @Issue("587") + def "should generate tests with message headers containing regular expression with escapes for Spock"() { + given: + def contractDsl = + org.springframework.cloud.contract.spec.Contract.make { + label 'trigger_event' + + input { + triggeredBy('requestIsCalled()') + } + + outputMessage { + sentTo 'topic.rateablequote' + headers { + header('processId', value(producer(regex(nonEmpty())), consumer('123'))) + } + body([ + eventId: value(producer(regex(nonEmpty())), consumer('1')) + ]) + } + } + MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl, properties) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + String expectedMsg = + ''' + when: + requestIsCalled() + + then: + ContractVerifierMessage response = contractVerifierMessaging.receive('topic.rateablequote') + assert response != null + response.getHeader('processId')?.toString() ==~ java.util.regex.Pattern.compile('[\\S\\s]+') + and: + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) + assertThatJson(parsedJson).field("['eventId']").matches("[\\S\\s]+") +''' + stripped(test) == stripped(expectedMsg) + } + @Issue("440") def "should generate tests with sentTo having a method execution for Spock"() { given: