diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy index 070b86ba30..16f89a5dec 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy @@ -1,17 +1,17 @@ /* - * Copyright 2013-2016 the original author or authors. + *Copyright 2013-2016 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 + *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 * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://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. + *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.builder @@ -26,6 +26,7 @@ import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.MatchingStrategy import org.springframework.cloud.contract.spec.internal.NamedProperty import org.springframework.cloud.contract.spec.internal.QueryParameter +import org.springframework.cloud.contract.spec.internal.QueryParameters import org.springframework.cloud.contract.spec.internal.Response import org.springframework.cloud.contract.spec.internal.Url import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties @@ -50,6 +51,7 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { protected final Request request protected final Response response + private static final String DOUBLE_QUOTE = '"' RequestProcessingMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { super(configProperties) @@ -106,14 +108,50 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { bb.addLine(getInputString(request)) bb.indent() - String url = buildUrl(request) - String method = request.method.serverValue.toString().toLowerCase() - - bb.addLine(/.${method}($url)/) + Url url = getUrl(request) + + addUrlParameters(url, bb) addColonIfRequired(bb) + bb.unindent() } + @TypeChecked(TypeCheckingMode.SKIP) + private addUrlParameters(Url buildUrl, BlockBuilder bb) { + String url =MapConverter.getTestSideValues(buildUrl) + String method = request.method.serverValue.toString().toLowerCase() + + if(hasQueryParams(buildUrl)){ + List queryParameters = buildUrl.queryParameters.parameters.findAll(this.&allowedQueryParameter) + bb.addLine(/.${method}(${DOUBLE_QUOTE}${url}?${buildQueryParameterTemplates(queryParameters)}${DOUBLE_QUOTE},${buildQueryParameterValues(queryParameters)})/) + } + else + bb.addLine(/.${method}(${DOUBLE_QUOTE}${url}${DOUBLE_QUOTE})/) + } + + + @TypeChecked(TypeCheckingMode.SKIP) + protected String buildQueryParameterTemplates(List queryParameters){ + final String open = '{' + final String close ='}' + String params = queryParameters + .inject([] as List) { List result, QueryParameter param -> + result << "${param.name}=${open}${param.name}${close}" + } + .join('&') + return "$params" + } + + @TypeChecked(TypeCheckingMode.SKIP) + protected String buildQueryParameterValues(List queryParameters){ + String params = queryParameters + .inject([] as List) { List result, QueryParameter param -> + result << "${DOUBLE_QUOTE}${resolveParamValue(param).toString()}${DOUBLE_QUOTE}" + } + .join(',') + return "$params" + } + @Override protected void then(BlockBuilder bb) { validateResponseCodeBlock(bb) @@ -163,35 +201,17 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { } /** - * Builds a String URL from {@link Request}'s test side values. It can be + * Returns a String URL from {@link Request}'s test side values. It can be * a concrete value of the URL or a path. */ - protected String buildUrl(Request request) { + protected Url getUrl(Request request) { if (request.url) - return getTestSideValue(buildUrlFromUrlPath(request.url)) + return request.url if (request.urlPath) - return getTestSideValue(buildUrlFromUrlPath(request.urlPath)) + return request.urlPath throw new IllegalStateException("URL is not set!") } - /** - * Depending on the presence of query parameters builds the String value - * of the URL. Retrieves any present test side values - */ - @TypeChecked(TypeCheckingMode.SKIP) - protected String buildUrlFromUrlPath(Url url) { - if (hasQueryParams(url)) { - String params = url.queryParameters.parameters - .findAll(this.&allowedQueryParameter) - .inject([] as List) { List result, QueryParameter param -> - result << "${param.name}=${resolveParamValue(param).toString()}" - } - .join('&') - return "${MapConverter.getTestSideValues(url.serverValue)}?$params" - } - return MapConverter.getTestSideValues(url.serverValue) - } - /** * Returns a line of code to send a multi part parameter in the request */ @@ -202,7 +222,6 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { return getParameterString(parameter) } - private boolean hasQueryParams(Url url) { return url.queryParameters } diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy index 7677e08e16..79518e475b 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -559,7 +559,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - test.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + test.contains('get("/users?limit={limit}&offset={offset}&filter={filter}&sort={sort}&search={search}&age={age}&name={name}&email={email}","10","20","email","name","55","99","Denis.Stepanov","bob@email.com")') test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: @@ -607,7 +607,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - test.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + test.contains('get("/foo/123456?limit={limit}&offset={offset}&filter={filter}&sort={sort}&search={search}&age={age}&name={name}&email={email}","10","20","email","name","55","99","Denis.Stepanov","bob@email.com")') test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: