Simplification of the dsl (#151)
with this change to DSL we're adding some helper methods and DSL simplifications - c(...) / p(...) - for consumer / producer - for regex - e.g. $(anyUrl()) - insead of $(consumer(regex(url())) - Added helper headers and media types - Added helper http methods fixes #149
This commit is contained in:
committed by
GitHub
parent
df80cc8f1f
commit
b1175ff9bd
@@ -29,4 +29,8 @@ class ClientDslProperty extends DslProperty {
|
||||
ClientDslProperty(Object singleValue) {
|
||||
super(singleValue)
|
||||
}
|
||||
|
||||
ClientDslProperty(Object client, Object server) {
|
||||
super(client, server)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,17 @@ class Common {
|
||||
return new ServerDslProperty(serverValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to provide a better name for the consumer side
|
||||
*/
|
||||
ClientDslProperty c(Object clientValue) {
|
||||
return new ClientDslProperty(clientValue)
|
||||
}
|
||||
|
||||
ServerDslProperty p(Object serverValue) {
|
||||
return new ServerDslProperty(serverValue)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to provide a better name for the producer side
|
||||
*/
|
||||
|
||||
@@ -42,4 +42,10 @@ class DslProperty<T> {
|
||||
this.clientValue = singleValue
|
||||
this.serverValue = singleValue
|
||||
}
|
||||
|
||||
boolean isSingleValue() {
|
||||
return this.clientValue == this.serverValue ||
|
||||
(this.clientValue != null && this.serverValue == null ) ||
|
||||
(this.serverValue != null && this.clientValue == null )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,9 @@ import groovy.transform.TypeChecked
|
||||
@TypeChecked
|
||||
class Headers {
|
||||
|
||||
@Delegate MediaTypes mediaTypes = new MediaTypes()
|
||||
@Delegate HttpHeaders httpHeaders = new HttpHeaders()
|
||||
|
||||
Set<Header> entries = []
|
||||
|
||||
void header(Map<String, Object> singleHeader) {
|
||||
@@ -47,6 +50,24 @@ class Headers {
|
||||
}
|
||||
}
|
||||
|
||||
void accept(String contentType) {
|
||||
header(accept(), matching(contentType))
|
||||
}
|
||||
|
||||
void contentType(String contentType) {
|
||||
header(httpHeaders.contentType(), matching(contentType))
|
||||
}
|
||||
|
||||
/**
|
||||
* If for the consumer / producer you want to match exactly only
|
||||
* the root of content type. I.e. {@code application/json;charset=UTF8}
|
||||
* you care only about {@code application/json} then you should
|
||||
* use this method
|
||||
*/
|
||||
DslProperty matching(String value) {
|
||||
return new DslProperty(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the headers into their stub side representations and returns as
|
||||
* a map of String key => Object value.
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Contains most commonly used http headers
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.2
|
||||
*/
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class HttpHeaders {
|
||||
|
||||
/**
|
||||
* The HTTP {@code Accept} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.3.2">Section 5.3.2 of RFC 7231</a>
|
||||
*/
|
||||
String accept() {
|
||||
return "Accept"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Accept-Charset} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.3.3">Section 5.3.3 of RFC 7231</a>
|
||||
*/
|
||||
String acceptCharset() {
|
||||
return "Accept-Charset"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Accept-Encoding} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.3.4">Section 5.3.4 of RFC 7231</a>
|
||||
*/
|
||||
String acceptEncoding() {
|
||||
return "Accept-Encoding"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Accept-Language} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.3.5">Section 5.3.5 of RFC 7231</a>
|
||||
*/
|
||||
String acceptLanguage() {
|
||||
return "Accept-Language"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Accept-Ranges} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7233#section-2.3">Section 5.3.5 of RFC 7233</a>
|
||||
*/
|
||||
String acceptRanges() {
|
||||
return "Accept-Ranges"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Allow-Credentials} response header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlAllowCredentials() {
|
||||
return "Access-Control-Allow-Credentials"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Allow-Headers} response header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlAllowHeaders() {
|
||||
return "Access-Control-Allow-Headers"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Allow-Methods} response header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlAllowMethods() {
|
||||
return "Access-Control-Allow-Methods"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Allow-Origin} response header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlAllowOrigin() {
|
||||
return "Access-Control-Allow-Origin"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Expose-Headers} response header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlExposeHeaders() {
|
||||
return "Access-Control-Expose-Headers"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Max-Age} response header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlMaxAge() {
|
||||
return "Access-Control-Max-Age"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Request-Headers} request header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlRequestHeaders() {
|
||||
return "Access-Control-Request-Headers"
|
||||
}
|
||||
/**
|
||||
* The CORS {@code Access-Control-Request-Method} request header field name.
|
||||
* @see <a href="http://www.w3.org/TR/cors/">CORS W3C recommendation</a>
|
||||
*/
|
||||
String accessControlRequestMethod() {
|
||||
return "Access-Control-Request-Method"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Age} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7234#section-5.1">Section 5.1 of RFC 7234</a>
|
||||
*/
|
||||
String age() {
|
||||
return "Age"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Allow} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-7.4.1">Section 7.4.1 of RFC 7231</a>
|
||||
*/
|
||||
String allow() {
|
||||
return "Allow"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Authorization} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7235#section-4.2">Section 4.2 of RFC 7235</a>
|
||||
*/
|
||||
String authorization() {
|
||||
return "Authorization"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Cache-Control} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7234#section-5.2">Section 5.2 of RFC 7234</a>
|
||||
*/
|
||||
String cacheControl() {
|
||||
return "Cache-Control"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Connection} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-6.1">Section 6.1 of RFC 7230</a>
|
||||
*/
|
||||
String connection() {
|
||||
return "Connection"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Content-Encoding} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-3.1.2.2">Section 3.1.2.2 of RFC 7231</a>
|
||||
*/
|
||||
String contentEncoding() {
|
||||
return "Content-Encoding"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Content-Disposition} header field name
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6266">RFC 6266</a>
|
||||
*/
|
||||
String contentDisposition() {
|
||||
return "Content-Disposition"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Content-Language} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-3.1.3.2">Section 3.1.3.2 of RFC 7231</a>
|
||||
*/
|
||||
String contentLanguage() {
|
||||
return "Content-Language"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Content-Length} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-3.3.2">Section 3.3.2 of RFC 7230</a>
|
||||
*/
|
||||
String contentLength() {
|
||||
return "Content-Length"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Content-Location} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-3.1.4.2">Section 3.1.4.2 of RFC 7231</a>
|
||||
*/
|
||||
String contentLocation() {
|
||||
return "Content-Location"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Content-Range} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7233#section-4.2">Section 4.2 of RFC 7233</a>
|
||||
*/
|
||||
String contentRange() {
|
||||
return "Content-Range"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Content-Type} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-3.1.1.5">Section 3.1.1.5 of RFC 7231</a>
|
||||
*/
|
||||
String contentType() {
|
||||
return "Content-Type"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Cookie} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2109#section-4.3.4">Section 4.3.4 of RFC 2109</a>
|
||||
*/
|
||||
String cookie() {
|
||||
return "Cookie"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Date} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-7.1.1.2">Section 7.1.1.2 of RFC 7231</a>
|
||||
*/
|
||||
String date() {
|
||||
return "Date"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code ETag} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7232#section-2.3">Section 2.3 of RFC 7232</a>
|
||||
*/
|
||||
String etag() {
|
||||
return "ETag"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Expect} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.1.1">Section 5.1.1 of RFC 7231</a>
|
||||
*/
|
||||
String expect() {
|
||||
return "Expect"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Expires} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7234#section-5.3">Section 5.3 of RFC 7234</a>
|
||||
*/
|
||||
String expires() {
|
||||
return "Expires"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code From} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.5.1">Section 5.5.1 of RFC 7231</a>
|
||||
*/
|
||||
String from() {
|
||||
return "From"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Host} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-5.4">Section 5.4 of RFC 7230</a>
|
||||
*/
|
||||
String host() {
|
||||
return "Host"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code If-Match} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7232#section-3.1">Section 3.1 of RFC 7232</a>
|
||||
*/
|
||||
String ifMatch() {
|
||||
return "If-Match"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code If-Modified-Since} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7232#section-3.3">Section 3.3 of RFC 7232</a>
|
||||
*/
|
||||
String ifModifiedSince() {
|
||||
return "If-Modified-Since"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code If-None-Match} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7232#section-3.2">Section 3.2 of RFC 7232</a>
|
||||
*/
|
||||
String ifNoneMatch() {
|
||||
return "If-None-Match"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code If-Range} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7233#section-3.2">Section 3.2 of RFC 7233</a>
|
||||
*/
|
||||
String ifRange() {
|
||||
return "If-Range"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code If-Unmodified-Since} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7232#section-3.4">Section 3.4 of RFC 7232</a>
|
||||
*/
|
||||
String ifUnmodifiedSince() {
|
||||
return "If-Unmodified-Since"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Last-Modified} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7232#section-2.2">Section 2.2 of RFC 7232</a>
|
||||
*/
|
||||
String lastModified() {
|
||||
return "Last-Modified"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Link} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc5988">RFC 5988</a>
|
||||
*/
|
||||
String link() {
|
||||
return "Link"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Location} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-7.1.2">Section 7.1.2 of RFC 7231</a>
|
||||
*/
|
||||
String location() {
|
||||
return "Location"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Max-Forwards} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.1.2">Section 5.1.2 of RFC 7231</a>
|
||||
*/
|
||||
String max_forwards() {
|
||||
return "Max-Forwards"
|
||||
}
|
||||
/**
|
||||
* The HTTP {@code Origin} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6454">RFC 6454</a>
|
||||
*/
|
||||
String origin() {
|
||||
return "Origin"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Pragma} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7234#section-5.4">Section 5.4 of RFC 7234</a>
|
||||
*/
|
||||
String pragma() {
|
||||
return "Pragma"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Proxy-Authenticate} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7235#section-4.3">Section 4.3 of RFC 7235</a>
|
||||
*/
|
||||
String proxyAuthenticate() {
|
||||
return "Proxy-Authenticate"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Proxy-Authorization} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7235#section-4.4">Section 4.4 of RFC 7235</a>
|
||||
*/
|
||||
String proxyAuthorization() {
|
||||
return "Proxy-Authorization"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Range} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7233#section-3.1">Section 3.1 of RFC 7233</a>
|
||||
*/
|
||||
String range() {
|
||||
return "Range"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Referer} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.5.2">Section 5.5.2 of RFC 7231</a>
|
||||
*/
|
||||
String referer() {
|
||||
return "Referer"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Retry-After} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-7.1.3">Section 7.1.3 of RFC 7231</a>
|
||||
*/
|
||||
String retryAfter() {
|
||||
return "Retry-After"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Server} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-7.4.2">Section 7.4.2 of RFC 7231</a>
|
||||
*/
|
||||
String server() {
|
||||
return "Server"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Set-Cookie} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2109#section-4.2.2">Section 4.2.2 of RFC 2109</a>
|
||||
*/
|
||||
String setCookie() {
|
||||
return "Set-Cookie"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Set-Cookie2} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2965">RFC 2965</a>
|
||||
*/
|
||||
String setCookie2() {
|
||||
return "Set-Cookie2"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code TE} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-4.3">Section 4.3 of RFC 7230</a>
|
||||
*/
|
||||
String te() {
|
||||
return "TE"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Trailer} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-4.4">Section 4.4 of RFC 7230</a>
|
||||
*/
|
||||
String trailer() {
|
||||
return "Trailer"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Transfer-Encoding} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-3.3.1">Section 3.3.1 of RFC 7230</a>
|
||||
*/
|
||||
String transferEncoding() {
|
||||
return "Transfer-Encoding"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Upgrade} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-6.7">Section 6.7 of RFC 7230</a>
|
||||
*/
|
||||
String upgrade() {
|
||||
return "Upgrade"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code User-Agent} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-5.5.3">Section 5.5.3 of RFC 7231</a>
|
||||
*/
|
||||
String user_agent() {
|
||||
return "User-Agent"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Vary} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7231#section-7.1.4">Section 7.1.4 of RFC 7231</a>
|
||||
*/
|
||||
String vary() {
|
||||
return "Vary"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Via} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7230#section-5.7.1">Section 5.7.1 of RFC 7230</a>
|
||||
*/
|
||||
String via() {
|
||||
return "Via"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code Warning} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7234#section-5.5">Section 5.5 of RFC 7234</a>
|
||||
*/
|
||||
String warning() {
|
||||
return "Warning"
|
||||
}
|
||||
|
||||
/**
|
||||
* The HTTP {@code WWW-Authenticate} header field name.
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7235#section-4.1">Section 4.1 of RFC 7235</a>
|
||||
*/
|
||||
String wwwAuthenticate() {
|
||||
return "WWW-Authenticate"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Contains Http Methods
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.2
|
||||
*/
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class HttpMethods {
|
||||
|
||||
HttpMethod GET() {
|
||||
return HttpMethod.GET
|
||||
}
|
||||
|
||||
HttpMethod HEAD() {
|
||||
return HttpMethod.HEAD
|
||||
}
|
||||
|
||||
HttpMethod POST() {
|
||||
return HttpMethod.POST
|
||||
}
|
||||
|
||||
HttpMethod PUT() {
|
||||
return HttpMethod.PUT
|
||||
}
|
||||
|
||||
HttpMethod PATCH() {
|
||||
return HttpMethod.PATCH
|
||||
}
|
||||
|
||||
HttpMethod DELETE() {
|
||||
return HttpMethod.DELETE
|
||||
}
|
||||
|
||||
HttpMethod OPTIONS() {
|
||||
return HttpMethod.OPTIONS
|
||||
}
|
||||
|
||||
HttpMethod TRACE() {
|
||||
return HttpMethod.TRACE
|
||||
}
|
||||
|
||||
enum HttpMethod {
|
||||
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Contains most commonly used media types
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 1.0.2
|
||||
*/
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class MediaTypes {
|
||||
|
||||
String allValue() {
|
||||
return "*/*"
|
||||
}
|
||||
|
||||
String applicationAtomXml() {
|
||||
return "application/atom+xml"
|
||||
}
|
||||
|
||||
String applicationFormUrlencoded() {
|
||||
return "application/x-www-form-urlencoded"
|
||||
}
|
||||
|
||||
String applicationJson() {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
String applicationJsonUtf8() {
|
||||
return applicationJson() + ";charset=UTF-8"
|
||||
}
|
||||
|
||||
String applicationOctetStream() {
|
||||
return "application/octet-stream"
|
||||
}
|
||||
|
||||
String applicationPdf() {
|
||||
return "application/pdf"
|
||||
}
|
||||
|
||||
String applicationXhtmlXml() {
|
||||
return "application/xhtml+xml"
|
||||
}
|
||||
|
||||
String applicationXml() {
|
||||
return "application/xml"
|
||||
}
|
||||
|
||||
String imageGif() {
|
||||
return "image/gif"
|
||||
}
|
||||
|
||||
String imageJpeg() {
|
||||
return "image/jpeg"
|
||||
}
|
||||
|
||||
String imagePng() {
|
||||
return "image/png"
|
||||
}
|
||||
|
||||
String multipartFormData() {
|
||||
return "multipart/form-data"
|
||||
}
|
||||
|
||||
String textHtml() {
|
||||
return "text/html"
|
||||
}
|
||||
|
||||
String textMarkdown() {
|
||||
return "text/markdown"
|
||||
}
|
||||
|
||||
String textPlain() {
|
||||
return "text/plain"
|
||||
}
|
||||
|
||||
String textXml() {
|
||||
return "text/xml"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.PackageScope
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@PackageScope
|
||||
@CompileStatic
|
||||
abstract class PatternValueDslProperty<T extends DslProperty> {
|
||||
|
||||
private final Random random = new Random()
|
||||
|
||||
protected T createAndValidateProperty(Pattern pattern, Object object = null) {
|
||||
if (object) {
|
||||
String generatedValue = object as String
|
||||
boolean matches = pattern.matcher(generatedValue).matches()
|
||||
if (!matches) {
|
||||
throw new IllegalStateException("The generated value [${generatedValue}] doesn't match the pattern [${pattern.pattern()}]")
|
||||
}
|
||||
return createProperty(pattern, generatedValue)
|
||||
}
|
||||
return createProperty(pattern, object)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to generate the PatternValue. The resulting implementation
|
||||
* will create either a Client or a Server side impl.
|
||||
*
|
||||
* @param pattern - pattern for which the value will be generated or reused
|
||||
* @param generatedValue - Nullable - potential generated value to be reused
|
||||
* @return {@link DslProperty} wrapping a pattern and generated value
|
||||
*/
|
||||
protected abstract T createProperty(Pattern pattern, Object generatedValue)
|
||||
|
||||
T anyAlphaUnicode() {
|
||||
return createAndValidateProperty(RegexPatterns.ONLY_ALPHA_UNICODE, randomString(20))
|
||||
}
|
||||
|
||||
T anyNumber() {
|
||||
return createAndValidateProperty(RegexPatterns.NUMBER, this.random.nextInt())
|
||||
}
|
||||
|
||||
T aBoolean() {
|
||||
return createAndValidateProperty(RegexPatterns.TRUE_OR_FALSE)
|
||||
}
|
||||
|
||||
T anyIpAddress() {
|
||||
return createAndValidateProperty(RegexPatterns.IP_ADDRESS)
|
||||
}
|
||||
|
||||
T anyHostname() {
|
||||
return createAndValidateProperty(RegexPatterns.HOSTNAME_PATTERN, "http://foo" + this.random.nextInt() + ".com")
|
||||
}
|
||||
|
||||
T anyEmail() {
|
||||
return createAndValidateProperty(RegexPatterns.EMAIL, "foo@bar" + this.random.nextInt() + ".com")
|
||||
}
|
||||
|
||||
T anyUrl() {
|
||||
return createAndValidateProperty(RegexPatterns.URL, "http://foo" + this.random.nextInt() + ".com")
|
||||
}
|
||||
|
||||
T anyUuid(){
|
||||
return createAndValidateProperty(RegexPatterns.UUID, UUID.randomUUID().toString())
|
||||
}
|
||||
|
||||
private static String randomString(int length) {
|
||||
char[] characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()
|
||||
Random random = new Random()
|
||||
char[] result = new char[length]
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
// picks a random index out of character set > random character
|
||||
int randomCharIndex = random.nextInt(characterSet.length)
|
||||
result[i] = characterSet[randomCharIndex]
|
||||
}
|
||||
return new String(result)
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package org.springframework.cloud.contract.spec.internal
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* Contains most common regular expression patterns
|
||||
*
|
||||
@@ -29,14 +28,14 @@ import java.util.regex.Pattern
|
||||
class RegexPatterns {
|
||||
|
||||
// tag::regexps[]
|
||||
private static final Pattern TRUE_OR_FALSE = Pattern.compile(/(true|false)/)
|
||||
private static final Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/)
|
||||
private static final Pattern NUMBER = Pattern.compile('-?\\d*(\\.\\d+)?')
|
||||
private static final Pattern IP_ADDRESS = Pattern.compile('([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])');
|
||||
private static final Pattern HOSTNAME_PATTERN = Pattern.compile('((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?');
|
||||
private static final Pattern EMAIL = Pattern.compile('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}');
|
||||
private static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])')
|
||||
private static final Pattern UUID = Pattern.compile('[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}')
|
||||
protected static final Pattern TRUE_OR_FALSE = Pattern.compile(/(true|false)/)
|
||||
protected static final Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/)
|
||||
protected static final Pattern NUMBER = Pattern.compile('-?\\d*(\\.\\d+)?')
|
||||
protected static final Pattern IP_ADDRESS = Pattern.compile('([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])');
|
||||
protected static final Pattern HOSTNAME_PATTERN = Pattern.compile('((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?');
|
||||
protected static final Pattern EMAIL = Pattern.compile('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}');
|
||||
protected static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])')
|
||||
protected static final Pattern UUID = Pattern.compile('[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}')
|
||||
|
||||
String onlyAlphaUnicode() {
|
||||
return ONLY_ALPHA_UNICODE.pattern()
|
||||
|
||||
@@ -20,6 +20,7 @@ import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.util.RegexpUtils
|
||||
import repackaged.nl.flotsam.xeger.Xeger
|
||||
|
||||
import java.util.regex.Pattern
|
||||
@@ -33,10 +34,13 @@ import java.util.regex.Pattern
|
||||
@ToString(includePackage = false, includeNames = true)
|
||||
class Request extends Common {
|
||||
|
||||
@Delegate ClientPatternValueDslProperty property = new ClientPatternValueDslProperty()
|
||||
@Delegate HttpMethods httpMethods = new HttpMethods()
|
||||
|
||||
DslProperty method
|
||||
Url url
|
||||
UrlPath urlPath
|
||||
Headers headers
|
||||
RequestHeaders headers
|
||||
Body body
|
||||
Multipart multipart
|
||||
|
||||
@@ -56,6 +60,10 @@ class Request extends Common {
|
||||
this.method = toDslProperty(method)
|
||||
}
|
||||
|
||||
void method(HttpMethods.HttpMethod httpMethod) {
|
||||
this.method = toDslProperty(httpMethod.toString())
|
||||
}
|
||||
|
||||
void method(DslProperty method) {
|
||||
this.method = toDslProperty(method)
|
||||
}
|
||||
@@ -100,8 +108,8 @@ class Request extends Common {
|
||||
closure()
|
||||
}
|
||||
|
||||
void headers(@DelegatesTo(Headers) Closure closure) {
|
||||
this.headers = new Headers()
|
||||
void headers(@DelegatesTo(RequestHeaders) Closure closure) {
|
||||
this.headers = new RequestHeaders()
|
||||
closure.delegate = headers
|
||||
closure()
|
||||
}
|
||||
@@ -176,8 +184,10 @@ class Request extends Common {
|
||||
|
||||
DslProperty value(ClientDslProperty client) {
|
||||
Object clientValue = client.clientValue
|
||||
if (client.clientValue instanceof Pattern) {
|
||||
if (client.clientValue instanceof Pattern && client.isSingleValue()) {
|
||||
clientValue = new Xeger(((Pattern)client.clientValue).pattern()).generate()
|
||||
} else if (client.clientValue instanceof Pattern && !client.isSingleValue()) {
|
||||
clientValue = client.serverValue
|
||||
}
|
||||
return new DslProperty(client.clientValue, clientValue)
|
||||
}
|
||||
@@ -202,22 +212,44 @@ class Request extends Common {
|
||||
return super.value(server, client)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ServerRequest extends Request {
|
||||
ServerRequest(Request request) {
|
||||
super(request)
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class ServerRequest extends Request {
|
||||
ServerRequest(Request request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ClientRequest extends Request {
|
||||
ClientRequest(Request request) {
|
||||
super(request)
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class ClientRequest extends Request {
|
||||
ClientRequest(Request request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class RequestHeaders extends Headers {
|
||||
|
||||
@Override
|
||||
DslProperty matching(String value) {
|
||||
return $(c(regex("${RegexpUtils.escapeSpecialRegexWithSingleEscape(value)}.*")),
|
||||
p(value))
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class ClientPatternValueDslProperty extends PatternValueDslProperty<ClientDslProperty> {
|
||||
|
||||
@Override
|
||||
protected ClientDslProperty createProperty(Pattern pattern, Object generatedValue) {
|
||||
return new ClientDslProperty(pattern, generatedValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,10 +20,10 @@ import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.util.RegexpUtils
|
||||
import repackaged.nl.flotsam.xeger.Xeger
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* Represents the response side of the HTTP communication
|
||||
*
|
||||
@@ -34,9 +34,11 @@ import java.util.regex.Pattern
|
||||
@ToString(includePackage = false, includeFields = true)
|
||||
class Response extends Common {
|
||||
|
||||
@Delegate ServerPatternValueDslProperty property = new ServerPatternValueDslProperty()
|
||||
|
||||
DslProperty status
|
||||
DslProperty delay
|
||||
Headers headers
|
||||
ResponseHeaders headers
|
||||
Body body
|
||||
boolean async
|
||||
|
||||
@@ -57,8 +59,8 @@ class Response extends Common {
|
||||
this.status = toDslProperty(status)
|
||||
}
|
||||
|
||||
void headers(@DelegatesTo(Headers) Closure closure) {
|
||||
this.headers = new Headers()
|
||||
void headers(@DelegatesTo(ResponseHeaders) Closure closure) {
|
||||
this.headers = new ResponseHeaders()
|
||||
closure.delegate = headers
|
||||
closure()
|
||||
}
|
||||
@@ -89,8 +91,10 @@ class Response extends Common {
|
||||
|
||||
DslProperty value(ServerDslProperty server) {
|
||||
Object value = server.clientValue
|
||||
if (server.clientValue instanceof Pattern) {
|
||||
if (server.clientValue instanceof Pattern && server.isSingleValue()) {
|
||||
value = new Xeger(((Pattern)server.clientValue).pattern()).generate()
|
||||
} else if (server.clientValue instanceof Pattern && !server.isSingleValue()) {
|
||||
value = server.serverValue
|
||||
}
|
||||
return new DslProperty(value, server.serverValue)
|
||||
}
|
||||
@@ -114,22 +118,46 @@ class Response extends Common {
|
||||
}
|
||||
return super.value(server, client)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ServerResponse extends Response {
|
||||
ServerResponse(Response request) {
|
||||
super(request)
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class ServerResponse extends Response {
|
||||
ServerResponse(Response request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class ClientResponse extends Response {
|
||||
ClientResponse(Response request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class ResponseHeaders extends Headers {
|
||||
|
||||
@Override
|
||||
DslProperty matching(String value) {
|
||||
return $(p(Pattern.compile("${RegexpUtils.escapeSpecialRegexWithSingleEscape(value)}.*")),
|
||||
c(value))
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
private class ServerPatternValueDslProperty extends PatternValueDslProperty<ServerDslProperty> {
|
||||
|
||||
@Override
|
||||
protected ServerDslProperty createProperty(Pattern pattern, Object generatedValue) {
|
||||
return new ServerDslProperty(pattern, generatedValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ClientResponse extends Response {
|
||||
ClientResponse(Response request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,8 @@ class ServerDslProperty extends DslProperty {
|
||||
ServerDslProperty(Object singleValue) {
|
||||
super(singleValue)
|
||||
}
|
||||
|
||||
ServerDslProperty(Object server, Object client) {
|
||||
super(client, server)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2013-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.contract.spec.util
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* Useful utility methods to work with regular expresisons
|
||||
*
|
||||
* @since 1.0.2
|
||||
*/
|
||||
@CompileStatic
|
||||
class RegexpUtils {
|
||||
|
||||
private final static Pattern SPECIAL_REGEX_CHARS = Pattern.compile('[{}()\\[\\].+*?^$\\\\|]')
|
||||
|
||||
static String escapeSpecialRegexChars(String str) {
|
||||
return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\\\\\$0')
|
||||
}
|
||||
|
||||
static String escapeSpecialRegexWithSingleEscape(String str) {
|
||||
return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\$0')
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,18 +9,18 @@ org.springframework.cloud.contract.spec.Contract.make {
|
||||
"""
|
||||
)
|
||||
headers {
|
||||
header("""Content-Type""", """application/vnd.fraud.v1+json""")
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body( """{
|
||||
"fraudCheckStatus": "${value(consumer('FRAUD'), producer(regex('[A-Z]{5}')))}",
|
||||
"fraudCheckStatus": "${value(c('FRAUD'), p(regex('[A-Z]{5}')))}",
|
||||
"rejectionReason": "Amount too high"
|
||||
}""")
|
||||
headers {
|
||||
header('Content-Type': value(producer(regex('application/vnd.fraud.v1.json.*')), consumer('application/vnd.fraud.v1+json')))
|
||||
contentType("application/vnd.fraud.v1+json")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.contract.verifier.util
|
||||
import groovy.transform.TypeChecked
|
||||
import org.codehaus.groovy.runtime.GStringImpl
|
||||
import org.springframework.cloud.contract.spec.internal.DslProperty
|
||||
import org.springframework.cloud.contract.spec.util.RegexpUtils
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -97,10 +98,8 @@ class RegexpBuilders {
|
||||
return o.toString().replaceAll('\\\\', '\\\\\\\\')
|
||||
}
|
||||
|
||||
private final static Pattern SPECIAL_REGEX_CHARS = Pattern.compile('[{}()\\[\\].+*?^$\\\\|]')
|
||||
|
||||
static String escapeSpecialRegexChars(String str) {
|
||||
return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\\\\\$0')
|
||||
return RegexpUtils.escapeSpecialRegexChars(str)
|
||||
}
|
||||
|
||||
private final static String WS = /\s*/
|
||||
|
||||
@@ -138,8 +138,10 @@ class ContractHttpDocsSpec extends Specification {
|
||||
//...
|
||||
|
||||
// Each header is added in form `'Header-Name' : 'Header-Value'`.
|
||||
// there are also some helper methods
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
header 'key': 'value'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
|
||||
//...
|
||||
@@ -210,10 +212,7 @@ class ContractHttpDocsSpec extends Specification {
|
||||
response {
|
||||
status 200
|
||||
body(
|
||||
id: value(
|
||||
consumer('123'),
|
||||
producer(regex('[0-9]+'))
|
||||
),
|
||||
id: $(anyNumber()),
|
||||
surname: $(
|
||||
consumer('Kowalsky'),
|
||||
producer(regex('[a-zA-Z]+'))
|
||||
@@ -239,7 +238,7 @@ class ContractHttpDocsSpec extends Specification {
|
||||
method 'POST'
|
||||
url '/users/password'
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
email: $(consumer(optional(regex(email()))), producer('abc@abc.com')),
|
||||
|
||||
@@ -339,7 +339,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
)
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -371,9 +370,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
body("""{"property1":"a","property2":"${value(consumer('123'), producer(regex('[0-9]{3}')))}"}""")
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
@@ -628,7 +625,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header('Content-Type': 'application/json;charset=UTF-8')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body """
|
||||
{"id":"789fgh","other_data":1268}
|
||||
@@ -766,6 +763,29 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
test.contains("assertThat(responseBody).matches(\".*\");")
|
||||
}
|
||||
|
||||
@Issue('#150')
|
||||
def "should support body matching in response in Spock"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
url '/get'
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
status 200
|
||||
body(value(stub("HELLO FROM STUB"), server(regex(".*"))))
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new JaxRsClientSpockMethodRequestProcessingBodyBuilder(contractDsl, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.then(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains("responseBody ==~ java.util.regex.Pattern.compile('.*')")
|
||||
}
|
||||
|
||||
@Issue('#150')
|
||||
def "should support custom method execution in response"() {
|
||||
given:
|
||||
@@ -789,6 +809,125 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
test.contains("foo(responseBody);")
|
||||
}
|
||||
|
||||
@Issue('#150')
|
||||
def "should support custom method execution in response in Spock"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
url '/get'
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
status 200
|
||||
body(value(stub("HELLO FROM STUB"), server(execute('foo($it)'))))
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new JaxRsClientSpockMethodRequestProcessingBodyBuilder(contractDsl, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.then(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains("foo(responseBody)")
|
||||
}
|
||||
|
||||
def "should allow c/p version of consumer producer"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "test"
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body(
|
||||
property1: "a",
|
||||
property2: $(
|
||||
c('123'),
|
||||
p(regex('[0-9]{3}'))
|
||||
)
|
||||
)
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
then:
|
||||
blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""")
|
||||
blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""")
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
|
||||
}
|
||||
|
||||
@Issue('#149')
|
||||
def "should allow easier way of providing dynamic values"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
urlPath '/get'
|
||||
body([
|
||||
alpha: $(anyAlphaUnicode()),
|
||||
number: $(anyNumber()),
|
||||
aBoolean: $(aBoolean()),
|
||||
ip: $(anyIpAddress()),
|
||||
hostname: $(anyHostname()),
|
||||
email: $(anyEmail()),
|
||||
url: $(anyUrl()),
|
||||
uuid: $(anyUuid())
|
||||
])
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body([
|
||||
alpha: $(anyAlphaUnicode()),
|
||||
number: $(anyNumber()),
|
||||
aBoolean: $(aBoolean()),
|
||||
ip: $(anyIpAddress()),
|
||||
hostname: $(anyHostname()),
|
||||
email: $(anyEmail()),
|
||||
url: $(anyUrl()),
|
||||
uuid: $(anyUuid())
|
||||
])
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('assertThatJson(parsedJson).field("aBoolean").matches("(true|false)")')
|
||||
test.contains('assertThatJson(parsedJson).field("alpha").matches("[\\\\p{L}]*")')
|
||||
test.contains('assertThatJson(parsedJson).field("hostname").matches("((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?")')
|
||||
test.contains('assertThatJson(parsedJson).field("url").matches("((www\\\\.|(http|https|ftp|news|file)+\\\\:\\\\/\\\\/)[_.a-z0-9-]+\\\\.[a-z0-9\\\\/_:@=.+?,##%&~-]*[^.|\\\\\'|\\\\# |!|\\\\(|?|,| |>|<|;|\\\\)])")')
|
||||
test.contains('assertThatJson(parsedJson).field("number").matches("-?\\\\d*(\\\\.\\\\d+)?")')
|
||||
test.contains('assertThatJson(parsedJson).field("email").matches("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}")')
|
||||
test.contains('assertThatJson(parsedJson).field("ip").matches("([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])")')
|
||||
test.contains('assertThatJson(parsedJson).field("uuid").matches("[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}")')
|
||||
!test.contains('cursor')
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
|
||||
}
|
||||
|
||||
private String stripped(String string) {
|
||||
return string.stripMargin().stripIndent().replace('\t', '').replace('\n', '').replace(' ','')
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
method 'POST'
|
||||
url '/users/password'
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
email: $(consumer(optional(regex(email()))), producer('abc@abc.com')),
|
||||
@@ -50,7 +50,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
response {
|
||||
status 404
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
code: value(consumer("123123"), producer(optional("123123"))),
|
||||
@@ -67,7 +67,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
method 'POST'
|
||||
url '/users/password'
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
""" {
|
||||
@@ -84,7 +84,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
response {
|
||||
status 404
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
""" {
|
||||
@@ -102,7 +102,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method "GET"
|
||||
method GET()
|
||||
url "test"
|
||||
}
|
||||
response {
|
||||
@@ -133,7 +133,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method "GET"
|
||||
method GET()
|
||||
url "test"
|
||||
}
|
||||
response {
|
||||
@@ -439,7 +439,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
)
|
||||
)
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -471,7 +471,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
value(consumer('123'), producer(regex('[0-9]{3}')))
|
||||
}"}""")
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -504,7 +504,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
value(consumer('123'), producer(regex('\\d+')))
|
||||
}"}""")
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,7 +621,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method('POST')
|
||||
method(POST())
|
||||
url("/ws/payments")
|
||||
body("")
|
||||
}
|
||||
@@ -679,7 +679,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
request {
|
||||
method 'POST'
|
||||
url $(consumer(regex('/partners/[0-9]+/users')), producer('/partners/1000/users'))
|
||||
headers { header 'Content-Type': 'application/json' }
|
||||
headers { contentType(applicationJson()) }
|
||||
body(
|
||||
first_name: 'John',
|
||||
last_name: 'Smith',
|
||||
@@ -718,7 +718,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
request {
|
||||
method 'POST'
|
||||
url $(consumer(regex('/partners/[0-9]+/users')), producer('/partners/1000/users'))
|
||||
headers { header 'Content-Type': 'application/json' }
|
||||
headers { contentType(applicationJson()) }
|
||||
body(
|
||||
first_name: 'John',
|
||||
last_name: 'Smith',
|
||||
@@ -758,7 +758,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
method 'POST'
|
||||
url '/validation/client'
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
bank_account_number: '0014282912345698765432161182',
|
||||
@@ -796,10 +796,10 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
Contract contractDsl = Contract.make {
|
||||
|
||||
request {
|
||||
method 'PUT'
|
||||
method PUT()
|
||||
url "/partners/${value(consumer(regex('^[0-9]*$')), producer('11'))}/agents/11/customers/09665703Z"
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
first_name: 'Josef',
|
||||
@@ -829,10 +829,10 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
Contract contractDsl = Contract.make {
|
||||
priority 1
|
||||
request {
|
||||
method 'POST'
|
||||
method POST()
|
||||
url '/users/password'
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
email: $(consumer(regex(email())), producer('not.existing@user.com')),
|
||||
@@ -842,7 +842,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
response {
|
||||
status 404
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
code: 4,
|
||||
@@ -965,7 +965,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
method "PUT"
|
||||
url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data"
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
client: [
|
||||
@@ -1000,7 +1000,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1029,7 +1029,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
method "PUT"
|
||||
url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев"
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body(
|
||||
client: [
|
||||
@@ -1041,7 +1041,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header('Content-Type': 'application/json')
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1094,7 +1094,7 @@ World.'''"""
|
||||
method "PUT"
|
||||
url "/multipart"
|
||||
headers {
|
||||
header('content-type', 'multipart/form-data;boundary=AaB03x')
|
||||
contentType('multipart/form-data;boundary=AaB03x')
|
||||
}
|
||||
multipart(
|
||||
formParameter: value(consumer(regex('.+')), producer('"formParameterValue"')),
|
||||
@@ -1275,7 +1275,7 @@ World.'''"""
|
||||
producer(regex('[0-9]+'))
|
||||
)]])
|
||||
headers {
|
||||
header('Content-Type': 'application/json;charset=UTF-8')
|
||||
contentType(applicationJsonUtf8())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1525,22 +1525,19 @@ World.'''"""
|
||||
method 'PUT'
|
||||
url value(consumer(regex('/foo/[0-9]{5}')))
|
||||
body([
|
||||
requestElement: value(consumer(regex('[0-9]{5}')))
|
||||
requestElement: $(consumer(regex('[0-9]{5}')))
|
||||
])
|
||||
headers {
|
||||
header('header', value(consumer(regex('application\\/vnd\\.fraud\\.v1\\+json;.*'))))
|
||||
header('header', $(consumer(regex('application\\/vnd\\.fraud\\.v1\\+json;.*'))))
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body([
|
||||
responseElement: value(producer(regex('[0-9]{7}')))
|
||||
responseElement: $(producer(regex('[0-9]{7}')))
|
||||
])
|
||||
headers {
|
||||
header('Content-Type': value(
|
||||
producer(regex('application/vnd.fraud.v1.json.*')),
|
||||
consumer('application/vnd.fraud.v1+json'))
|
||||
)
|
||||
contentType("application/vnd.fraud.v1.json")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1560,7 +1557,7 @@ World.'''"""
|
||||
strippedTest.matches(""".*header\\("header", "application\\/vnd\\.fraud\\.v1\\+json;.*"\\).*""")
|
||||
strippedTest.matches(""".*body\\('''\\{"requestElement":"[0-9]{5}"\\}'''\\).*""")
|
||||
strippedTest.matches(""".*put\\("/foo/[0-9]{5}"\\).*""")
|
||||
strippedTest.contains("""response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application/vnd.fraud.v1.json.*')""")
|
||||
strippedTest.contains("""response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application/vnd\\.fraud\\.v1\\.json.*')""")
|
||||
"application/vnd.fraud.v1+json;charset=UTF-8".matches('application/vnd.fraud.v1.json.*')
|
||||
strippedTest.contains("""assertThatJson(parsedJson).field("responseElement").matches("[0-9]{7}")""")
|
||||
}
|
||||
@@ -1668,4 +1665,88 @@ World.'''"""
|
||||
test.contains("foo(responseBody)")
|
||||
}
|
||||
|
||||
@Issue('#149')
|
||||
def "should allow c/p version of consumer producer"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
urlPath '/get'
|
||||
headers {
|
||||
header('authorization', $(c('Bearer token'), p(execute('getOAuthTokenHeader()'))))
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body([
|
||||
fraudCheckStatus: "OK",
|
||||
rejectionReason : [
|
||||
title: $(c(null), p(execute('assertThatRejectionReasonIsNull($it)')))
|
||||
]
|
||||
])
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.given(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('.header("authorization", getOAuthTokenHeader())')
|
||||
}
|
||||
|
||||
@Issue('#149')
|
||||
def "should allow easier way of providing dynamic values"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
urlPath '/get'
|
||||
body([
|
||||
alpha: $(anyAlphaUnicode()),
|
||||
number: $(anyNumber()),
|
||||
aBoolean: $(aBoolean()),
|
||||
ip: $(anyIpAddress()),
|
||||
hostname: $(anyHostname()),
|
||||
email: $(anyEmail()),
|
||||
url: $(anyUrl()),
|
||||
uuid: $(anyUuid())
|
||||
])
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body([
|
||||
alpha: $(anyAlphaUnicode()),
|
||||
number: $(anyNumber()),
|
||||
aBoolean: $(aBoolean()),
|
||||
ip: $(anyIpAddress()),
|
||||
hostname: $(anyHostname()),
|
||||
email: $(anyEmail()),
|
||||
url: $(anyUrl()),
|
||||
uuid: $(anyUuid())
|
||||
])
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('assertThatJson(parsedJson).field("aBoolean").matches("(true|false)")')
|
||||
test.contains('assertThatJson(parsedJson).field("alpha").matches("[\\\\p{L}]*")')
|
||||
test.contains('assertThatJson(parsedJson).field("hostname").matches("((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?")')
|
||||
test.contains('assertThatJson(parsedJson).field("url").matches("((www\\\\.|(http|https|ftp|news|file)+\\\\:\\\\/\\\\/)[_.a-z0-9-]+\\\\.[a-z0-9\\\\/_:@=.+?,##%&~-]*[^.|\\\\\'|\\\\# |!|\\\\(|?|,| |>|<|;|\\\\)])")')
|
||||
test.contains('assertThatJson(parsedJson).field("number").matches("-?\\\\d*(\\\\.\\\\d+)?")')
|
||||
test.contains('assertThatJson(parsedJson).field("email").matches("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}")')
|
||||
test.contains('assertThatJson(parsedJson).field("ip").matches("([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])\\\\.([01]?\\\\d\\\\d?|2[0-4]\\\\d|25[0-5])")')
|
||||
test.contains('assertThatJson(parsedJson).field("uuid").matches("[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}")')
|
||||
!test.contains('cursor')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ Contract.make {
|
||||
request {
|
||||
method('PUT')
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
contentType(applicationJson())
|
||||
}
|
||||
body("""\
|
||||
{
|
||||
@@ -42,7 +42,7 @@ Contract.make {
|
||||
"""
|
||||
)
|
||||
headers {
|
||||
header 'Content-Type': 'text/plain'
|
||||
contentType(textPlain())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class CamelMessagingApplicationSpec extends Specification {
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
header('Content-Type', 'application/json')
|
||||
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
|
||||
Reference in New Issue
Block a user