From 297ee8e2ea0dbd82d4f99e361b3353958d229c82 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 21 Mar 2018 14:03:06 +0100 Subject: [PATCH] Changed the Groovy equals & hashcode usage to manual one there's a bug in Groovy with autogenerated hashCode and byte arrays to fix it we've migrated from the AST to manual hashcode and equals generation fixes gh-546 --- .../contract/spec/internal/DslProperty.groovy | 18 ++++- .../DslToWireMockClientConverterSpec.groovy | 79 +++++++++++++++++-- .../MockMvcMethodBodyBuilderSpec.groovy | 6 +- 3 files changed, 90 insertions(+), 13 deletions(-) diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy index 12a48a5756..e40993229c 100644 --- a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy @@ -17,7 +17,6 @@ package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode import groovy.transform.ToString /** * Represents an element of a DSL that can contain client or sever side values @@ -25,7 +24,6 @@ import groovy.transform.ToString * @since 1.0.0 */ @CompileStatic -@EqualsAndHashCode @ToString(includePackage = false, includeNames = true) class DslProperty { @@ -47,4 +45,20 @@ class DslProperty { (this.clientValue != null && this.serverValue == null ) || (this.serverValue != null && this.clientValue == null ) } + + boolean equals(o) { + if (this.is(o)) return true + if (getClass() != o.class) return false + DslProperty that = (DslProperty) o + if (this.clientValue != that.clientValue) return false + if (this.serverValue != that.serverValue) return false + return true + } + + int hashCode() { + int result + result = (this.clientValue != null ? this.clientValue.hashCode() : 0) + result = 31 * result + (this.serverValue != null ? this.serverValue.hashCode() : 0) + return result + } } diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy index 9ad50a36a7..e51edec8e4 100755 --- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy +++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy @@ -16,6 +16,8 @@ package org.springframework.cloud.contract.verifier.wiremock +import java.util.regex.Pattern + import com.github.tomakehurst.wiremock.junit.WireMockRule import com.github.tomakehurst.wiremock.matching.RegexPattern import com.github.tomakehurst.wiremock.stubbing.StubMapping @@ -23,17 +25,20 @@ import groovy.json.JsonOutput import org.junit.Rule import org.junit.rules.TemporaryFolder import org.skyscreamer.jsonassert.JSONAssert -import org.springframework.boot.test.web.client.TestRestTemplate -import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubMapping -import org.springframework.cloud.contract.spec.Contract -import org.springframework.cloud.contract.verifier.file.ContractMetadata -import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter -import org.springframework.http.RequestEntity -import org.springframework.util.SocketUtils import spock.lang.Issue import spock.lang.Specification -import java.util.regex.Pattern +import org.springframework.boot.test.web.client.TestRestTemplate +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubMapping +import org.springframework.cloud.contract.verifier.file.ContractMetadata +import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter +import org.springframework.core.io.ByteArrayResource +import org.springframework.http.HttpEntity +import org.springframework.http.RequestEntity +import org.springframework.util.LinkedMultiValueMap +import org.springframework.util.MultiValueMap +import org.springframework.util.SocketUtils class DslToWireMockClientConverterSpec extends Specification { @@ -78,6 +83,64 @@ class DslToWireMockClientConverterSpec extends Specification { restTemplate.exchange(RequestEntity.put("${url}/12".toURI()).body(""), String) } + @Issue("#546") + def "should convert DSL file to WireMock JSON with byte arrays"() { + given: + def converter = new DslToWireMockClientConverter() + and: + File file = tmpFolder.newFile("dsl1.groovy") + file.write(""" + [ + org.springframework.cloud.contract.spec.Contract.make { + request { + method "POST" + url "/multipart" + headers { + contentType('multipart/form-data') + } + multipart( + file: named( + name: value(stub(regex('.+')), test('file')), + content: value(stub(regex('.+')), test([100, 117, 100, 97] as byte[])) + ) + ) + } + response { + status 200 + body "hello" + } + } + ] +""") + when: + String json = converter.convertContents("Test", new ContractMetadata(file.toPath(), false, 0, null, + ContractVerifierDslConverter.convertAsCollection(new File("/"),file))).values().first() + then: + JSONAssert.assertEquals(''' +{"request":{"url":"/multipart","method":"POST","headers":{"Content-Type":{"matches":"multipart/form-data.*"}},"bodyPatterns":[{"matches" : ".*--(.*)\\r\\nContent-Disposition: form-data; name=\\"file\\"; filename=\\".+\\"\\r\\n(Content-Type: .*\\r\\n)?(Content-Transfer-Encoding: .*\\r\\n)?(Content-Length: \\\\d+\\r\\n)?\\r\\n.+\\r\\n--\\\\1.*"}]},"response":{"status":200,"body":"hello","transformers":["response-template"]}} +''', json, false) + and: + StubMapping mapping = stubMappingIsValidWireMockStub(json) + and: + wireMockRule.addStubMapping(mapping) + and: + MultiValueMap parameters = new LinkedMultiValueMap() + parameters.add("file", new ByteArrayResource([100, 117, 100, 97] as byte[]) { + @Override + public String getFilename(){ + return "file" + } + }) + org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders() + headers.set("Content-Type", "multipart/form-data;boundary=AaB03xssssss") + headers.set("Accept", "text/plain") + String result = restTemplate.postForObject( + "${url}/multipart", + new HttpEntity>(parameters, headers), + String.class) + result == "hello" + } + def "should convert DSL file with list of contracts to WireMock JSONs"() { given: def converter = new DslToWireMockClientConverter() 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 7a6e19bc39..4837784a36 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 @@ -1232,7 +1232,7 @@ World.'''""" multipart( file: named( name: value(stub(regex('.+')), test('file')), - content: value(stub(regex('.+')), test([100, 117, 112, 97] as byte[])) + content: value(stub(regex('.+')), test([100, 117, 100, 97] as byte[])) ) ) } @@ -1255,9 +1255,9 @@ World.'''""" where: methodBuilderName | methodBuilder | requestStrings "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - """.multiPart('file', 'file', [100, 117, 112, 97] as byte[])"""] + """.multiPart('file', 'file', [100, 117, 100, 97] as byte[])"""] "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"Content-Type", "multipart/form-data;boundary=AaB03x"', - '.multiPart("file", "file", new byte[] {100, 117, 112, 97});'] + '.multiPart("file", "file", new byte[] {100, 117, 100, 97});'] } @Issue('541')