Reworked DSL for headers

This commit is contained in:
Tim Ysewyn
2019-08-09 23:35:00 +02:00
parent 17f72115b1
commit c6b0d1f6eb
18 changed files with 517 additions and 72 deletions

View File

@@ -24,7 +24,7 @@ contract {
url = url("/1")
method = PUT
headers {
contentType(applicationOctetStream())
contentType = APPLICATION_OCTET_STREAM
}
body = bodyFromFileAsBytes("request.pdf")
}
@@ -32,7 +32,7 @@ contract {
status = OK
body = bodyFromFileAsBytes("response.pdf")
headers {
contentType(applicationOctetStream())
contentType = APPLICATION_OCTET_STREAM
}
}
}

View File

@@ -27,7 +27,7 @@ contract {
"client.id" to value(regex("[0-9]{10}")),
"loanAmount" to 99999)
headers { // (5)
contentType("application/json")
contentType = "application/json"
}
}
response { // (6)
@@ -36,7 +36,7 @@ contract {
"fraudCheckStatus" to "FRAUD",
"rejection.reason" to "Amount too high")
headers { // (9)
contentType("application/json")
contentType = "application/json"
}
}
}

View File

@@ -27,7 +27,7 @@ contract {
"client.id" to value(consumer(regex("[0-9]{10}")), producer("1234567890")),
"loanAmount" to 123.123)
headers {
contentType("application/json")
contentType = "application/json"
}
}
response {
@@ -37,7 +37,7 @@ contract {
"rejection.reason" to value(consumer(null), producer(execute("assertThatRejectionReasonIsNull(\$it)")))
)
headers {
contentType("application/json")
contentType = "application/json"
}
}
}

View File

@@ -33,7 +33,7 @@ listOf(
"count" to value(regex("[2-9][0-9][0-9]"))
)
headers {
contentType("application/json")
contentType = "application/json"
}
}
},
@@ -48,7 +48,7 @@ listOf(
"count" to 100
)
headers {
contentType("application/json")
contentType = "application/json"
}
}
}

View File

@@ -28,7 +28,7 @@ contract {
url = url("/frauds/name")
body = body("name" to "fraud")
headers {
contentType("application/json")
contentType = "application/json"
}
}
response {

View File

@@ -26,7 +26,7 @@ contract {
url = url("/frauds/name")
body = body("name" to `$`(anyAlphaUnicode()))
headers {
contentType("application/json")
contentType = "application/json"
}
}
response {

View File

@@ -36,14 +36,14 @@ contract {
value("application/json"))
))
headers {
contentType("multipart/form-data")
contentType = "multipart/form-data"
}
}
response {
status = OK
body = body("status" to "ok")
headers {
contentType("application/json")
contentType = "application/json"
}
}
}

View File

