From 6b2de1b0c00505c3bd2547412dac650d478b1e8d Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Tue, 23 Jun 2015 15:27:53 +0200 Subject: [PATCH] Added absent matching strategy --- .../builder/SpockMethodBodyBuilder.groovy | 16 +++++- .../dsl/BaseWiremockStubStrategy.groovy | 4 ++ .../accurest/dsl/internal/Common.groovy | 22 ++++++++ .../dsl/internal/MatchingStrategy.groovy | 2 +- .../accurest/dsl/internal/Request.groovy | 4 ++ .../accurest/util/ValidateUtils.groovy | 7 ++- .../builder/SpockMethodBuilderSpec.groovy | 2 + .../accurest/dsl/WiremockGroovyDslSpec.groovy | 54 +++++++++++++++++++ 8 files changed, 108 insertions(+), 3 deletions(-) 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 cc35423d97..7e7bb697bc 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 @@ -120,12 +120,26 @@ class SpockMethodBodyBuilder { } private String buildUrlFromUrlPath(UrlPath urlPath) { - String params = urlPath.queryParameters.parameters.inject([]) { result, param -> + String params = urlPath.queryParameters.parameters + .findAll(this.&allowedQueryParameter) + .inject([]) { result, param -> result << "${param.name}=${resolveParamValue(param).toString()}" }.join('&') return "$urlPath.serverValue?$params" } + private boolean allowedQueryParameter(QueryParameter param) { + return allowedQueryParameter(param.serverValue) + } + + private boolean allowedQueryParameter(MatchingStrategy matchingStrategy) { + return matchingStrategy.type != MatchingStrategy.Type.ABSENT + } + + private boolean allowedQueryParameter(Object o) { + return true + } + private String resolveParamValue(QueryParameter param) { resolveParamValue(param.serverValue) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy index a5c100341b..e3285a9467 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -53,6 +53,10 @@ abstract class BaseWiremockStubStrategy { return parseBody(value.toString(), contentType) } + public Boolean parseBody(Boolean value, ContentType contentType) { + return value + } + public String parseBody(Map map, ContentType contentType) { def transformedMap = transformValues(map, transform) return parseBody(toJson(transformedMap), contentType) 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 3dca0390ef..87d509de59 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 @@ -88,6 +88,28 @@ class Common { assert firstSide ==~ secondSide } + void assertThatSidesMatch(MatchingStrategy firstSide, MatchingStrategy secondSide) { + if (firstSide.type == MatchingStrategy.Type.ABSENT && secondSide != MatchingStrategy.Type.ABSENT) { + throwAbsentError() + } + } + + void assertThatSidesMatch(MatchingStrategy firstSide, Object secondSide) { + if (firstSide.type == MatchingStrategy.Type.ABSENT) { + throwAbsentError() + } + } + + void assertThatSidesMatch(Object firstSide, MatchingStrategy secondSide) { + if (secondSide.type == MatchingStrategy.Type.ABSENT) { + throwAbsentError() + } + } + + private void throwAbsentError() { + throw new IllegalStateException("Absent cannot only be used only on one side") + } + void assertThatSidesMatch(Object firstSide, Object secondSide) { // do nothing } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy index e9093dc9aa..c31c0b4bf6 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy @@ -35,7 +35,7 @@ class MatchingStrategy extends DslProperty { enum Type { EQUAL_TO("equalTo"), CONTAINS("contains"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"), - EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml") + EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml"), ABSENT("absent") final String name 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 1ed604d4fb..9be791488a 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 @@ -125,6 +125,10 @@ class Request extends Common { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON) } + MatchingStrategy absent() { + return new MatchingStrategy(true, MatchingStrategy.Type.ABSENT) + } + } @CompileStatic diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy index eac7bce25c..7cb6e0f0ef 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy @@ -6,6 +6,9 @@ import io.codearte.accurest.dsl.internal.MatchingStrategy import java.util.regex.Pattern +import static io.codearte.accurest.dsl.internal.MatchingStrategy.Type.ABSENT +import static io.codearte.accurest.dsl.internal.MatchingStrategy.Type.EQUAL_TO + @TypeChecked class ValidateUtils { @@ -23,8 +26,10 @@ class ValidateUtils { throw new IllegalStateException("$msg can't be a pattern for the server side") } + static List ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE = [EQUAL_TO, ABSENT] + static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { - if (matchingStrategy.type != MatchingStrategy.Type.EQUAL_TO) { + if (!ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE.contains(matchingStrategy.type)) { throw new IllegalStateException("$msg can't be of a matching type: $matchingStrategy.type for the server side") } validateServerValue(matchingStrategy.serverValue, msg) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy index b38ec458b1..964f03811b 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -260,6 +260,8 @@ class SpockMethodBuilderSpec extends Specification { 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() } } } 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 80540ec70d..5e0b681604 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 @@ -695,6 +695,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("10")) parameter 'age': $(client(notMatching("^\\w*\$")), server(10)) parameter 'name': $(client(matching("Denis.*")), server("Denis")) + parameter 'credit': absent() } } } @@ -731,6 +732,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "name": { "matches": "Denis.*" + }, + "credit": { + "absent": true } } }, @@ -863,6 +867,56 @@ class WiremockGroovyDslSpec extends WiremockSpec { e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side" } + def "should not allow query parameter with a different absent variation for server/client"() { + when: + GroovyDsl.make dsl + then: + def e = thrown(IllegalStateException) + e.message.contains "Absent cannot only be used only on one side" + where: + dsl << [ + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server("")) + } + } + } + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(""), server(absent())) + } + } + } + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server(matching("abc"))) + } + } + } + response { + status 200 + } + } + ] + } + def "should generate request with url and queryParameters for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make {