From 3ca2cd35cbcb7476a8feb14a5272212d5478337d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 22 Feb 2015 10:50:27 +0100 Subject: [PATCH] Fixed header generation (someone can review this code later ;) ) --- .../wiremock/WiremockToDslConverter.groovy | 12 ++- .../WiremockToDslConverterSpec.groovy | 23 ++-- .../builder/SpockMethodBodyBuilder.groovy | 10 +- .../dsl/BaseWiremockStubStrategy.groovy | 53 ++++----- .../dsl/WiremockRequestStubStrategy.groovy | 2 +- .../dsl/WiremockResponseStubStrategy.groovy | 4 +- .../accurest/dsl/internal/Header.groovy | 23 ++++ .../accurest/dsl/internal/Headers.groovy | 25 ++--- .../dsl/internal/WithValuePattern.groovy | 102 ------------------ .../dsl/WiremockGroovyDslResponseSpec.groovy | 6 +- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 23 ++-- 11 files changed, 90 insertions(+), 193 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy delete mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index 7cc47e2bf8..d6da45bef5 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,5 +1,4 @@ package io.codearte.accurest.wiremock - import groovy.io.FileType import groovy.json.JsonOutput import groovy.json.JsonSlurper @@ -29,7 +28,7 @@ class WiremockToDslConverter { def assertion = it.value String headerName = it.key as String def entry = assertion.entrySet().first() - """header(\"\"\"$headerName\"\"\").$entry.key(\"\"\"${escapeJava(entry.value)}\"\"\")\n""" + """header(\"\"\"$headerName\"\"\", ${buildHeader(entry.key, entry.value)})\n""" }.join('') } } @@ -49,6 +48,15 @@ class WiremockToDslConverter { """ } + private String buildHeader(String method, Object value) { + switch (method) { + case 'equalTo': + return wrapWithMultilineGString(value) + default: + return "regex(${wrapWithMultilineGString(escapeJava(value as String))})" + } + } + private Object buildBody(Map responseBody) { return responseBody.entrySet().collectAll(withQuotedMapStringElements()).inject([:], appendToIterable()) } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index a2e7435cf8..35a5c88caf 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -16,9 +16,6 @@ class WiremockToDslConverterSpec extends Specification { "Accept": { "matches": "text/.*" }, - "etag": { - "doesNotMatch": "abcd.*" - }, "X-Custom-Header": { "contains": "2134" } @@ -46,9 +43,15 @@ class WiremockToDslConverterSpec extends Specification { method 'GET' url '/path' headers { - header('Accept').matches('text/.*') - header('etag').doesNotMatch('abcd.*') - header('X-Custom-Header').contains('2134') + header('Accept': $( + client(regex('text/.*')), + server('text/plain') + )) + header('X-Custom-Header': $( + client(regex('^.*2134.*$')), + server('121345') + )) + } } response { @@ -103,7 +106,7 @@ class WiremockToDslConverterSpec extends Specification { method 'DELETE' url $(client(~/\/credit-card-verification-data\/[0-9]+/), server('')) headers { - header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') + header('Content-Type': 'application/vnd.mymoid-adapter.v2+json; charset=UTF-8') } } response { @@ -154,7 +157,7 @@ class WiremockToDslConverterSpec extends Specification { method 'POST' url '/charge/count' headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + header('Content-Type': 'application/vnd.creditcard-reporter.v1+json') } } response { @@ -207,7 +210,7 @@ class WiremockToDslConverterSpec extends Specification { method 'POST' url '/charge/count' headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + header('Content-Type': 'application/vnd.creditcard-reporter.v1+json') } } response { @@ -257,7 +260,7 @@ class WiremockToDslConverterSpec extends Specification { method 'POST' url '/charge/search?pageNumber=0&size=2147483647' headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + header('Content-Type': 'application/vnd.creditcard-reporter.v1+json') } } response { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 6adbe09902..f37f74143f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -18,8 +18,8 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('given:').startBlock() blockBuilder.addLine('def request = given()') blockBuilder.indent() - stubDefinition.request.headers.valueHeaders().each { - blockBuilder.addLine(".header('$it.key', '$it.value')") + stubDefinition.request.headers.headers.collectEntries { [(it.name): it.serverValue] }.each { Map.Entry entry -> + blockBuilder.addLine(".header('${entry.key}', '${entry.value}')") } if (stubDefinition.request.body) { String matches = new JsonOutput().toJson(stubDefinition.request.body.serverValue) @@ -31,14 +31,14 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('when:').startBlock() blockBuilder.addLine('def response = given().spec(request)') blockBuilder.indent() - blockBuilder.addLine(".${stubDefinition.request.method. serverValue.toLowerCase()}(\"$stubDefinition.request.url.serverValue\")") + blockBuilder.addLine(".${stubDefinition.request.method.serverValue.toLowerCase()}(\"$stubDefinition.request.url.serverValue\")") blockBuilder.unindent().endBlock().addEmptyLine() blockBuilder.addLine('then:').startBlock() blockBuilder.addLine("response.statusCode == $stubDefinition.response.status.serverValue") - stubDefinition.response.headers?.valueHeaders().each { - blockBuilder.addLine("response.header('$it.key') == '$it.value'") + stubDefinition.response.headers?.headers?.collectEntries { [(it.name): it.serverValue] }?.each { Map.Entry entry -> + blockBuilder.addLine("response.header('$entry.key') == '$entry.value'") } if (stubDefinition.response.body) { blockBuilder.endBlock() diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index 9dad3f56ea..3052e7efd4 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,56 +1,41 @@ package io.coderate.accurest.dsl -import groovy.transform.CompileStatic -import io.coderate.accurest.dsl.internal.DslProperty +import groovy.transform.TypeChecked +import io.coderate.accurest.dsl.internal.Header import io.coderate.accurest.dsl.internal.Headers -import io.coderate.accurest.dsl.internal.WithValuePattern -@CompileStatic +import java.util.regex.Pattern + +@TypeChecked abstract class BaseWiremockStubStrategy { - protected Map buildClientHeadersSection(Headers headers) { + protected Map buildClientRequestHeadersSection(Headers headers) { if (!headers) { return null } - return withAssertionHeaders(headers) { - Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] - } << headers.valueHeaders() + return headers.headers.collectEntries { Header entry -> + parseHeader(entry.name, entry.clientValue) + } } - protected Map buildServerHeadersSection(Headers headers) { + protected Map buildClientResponseHeadersSection(Headers headers) { if (!headers) { return null } - return withAssertionHeaders(headers) { - Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] - } << headers.valueHeaders() + return headers.headers.collectEntries { Header entry -> + [(entry.name) : entry.clientValue] + } } - private Map withAssertionHeaders(Headers headers, Closure closure) { - return headers?.assertionEntries()?.collectEntries(closure) + protected Map parseHeader(String entryKey, Object entry) { + return [(entryKey): [equalTo : entry]] } - private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { - return getValuePatternSection(valuePattern) - .findAll { it.value } - .collectEntries { [(it.key): it.value.clientValue] } + protected Map parseHeader(String entryKey, String entry) { + return [(entryKey): [equalTo : entry]] } - private Map buildServerHeaderFromValuePattern(WithValuePattern valuePattern) { - return getValuePatternSection(valuePattern) - .findAll { it.value } - .collectEntries { [(it.key): it.value.serverValue] } + protected Map parseHeader(String entryKey, Pattern entry) { + return [(entryKey): [matches : entry.pattern()]] } - private Map getValuePatternSection(WithValuePattern valuePattern) { - return [equalToJson : valuePattern.equalToJson, - equalToXml : valuePattern.equalToXml, - matchesXPath : valuePattern.matchesXPath, - jsonCompareMode: valuePattern.jsonCompareMode, - equalTo : valuePattern.equalTo, - contains : valuePattern.contains, - matches : valuePattern.matches, - doesNotMatch : valuePattern.doesNotMatch, - absent : valuePattern.absent, - matchesJsonPath: valuePattern.matchesJsonPath] - } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 95177f16bc..65d6dea03a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -28,7 +28,7 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map buildRequestContent(ClientRequest request) { return ([method : request?.method?.clientValue, - headers : buildClientHeadersSection(request.headers) + headers : buildClientRequestHeadersSection(request.headers) ] << appendUrl(request) << appendBody(request)).findAll { it.value } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index 2f27d4293d..a1d9f2eb68 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -1,10 +1,8 @@ package io.coderate.accurest.dsl - import groovy.transform.CompileStatic import groovy.transform.PackageScope import io.coderate.accurest.dsl.internal.ClientResponse import io.coderate.accurest.dsl.internal.Response -import io.coderate.accurest.dsl.internal.ServerResponse @CompileStatic @PackageScope @@ -24,6 +22,6 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { private Map buildResponseContent(ClientResponse response) { return [status : response?.status?.clientValue, body : response?.body?.clientValue, - headers: buildClientHeadersSection(response.headers)].findAll { it.value } + headers: buildClientResponseHeadersSection(response.headers)].findAll { it.value } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy new file mode 100644 index 0000000000..90de0873f8 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy @@ -0,0 +1,23 @@ +package io.coderate.accurest.dsl.internal +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@CompileStatic +class Header extends DslProperty { + + String name + + Header(String name, DslProperty dslProperty) { + super(dslProperty.clientValue, dslProperty.serverValue) + this.name = name + } + + Header(String name, Object value) { + super(value) + this.name = name + } + +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 625fd8658c..06e294e488 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -2,31 +2,22 @@ package io.coderate.accurest.dsl.internal import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +import groovy.transform.TypeChecked @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@TypeChecked class Headers { - private Map assertionHeaders = [:] - private Map valueHeaders = [:] + Set
headers = [] - WithValuePattern header(String headerName) { - WithValuePattern withValuePattern = new WithValuePattern() - assertionHeaders[headerName] = withValuePattern - return withValuePattern + void header(Map singleHeader) { + Map.Entry first = singleHeader.entrySet().first() + headers << new Header(first?.key, first?.value) } - void header(Map singleHeader) { - Map.Entry first = singleHeader.entrySet().first() - valueHeaders[first?.key] = first?.value - } - - Map valueHeaders() { - return Collections.unmodifiableMap(valueHeaders) - } - - Set> assertionEntries() { - return Collections.unmodifiableSet(assertionHeaders.entrySet()) + void header(String headerKey, Object headerValue) { + headers << new Header(headerKey, headerValue) } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy deleted file mode 100644 index 0fc53aefb3..0000000000 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy +++ /dev/null @@ -1,102 +0,0 @@ -package io.coderate.accurest.dsl.internal - -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString -import groovy.transform.TypeChecked - -@TypeChecked -@EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) -class WithValuePattern { - - DslProperty equalTo - DslProperty equalToJson - DslProperty equalToXml - DslProperty matchesXPath - DslProperty jsonCompareMode - DslProperty contains - DslProperty matches - DslProperty doesNotMatch - DslProperty absent - DslProperty matchesJsonPath - - void equalTo(String equalTo) { - this.equalTo = new DslProperty(equalTo) - } - - void equalTo(DslProperty equalTo) { - this.equalTo = equalTo - } - - void equalToJson(String equalToJson) { - this.equalToJson = new DslProperty(equalToJson) - } - - void equalToJson(DslProperty equalToJson) { - this.equalToJson = equalToJson - } - - void equalToXml(String equalToXml) { - this.equalToXml = new DslProperty(equalToXml) - } - - void equalToXml(DslProperty equalToXml) { - this.equalToXml = equalToXml - } - - void matchesXPath(String matchesXPath) { - this.matchesXPath = new DslProperty(matchesXPath) - } - - void matchesXPath(DslProperty matchesXPath) { - this.matchesXPath = matchesXPath - } - - void jsonCompareMode(JSONCompareMode jsonCompareMode) { - this.jsonCompareMode = new DslProperty(jsonCompareMode) - } - - void jsonCompareMode(DslProperty jsonCompareMode) { - this.jsonCompareMode = jsonCompareMode - } - - void contains(String contains) { - this.contains = new DslProperty(contains) - } - - void contains(DslProperty contains) { - this.contains = contains - } - - void matches(String matches) { - this.matches = new DslProperty(matches) - } - - void matches(DslProperty matches) { - this.matches = matches - } - - void doesNotMatch(String doesNotMatch) { - this.doesNotMatch = new DslProperty(doesNotMatch) - } - - void doesNotMatch(DslProperty doesNotMatch) { - this.doesNotMatch = doesNotMatch - } - - void absent(String absent) { - this.absent = new DslProperty(absent) - } - - void absent(DslProperty absent) { - this.absent = absent - } - - void matchesJsonPath(String matchesJsonPath) { - this.matchesJsonPath = new DslProperty(matchesJsonPath) - } - - void matchesJsonPath(DslProperty matchesJsonPath) { - this.matchesJsonPath = matchesJsonPath - } -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy index eba8b29783..ae33f3ccdc 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy @@ -35,7 +35,7 @@ class WiremockGroovyDslResponseSpec extends Specification { GroovyDsl dsl = GroovyDsl.make { response { headers { - header('Content-Type').matches $(client('text/xml'), server('text/*')) + header 'Content-Type', $(client('text/xml'), server('text/*')) } status 200 } @@ -44,9 +44,7 @@ class WiremockGroovyDslResponseSpec extends Specification { new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' { "headers": { - "Content-Type": { - "matches": "text/xml" - }, + "Content-Type": "text/xml" }, "status": 200 } 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 af5431b36a..75c0e17cfb 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -212,19 +212,15 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { headers { - header('Content-Type').equalTo('text/xml') - header('Accept').matches $( - client('text/.*'), + header('Content-Type': 'text/xml') + header('Accept': $( + client(regex('text/.*')), server('text/plain') - ) - header('etag').doesNotMatch $( - client('abcd.*'), - server('abcdef') - ) - header('X-Custom-Header').contains $( - client('2134'), + )) + header('X-Custom-Header': $( + client(regex('^.*2134.*$')), server('121345') - ) + )) } } } @@ -238,11 +234,8 @@ class WiremockGroovyDslSpec extends Specification { "Accept": { "matches": "text/.*" }, - "etag": { - "doesNotMatch": "abcd.*" - }, "X-Custom-Header": { - "contains": "2134" + "matches": "^.*2134.*$" } } }