@@ -36,14 +36,14 @@ contract {
value("application/json"))
))
headers {
contentType("multipart/form-data")
contentType = "multipart/form-data"
}
}
response {
status = OK
body = body("status" to "ok")
headers {
contentType("application/json")
contentType = "application/json"
}
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2013-2019 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
*
* https://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.internal
import kotlin.properties.Delegates
/**
* @author Tim Ysewyn
*/
class HeaderDsl {
var name: String by Delegates.notNull()
var value: Any by Delegates.notNull()
}

View File

@@ -19,14 +19,316 @@ package org.springframework.cloud.contract.spec.internal
/**
* @author Tim Ysewyn
*/
@ContractDslMarker
class HeadersDsl {
open class HeadersDsl: CommonDsl() {
var accept: String? = null
var contentType: String? = null
internal val headers = LinkedHashMap<String, Any>()
fun header(headerKey: String, headerValue: Any) {
var accept: Any?
get() = headers[HttpHeaders.ACCEPT]
set(accept) = storeHeaderValue(HttpHeaders.ACCEPT, matching(accept))
var acceptCharset: Any?
get() = headers[HttpHeaders.ACCEPT_CHARSET]
set(acceptCharset) = storeHeaderValue(HttpHeaders.ACCEPT_CHARSET, acceptCharset)
var acceptEncoding: Any?
get() = headers[HttpHeaders.ACCEPT_ENCODING]
set(acceptEncoding) = storeHeaderValue(HttpHeaders.ACCEPT_ENCODING, acceptEncoding)
var acceptLanguage: Any?
get() = headers[HttpHeaders.ACCEPT_LANGUAGE]
set(acceptLanguage) = storeHeaderValue(HttpHeaders.ACCEPT_LANGUAGE, acceptLanguage)
var acceptRanges: Any?
get() = headers[HttpHeaders.ACCEPT_RANGES]
set(acceptRanges) = storeHeaderValue(HttpHeaders.ACCEPT_RANGES, acceptRanges)
var accessControlAllowCredentials: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS]
set(accessControlAllowCredentials) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, accessControlAllowCredentials)
var accessControlAllowHeaders: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS]
set(accessControlAllowHeaders) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, accessControlAllowHeaders)
var accessControlAllowMethods: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS]
set(accessControlAllowMethods) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, accessControlAllowMethods)
var accessControlAllowOrigin: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN]
set(accessControlAllowOrigin) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, accessControlAllowOrigin)
var accessControlExposeHeaders: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS]
set(accessControlExposeHeaders) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, accessControlExposeHeaders)
var accessControlMaxAge: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_MAX_AGE]
set(accessControlMaxAge) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_MAX_AGE, accessControlMaxAge)
var accessControlRequestHeaders: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS]
set(accessControlRequestHeaders) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, accessControlRequestHeaders)
var accessControlRequestMethod: Any?
get() = headers[HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD]
set(accessControlRequestMethod) = storeHeaderValue(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, accessControlRequestMethod)
var age: Any?
get() = headers[HttpHeaders.AGE]
set(age) = storeHeaderValue(HttpHeaders.AGE, age)
var allow: Any?
get() = headers[HttpHeaders.ALLOW]
set(allow) = storeHeaderValue(HttpHeaders.ALLOW, allow)
var authorization: Any?
get() = headers[HttpHeaders.AUTHORIZATION]
set(authorization) = storeHeaderValue(HttpHeaders.AUTHORIZATION, authorization)
var cacheControl: Any?
get() = headers[HttpHeaders.CACHE_CONTROL]
set(cacheControl) = storeHeaderValue(HttpHeaders.CACHE_CONTROL, cacheControl)
var connection: Any?
get() = headers[HttpHeaders.CONNECTION]
set(connection) = storeHeaderValue(HttpHeaders.CONNECTION, connection)
var contentEncoding: Any?
get() = headers[HttpHeaders.CONTENT_ENCODING]
set(contentEncoding) = storeHeaderValue(HttpHeaders.CONTENT_ENCODING, contentEncoding)
var contentDisposition: Any?
get() = headers[HttpHeaders.CONTENT_DISPOSITION]
set(contentDisposition) = storeHeaderValue(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
var contentLanguage: Any?
get() = headers[HttpHeaders.CONTENT_LANGUAGE]
set(contentLanguage) = storeHeaderValue(HttpHeaders.CONTENT_LANGUAGE, contentLanguage)
var contentLength: Any?
get() = headers[HttpHeaders.CONTENT_LENGTH]
set(contentLength) = storeHeaderValue(HttpHeaders.CONTENT_LENGTH, contentLength)
var contentLocation: Any?
get() = headers[HttpHeaders.CONTENT_LOCATION]
set(contentLocation) = storeHeaderValue(HttpHeaders.CONTENT_LOCATION, contentLocation)
var contentRange: Any?
get() = headers[HttpHeaders.CONTENT_RANGE]
set(contentRange) = storeHeaderValue(HttpHeaders.CONTENT_RANGE, contentRange)
var contentType: Any?
get() = headers[HttpHeaders.CONTENT_TYPE]
set(contentType) = storeHeaderValue(HttpHeaders.CONTENT_TYPE, matching(contentType))
var cookie: Any?
get() = headers[HttpHeaders.COOKIE]
set(cookie) = storeHeaderValue(HttpHeaders.COOKIE, cookie)
var date: Any?
get() = headers[HttpHeaders.DATE]
set(date) = storeHeaderValue(HttpHeaders.DATE, date)
var etag: Any?
get() = headers[HttpHeaders.ETAG]
set(etag) = storeHeaderValue(HttpHeaders.ETAG, etag)
var expect: Any?
get() = headers[HttpHeaders.EXPECT]
set(expect) = storeHeaderValue(HttpHeaders.EXPECT, expect)
var expires: Any?
get() = headers[HttpHeaders.EXPIRES]
set(expires) = storeHeaderValue(HttpHeaders.EXPIRES, expires)
var from: Any?
get() = headers[HttpHeaders.FROM]
set(from) = storeHeaderValue(HttpHeaders.FROM, from)
var host: Any?
get() = headers[HttpHeaders.HOST]
set(host) = storeHeaderValue(HttpHeaders.HOST, host)
var ifMatch: Any?
get() = headers[HttpHeaders.IF_MATCH]
set(ifMatch) = storeHeaderValue(HttpHeaders.IF_MATCH, ifMatch)
var ifModifiedSince: Any?
get() = headers[HttpHeaders.IF_MODIFIED_SINCE]
set(ifModifiedSince) = storeHeaderValue(HttpHeaders.IF_MODIFIED_SINCE, ifModifiedSince)
var ifNoneMatch: Any?
get() = headers[HttpHeaders.IF_NONE_MATCH]
set(ifNoneMatch) = storeHeaderValue(HttpHeaders.IF_NONE_MATCH, ifNoneMatch)
var ifRange: Any?
get() = headers[HttpHeaders.IF_RANGE]
set(ifRange) = storeHeaderValue(HttpHeaders.IF_RANGE, ifRange)
var ifUnmodifiedSince: Any?
get() = headers[HttpHeaders.IF_UNMODIFIED_SINCE]
set(ifUnmodifiedSince) = storeHeaderValue(HttpHeaders.IF_UNMODIFIED_SINCE, ifUnmodifiedSince)
var lastModified: Any?
get() = headers[HttpHeaders.LAST_MODIFIED]
set(lastModified) = storeHeaderValue(HttpHeaders.LAST_MODIFIED, lastModified)
var link: Any?
get() = headers[HttpHeaders.LINK]
set(link) = storeHeaderValue(HttpHeaders.LINK, link)
var location: Any?
get() = headers[HttpHeaders.LOCATION]
set(location) = storeHeaderValue(HttpHeaders.LOCATION, location)
var max_forwards: Any?
get() = headers[HttpHeaders.MAX_FORWARDS]
set(max_forwards) = storeHeaderValue(HttpHeaders.MAX_FORWARDS, max_forwards)
var origin: Any?
get() = headers[HttpHeaders.ORIGIN]
set(origin) = storeHeaderValue(HttpHeaders.ORIGIN, origin)
var pragma: Any?
get() = headers[HttpHeaders.PRAGMA]
set(pragma) = storeHeaderValue(HttpHeaders.PRAGMA, pragma)
var proxyAuthenticate: Any?
get() = headers[HttpHeaders.PROXY_AUTHENTICATE]
set(proxyAuthenticate) = storeHeaderValue(HttpHeaders.PROXY_AUTHENTICATE, proxyAuthenticate)
var proxyAuthorization: Any?
get() = headers[HttpHeaders.PROXY_AUTHORIZATION]
set(proxyAuthorization) = storeHeaderValue(HttpHeaders.PROXY_AUTHORIZATION, proxyAuthorization)
var range: Any?
get() = headers[HttpHeaders.RANGE]
set(range) = storeHeaderValue(HttpHeaders.RANGE, range)
var referer: Any?
get() = headers[HttpHeaders.REFERER]
set(referer) = storeHeaderValue(HttpHeaders.REFERER, referer)
var retryAfter: Any?
get() = headers[HttpHeaders.RETRY_AFTER]
set(retryAfter) = storeHeaderValue(HttpHeaders.RETRY_AFTER, retryAfter)
var server: Any?
get() = headers[HttpHeaders.SERVER]
set(server) = storeHeaderValue(HttpHeaders.SERVER, server)
var setCookie: Any?
get() = headers[HttpHeaders.SET_COOKIE]
set(setCookie) = storeHeaderValue(HttpHeaders.SET_COOKIE, setCookie)
var setCookie2: Any?
get() = headers[HttpHeaders.SET_COOKIE_2]
set(setCookie2) = storeHeaderValue(HttpHeaders.SET_COOKIE_2, setCookie2)
var te: Any?
get() = headers[HttpHeaders.TE]
set(te) = storeHeaderValue(HttpHeaders.TE, te)
var trailer: Any?
get() = headers[HttpHeaders.TRAILER]
set(trailer) = storeHeaderValue(HttpHeaders.TRAILER, trailer)
var transferEncoding: Any?
get() = headers[HttpHeaders.TRANSFER_ENCODING]
set(transferEncoding) = storeHeaderValue(HttpHeaders.TRANSFER_ENCODING, transferEncoding)
var upgrade: Any?
get() = headers[HttpHeaders.UPGRADE]
set(upgrade) = storeHeaderValue(HttpHeaders.UPGRADE, upgrade)
var user_agent: Any?
get() = headers[HttpHeaders.USER_AGENT]
set(user_agent) = storeHeaderValue(HttpHeaders.USER_AGENT, user_agent)
var vary: Any?
get() = headers[HttpHeaders.VARY]
set(vary) = storeHeaderValue(HttpHeaders.VARY, vary)
var via: Any?
get() = headers[HttpHeaders.VIA]
set(via) = storeHeaderValue(HttpHeaders.VIA, via)
var warning: Any?
get() = headers[HttpHeaders.WARNING]
set(warning) = storeHeaderValue(HttpHeaders.WARNING, warning)
var wwwAuthenticate: Any?
get() = headers[HttpHeaders.WWW_AUTHENTICATE]
set(wwwAuthenticate) = storeHeaderValue(HttpHeaders.WWW_AUTHENTICATE, wwwAuthenticate)
var messagingContentType: Any?
get() = headers[MessagingHeaders.MESSAGING_CONTENT_TYPE]
set(messagingContentType) = storeHeaderValue(MessagingHeaders.MESSAGING_CONTENT_TYPE, matching(messagingContentType))
open fun matching(value: Any?): Any? = value
private fun storeHeaderValue(header: String, value: Any?) {
value?.also { headers[header] = value }
}
/* HELPER VARIABLES */
/* MEDIA TYPES */
val ALL_VALUE = MediaTypes.ALL_VALUE
val APPLICATION_ATOM_XML = MediaTypes.APPLICATION_ATOM_XML
val APPLICATION_FORM_URLENCODED = MediaTypes.APPLICATION_FORM_URLENCODED
val APPLICATION_JSON = MediaTypes.APPLICATION_JSON
val APPLICATION_JSON_UTF8 = MediaTypes.APPLICATION_JSON_UTF8
val APPLICATION_OCTET_STREAM = MediaTypes.APPLICATION_OCTET_STREAM
val APPLICATION_PDF = MediaTypes.APPLICATION_PDF
val APPLICATION_XHTML_XML = MediaTypes.APPLICATION_XHTML_XML
val APPLICATION_XML = MediaTypes.APPLICATION_XML
val IMAGE_GIF = MediaTypes.IMAGE_GIF
val IMAGE_JPEG = MediaTypes.IMAGE_JPEG
val IMAGE_PNG = MediaTypes.IMAGE_PNG
val MULTIPART_FORM_DATA = MediaTypes.MULTIPART_FORM_DATA
val TEXT_HTML = MediaTypes.TEXT_HTML
val TEXT_MARKDOWN = MediaTypes.TEXT_MARKDOWN
val TEXT_PLAIN = MediaTypes.TEXT_PLAIN
val TEXT_XML = MediaTypes.TEXT_XML
/**
* Adds and configures a configurer.
*
* @param configurer The lambda to configure the configurer.
*/
fun header(configurer: HeaderDsl.() -> Unit) {
try {
val header = HeaderDsl().apply(configurer)
this.headers[header.name] = header.value
} catch (ex: IllegalStateException) {
throw IllegalStateException("Header is missing its name or value")
}
}
internal fun get(): Headers {
val headers = Headers()
this.headers.forEach { (key, value) -> headers.header(key, value) }
return headers
}
}

