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 fefb71c727..57468993cb 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.PackageScope @@ -28,11 +27,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 @@ -41,6 +42,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 @@ -137,6 +139,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) @@ -183,7 +201,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.java b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContract.java index 615ca30aa0..3bb2b75686 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContract.java +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/YamlContract.java @@ -17,6 +17,7 @@ package org.springframework.cloud.contract.verifier.converter; import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -254,7 +255,14 @@ public class YamlContract { public enum MatchingType { - equal_to, containing, matching, not_matching, equal_to_json, equal_to_xml, absent; + equal_to, containing, matching, not_matching, equal_to_json, equal_to_xml, absent, binary_equal_to; + + static MatchingType from(String string) { + return Arrays.stream(values()) + .filter(matchingType -> matchingType.name().replace("_", "") + .equalsIgnoreCase(string.toLowerCase().replace("_", ""))) + .findFirst().orElse(null); + } } diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy index b0516b735e..3fa8dad012 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy @@ -35,8 +35,6 @@ import org.springframework.util.StringUtils @Commons class ContractVerifierDslConverter { - private static final String SCENARIO_MATCHER = '^[0-9].*$' - /** * @deprecated - use {@link ContractVerifierDslConverter#convertAsCollection(java.io.File, java.lang.String)} */ @@ -137,7 +135,7 @@ class ContractVerifierDslConverter { private static Collection withName(File file, Collection contracts) { int counter = 0 return contracts.collect { - if (contractNameEmpty(it) && !relatedToScenarios(file, it)) { + if (contractNameEmpty(it)) { it.name(NamesUtil.defaultContractName(file, contracts, counter)) } counter++ @@ -148,8 +146,4 @@ class ContractVerifierDslConverter { private static boolean contractNameEmpty(Contract it) { return it != null && StringUtils.isEmpty(it.name) } - - private static boolean relatedToScenarios(File file, Contract contract) { - return contract.name?.matches(SCENARIO_MATCHER) || file.name.matches(SCENARIO_MATCHER) - } } 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 d285dc15fe..f39fc1d2d5 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 @@ -357,7 +357,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 @@ -384,11 +389,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 == [ @@ -402,6 +411,9 @@ class DslToYamlContractConverterSpec extends Specification { value: "[0-9]{10}", regexType: YamlContract.RegexType.as_string), ] + 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 + } +} +