Reworked DSL for cookies

This commit is contained in:
Tim Ysewyn
2019-08-09 23:42:58 +02:00
parent c6b0d1f6eb
commit 232634090b
6 changed files with 215 additions and 7 deletions

View File

@@ -24,8 +24,14 @@ contract {
method = GET
url = url("/frauds/name")
cookies {
cookie("name", "foo")
cookie(mapOf("name2" to "bar"))
cookie {
name = "name"
value = "foo"
}
cookie{
name = "name2"
value = "bar"
}
}
}
response {

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 CookieDsl {
var name: String by Delegates.notNull()
var value: Any by Delegates.notNull()
}

View File

@@ -0,0 +1,48 @@
/*
* 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
/**
* @author Tim Ysewyn
*/
open class CookiesDsl : CommonDsl() {
private val cookies = LinkedHashMap<String, Any>()
open fun matching(value: Any?): Any? = value
/**
* Adds and configures a cookie.
*
* @param configurer The lambda to configure the cookie.
*/
fun cookie(configurer: CookieDsl.() -> Unit) {
try {
val cookie = CookieDsl().apply(configurer)
this.cookies[cookie.name] = cookie.value
} catch (ex: IllegalStateException) {
throw IllegalStateException("Cookie is missing its name or value")
}
}
internal fun get(): Cookies {
val cookies = Cookies()
this.cookies.forEach { (name, value) -> cookies.cookie(name, value) }
return cookies
}
}

View File

@@ -54,8 +54,8 @@ open class RequestDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
this.headers = RequestHeadersDsl().apply(headers).get()
}
fun cookies(cookies: Cookies.() -> Unit) {
this.cookies = Request.RequestCookies().apply(cookies)
fun cookies(cookies: CookiesDsl.() -> Unit) {
this.cookies = RequestCookiesDsl().apply(cookies).get()
}
fun body(body: Map<String, Any>) = Body(body.toDslProperties())
@@ -266,4 +266,22 @@ open class RequestDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
}
}
private class RequestCookiesDsl: CookiesDsl() {
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

@@ -45,9 +45,9 @@ class ResponseDsl : CommonDsl(), RegexCreatingProperty<ServerDslProperty> {
this.headers = ResponseHeadersDsl().apply(headers).get()
}
fun cookies(cookies: Cookies.() -> Unit) {
this.cookies = Response.ResponseCookies().apply(cookies)
}
fun cookies(cookies: CookiesDsl.() -> Unit) {
this.cookies = ResponseCookiesDsl().apply(cookies).get()
}
fun body(body: Map<String, Any>) = Body(body.toDslProperties())
@@ -305,4 +305,22 @@ class ResponseDsl : CommonDsl(), RegexCreatingProperty<ServerDslProperty> {
}
}
private class ResponseCookiesDsl: CookiesDsl() {
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(regex(RegexpUtils.escapeSpecialRegexWithSingleEscape(value) + ".*"))
)
else -> value
}
}
}
}
}

View File

@@ -21,6 +21,7 @@ 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.Cookie
import org.springframework.cloud.contract.spec.internal.RegexProperty
/**
@@ -701,4 +702,92 @@ then:
}
}
@Test
fun `should work with cookies`() {
val contract = contract {
request {
method = GET
url = url("/cookie")
cookies {
cookie {
name = "name"
value = "foo"
}
cookie {
name = "name2"
value = "bar"
}
}
}
response {
status = OK
cookies {
cookie {
name = "name"
value = "foo"
}
cookie {
name = "name2"
value = "bar"
}
}
}
}
assertDoesNotThrow {
Contract.assertContract(contract)
}.also {
val request = contract.request
val cookies = request.cookies.entries
assertThat(cookies).hasSize(2)
assertThat(cookies).containsExactlyInAnyOrder(Cookie.build("name", "foo"), Cookie.build("name2", "bar"))
}.also {
val response = contract.response
val cookies = response.cookies.entries
assertThat(cookies).hasSize(2)
assertThat(cookies).containsExactlyInAnyOrder(Cookie.build("name", "foo"), Cookie.build("name2", "bar"))
}
}
@Test
fun `should throw error when cookie is not configured correctly`() {
assertThrows<IllegalStateException> {
contract {
request {
method = GET
url = url("/cookie")
cookies {
cookie {
value = "bar"
}
}
}
response {
status = OK
}
}
}.also {
assertThat(it.message).contains("Cookie is missing its name or value")
}
assertThrows<IllegalStateException> {
contract {
request {
method = GET
url = url("/cookie")
cookies {
cookie {
name = "foo"
}
}
}
response {
status = OK
}
}
}.also {
assertThat(it.message).contains("Cookie is missing its name or value")
}
}
}