From ced19c2c8a918116349dedaa164aba21147ee428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Fejzer?= Date: Mon, 30 Nov 2015 15:53:19 +0100 Subject: [PATCH 1/4] Add Multipart and NamedProperty --- .../MockMvcSpockMethodBodyBuilder.groovy | 6 ++- .../builder/SpockMethodBodyBuilder.groovy | 12 ++++++ .../accurest/dsl/internal/Common.groovy | 4 ++ .../accurest/dsl/internal/Multipart.groovy | 41 +++++++++++++++++++ .../dsl/internal/NamedProperty.groovy | 19 +++++++++ .../accurest/dsl/internal/Request.groovy | 22 ++++++++++ .../MockMvcSpockMethodBuilderSpec.groovy | 25 +++++++++++ 7 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy 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 c913d97acf..a80ce77f89 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 @@ -1,6 +1,5 @@ package io.codearte.accurest.builder -import java.util.regex.Pattern import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode @@ -11,6 +10,8 @@ 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 + @PackageScope @TypeChecked class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { @@ -28,6 +29,9 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { if (request.body) { bb.addLine(".body('''$bodyAsString''')") } + if (request.multipart) { + bb.addLine(".multiPart('''$fileAsString''', '''$filenameAsString''', '''$fileContentAsString'''.bytes)") + } bb.unindent() } 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 192ec4a2ab..ddd905e711 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 @@ -122,6 +122,18 @@ abstract class SpockMethodBodyBuilder { return trimRepeatedQuotes(json) } + protected String getFileContentAsString() { + return request.multipart.serverValue //TODO replace to working extraction + } + + protected String getFilenameAsString() { + return request.multipart.serverValue //TODO replace to working extraction + } + + protected String getFileAsString() { + return request.multipart.serverValue //TODO replace to working extraction + } + protected String convertUnicodeEscapes(String json) { return StringEscapeUtils.unescapeJavaScript(json) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index c96ff4b2d4..89ab8252d2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -48,6 +48,10 @@ class Common { return property } + NamedProperty named(DslProperty name, DslProperty value){ + return new NamedProperty(name, value) + } + DslProperty value(ClientDslProperty client, ServerDslProperty server) { assertThatSidesMatch(client.clientValue, server.serverValue) return new DslProperty(client.clientValue, server.serverValue) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy new file mode 100644 index 0000000000..b11bd85db2 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy @@ -0,0 +1,41 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class Multipart extends DslProperty { + + Multipart(Map multipart) { + super(extractValue(multipart, { DslProperty p -> p.clientValue}), extractValue(multipart, {DslProperty p -> p.serverValue})) + } + + private static Map extractValue(Map multipart, Closure valueProvider) { + multipart.collectEntries { Map.Entry entry -> + [(entry.key): valueProvider(entry.value)] + } as Map + } + + Multipart(List multipartAsList) { + super(multipartAsList.collect { DslProperty p -> p.clientValue }, multipartAsList.collect { DslProperty p -> p.serverValue }) + } + + Multipart(Object multipartAsValue) { + this("${multipartAsValue}") + } + + Multipart(GString multipartAsValue) { + super(multipartAsValue, multipartAsValue) + } + + Multipart(DslProperty multipartAsValue) { + super(multipartAsValue.clientValue, multipartAsValue.serverValue) + } + + Multipart(MatchingStrategy matchingStrategy) { + super(matchingStrategy, matchingStrategy) + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy new file mode 100644 index 0000000000..b02a6a2c3f --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy @@ -0,0 +1,19 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class NamedProperty { + + DslProperty name + DslProperty value + + NamedProperty(DslProperty name, DslProperty value) { + this.name = name + this.value = value + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 9adf7048a8..0ddff73bdc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -14,6 +14,7 @@ class Request extends Common { UrlPath urlPath Headers headers Body body + Multipart multipart Request() { } @@ -24,6 +25,7 @@ class Request extends Common { this.urlPath = request.urlPath this.headers = request.headers this.body = request.body + this.multipart = request.multipart } void method(String method) { @@ -100,6 +102,26 @@ class Request extends Common { return body } + void multipart(Map body) { + this.multipart = new Multipart(convertObjectsToDslProperties(body)) + } + + void multipart(List multipartAsList) { + this.multipart = new Multipart(convertObjectsToDslProperties(multipartAsList)) + } + + void multipart(DslProperty dslProperty) { + this.multipart = new Multipart(dslProperty) + } + + void multipart(Object multipartAsValue) { + this.multipart = new Multipart(multipartAsValue) + } + + Multipart getMultipart() { + return multipart + } + MatchingStrategy equalTo(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 56da904a8e..d98b2b1e64 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -836,4 +836,29 @@ World.''') World.'''""") } + def "should generate proper test code when having multipart parameters"(){ + 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(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('.multiPart') + } + } From c481572c32a4d75731182304fca0f1291c212f74 Mon Sep 17 00:00:00 2001 From: Milosz Rembisz Date: Tue, 1 Dec 2015 10:51:58 +0100 Subject: [PATCH 2/4] generating client stub from multipart dsl --- .../dsl/WireMockRequestStubStrategy.groovy | 32 +++++++++++-- .../accurest/dsl/internal/Common.groovy | 4 ++ .../dsl/internal/RegexPatterns.groovy | 8 ++++ .../MockMvcSpockMethodBuilderSpec.groovy | 30 ++++++++++++ .../accurest/dsl/WireMockGroovyDslSpec.groovy | 46 +++++++++++++++++++ 5 files changed, 117 insertions(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index cf69737c95..03304bdbc3 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -6,16 +6,25 @@ import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode -import io.codearte.accurest.dsl.internal.* +import io.codearte.accurest.dsl.internal.Body +import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.MatchingStrategy +import io.codearte.accurest.dsl.internal.NamedProperty +import io.codearte.accurest.dsl.internal.QueryParameters +import io.codearte.accurest.dsl.internal.RegexPatterns +import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.ContentUtils -import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.JsonPaths +import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.* +import static io.codearte.accurest.util.ContentUtils.getEqualsTypeFromContentType +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromMatchingStrategy import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpForStubSide import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch @@ -37,6 +46,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { appendUrl(requestPattern) appendQueryParameters(requestPattern) appendBody(requestPattern) + appendMultipart(requestPattern) return requestPattern } @@ -69,6 +79,22 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { requestPattern.bodyPatterns = [convertToValuePattern(getMatchingStrategy(request.body.clientValue))] } } + + private void appendMultipart(RequestPattern requestPattern) { + if (!request.multipart) { + return + } + + if (request.multipart.clientValue instanceof Map) { + List multipartPatterns = (request.multipart.clientValue as Map).collect { + (it.value instanceof NamedProperty + ? ValuePattern.matches(RegexPatterns.multipartFile(it.key, (it.value as NamedProperty).name.clientValue, (it.value as NamedProperty).value.clientValue)) + : ValuePattern.matches(RegexPatterns.multipartParam(it.key, it.value)) ) + } + + requestPattern.bodyPatterns ? requestPattern.bodyPatterns.addAll(multipartPatterns) : (requestPattern.bodyPatterns = multipartPatterns) + } + } private void appendHeaders(RequestPattern requestPattern) { if(!request.headers) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 89ab8252d2..cdf6d3db1f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -52,6 +52,10 @@ class Common { return new NamedProperty(name, value) } + NamedProperty named(Map namedMap){ + return new NamedProperty(namedMap.get('name'), namedMap.get('content')) + } + DslProperty value(ClientDslProperty client, ServerDslProperty server) { assertThatSidesMatch(client.clientValue, server.serverValue) return new DslProperty(client.clientValue, server.serverValue) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy index 3daa34ec90..1c18226fd9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy @@ -43,4 +43,12 @@ class RegexPatterns { String url() { return URL.pattern() } + + static String multipartParam(Object name, Object value) { + return ".*--(.*)\r\nContent-Disposition: form-data; name=\"$name\"\r\n(Content-Type: .*\r\n)?(Content-Length: \\d+\r\n)?\r\n$value\r\n--\\1.*" + } + + static String multipartFile(Object name, Object filename, Object content) { + return ".*--(.*)\r\nContent-Disposition: form-data; name=\"$name\"; filename=\"$filename\"\r\n(Content-Type: .*\r\n)?(Content-Length: \\d+\r\n)?\r\n$content\r\n--\\1.*"; + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index d98b2b1e64..195886ce0e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.builder + import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier @@ -7,6 +8,7 @@ import spock.lang.Specification import spock.lang.Unroll import java.util.regex.Pattern + /** * @author Jakub Kubrynski */ @@ -861,4 +863,32 @@ World.'''""") spockTest.contains('.multiPart') } + 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 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('.multiPart') + } + + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy index 7502ada771..866a451f47 100755 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy @@ -1398,4 +1398,50 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie String toWireMockClientJsonStub(groovyDsl) { new WireMockStubStrategy(groovyDsl).toWireMockClientStub() } + + @Issue('180') + @Unroll + def 'should generate stub with multipart parameters'() { + 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 + } + } + when: + String wireMockStub = new WireMockStubStrategy(contractDsl).toWireMockClientStub() + then: + println wireMockStub + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "url" : "/multipart", + "method" : "PUT", + "bodyPatterns" : [ { + "matches" : ".*--(.*)\\r\\nContent-Disposition: form-data; name=\\"formParameter\\"\\r\\n(Content-Type: .*\\r\\n)?(Content-Length: \\\\d+\\r\\n)?\\r\\n\\".+\\"\\r\\n--\\\\1.*" + }, { + "matches" : ".*--(.*)\\r\\nContent-Disposition: form-data; name=\\"someBooleanParameter\\"\\r\\n(Content-Type: .*\\r\\n)?(Content-Length: \\\\d+\\r\\n)?\\r\\n(true|false)\\r\\n--\\\\1.*" + }, { + "matches" : ".*--(.*)\\r\\nContent-Disposition: form-data; name=\\"file\\"; filename=\\".+\\"\\r\\n(Content-Type: .*\\r\\n)?(Content-Length: \\\\d+\\r\\n)?\\r\\n.+\\r\\n--\\\\1.*" + } ] + }, + "response" : { + "status" : 200 + } + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } } From 683fb9b732a43d558c1a3ffd24c94c31a0055217 Mon Sep 17 00:00:00 2001 From: Wiktor Szwechowicz Date: Tue, 1 Dec 2015 11:38:00 +0100 Subject: [PATCH 3/4] Add support for multipart on server side --- .../builder/MockMvcSpockMethodBodyBuilder.groovy | 2 +- .../builder/SpockMethodBodyBuilder.groovy | 15 +++++++-------- .../io/codearte/accurest/util/ContentUtils.groovy | 5 +++++ .../builder/MockMvcSpockMethodBuilderSpec.groovy | 12 ++++++++++-- 4 files changed, 23 insertions(+), 11 deletions(-) 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 a80ce77f89..8e8b7a9f4b 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 @@ -30,7 +30,7 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { bb.addLine(".body('''$bodyAsString''')") } if (request.multipart) { - bb.addLine(".multiPart('''$fileAsString''', '''$filenameAsString''', '''$fileContentAsString'''.bytes)") + multipartParameters.each { entry -> bb.addLine(getMultipartParameterLine(entry)) } } bb.unindent() } 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 ddd905e711..8bbd5a0a07 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 @@ -122,16 +122,15 @@ abstract class SpockMethodBodyBuilder { return trimRepeatedQuotes(json) } - protected String getFileContentAsString() { - return request.multipart.serverValue //TODO replace to working extraction + protected Map getMultipartParameters() { + return (Map)request.multipart.serverValue } - protected String getFilenameAsString() { - return request.multipart.serverValue //TODO replace to working extraction - } - - protected String getFileAsString() { - return request.multipart.serverValue //TODO replace to working extraction + protected String getMultipartParameterLine(Map.Entry parameter) { + if (parameter.value instanceof NamedProperty) { + return ".multiPart(${getMultipartFileParameterContent(parameter.key, (NamedProperty) parameter.value)})" + } + return ".param('$parameter.key', '$parameter.value')" } protected String convertUnicodeEscapes(String json) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 1b370b7126..e73990d9f4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -8,6 +8,7 @@ import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.dsl.internal.MatchingStrategy +import io.codearte.accurest.dsl.internal.NamedProperty import io.codearte.accurest.dsl.internal.OptionalProperty import org.codehaus.groovy.runtime.GStringImpl @@ -320,4 +321,8 @@ class ContentUtils { return ContentType.UNKNOWN } + static String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) { + return "'$propertyName', '$propertyValue.name.serverValue', '$propertyValue.value.serverValue'.bytes" + } + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 195886ce0e..f5217c6266 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -838,14 +838,18 @@ World.''') World.'''""") } + @Issue('180') 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"')), + 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'))) ) @@ -860,9 +864,13 @@ World.'''""") builder.given(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('.multiPart') + spockTest.contains("""'content-type', 'multipart/form-data;boundary=AaB03x'""") + spockTest.contains(""".param('formParameter', '"formParameterValue"'""") + spockTest.contains(""".param('someBooleanParameter', 'true')""") + spockTest.contains(""".multiPart('file', 'filename.csv', 'file content'.bytes)""") } + @Issue('180') def "should generate proper test code when having multipart parameters with named as map"() { given: GroovyDsl contractDsl = GroovyDsl.make { From 61e435e543ee747400138decfa35ad3de6ed03c1 Mon Sep 17 00:00:00 2001 From: Milosz Rembisz Date: Wed, 2 Dec 2015 12:56:51 +0100 Subject: [PATCH 4/4] review fixes --- .../accurest/builder/MockMvcSpockMethodBodyBuilder.groovy | 2 +- .../codearte/accurest/builder/SpockMethodBodyBuilder.groovy | 2 +- .../groovy/io/codearte/accurest/dsl/internal/Common.groovy | 2 +- .../io/codearte/accurest/dsl/internal/Multipart.groovy | 2 +- .../io/codearte/accurest/dsl/internal/NamedProperty.groovy | 6 ++++++ .../groovy/io/codearte/accurest/dsl/internal/Request.groovy | 4 ---- 6 files changed, 10 insertions(+), 8 deletions(-) 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 8e8b7a9f4b..64cf5e4afc 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 @@ -30,7 +30,7 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { bb.addLine(".body('''$bodyAsString''')") } if (request.multipart) { - multipartParameters.each { entry -> bb.addLine(getMultipartParameterLine(entry)) } + multipartParameters?.each { Map.Entry entry -> bb.addLine(getMultipartParameterLine(entry)) } } bb.unindent() } 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 8bbd5a0a07..ecff2bc043 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 @@ -123,7 +123,7 @@ abstract class SpockMethodBodyBuilder { } protected Map getMultipartParameters() { - return (Map)request.multipart.serverValue + return (Map)request?.multipart?.serverValue } protected String getMultipartParameterLine(Map.Entry parameter) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index cdf6d3db1f..a6d86e080b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -53,7 +53,7 @@ class Common { } NamedProperty named(Map namedMap){ - return new NamedProperty(namedMap.get('name'), namedMap.get('content')) + return new NamedProperty(namedMap) } DslProperty value(ClientDslProperty client, ServerDslProperty server) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy index b11bd85db2..1ebc06e1e7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy @@ -14,7 +14,7 @@ class Multipart extends DslProperty { } private static Map extractValue(Map multipart, Closure valueProvider) { - multipart.collectEntries { Map.Entry entry -> + return multipart.collectEntries { Map.Entry entry -> [(entry.key): valueProvider(entry.value)] } as Map } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy index b02a6a2c3f..70c6d30879 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy @@ -9,6 +9,8 @@ import groovy.transform.ToString @CompileStatic class NamedProperty { + private static final String NAME = 'name' + private static final String CONTENT = 'content' DslProperty name DslProperty value @@ -16,4 +18,8 @@ class NamedProperty { this.name = name this.value = value } + + NamedProperty(Map namedMap) { + this(namedMap?.get(NAME), namedMap?.get(CONTENT)) + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 0ddff73bdc..54d57e8c53 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -118,10 +118,6 @@ class Request extends Common { this.multipart = new Multipart(multipartAsValue) } - Multipart getMultipart() { - return multipart - } - MatchingStrategy equalTo(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) }