diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ContractsToYaml.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ContractsToYaml.groovy index 6871327d74..65584f06da 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ContractsToYaml.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ContractsToYaml.groovy @@ -16,7 +16,6 @@ package org.springframework.cloud.contract.verifier.converter - import java.util.regex.Pattern import groovy.transform.CompileStatic @@ -29,11 +28,13 @@ import org.springframework.cloud.contract.spec.internal.DslProperty import org.springframework.cloud.contract.spec.internal.ExecutionProperty import org.springframework.cloud.contract.spec.internal.FromFileProperty import org.springframework.cloud.contract.spec.internal.Headers +import org.springframework.cloud.contract.spec.internal.MatchingStrategy import org.springframework.cloud.contract.spec.internal.MatchingType import org.springframework.cloud.contract.spec.internal.Multipart import org.springframework.cloud.contract.spec.internal.NamedProperty import org.springframework.cloud.contract.spec.internal.NotToEscapePattern import org.springframework.cloud.contract.spec.internal.RegexProperty +import org.springframework.cloud.contract.spec.internal.Url import org.springframework.cloud.contract.verifier.converter.YamlContract.RegexType import org.springframework.cloud.contract.verifier.util.ContentType import org.springframework.cloud.contract.verifier.util.JsonPaths @@ -42,6 +43,7 @@ import org.springframework.cloud.contract.verifier.util.MapConverter import static org.springframework.cloud.contract.verifier.util.ContentType.XML import static org.springframework.cloud.contract.verifier.util.ContentUtils.evaluateContentType + /** * @author Marcin Grzejszczak * @author Olga Maciaszek-Sharma @@ -139,6 +141,22 @@ class ContractsToYaml { request.method = contract.request?.method?.serverValue request.url = contract.request?.url?.serverValue request.urlPath = contract.request?.urlPath?.serverValue + request.matchers = new YamlContract.StubMatchers() + Url requestUrl = contract.request.url ?: contract.request.urlPath + if (requestUrl.queryParameters != null) { + request.queryParameters = requestUrl.queryParameters + .parameters.collectEntries { + def testSide = MapConverter.getTestSideValuesForNonBody(it) + def stubSide = it.clientValue + if (stubSide instanceof RegexProperty || stubSide instanceof Pattern) { + request.matchers.queryParameters.add(new YamlContract.QueryParameterMatcher(key: it.name, type: YamlContract.MatchingType.matching, value: new RegexProperty(stubSide).pattern())) + } + else if (stubSide instanceof MatchingStrategy) { + request.matchers.queryParameters.add(new YamlContract.QueryParameterMatcher(key: it.name, type: YamlContract.MatchingType.from(stubSide.getType().name), value: MapConverter.getStubSideValuesForNonBody(stubSide))) + } + return [(it.name): testSide] + } + } request.headers = (contract.request?.headers as Headers)?.asMap { String headerName, DslProperty prop -> def testSideValue = MapConverter.getTestSideValues(prop) @@ -185,7 +203,6 @@ class ContractsToYaml { } } } - request.matchers = new YamlContract.StubMatchers() contract.request?.bodyMatchers?.matchers()?.each { BodyMatcher matcher -> request.matchers.body << new YamlContract.BodyStubMatcher( path: matcher.path(), diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContract.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContract.groovy index c3877673d4..edfbe2858a 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContract.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContract.groovy @@ -93,7 +93,12 @@ class YamlContract { @CompileStatic enum MatchingType { equal_to, containing, matching, not_matching, equal_to_json, - equal_to_xml, absent + equal_to_xml, absent, binary_equal_to + + static MatchingType from(String string) { + return values() + .find { MatchingType type -> (type.name().replace("_", "") == string.toLowerCase().replace("_", "")) } + } } @CompileStatic diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/DslToYamlContractConverterSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/DslToYamlContractConverterSpec.groovy index cc1f702518..5c7270388f 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/DslToYamlContractConverterSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/DslToYamlContractConverterSpec.groovy @@ -354,7 +354,12 @@ class DslToYamlContractConverterSpec extends Specification { List contracts = [Contract.make { request { // (1) method 'PUT' // (2) - url '/fraudcheck' // (3) + urlPath('/fraudcheck') { + queryParameters { + parameter("foo", "bar") + parameter("foo2", $(c(equalToJson('''{"foo":"bar"}''')), p("foo3"))) + } + } body([ // (4) "client.id": $(regex('[0-9]{10}')), loanAmount : 99999 @@ -381,11 +386,15 @@ class DslToYamlContractConverterSpec extends Specification { yamlContracts.size() == 1 YamlContract yamlContract = yamlContracts.first() yamlContract.request.method == "PUT" - yamlContract.request.url == "/fraudcheck" + yamlContract.request.urlPath == "/fraudcheck" + yamlContract.request.queryParameters == [ + foo2: "foo3", + foo : "bar" + ] yamlContract.request.body["client.id"] =~ /[0-9]{10}/ yamlContract.request.body["loanAmount"] == 99999 yamlContract.request.headers == [ - "Content-Type": "application/json", + "Content-Type" : "application/json", "Authorization": 'Bearer SOMETOKEN' ] yamlContract.request.matchers.headers == [ @@ -398,6 +407,9 @@ class DslToYamlContractConverterSpec extends Specification { type: YamlContract.StubMatcherType.by_regex, value: "[0-9]{3}"), ] + yamlContract.request.matchers.queryParameters == [ + new YamlContract.QueryParameterMatcher(key: "foo2", type: YamlContract.MatchingType.equal_to_json, value: '''{"foo":"bar"}'''), + ] yamlContract.response.status == 200 yamlContract.response.body == [fraudCheckStatus : "FRAUD", "rejection.reason": "Amount too high"] diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractSpec.groovy new file mode 100644 index 0000000000..47c2bb92f6 --- /dev/null +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractSpec.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.converter + +import spock.lang.Specification + +class YamlContractSpec extends Specification { + + def "should convert to matching type from string"() { + when: + YamlContract.MatchingType type = YamlContract.MatchingType.from(string) + then: + type == expectedType + where: + string || expectedType + "equalTo" || YamlContract.MatchingType.equal_to + "equalToJson" || YamlContract.MatchingType.equal_to_json + "containing" || YamlContract.MatchingType.containing + "unknown" || null + } +} +