diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy index 62d97fdda7..3ab11e9359 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy @@ -62,6 +62,17 @@ class BlockBuilder { return this } + BlockBuilder addAtTheEnd(String toAdd) { + if (builder.charAt(builder.length() - 1) as String == '\n') { + builder.replace(builder.length() - 1, builder.length(), toAdd) + builder << '\n' + } else { + builder << toAdd + } + return this + } + + @Override String toString() { return builder.toString() diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index 1c54d464c9..f6153341d1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -5,6 +5,8 @@ import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.ExecutionProperty +import io.codearte.accurest.dsl.internal.Header +import io.codearte.accurest.dsl.internal.Request /** * @author Jakub Kubrynski @@ -18,14 +20,9 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { super(stubDefinition) } - @Override - protected void when(BlockBuilder bb) { - - } - @Override protected String getResponseAsString() { - return null + return "response.getBody().asString()" } @Override @@ -34,8 +31,9 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { } @Override - protected String addColonIfRequired(String baseString) { - return "$baseString;" + protected BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) { + blockBuilder.addAtTheEnd(';') + return blockBuilder } @Override @@ -60,7 +58,8 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { @Override protected String convertUnicodeEscapesIfRequired(String json) { - return json // TODO: verify if that's fine or escapeJava required + String unescapedJson = StringEscapeUtils.unescapeJavaScript(json) + return StringEscapeUtils.escapeJava(unescapedJson) } @Override @@ -77,4 +76,24 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { protected String getSimpleResponseBodyString(String responseString) { return "Object responseBody = ($responseString);" } + + @Override + protected String getResponseString(Request request) { + return 'ResponseOptions response = given().spec(request)' + } + + @Override + protected String getRequestString() { + return 'MockMvcRequestSpecification request = given()' + } + + @Override + protected String getHeaderString(Header header) { + return ".header(\"${getTestSideValue(header.name)}\", \"${getTestSideValue(header.serverValue)}\")" + } + + @Override + protected String getBodyString(String bodyAsString) { + return ".body(\"$bodyAsString\")" + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy index abf43d77fc..0a5339f0e0 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.builder + import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.GroovyDsl @@ -14,6 +15,9 @@ class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { super(stubDefinition) } + @Override + protected void given(BlockBuilder bb) {} + @Override protected void givenBlock(BlockBuilder bb) { } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index 5580687632..3f92a12f5e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -3,13 +3,16 @@ package io.codearte.accurest.builder import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked +import groovy.transform.TypeCheckingMode import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty +import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.MatchingStrategy import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.Response +import io.codearte.accurest.dsl.internal.Url import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.JsonPaths import io.codearte.accurest.util.JsonToJsonPathsConverter @@ -39,15 +42,11 @@ abstract class MethodBodyBuilder { protected abstract void validateResponseHeadersBlock(BlockBuilder bb) - protected void given(BlockBuilder bb) {} - - protected abstract void when(BlockBuilder bb) - protected abstract String getResponseAsString() protected abstract String addCommentSignIfRequired(String baseString) - protected abstract String addColonIfRequired(String baseString) + protected abstract BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) protected abstract String getResponseBodyPropertyComparisonString(String property, String value) @@ -65,6 +64,14 @@ abstract class MethodBodyBuilder { protected abstract String getSimpleResponseBodyString(String responseString) + protected abstract String getResponseString(Request request) + + protected abstract String getRequestString() + + protected abstract String getHeaderString(Header header) + + protected abstract String getBodyString(String bodyAsString) + void appendTo(BlockBuilder blockBuilder) { blockBuilder.startBlock() @@ -74,6 +81,7 @@ abstract class MethodBodyBuilder { blockBuilder.endBlock() } + protected void thenBlock(BlockBuilder bb) { bb.addLine(addCommentSignIfRequired('then:')) bb.startBlock() @@ -95,6 +103,32 @@ abstract class MethodBodyBuilder { bb.endBlock().addEmptyLine() } + protected void given(BlockBuilder bb) { + bb.addLine(getRequestString()) + bb.indent() + request.headers?.collect { Header header -> + bb.addLine(getHeaderString(header)) + } + if (request.body) { + bb.addLine(getBodyString(bodyAsString)) + } + if (request.multipart) { + multipartParameters?.each { Map.Entry entry -> bb.addLine(getMultipartParameterLine(entry)) } + } + addColonIfRequired(bb) + bb.unindent() + } + + protected void when(BlockBuilder bb) { + bb.addLine(getResponseString(request)) + bb.indent() + + String url = buildUrl(request) + String method = request.method.serverValue.toString().toLowerCase() + + bb.addLine(/.${method}("$url");/) + bb.unindent() + } protected void then(BlockBuilder bb) { validateResponseCodeBlock(bb) @@ -103,7 +137,7 @@ abstract class MethodBodyBuilder { } if (response.body) { bb.endBlock() - bb.addLine('and:').startBlock() + bb.addLine(addCommentSignIfRequired('and:')).startBlock() validateResponseBodyBlock(bb) } } @@ -115,18 +149,21 @@ abstract class MethodBodyBuilder { responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) } if (contentType == ContentType.JSON) { - appendJsonPath(bb, responseAsString) + appendJsonPath(bb, getResponseAsString()) JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) jsonPaths.each { bb.addLine("assertThat(parsedJson)" + it.method()) + addColonIfRequired(bb) } processBodyElement(bb, "", responseBody) } else if (contentType == ContentType.XML) { - bb.addLine(getParsedXmlResponseBodyString(responseAsString)) + bb.addLine(getParsedXmlResponseBodyString(getResponseAsString())) + addColonIfRequired(bb) // TODO xml validation - } else { - bb.addLine(getSimpleResponseBodyString(responseAsString)) + } else { + bb.addLine(getSimpleResponseBodyString(getResponseAsString())) processText(bb, "", responseBody as String) + addColonIfRequired(bb) } } @@ -139,15 +176,18 @@ abstract class MethodBodyBuilder { } protected void appendJsonPath(BlockBuilder blockBuilder, String json) { - blockBuilder.addLine(addColonIfRequired("DocumentContext parsedJson = JsonPath.parse($json)")) + blockBuilder.addLine(("DocumentContext parsedJson = JsonPath.parse($json)")) + addColonIfRequired(blockBuilder) } protected void processText(BlockBuilder blockBuilder, String property, String value) { if (value.startsWith('$')) { value = value.substring(1).replaceAll('\\$value', "responseBody$property") blockBuilder.addLine(value) + addColonIfRequired(blockBuilder) } else { blockBuilder.addLine(getResponseBodyPropertyComparisonString(property, value)) + addColonIfRequired(blockBuilder) } } @@ -226,4 +266,32 @@ abstract class MethodBodyBuilder { processBodyElement(blockBuilder, prop, listElement) } } + + protected String buildUrl(Request request) { + if (request.url) + return getTestSideValue(buildUrlFromUrlPath(request.url)) + if (request.urlPath) + return getTestSideValue(buildUrlFromUrlPath(request.urlPath)) + throw new IllegalStateException("URL is not set!") + } + + + @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) + } + + + private boolean hasQueryParams(Url url) { + return url.queryParameters + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy index 707a2eae42..6bfc8c357f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -9,7 +9,7 @@ import java.util.regex.Pattern * @author Olga Maciaszek-Sharma * @since 2016-02-17 */ -class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder{ +class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { MockMvcJUnitMethodBodyBuilder(GroovyDsl stubDefinition) { super(stubDefinition) @@ -28,10 +28,12 @@ class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder{ } private String createHeaderComparison(Object headerValue) { - return "isEqualTo(\"$headerValue\");" + String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") + return "isEqualTo(\"$escapedHeader\");" } private String createHeaderComparison(Pattern headerValue) { - return "matches(\"$headerValue\");" + String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") + return "matches(\"$escapedHeader\");" } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index 64cf5e4afc..fe18c08a19 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -2,13 +2,8 @@ package io.codearte.accurest.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import groovy.transform.TypeCheckingMode import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header -import io.codearte.accurest.dsl.internal.QueryParameter -import io.codearte.accurest.dsl.internal.Request -import io.codearte.accurest.dsl.internal.Url -import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern @@ -20,36 +15,12 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { super(stubDefinition) } - protected void given(BlockBuilder bb) { - bb.addLine('def request = given()') - bb.indent() - request.headers?.collect { Header header -> - bb.addLine(".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')") - } - if (request.body) { - bb.addLine(".body('''$bodyAsString''')") - } - if (request.multipart) { - multipartParameters?.each { Map.Entry entry -> bb.addLine(getMultipartParameterLine(entry)) } - } - bb.unindent() - } - - protected void when(BlockBuilder bb) { - bb.addLine('def response = given().spec(request)') - bb.indent() - - String url = buildUrl(request) - String method = request.method.serverValue.toString().toLowerCase() - - bb.addLine(/.${method}("$url")/) - bb.unindent() - } - + @Override protected void validateResponseCodeBlock(BlockBuilder bb) { bb.addLine("response.statusCode == $response.status.serverValue") } + @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { response.headers?.collect { Header header -> bb.addLine("response.header('$header.name') ${convertHeaderComparison(header.serverValue)}") @@ -68,30 +39,4 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { protected String getResponseAsString() { return 'response.body.asString()' } - - protected String buildUrl(Request request) { - if (request.url) - return getTestSideValue(buildUrlFromUrlPath(request.url)) - if (request.urlPath) - return getTestSideValue(buildUrlFromUrlPath(request.urlPath)) - throw new IllegalStateException("URL is not set!") - } - - @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) - } - - private boolean hasQueryParams(Url url) { - return url.queryParameters - } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 3f40878d9a..b61807f689 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,22 +1,15 @@ package io.codearte.accurest.builder -import groovy.json.JsonOutput import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty -import io.codearte.accurest.dsl.internal.MatchingStrategy +import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.NamedProperty -import io.codearte.accurest.dsl.internal.QueryParameter -import io.codearte.accurest.util.ContentType -import io.codearte.accurest.util.MapConverter +import io.codearte.accurest.dsl.internal.Request -import static io.codearte.accurest.util.ContentUtils.extractValue import static io.codearte.accurest.util.ContentUtils.getMultipartFileParameterContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader /** * @author Jakub Kubrynski @@ -58,8 +51,8 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { } @Override - protected String addColonIfRequired(String baseString) { - return baseString + protected BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) { + return blockBuilder } @Override @@ -74,11 +67,32 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { @Override protected String getParsedXmlResponseBodyString(String responseString) { - return "def responseBody = new XmlSlurper().parseText($responseAsString)" + return "def responseBody = new XmlSlurper().parseText($responseString)" } @Override protected String getSimpleResponseBodyString(String responseString) { - return "def responseBody = ($responseAsString)" + return "def responseBody = ($responseString)" } + + @Override + protected String getResponseString(Request request) { + return 'def response = given().spec(request)' + } + + @Override + protected String getRequestString() { + return 'def request = given()' + } + + @Override + protected String getHeaderString(Header header) { + return ".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')" + } + + @Override + protected String getBodyString(String bodyAsString) { + return ".body('''$bodyAsString''')" + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index 3148dc6a97..410375b385 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -2,6 +2,8 @@ package io.codearte.accurest.util; import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; +import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; + /** * @author Marcin Grzejszczak */ @@ -11,7 +13,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { private final StringBuffer methodsBuffer; DelegatingJsonVerifiable(JsonVerifiable delegate, - StringBuffer methodsBuffer) { + StringBuffer methodsBuffer) { this.delegate = delegate; this.methodsBuffer = new StringBuffer(methodsBuffer.toString()); } @@ -100,7 +102,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.appendMethodWithQuotedValue("isEqualTo", value); + readyToCheck.appendMethodWithQuotedValue("isEqualTo", escapeJava(value)); } return readyToCheck; } @@ -137,7 +139,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.appendMethodWithQuotedValue("matches", value); + readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value)); } return readyToCheck; } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy new file mode 100644 index 0000000000..7e78ab2475 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy @@ -0,0 +1,973 @@ +package io.codearte.accurest.builder + +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.WireMockStubStrategy +import io.codearte.accurest.dsl.WireMockStubVerifier +import io.codearte.accurest.file.Contract +import jdk.nashorn.internal.ir.annotations.Ignore +import spock.lang.Issue +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.regex.Pattern + +/** + * @author Olga Maciaszek-Sharma + * @since 2015-08-07 + */ +class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStubVerifier { + + def "should generate assertions for simple response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": "a", + "property2": "b" +}""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains('assertThat(parsedJson).field("property1").isEqualTo("a");') + blockBuilder.toString().contains('assertThat(parsedJson).field("property2").isEqualTo("b");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#187") + def "should generate assertions for null and boolean values"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": "true", + "property2": null, + "property3": false +}""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull();""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false);""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#79") + def "should generate assertions for simple response body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#82") + def "should generate proper request when body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + items: ['HOP'] + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains('.body("{\\"items\\":[\\"HOP\\"]}")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#88") + def "should generate proper request when body constructed from GString"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + "property1=VAL1" + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains('.body("\\"property1=VAL1\\"")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("185") + def "should generate assertions for a response body containing map with integers as keys"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property: [ + 14: 0.0, + 7 : 0.0 + ] + ) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(7).isEqualTo(0.0);""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(14).isEqualTo(0.0);""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate assertions for array in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """[ +{ + "property1": "a" +}, +{ + "property2": "b" +}]""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate assertions for array inside response body element"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": [ + { "property2": "test1"}, + { "property3": "test2"} + ] +}""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate assertions for nested objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body '''\ +{ + "property1": "a", + "property2": {"property3": "b"} +} +''' + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate regex assertions for map objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: "a", + property2: value( + client('123'), + server(regex('[0-9]{3}')) + ) + ) + headers { + header('Content-Type': 'application/json') + + } + + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + + def "should generate regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') + + } + + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue(["#126", "#143"]) + def "should generate escaped regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property":" ${value(client('123'), server(regex('\\d+')))}"}""") + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").matches("\\\\d+");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate a call with an url path and query parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + jUnitTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') + jUnitTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue('#169') + def "should generate a call with an url path and query parameters with url containing a pattern"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + jUnitTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') + jUnitTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate test for empty body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method('POST') + url("/ws/payments") + body("") + } + response { + status 406 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains(".body(\"\\\"\\\"\")") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate test for String in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "POST" + url "test" + } + response { + status 200 + body "test" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('Object responseBody = (response.getBody().asString());') + jUnitTest.contains('assertThat(responseBody).isEqualTo("test");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue('113') + def "should generate regex test for String in response header"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue('115') + def "should generate regex with helper method"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should work with more complex stuff and jsonpaths"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + priority 10 + request { + method 'POST' + url '/validation/client' + headers { + header 'Content-Type': 'application/json' + } + body( + bank_account_number: '0014282912345698765432161182', + email: 'foo@bar.com', + phone_number: '100299300', + personal_id: 'ABC123456' + ) + } + + response { + status 200 + body(errors: [ + [property: "bank_account_number", message: "incorrect_format"] + ]) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains("""assertThat(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number");""") + jUnitTest.contains("""assertThat(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + + } + + def "should work properly with GString url"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + + request { + method 'PUT' + url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" + headers { + header 'Content-Type': 'application/json' + } + body( + first_name: 'Josef', + ) + } + response { + status 422 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains("/partners/11/agents/11/customers/09665703Z") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should resolve properties in GString with regular expression"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(client(regex(email())), server('not.existing@user.com')), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: 4, + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') + } + + + @Issue('42') + @Unroll + def "should not omit the optional field in the test creation"() { + given: + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('\\"email\\":\\"abc@abc.com\\"') + jUnitTest.contains('assertThat(parsedJson).field("code").matches("(123123)?");') + !jUnitTest.contains('''REGEXP''') + !jUnitTest.contains('''OPTIONAL''') + !jUnitTest.contains('''OptionalProperty''') + where: + contractDsl << [ + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } + }, + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", + "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" + } + """ + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "code" : "${value(stub(123123), test(optional(123123)))}", + "message" : "User not found by email = [${ + value(server(regex(email())), client('not.existing@user.com')) + }]" + } + """ + ) + } + } + ] + } + + @Issue('72') + @Ignore + //TODO: fix exec method for jUnit + def "should make the execute method work"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + + } + + } + response { + status 200 + body("""{ + "fraudCheckStatus": "OK", + "rejectionReason": ${value(client(null), server(execute('assertThatRejectionReasonIsNull($it)')))} +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + + } + + } + + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''') + } + + def "should support inner map and list definitions"() { + given: + + Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) + Pattern ANYSTRING = Pattern.compile(/.*/) + Pattern NUMBERS = Pattern.compile(/[\d\.]*/) + Pattern DATETIME = ANYSTRING + + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" + headers { + header('Content-Type': 'application/json') + } + body( + client: [ + first_name : $(stub(regex(onlyAlphaUnicode())), test('Denis')), + last_name : $(stub(regex(onlyAlphaUnicode())), test('FakeName')), + email : $(stub(regex(email())), test('fakemail@fakegmail.com')), + fax : $(stub(PHONE_NUMBER), test('+xx001213214')), + phone : $(stub(PHONE_NUMBER), test('2223311')), + data_of_birth: $(stub(DATETIME), test('2002-10-22T00:00:00Z')) + ], + client_id_card: [ + id : $(stub(ANYSTRING), test('ABC12345')), + date_of_issue: $(stub(ANYSTRING), test('2002-10-02T00:00:00Z')), + address : [ + street : $(stub(ANYSTRING), test('Light Street')), + city : $(stub(ANYSTRING), test('Fire')), + region : $(stub(ANYSTRING), test('Skys')), + country: $(stub(ANYSTRING), test('HG')), + zip : $(stub(NUMBERS), test('658965')) + ] + ], + incomes_and_expenses: [ + monthly_income : $(stub(NUMBERS), test('0.0')), + monthly_loan_repayments: $(stub(NUMBERS), test('100')), + monthly_living_expenses: $(stub(NUMBERS), test('22')) + ], + additional_info: [ + allow_to_contact: $(stub(optional(regex(anyBoolean()))), test('true')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains '\\"street\\":\\"Light Street\\"' + !jUnitTest.contains("clientValue") + !jUnitTest.contains("cursor") + } + + def "shouldn't generate unicode escape characters"() { + given: + Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) + + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" + headers { + header('Content-Type': 'application/json') + } + body( + client: [ + first_name: $(stub(ONLY_ALPHA_UNICODE), test('Пенева')), + last_name : $(stub(ONLY_ALPHA_UNICODE), test('Пенева')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + !jUnitTest.contains("\\u041f") + } + + @Issue('177') + def "should generate proper test code when having multiline body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multiline" + body('''hello, +World.''') + } + response { + status 200 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains("""'''hello, +World.'''""") + } + + @Issue('180') + @Ignore + //TODO: fix multiparts in JUnit + def "should generate proper test code when having multipart parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + headers { + header('content-type', 'multipart/form-data;boundary=AaB03x') + } + multipart( + formParameter: value(client(regex('.+')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains("""'content-type', 'multipart/form-data;boundary=AaB03x'""") + jUnitTest.contains(""".param('formParameter', '"formParameterValue"'""") + jUnitTest.contains(""".param('someBooleanParameter', 'true')""") + jUnitTest.contains(""".multiPart('file', 'filename.csv', 'file content'.bytes)""") + } + + @Issue('180') + @Ignore + //TODO: fix multiparts in JUnit + def "should generate proper test code when having multipart parameters with named as map"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + multipart( + formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named( + name: value(client(regex('.+')), server('filename.csv')), + content: value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('.multiPart') + } + + +}