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') + } + }