From f9c7ebc64450e7e21022dde9c61828ff967cd546 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 3 Sep 2015 14:17:59 +0200 Subject: [PATCH] Fixed issues with GString and Regex --- .../MockMvcSpockMethodBodyBuilder.groovy | 7 +- .../builder/SpockMethodBodyBuilder.groovy | 5 + .../dsl/BaseWireMockStubStrategy.groovy | 20 +++- .../dsl/WireMockRequestStubStrategy.groovy | 28 ++--- .../util/JsonToJsonPathsConverter.groovy | 22 +--- .../accurest/util/MapConverter.groovy | 18 +++ .../JaxRsClientSpockMethodBuilderSpec.groovy | 33 +++++- .../MockMvcSpockMethodBuilderSpec.groovy | 63 ++++++++++- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 106 +++++++++++++++++- ...pec.groovy => WireMockStubVerifier.groovy} | 5 +- 10 files changed, 260 insertions(+), 47 deletions(-) rename accurest-core/src/test/groovy/io/codearte/accurest/dsl/{WireMockSpec.groovy => WireMockStubVerifier.groovy} (82%) 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 d686bcc54e..1b2e9a9d24 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,5 +1,4 @@ package io.codearte.accurest.builder - import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode @@ -23,7 +22,7 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { bb.addLine('def request = given()') bb.indent() request.headers?.collect { Header header -> - bb.addLine(".header('${header.name}', '${header.serverValue}')") + bb.addLine(".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')") } if (request.body) { bb.addLine(".body('$bodyAsString')") @@ -67,9 +66,9 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { protected String buildUrl(Request request) { if (request.url) - return request.url.serverValue; + return getTestSideValue(request.url.serverValue) if (request.urlPath) - return buildUrlFromUrlPath(request.urlPath) + return getTestSideValue(buildUrlFromUrlPath(request.urlPath)) throw new IllegalStateException("URL is not set!") } 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 dbd0663ac9..2789e52a2d 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 @@ -17,6 +17,8 @@ import static io.codearte.accurest.util.ContentUtils.* @TypeChecked abstract class SpockMethodBodyBuilder { + private static final Boolean TEST_SIDE = false + protected final Request request protected final Response response @@ -200,4 +202,7 @@ abstract class SpockMethodBodyBuilder { return contentType } + protected String getTestSideValue(Object object) { + return MapConverter.getClientOrServerSideValues(object, TEST_SIDE).toString() + } } 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 c69e5539fa..c485285281 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 @@ -6,6 +6,8 @@ import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.util.ContentType +import io.codearte.accurest.util.ContentUtils +import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern @@ -15,6 +17,12 @@ import static io.codearte.accurest.util.MapConverter.transformValues @TypeChecked abstract class BaseWireMockStubStrategy { + private static final Boolean STUB_SIDE = true + + protected getStubSideValue(Object object) { + return MapConverter.getClientOrServerSideValues(object, STUB_SIDE) + } + private static Closure transform = { it instanceof DslProperty ? transformValues(it.clientValue, transform) : it } @@ -58,7 +66,7 @@ abstract class BaseWireMockStubStrategy { } public String parseBody(Map map, ContentType contentType) { - def transformedMap = transformValues(map, transform) + def transformedMap = MapConverter.getClientOrServerSideValues(map, true) return parseBody(toJson(transformedMap), contentType) } @@ -82,4 +90,14 @@ abstract class BaseWireMockStubStrategy { return new JsonBuilder(value).toString() } + protected ContentType tryToGetContentType(Object body, Headers headers) { + ContentType contentType = ContentUtils.recognizeContentTypeFromHeader(headers) + if (contentType == ContentType.UNKNOWN) { + if (!body) { + return ContentType.UNKNOWN + } + return ContentUtils.getClientContentType(body) + } + return contentType + } } \ No newline at end of file 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 c87a1cebac..cf69737c95 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 @@ -51,7 +51,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { if (!request.body) { return } - ContentType contentType = tryToGetContentType() + ContentType contentType = tryToGetContentType(request.body.clientValue, request.headers) if (contentType == ContentType.JSON) { JsonPaths values = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(getMatchingStrategyFromBody(request.body)?.clientValue) if (values.empty) { @@ -70,17 +70,6 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { } } - private ContentType tryToGetContentType() { - ContentType contentType = recognizeContentTypeFromHeader(request.headers) - if (contentType == ContentType.UNKNOWN) { - if (!request.body.clientValue) { - return ContentType.UNKNOWN - } - return ContentUtils.getClientContentType(request.body.clientValue) - } - return contentType - } - private void appendHeaders(RequestPattern requestPattern) { if(!request.headers) { return @@ -93,12 +82,12 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { private void appendUrl(RequestPattern requestPattern) { Object urlPath = request?.urlPath?.clientValue if (urlPath) { - requestPattern.setUrlPath(urlPath.toString()) + requestPattern.setUrlPath(getStubSideValue(urlPath.toString()).toString()) } if(!request.url) { return } - Object url = request?.url?.clientValue + Object url = getUrlIfGstring(request?.url?.clientValue) if(url instanceof Pattern) { requestPattern.setUrlPattern(url.pattern()) } else { @@ -106,6 +95,17 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { } } + private Object getUrlIfGstring(Object clientSide) { + if (clientSide instanceof GString) { + if (clientSide.values.any { getStubSideValue(it) instanceof Pattern }) { + return Pattern.compile(getStubSideValue(clientSide).toString()) + } else { + return getStubSideValue(clientSide).toString() + } + } + return clientSide + } + private void appendQueryParameters(RequestPattern requestPattern) { QueryParameters queryParameters = request?.urlPath?.queryParameters ?: request?.url?.queryParameters queryParameters?.parameters?.each { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 6a749346a7..32affecef2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -1,7 +1,6 @@ package io.codearte.accurest.util import groovy.json.JsonSlurper -import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty import java.util.regex.Pattern @@ -29,7 +28,7 @@ class JsonToJsonPathsConverter { return new JsonPaths() } JsonPaths pathsAndValues = [] as Set - Object convertedJson = getClientOrServerSideValues(json, clientSide) + Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide) traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value -> if (value instanceof ExecutionProperty) { return @@ -40,25 +39,6 @@ class JsonToJsonPathsConverter { return pathsAndValues } - private static Object getClientOrServerSideValues(json, boolean clientSide) { - return MapConverter.transformValues(json) { - if (it instanceof DslProperty) { - DslProperty dslProperty = ((DslProperty) it) - return clientSide ? - getClientOrServerSideValues(dslProperty.clientValue, clientSide) : getClientOrServerSideValues(dslProperty.serverValue, clientSide) - } else if (it instanceof GString) { - return ContentUtils.extractValue(it , null, { - if (it instanceof DslProperty) { - return clientSide ? - getClientOrServerSideValues((it as DslProperty).clientValue, clientSide) : getClientOrServerSideValues((it as DslProperty).serverValue, clientSide) - } - return it - }) - } - return it - } - } - protected static def traverseRecursively(Class parentType, String key, def value, Closure closure) { if (value instanceof String && value) { try { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index 14568e7584..ca0717ba68 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -43,4 +43,22 @@ class MapConverter { } } + static Object getClientOrServerSideValues(json, boolean clientSide) { + return transformValues(json) { + if (it instanceof DslProperty) { + DslProperty dslProperty = ((DslProperty) it) + return clientSide ? + getClientOrServerSideValues(dslProperty.clientValue, clientSide) : getClientOrServerSideValues(dslProperty.serverValue, clientSide) + } else if (it instanceof GString) { + return ContentUtils.extractValue(it , null, { + if (it instanceof DslProperty) { + return clientSide ? + getClientOrServerSideValues((it as DslProperty).clientValue, clientSide) : getClientOrServerSideValues((it as DslProperty).serverValue, clientSide) + } + return it + }) + } + return it + } + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index 8bd272b7ac..f2ae54c6cf 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -1,10 +1,12 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.WireMockStubStrategy +import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Specification -class JaxRsClientSpockMethodBuilderSpec extends Specification { +class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMockStubVerifier { def "should generate assertions for simple response body"() { given: @@ -28,6 +30,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#79") @@ -57,6 +61,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#82") @@ -80,6 +86,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains("entity('{\"items\":[\"HOP\"]}', 'application/json')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#88") @@ -103,6 +111,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains("entity('property1=VAL1', 'application/octet-stream')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array in response body"() { @@ -130,6 +140,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array inside response body element"() { @@ -156,6 +168,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for nested objects in response body"() { @@ -182,6 +196,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { @@ -214,6 +230,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { @@ -240,6 +258,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should ignore 'Accept' header and use 'request' method"() { @@ -262,6 +282,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains("request('text/plain')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should ignore 'Content-Type' header and use 'entity' method"() { @@ -288,7 +310,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("entity('', 'text/plain')") blockBuilder.toString().contains("header('Timer', '123')") !blockBuilder.toString().contains("header('Content-Type'") - + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate a call with an url path and query parameters"() { @@ -337,6 +360,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { spockTest.contains("queryParam('email', 'bob@email.com'") spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for empty body"() { @@ -358,6 +383,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains("entity('', 'application/octet-stream')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for String in response body"() { @@ -380,6 +407,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: spockTest.contains('def responseBody = (response.body.asString())') spockTest.contains('responseBody == "test"') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } } 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 5d25d94874..a56df6014b 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,13 +1,15 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.WireMockStubStrategy +import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Specification /** * @author Jakub Kubrynski */ -class MockMvcSpockMethodBuilderSpec extends Specification { +class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStubVerifier { def "should generate assertions for simple response body"() { given: @@ -31,6 +33,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#79") @@ -60,6 +64,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#82") @@ -83,6 +89,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#88") @@ -106,6 +114,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains(".body('property1=VAL1')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array in response body"() { @@ -133,6 +143,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array inside response body element"() { @@ -159,6 +171,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for nested objects in response body"() { @@ -185,6 +199,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { @@ -217,6 +233,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { @@ -243,6 +261,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate a call with an url path and query parameters"() { @@ -284,6 +304,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for empty body"() { @@ -305,6 +327,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains(".body('')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for String in response body"() { @@ -327,6 +351,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: spockTest.contains('def responseBody = (response.body.asString())') spockTest.contains('responseBody == "test"') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue('113') @@ -360,6 +386,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue('115') @@ -393,6 +421,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should work with more complex stuff and jsonpaths"() { @@ -428,6 +458,37 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''') spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + + def "should work properly with GString url"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + + request { + method 'PUT' + url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" + headers { + header 'Content-Type': 'application/json' + } + body( + first_name: 'Josef', + ) + } + response { + status 422 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('''/partners/11/agents/11/customers/09665703Z''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should resolve properties in GString with regular expression"() { 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 548f309b00..2188321374 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 @@ -4,8 +4,9 @@ import groovy.json.JsonBuilder import groovy.json.JsonSlurper import io.codearte.accurest.util.AssertionUtil import spock.lang.Issue +import spock.lang.Specification -class WireMockGroovyDslSpec extends WireMockSpec { +class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifier { def 'should convert groovy dsl stub to wireMock stub for the client side'() { given: @@ -1189,6 +1190,109 @@ class WireMockGroovyDslSpec extends WireMockSpec { stubMappingIsValidWireMockStub(wireMockStub) } + def 'should generate stub properly resolving GString with regular expression'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(client(regex(email())), server('not.existing@user.com')), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: 4, + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "url" : "/users/password", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" + }, { + "matchesJsonPath" : "$[?(@.email =~ /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 404, + "body" : "{\\"code\\":4,\\"message\\":\\"User not found by email = [not.existing@user.com]\\"}", + "headers" : { + "Content-Type" : "application/json" + } + }, + "priority" : 1 + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } + + def 'should generate stub properly resolving GString with regular expression in url'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + + request { + method 'PUT' + url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" + headers { + header 'Content-Type': 'application/json' + } + body( + first_name: 'Josef', + ) + } + response { + status 422 + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "urlPattern" : "/partners/^[0-9]*$/agents/11/customers/09665703Z", + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.first_name == 'Josef')]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 422 + } + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy similarity index 82% rename from accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy index aad0fa879e..a970434c05 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy @@ -1,17 +1,16 @@ package io.codearte.accurest.dsl - import com.github.tomakehurst.wiremock.stubbing.StubMapping -import spock.lang.Specification import java.util.regex.Pattern -abstract class WireMockSpec extends Specification { +trait WireMockStubVerifier { void stubMappingIsValidWireMockStub(String mappingDefinition) { StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) stubMapping.request.bodyPatterns.findAll { it.matches }.every { Pattern.compile(it.matches) } + assert !mappingDefinition.contains('DslProperty') } }