Introduced adding of custom WireMock extensions (#429)

without this change we set only a single extension "response-transformer" without an option to provide any other ones
with this change we introduce the "spring.factories" based extension model. It's enough to provide your own implementation of `org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions` and register it in `spring.factories`. That way you can control all extensions (request / response).

fixes #425
This commit is contained in:
Marcin Grzejszczak
2017-10-05 15:52:27 +02:00
committed by GitHub
parent 4a46760ee2
commit 0758f4ec38
12 changed files with 271 additions and 57 deletions

View File

@@ -0,0 +1,39 @@
package org.springframework.cloud.contract.verifier.dsl.wiremock
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer
import wiremock.com.github.jknack.handlebars.Helper
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsEscapeHelper
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsJsonPathHelper
/**
* Default implementation of {@link ResponseTemplateTransformer} that contains
* default set of handlebars helpers
*
* @author Marcin Grzejszczak
* @since 1.2.0
*/
class DefaultResponseTransformer extends ResponseTemplateTransformer {
DefaultResponseTransformer() {
super(false, defaultHelpers())
}
DefaultResponseTransformer(boolean global) {
super(global)
}
DefaultResponseTransformer(boolean global, String helperName, Helper helper) {
super(global, helperName, helper)
}
DefaultResponseTransformer(boolean global, Map<String, Helper> helpers) {
super(global, helpers)
}
private static Map<String, Helper> defaultHelpers() {
Map<String, Helper> helpers = new HashMap<>()
helpers.put(HandlebarsJsonPathHelper.NAME, new HandlebarsJsonPathHelper())
helpers.put(HandlebarsEscapeHelper.NAME, new HandlebarsEscapeHelper())
return helpers
}
}

View File

@@ -0,0 +1,16 @@
package org.springframework.cloud.contract.verifier.dsl.wiremock;
import java.util.List;
import com.github.tomakehurst.wiremock.extension.Extension;
/**
* Contract that describes a list of {@link Extension} extensions
* that should be applied to the response
*
* @author Marcin Grzejszczak
* @since 1.2.0
*/
public interface WireMockExtensions {
List<Extension> extensions();
}

View File

@@ -17,16 +17,19 @@
package org.springframework.cloud.contract.verifier.dsl.wiremock
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder
import com.github.tomakehurst.wiremock.extension.Extension
import com.github.tomakehurst.wiremock.http.HttpHeader
import com.github.tomakehurst.wiremock.http.HttpHeaders
import com.github.tomakehurst.wiremock.http.ResponseDefinition
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.spec.internal.Request
import org.springframework.cloud.contract.spec.internal.Response
import org.springframework.cloud.contract.verifier.util.ContentType
import org.springframework.cloud.contract.verifier.util.MapConverter
import org.springframework.core.io.support.SpringFactoriesLoader
import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromContent
import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromHeader
@@ -56,10 +59,21 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy {
appendHeaders(builder)
appendBody(builder)
appendResponseDelayTime(builder)
builder.withTransformers("response-template")
builder.withTransformers(responseTransformerNames())
return builder.build()
}
private String[] responseTransformerNames() {
List<WireMockExtensions> wireMockExtensions = SpringFactoriesLoader.loadFactories(WireMockExtensions, null)
if (wireMockExtensions) {
return ((List<Extension>) wireMockExtensions
.collect { WireMockExtensions extension -> extension.extensions() }
.flatten())
.collect { Extension e -> e.getName()} as String[]
}
return [new DefaultResponseTransformer().getName()] as String[]
}
private void appendHeaders(ResponseDefinitionBuilder builder) {
if (response.headers) {
builder.withHeaders(new HttpHeaders(response.headers.entries?.collect {

View File

@@ -78,7 +78,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
''', wireMockStub)
@@ -126,7 +126,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"response" : {
"status" : 200,
"body" : "{\\"ingredients\\":[{\\"quantity\\":100,\\"type\\":\\"MALT\\"},{\\"quantity\\":200,\\"type\\":\\"WATER\\"},{\\"quantity\\":300,\\"type\\":\\"HOP\\"},{\\"quantity\\":400,\\"type\\":\\"YIEST\\"}]}",
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
''', wireMockStub)
@@ -180,7 +180,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"response": {
"status": 204,
"body": "{\\"foundExistingPayment\\":false,\\"paymentId\\":\\"4\\"}",
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
''', wireMockStub)
@@ -227,7 +227,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
''')
@@ -284,7 +284,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
''', wireMockStub)
@@ -335,7 +335,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), wireMockStub)
@@ -381,7 +381,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -427,7 +427,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -465,7 +465,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -499,7 +499,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"response": {
"status": 200,
"body":"<user><name>Jozo</name><jobId>&lt;test&gt;</jobId></user>",
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -535,7 +535,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -573,7 +573,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -624,7 +624,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), wireMockStub)
@@ -687,7 +687,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), wireMockStub)
@@ -754,7 +754,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -793,7 +793,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -834,7 +834,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -865,7 +865,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -895,7 +895,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -1049,7 +1049,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -1123,7 +1123,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), wireMockStub)
@@ -1184,7 +1184,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -1218,7 +1218,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 406,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -1248,7 +1248,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 406,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -1282,7 +1282,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), wireMockStub)
@@ -1320,7 +1320,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), wireMockStub)
@@ -1379,7 +1379,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
},
"priority" : 1
}
@@ -1425,7 +1425,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 422,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), wireMockStub)
@@ -1460,7 +1460,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Content-Type" : "application/json"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
},
"priority" : 1
}
@@ -1592,7 +1592,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''
@@ -1673,7 +1673,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"response" : {
"status" : 200,
"body" : "{\\"number\\":0,\\"last\\":true,\\"numberOfElements\\":1,\\"size\\":1,\\"totalPages\\":1,\\"sort\\":[{\\"nullHandling\\":\\"NATIVE\\",\\"ignoreCase\\":false,\\"property\\":\\"id\\",\\"ascending\\":true,\\"direction\\":\\"ASC\\"}],\\"content\\":[{\\"id\\":\\"00000000-0000-0000-0000-000000000000\\",\\"state\\":\\"ACTIVE\\",\\"type\\":\\"Extraordinary\\"}],\\"first\\":true,\\"totalElements\\":1}",
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -1802,7 +1802,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"headers" : {
"Authorization" : "{{{request.headers.Authorization.[0]}}};foo"
},
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
'''), json)
@@ -1994,7 +1994,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
"response" : {
"status" : 200,
"body" : "{\\"code\\":91015,\\"payload\\":null,\\"description\\":\\"\\",\\"lastUpdateTime\\":\\"0\\"}",
"transformers" : [ "response-template" ]
"transformers" : [ "response-template", "foo-transformer" ]
}
}
''', wireMockStub)

View File

@@ -0,0 +1,24 @@
package org.springframework.cloud.contract.verifier.dsl.wiremock
import com.github.tomakehurst.wiremock.extension.Extension
/**
* Extension that registers the default transformer and the custom one
*/
class TestWireMockExtensions implements WireMockExtensions {
@Override
List<Extension> extensions() {
return [
new DefaultResponseTransformer(),
new CustomExtension()
]
}
}
class CustomExtension implements Extension {
@Override
String getName() {
return "foo-transformer"
}
}

View File

@@ -1,3 +1,8 @@
# Converters
org.springframework.cloud.contract.spec.ContractConverter=\
org.springframework.cloud.contract.verifier.converter.YamlContractConverter
org.springframework.cloud.contract.verifier.converter.YamlContractConverter
# tag::extension[]
org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions=\
org.springframework.cloud.contract.verifier.dsl.wiremock.TestWireMockExtensions
# end::extension[]