diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy index d9a524eccd..7efc7e9963 100644 --- a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy @@ -16,7 +16,10 @@ package org.springframework.cloud.contract.spec.internal +import java.util.regex.Pattern + import groovy.transform.CompileStatic +import groovy.transform.PackageScope import groovy.transform.ToString /** @@ -41,6 +44,10 @@ class OptionalProperty implements Serializable { return "($value)?" } + protected Pattern optionalPatternValue() { + return Pattern.compile(optionalPattern()) + } + @Override String toString() { return optionalPattern() diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy index d7c7a861c0..c64f14f3ff 100644 --- a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy @@ -88,16 +88,26 @@ class OutputMessage extends Common { this.assertThat = new ExecutionProperty(assertThat) } - DslProperty value(ServerDslProperty server) { - Object value = server.clientValue - if (server.clientValue instanceof Pattern) { - value = StringEscapeUtils.escapeJava(new Xeger(((Pattern)server.clientValue).pattern()).generate()) + DslProperty value(ClientDslProperty clientDslProperty) { + Object clientValue = clientDslProperty.clientValue + // for the output messages ran via stub runner, + // entries have to have fixed values + if (clientDslProperty.clientValue instanceof Pattern) { + clientValue = StringEscapeUtils.escapeJava(new Xeger(((Pattern)clientDslProperty.clientValue).pattern()).generate()) } - return new DslProperty(value, server.serverValue) + return new DslProperty(clientValue, clientDslProperty.clientValue) } - DslProperty $(ServerDslProperty server) { - return value(server) + DslProperty $(ClientDslProperty client) { + return value(client) + } + + DslProperty $(Pattern pattern) { + return value(client(pattern)) + } + + DslProperty $(OptionalProperty property) { + return value(client(property.optionalPatternValue())) } void testMatchers(@DelegatesTo(ResponseBodyMatchers) Closure closure) { diff --git a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy index fdcfbf5f29..54f6c48e4f 100644 --- a/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy +++ b/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy @@ -147,6 +147,27 @@ class StubRunnerExecutorSpec extends Specification { executor.shutdown() } + def 'should generate regex values when message is to be set and it contains regex'() { + given: + MessageVerifier messageVerifier = Mock(MessageVerifier) + StubRunnerExecutor executor = new StubRunnerExecutor(portScanner, messageVerifier, []) + when: + def stubConf = new StubConfiguration('asd', 'asd', 'asd', '') + executor.runStubs(stubRunnerOptions, + new StubRepository(new File('src/test/resources/messages'), + [], new StubRunnerOptionsBuilder().build()), stubConf) + boolean triggered = executor.trigger("trigger") + then: + triggered + 1 * messageVerifier.send({ it -> + !it.toString().contains("cursor") + }, { Map map -> + !map.values().any { it.toString().contains("cursor")} + }, _) + cleanup: + executor.shutdown() + } + Map stubIdsWithPortsFromString(String stubIdsToPortMapping) { return stubIdsToPortMapping.split(',').collectEntries { String entry -> return StubsParser.fromStringWithPort(entry) diff --git a/spring-cloud-contract-stub-runner/src/test/resources/messages/message.groovy b/spring-cloud-contract-stub-runner/src/test/resources/messages/message.groovy new file mode 100644 index 0000000000..0e815b518f --- /dev/null +++ b/spring-cloud-contract-stub-runner/src/test/resources/messages/message.groovy @@ -0,0 +1,27 @@ +org.springframework.cloud.contract.spec.Contract.make { + description 'issue #650' + label 'trigger' + input { + triggeredBy('createNewPerson()') + } + outputMessage { + sentTo 'personEventsTopic' + headers { + [ + header('contentType': 'application/json'), + header('type': 'person'), + header('eventType': 'PersonChangedEvent'), + header('customerId': $(producer(regex(uuid())))) + ] + } + body([ + "type" : 'CREATED', + "personId" : $(producer(regex(uuid())), consumer('0fd552ba-8043-42da-ab97-4fc77e1057c9')), + "userId" : $(producer(optional(regex(uuid()))), consumer('f043ccf1-0b72-423b-ad32-4ef123718897')), + "firstName" : $(regex(nonEmpty())), + "middleName": $(optional(regex(nonEmpty()))), + "lastName" : $(regex(nonEmpty())), + "version" : $(producer(regex(number())), consumer(0l)) + ]) + } +} \ No newline at end of file