Referencing request from response (#238)
The best situation is to provide fixed values but sometimes you need to reference a request in your response. In order to do this you can profit from the fromRequest() method that allows you to reference a bunch of elements from the HTTP request. You can use the following options: - `fromRequest().url()` - return the request URL - `fromRequest().query(String key)` - return the first query parameter with a given name - `fromRequest().query(String key, int index)` - return the nth query parameter with a given name - `fromRequest().header(String key)` - return the first header with a given name - `fromRequest().header(String key, int index)` - return the nth header with a given name - `fromRequest().body()` - return the full request body - `fromRequest().body(String jsonPath)` - return the element from the request that matches the JSON Path fixes #237
This commit is contained in:
committed by
GitHub
parent
7340f2893d
commit
d6f2227f89
@@ -0,0 +1,72 @@
|
||||
package org.springframework.cloud.contract.spec
|
||||
|
||||
/**
|
||||
* Contract for defining templated responses.
|
||||
*
|
||||
* If no implementation is provided then Handlebars will be picked as a default implementation.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.1.0
|
||||
*/
|
||||
interface ContractTemplate {
|
||||
|
||||
/**
|
||||
* Handlebars is using the Mustache template thus it looks like this
|
||||
* {{{ Mustache }}}. In this case the opening template would return {{{
|
||||
*/
|
||||
String openingTemplate()
|
||||
|
||||
/**
|
||||
* Handlebars is using the Mustache template thus it looks like this
|
||||
* {{{ Mustache }}}. In this case the closing template would return }}}
|
||||
*/
|
||||
String closingTemplate()
|
||||
|
||||
/**
|
||||
* Returns the template for retrieving a URL from request
|
||||
*/
|
||||
String url()
|
||||
|
||||
/**
|
||||
* Returns the template for retrieving first value of a query parameter e.g. {{{ request.query.search }}}
|
||||
* @param key
|
||||
*/
|
||||
String query(String key)
|
||||
|
||||
/**
|
||||
* Returns the template for retrieving nth value of a query parameter (zero indexed) e.g. {{{ request.query.search.[5] }}}
|
||||
* @param key
|
||||
* @param index
|
||||
*/
|
||||
String query(String key, int index)
|
||||
|
||||
/**
|
||||
* Returns the template for retrieving the first value of a request header e.g. {{{ request.headers.X-Request-Id }}}
|
||||
* @param key
|
||||
*/
|
||||
String header(String key)
|
||||
|
||||
/**
|
||||
* Returns the template for retrieving the nth value of a request header (zero indexed) e.g. {{{ request.headers.X-Request-Id.[5] }}}
|
||||
* @param key
|
||||
* @param index
|
||||
*/
|
||||
String header(String key, int index)
|
||||
|
||||
/**
|
||||
* Request body text (avoid for non-text bodies) e.g. {{{ request.body }}} . The body will not be escaped
|
||||
* so you won't be able to directly embed it in a JSON for example.
|
||||
*/
|
||||
String body()
|
||||
|
||||
/**
|
||||
* Request body text (avoid for non-text bodies) e.g. {{{ escapejsonbody }}} . The body will not be escaped
|
||||
* so you will be able to embed it
|
||||
*/
|
||||
String escapedBody()
|
||||
|
||||
/**
|
||||
* Request body text for the given JsonPath. e.g. {{{ jsonpath this '$.a.b.c' }}}
|
||||
*/
|
||||
String body(String jsonPath)
|
||||
}
|
||||
@@ -205,4 +205,4 @@ class Common {
|
||||
void assertThatSidesMatch(Object firstSide, Object secondSide) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.springframework.cloud.contract.spec.ContractTemplate
|
||||
/**
|
||||
* Helper class to reference the request body parameters
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.1.0
|
||||
*/
|
||||
|
||||
@CompileStatic
|
||||
class FromRequest {
|
||||
|
||||
private final ContractTemplate template
|
||||
|
||||
FromRequest() {
|
||||
this.template = template()
|
||||
}
|
||||
|
||||
private ContractTemplate template() {
|
||||
return new HandlebarsContractTemplate()
|
||||
}
|
||||
|
||||
/**
|
||||
* URL path and query
|
||||
*/
|
||||
DslProperty url() {
|
||||
return new DslProperty(template.url())
|
||||
}
|
||||
|
||||
/**
|
||||
* First value of a query parameter e.g. request.query.search
|
||||
* @param key
|
||||
*/
|
||||
DslProperty query(String key) {
|
||||
return new DslProperty(template.query(key))
|
||||
}
|
||||
|
||||
/**
|
||||
* nth value of a query parameter (zero indexed) e.g. request.query.search.[5]
|
||||
* @param key
|
||||
* @param index
|
||||
*/
|
||||
DslProperty query(String key, int index) {
|
||||
return new DslProperty(template.query(key, index))
|
||||
}
|
||||
|
||||
/**
|
||||
* First value of a request header e.g. request.headers.X-Request-Id
|
||||
* @param key
|
||||
*/
|
||||
DslProperty header(String key) {
|
||||
return new DslProperty(template.header(key))
|
||||
}
|
||||
|
||||
/**
|
||||
* nth value of a request header (zero indexed) e.g. request.headers.X-Request-Id
|
||||
* @param key
|
||||
*/
|
||||
DslProperty header(String key, int index) {
|
||||
return new DslProperty(template.header(key, index))
|
||||
}
|
||||
|
||||
/**
|
||||
* Request body text (avoid for non-text bodies)
|
||||
*/
|
||||
DslProperty body() {
|
||||
return new DslProperty(template.body())
|
||||
}
|
||||
|
||||
/**
|
||||
* Request body text for the given JsonPath
|
||||
*/
|
||||
DslProperty body(String jsonPath) {
|
||||
return new DslProperty(template.body(jsonPath))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.springframework.cloud.contract.spec.ContractTemplate
|
||||
|
||||
/**
|
||||
* Represents the structure of templates using Handlebars compatible with
|
||||
* WireMock template model requirements.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@CompileStatic
|
||||
class HandlebarsContractTemplate implements ContractTemplate {
|
||||
|
||||
@Override
|
||||
String openingTemplate() {
|
||||
return "{{{"
|
||||
}
|
||||
|
||||
@Override
|
||||
String closingTemplate() {
|
||||
return "}}}"
|
||||
}
|
||||
|
||||
@Override
|
||||
String url() {
|
||||
return wrapped("request.url")
|
||||
}
|
||||
|
||||
@Override
|
||||
String query(String key) {
|
||||
return query(key, 0)
|
||||
}
|
||||
|
||||
@Override
|
||||
String query(String key, int index) {
|
||||
return wrapped("request.query.${key}.[${index}]")
|
||||
}
|
||||
|
||||
@Override
|
||||
String header(String key) {
|
||||
return header(key, 0)
|
||||
}
|
||||
|
||||
@Override
|
||||
String header(String key, int index) {
|
||||
return wrapped("request.headers.${key}.[${index}]")
|
||||
}
|
||||
|
||||
@Override
|
||||
String body() {
|
||||
return wrapped("request.body")
|
||||
}
|
||||
|
||||
@Override
|
||||
String escapedBody() {
|
||||
return wrapped("escapejsonbody")
|
||||
}
|
||||
|
||||
@Override
|
||||
String body(String jsonPath) {
|
||||
return wrapped("jsonpath this '${jsonPath}'")
|
||||
}
|
||||
|
||||
private String wrapped(String text) {
|
||||
return openingTemplate() + text + closingTemplate()
|
||||
}
|
||||
}
|
||||
@@ -118,6 +118,10 @@ class Response extends Common {
|
||||
closure()
|
||||
}
|
||||
|
||||
FromRequest fromRequest() {
|
||||
return new FromRequest()
|
||||
}
|
||||
|
||||
@Override
|
||||
DslProperty value(ClientDslProperty client, ServerDslProperty server) {
|
||||
if (client.clientValue instanceof Pattern) {
|
||||
|
||||
Reference in New Issue
Block a user