View File

@@ -24,7 +24,7 @@ class InputDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
var messageFrom: DslProperty<String>? = null
var triggeredBy: ExecutionProperty? = null
var messageHeaders: Headers? = null
var headers: Headers? = null
var messageBody: Input.BodyType? = null
var assertThat: ExecutionProperty? = null
var bodyMatchers: BodyMatchers? = null
@@ -33,8 +33,8 @@ class InputDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
this.messageFrom = DslProperty(messageFrom)
}
fun messageHeaders(headers: Headers.() -> Unit) {
this.messageHeaders = Headers().apply(headers)
fun headers(headers: HeadersDsl.() -> Unit) {
this.headers = HeadersDsl().apply(headers).get()
}
fun triggeredBy(triggeredBy: String) {
@@ -107,7 +107,7 @@ class InputDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
val input = Input()
messageFrom?.also { input.messageFrom = messageFrom!! }
triggeredBy?.also { input.triggeredBy = triggeredBy!! }
messageHeaders?.also { input.messageHeaders = messageHeaders!! }
headers?.also { input.messageHeaders = headers!! }
messageBody?.also { input.messageBody = messageBody!! }
assertThat?.also { input.assertThat = assertThat!! }
bodyMatchers?.also { input.bodyMatchers = bodyMatchers!! }

View File

@@ -32,8 +32,8 @@ class OutputMessageDsl : CommonDsl(), RegexCreatingProperty<ServerDslProperty> {
this.sentTo = DslProperty(sentTo)
}
fun headers(headers: Headers.() -> Unit) {
this.headers = Headers().apply(headers)
fun headers(headers: HeadersDsl.() -> Unit) {
this.headers = HeadersDsl().apply(headers).get()
}
fun body(body: Any) {

View File

@@ -18,6 +18,7 @@ package org.springframework.cloud.contract.spec.internal
import org.springframework.cloud.contract.spec.toDslProperties
import org.springframework.cloud.contract.spec.toDslProperty
import org.springframework.cloud.contract.spec.util.RegexpUtils
import java.util.regex.Pattern
/**
@@ -49,8 +50,8 @@ open class RequestDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
fun path(path: DslProperty<Any>) = UrlPath(path)
fun headers(headers: Headers.() -> Unit) {
this.headers = Request.RequestHeaders().apply(headers)
fun headers(headers: HeadersDsl.() -> Unit) {
this.headers = RequestHeadersDsl().apply(headers).get()
}
fun cookies(cookies: Cookies.() -> Unit) {
@@ -85,21 +86,21 @@ open class RequestDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
/* HTTP METHODS */
val GET = method(HttpMethods.HttpMethod.GET.name)
val GET = method(HttpMethods.GET)
val HEAD = method(HttpMethods.HttpMethod.HEAD.name)
val HEAD = method(HttpMethods.HEAD)
val POST = method(HttpMethods.HttpMethod.POST.name)
val POST = method(HttpMethods.POST)
val PUT = method(HttpMethods.HttpMethod.PUT.name)
val PUT = method(HttpMethods.PUT)
val PATCH = method(HttpMethods.HttpMethod.PATCH.name)
val PATCH = method(HttpMethods.PATCH)
val DELETE = method(HttpMethods.HttpMethod.DELETE.name)
val DELETE = method(HttpMethods.DELETE)
val OPTIONS = method(HttpMethods.HttpMethod.OPTIONS.name)
val OPTIONS = method(HttpMethods.OPTIONS)
val TRACE = method(HttpMethods.HttpMethod.TRACE.name)
val TRACE = method(HttpMethods.TRACE)
/* HELPER FUNCTIONS */
@@ -247,4 +248,22 @@ open class RequestDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
bodyMatchers?.also { request.bodyMatchers = bodyMatchers!! }
return request
}
private class RequestHeadersDsl: HeadersDsl() {
private val common = Common()
override fun matching(value: Any?): Any? {
return value?.also {
return when(value) {
is String -> this.common.value(
c(regex(RegexpUtils.escapeSpecialRegexWithSingleEscape(value) + ".*")),
p(value)
)
else -> value
}
}
}
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.cloud.contract.spec.internal
import org.springframework.cloud.contract.spec.toDslProperties
import org.springframework.cloud.contract.spec.toDslProperty
import org.springframework.cloud.contract.spec.util.RegexpUtils
import java.util.regex.Pattern
/**
@@ -40,8 +41,8 @@ class ResponseDsl : CommonDsl(), RegexCreatingProperty<ServerDslProperty> {
fun fixedMilliseconds(delay: Long) = delay.toDslProperty()
fun headers(headers: Headers.() -> Unit) {
this.headers = Response.ResponseHeaders().apply(headers)
fun headers(headers: HeadersDsl.() -> Unit) {
this.headers = ResponseHeadersDsl().apply(headers).get()
}
fun cookies(cookies: Cookies.() -> Unit) {
@@ -286,4 +287,22 @@ class ResponseDsl : CommonDsl(), RegexCreatingProperty<ServerDslProperty> {
bodyMatchers?.also { response.bodyMatchers = bodyMatchers }
return response
}
private class ResponseHeadersDsl: HeadersDsl() {
private val common = Common()
override fun matching(value: Any?): Any? {
return value?.also {
return when(value) {
is String -> return this.common.value(
c(value),
p(NotToEscapePattern(Pattern.compile(RegexpUtils.escapeSpecialRegexWithSingleEscape(value) + ".*")))
)
else -> value
}
}
}
}
}

View File

@@ -21,8 +21,6 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertDoesNotThrow
import org.junit.jupiter.api.assertThrows
import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract
import org.springframework.cloud.contract.spec.internal.HttpMethods
import org.springframework.cloud.contract.spec.internal.HttpStatus
import org.springframework.cloud.contract.spec.internal.RegexProperty
/**
@@ -39,14 +37,20 @@ class ContractTests {
url = url("/foo")
method = PUT
headers {
header("foo", "bar")
header {
name = "foo"
value = "bar"
}
}
body = body("foo" to "bar")
}
response {
status = OK
headers {
header("foo2", "bar")
header {
name = "foo2"
value = "bar"
}
}
body = body("foo2" to "bar")
}
@@ -141,15 +145,21 @@ class ContractTests {
input {
messageFrom("input")
messageBody("foo" to "bar")
messageHeaders {
header("foo", "bar")
headers {
header {
name = "foo"
value = "bar"
}
}
}
outputMessage {
sentTo("output")
body("foo2" to "bar")
headers {
header("foo2", "bar")
header {
name = "foo2"
value = "bar"
}
}
}
}
@@ -187,15 +197,21 @@ class ContractTests {
input {
messageFrom("input")
messageBody("foo" to anyNonBlankString())
messageHeaders {
header("foo", anyNumber())
headers {
header {
name = "foo"
value = anyNumber()
}
}
}
outputMessage {
sentTo("output")
body("foo2" to anyNonEmptyString())
headers {
header("foo2", anyIpAddress())
header {
name = "foo2"
value = anyIpAddress()
}
}
}
}
@@ -324,7 +340,7 @@ then:
request {
method = PUT
headers {
contentType(applicationJson())
contentType = APPLICATION_JSON
}
url = url("/$index")
}
@@ -336,7 +352,7 @@ then:
request {
method = PUT
headers {
contentType(applicationJson())
contentType = APPLICATION_JSON
}
url = url("/$index")
}
@@ -360,7 +376,7 @@ then:
request {
method = PUT
headers {
contentType(applicationJson())
contentType = APPLICATION_JSON
}
url = url("/$index")
}
@@ -373,7 +389,7 @@ then:
request {
method = PUT
headers {
contentType(applicationJson())
contentType = APPLICATION_JSON
}
url = url("/$index")
}
@@ -397,14 +413,20 @@ then:
method = GET
url = url("/path")
headers {
header("Accept", value(
header {
name = "Accept"
value = value(
consumer(regex("text/.*")),
producer("text/plain")
))
header("X-Custom-Header", value(
)
}
header {
name = "X-Custom-Header"
value = value(
consumer(regex("^.*2134.*$")),
producer("121345")
))
)
}
}
}
response {
@@ -415,7 +437,10 @@ then:
"created" to "2014-02-02 12:23:43"
)
headers {
header("Content-Type", "text/plain")
header {
name = "Content-Type"
value = "text/plain"
}
}
}
}
@@ -424,14 +449,20 @@ then:
method = GET
url = url("/path")
headers {
header("Accept", value(
consumer(regex("text/.*")),
producer("text/plain")
))
header("X-Custom-Header", value(
consumer(regex("^.*2134.*$")),
producer("121345")
))
header {
name = "Accept"
value = value(
consumer(regex("text/.*")),
producer("text/plain")
)
}
header {
name = "X-Custom-Header"
value = value(
consumer(regex("^.*2134.*$")),
producer("121345")
)
}
}
}
response {
@@ -442,7 +473,10 @@ then:
"created" to "2014-02-02 12:23:43"
)
headers {
header("Content-Type", "text/plain")
header {
name = "Content-Type"
value = "text/plain"
}
}
}
}
@@ -508,7 +542,7 @@ then:
"created" to "2014-02-02 12:23:43"
)
headers {
contentType(applicationJson())
contentType = APPLICATION_JSON
}
bodyMatchers {
jsonPath("$.created", byTimestamp())
@@ -625,4 +659,46 @@ then:
assertThat(response.body.serverValue).isEqualTo(listOf("foo2", "bar2"))
}
}
@Test
fun `should throw error when header is not configured correctly`() {
assertThrows<IllegalStateException> {
contract {
request {
method = GET
url = url("/cookie")
headers {
header {
name = "foo"
}
}
}
response {
status = OK
}
}
}.also {
assertThat(it.message).contains("Header is missing its name or value")
}
assertThrows<IllegalStateException> {
contract {
request {
method = GET
url = url("/cookie")
headers {
header {
value = "bar"
}
}
}
response {
status = OK
}
}
}.also {
assertThat(it.message).contains("Header is missing its name or value")
}
}
}

View File

@@ -28,7 +28,7 @@ arrayOf(
status = OK
body = body("count" to 200)
headers {
contentType("application/vnd.fraud.v1+json")
contentType = "application/vnd.fraud.v1+json"
}
}
},
@@ -41,7 +41,7 @@ arrayOf(
status = OK
body = body("count" to 100)
headers {
contentType("application/vnd.fraud.v1+json")
contentType = "application/vnd.fraud.v1+json"
}
}
}

View File

@@ -24,7 +24,7 @@ contract {
url = url("/1")
method = PUT
headers {
contentType(applicationOctetStream())
contentType = APPLICATION_OCTET_STREAM
}
body = bodyFromFileAsBytes("contracts/request.pdf")
}
@@ -32,7 +32,7 @@ contract {
status = OK
body = bodyFromFileAsBytes("contracts/response.pdf")
headers {
contentType(applicationOctetStream())
contentType = APPLICATION_OCTET_STREAM
}
}
}

View File

@@ -26,7 +26,7 @@ contract {
"loanAmount" to 123.123
)
headers {
contentType("application/vnd.fraud.v1+json")
contentType = "application/vnd.fraud.v1+json"
}
}
@@ -37,7 +37,7 @@ contract {
"rejectionReason" to listOf(value(consumer(null), producer("assertThatRejectionReasonIsNull(\$it)")))
)
headers {
contentType("application/vnd.fraud.v1+json")
contentType = "application/vnd.fraud.v1+json"
}
}
}