Add cookie header check to contract verifier
This commit is contained in:
@@ -64,6 +64,12 @@ interface ContractTemplate {
|
||||
*/
|
||||
String header(String key, int index)
|
||||
|
||||
/**
|
||||
* Retruns the tempalte for retrieving the first value of a cookie with certain key
|
||||
* @param key
|
||||
*/
|
||||
String cookie(String key)
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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.internal
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Represents a http cookie
|
||||
*
|
||||
* @author Alex Xandra Albert Sim
|
||||
* @since 1.3.8
|
||||
*/
|
||||
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true, includeSuper = true)
|
||||
@CompileStatic
|
||||
class Cookie extends DslProperty {
|
||||
|
||||
String key
|
||||
|
||||
Cookie(String key, DslProperty dslProperty) {
|
||||
super(dslProperty.clientValue, dslProperty.serverValue)
|
||||
this.key = key
|
||||
}
|
||||
|
||||
Cookie(String key, MatchingStrategy value) {
|
||||
super(value)
|
||||
this.key = key
|
||||
}
|
||||
|
||||
Cookie(String key, Object value) {
|
||||
super(value)
|
||||
this.key = key
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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.internal
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TypeChecked
|
||||
|
||||
/**
|
||||
* Represents a set of http cookies
|
||||
*
|
||||
* @author Alex Xandra Albert Sim
|
||||
* @since 1.3.8
|
||||
*/
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true)
|
||||
@TypeChecked
|
||||
class Cookies {
|
||||
|
||||
Set<Cookie> cookies = []
|
||||
|
||||
void cookie(Map<String, Object> singleCookie) {
|
||||
Map.Entry<String, Object> first = singleCookie.entrySet().first()
|
||||
cookies << new Cookie(first?.key, first?.value)
|
||||
}
|
||||
|
||||
void cookie(String cookieKey, Object cookieValue) {
|
||||
cookies << new Cookie(cookieKey, cookieValue)
|
||||
}
|
||||
|
||||
void executeForEachCookie(Closure closure) {
|
||||
cookies?.each {
|
||||
cookie -> closure(cookie)
|
||||
}
|
||||
}
|
||||
|
||||
DslProperty matching(String value) {
|
||||
return new DslProperty(value)
|
||||
}
|
||||
|
||||
boolean equals(o) {
|
||||
if (this.is(o)) return true
|
||||
if (getClass() != o.class) return false
|
||||
Cookies cookies = (Cookies) o
|
||||
if (cookies != cookies.cookies) return false
|
||||
return true
|
||||
}
|
||||
|
||||
int hashCode() {
|
||||
return cookies.hashCode()
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,14 @@ class FromRequest {
|
||||
return new DslProperty(template.header(key, index))
|
||||
}
|
||||
|
||||
/**
|
||||
* Retruns the tempalte for retrieving the first value of a cookie with certain key
|
||||
* @param key
|
||||
*/
|
||||
DslProperty cookie(String key) {
|
||||
return new DslProperty(template.cookie(key))
|
||||
}
|
||||
|
||||
/**
|
||||
* Request body text (avoid for non-text bodies)
|
||||
*/
|
||||
|
||||
@@ -58,6 +58,11 @@ class HandlebarsContractTemplate implements ContractTemplate {
|
||||
return wrapped("request.headers.${key}.[${index}]")
|
||||
}
|
||||
|
||||
@Override
|
||||
String cookie(String key) {
|
||||
return wrapped("request.cookies.${key}")
|
||||
}
|
||||
|
||||
@Override
|
||||
String body() {
|
||||
return wrapped("request.body")
|
||||
|
||||
@@ -34,6 +34,7 @@ class OutputMessage extends Common {
|
||||
|
||||
DslProperty<String> sentTo
|
||||
Headers headers
|
||||
Cookies cookies
|
||||
DslProperty body
|
||||
ExecutionProperty assertThat
|
||||
ResponseBodyMatchers matchers
|
||||
@@ -43,6 +44,7 @@ class OutputMessage extends Common {
|
||||
OutputMessage(OutputMessage outputMessage) {
|
||||
this.sentTo = outputMessage.sentTo
|
||||
this.headers = outputMessage.headers
|
||||
this.cookies = outputMessage.cookies
|
||||
this.body = outputMessage.body
|
||||
}
|
||||
|
||||
@@ -68,6 +70,12 @@ class OutputMessage extends Common {
|
||||
closure()
|
||||
}
|
||||
|
||||
void cookies(@DelegatesTo(Cookies) Closure closure) {
|
||||
this.cookies = new Cookies()
|
||||
closure.delegate = cookies
|
||||
closure()
|
||||
}
|
||||
|
||||
void assertThat(String assertThat) {
|
||||
this.assertThat = new ExecutionProperty(assertThat)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ class Request extends Common {
|
||||
Url url
|
||||
UrlPath urlPath
|
||||
Headers headers
|
||||
Cookies cookies
|
||||
Body body
|
||||
Multipart multipart
|
||||
BodyMatchers matchers
|
||||
@@ -55,6 +56,7 @@ class Request extends Common {
|
||||
this.url = request.url
|
||||
this.urlPath = request.urlPath
|
||||
this.headers = request.headers
|
||||
this.cookies = request.cookies
|
||||
this.body = request.body
|
||||
this.multipart = request.multipart
|
||||
}
|
||||
@@ -117,6 +119,12 @@ class Request extends Common {
|
||||
closure()
|
||||
}
|
||||
|
||||
void cookies(@DelegatesTo(RequestCookies) Closure closure) {
|
||||
this.cookies = new RequestCookies()
|
||||
closure.delegate = cookies
|
||||
closure()
|
||||
}
|
||||
|
||||
void body(Map<String, Object> body) {
|
||||
this.body = new Body(convertObjectsToDslProperties(body))
|
||||
}
|
||||
@@ -259,6 +267,18 @@ class Request extends Common {
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@ToString(includePackage = false)
|
||||
private class RequestCookies extends Cookies {
|
||||
|
||||
@Override
|
||||
DslProperty matching(String value) {
|
||||
return $(c(regex("${RegexpUtils.escapeSpecialRegexWithSingleEscape(value)}.*")),
|
||||
p(value))
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@ToString(includePackage = false)
|
||||
|
||||
@@ -40,6 +40,7 @@ class Response extends Common {
|
||||
DslProperty status
|
||||
DslProperty delay
|
||||
Headers headers
|
||||
Cookies cookies
|
||||
Body body
|
||||
boolean async
|
||||
ResponseBodyMatchers matchers
|
||||
@@ -50,6 +51,7 @@ class Response extends Common {
|
||||
Response(Response response) {
|
||||
this.status = response.status
|
||||
this.headers = response.headers
|
||||
this.cookies = response.cookies
|
||||
this.body = response.body
|
||||
}
|
||||
|
||||
@@ -67,6 +69,12 @@ class Response extends Common {
|
||||
closure()
|
||||
}
|
||||
|
||||
void cookies(@DelegatesTo(ResponseCookies) Closure closure) {
|
||||
this.cookies = new ResponseCookies()
|
||||
closure.delegate = cookies
|
||||
closure()
|
||||
}
|
||||
|
||||
void body(Map<String, Object> body) {
|
||||
this.body = new Body(convertObjectsToDslProperties(body))
|
||||
}
|
||||
@@ -169,6 +177,17 @@ class Response extends Common {
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@ToString(includePackage = false)
|
||||
private class ResponseCookies extends Cookies {
|
||||
|
||||
@Override
|
||||
DslProperty matching(String value) {
|
||||
return $(p(regex("${RegexpUtils.escapeSpecialRegexWithSingleEscape(value)}.*")), c(value))
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
@ToString(includePackage = false)
|
||||
|
||||
@@ -20,6 +20,7 @@ import groovy.json.StringEscapeUtils
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.Input
|
||||
@@ -113,6 +114,19 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
blockBuilder.addLine("${exec.insertValue("response.getHeader(\"$property\").toString()")};")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, String value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, GString value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Pattern pattern) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCodeBlock(BlockBuilder bb) {
|
||||
|
||||
@@ -129,6 +143,10 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCookiesBlock(BlockBuilder bb) {
|
||||
}
|
||||
|
||||
private String sentToValue(Object sentTo) {
|
||||
if (sentTo instanceof ExecutionProperty) {
|
||||
return ((ExecutionProperty) sentTo).executionCommand
|
||||
@@ -192,6 +210,11 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
return ".header(${getTestSideValue(header.name)}, ${getTestSideValue(header.serverValue)})"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCookieString(Cookie cookie) {
|
||||
return ""
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBodyString(Object body) {
|
||||
return ""
|
||||
|
||||
@@ -20,6 +20,7 @@ import groovy.json.StringEscapeUtils
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
@@ -147,6 +148,11 @@ abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder
|
||||
return ".header(${getTestSideValue(header.name)}, ${getTestSideValue(header.serverValue)})"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCookieString(Cookie cookie) {
|
||||
return ".cookie(${getTestSideValue(cookie.key)}, ${getTestSideValue(cookie.serverValue)})"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBodyString(Object body) {
|
||||
String value
|
||||
@@ -177,6 +183,15 @@ abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder
|
||||
return buildEscapedMatchesMethod(headerValue) + ";"
|
||||
}
|
||||
|
||||
protected String createCookieComparison(Object cookieValue) {
|
||||
String escapedCookie = convertUnicodeEscapesIfRequired("$cookieValue")
|
||||
return "isEqualTo(\"$escapedCookie\");"
|
||||
}
|
||||
|
||||
protected String createCookieComparison(Pattern cookieValue) {
|
||||
return buildEscapedMatchesMethod(cookieValue) + ";"
|
||||
}
|
||||
|
||||
private String buildEscapedMatchesMethod(Pattern escapedValue) {
|
||||
String escapedHeader = convertUnicodeEscapesIfRequired("$escapedValue")
|
||||
return createMatchesMethod(escapedHeader)
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.contract.verifier.builder
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.DslProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
|
||||
@@ -65,6 +66,7 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
|
||||
appendUrlPathAndQueryParameters(bb)
|
||||
appendRequestWithRequiredResponseContentType(bb)
|
||||
appendHeaders(bb)
|
||||
appendCookies(bb)
|
||||
appendMethodAndBody(bb)
|
||||
bb.addAtTheEnd(JUNIT.lineSuffix)
|
||||
|
||||
@@ -123,6 +125,16 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
protected appendCookies(BlockBuilder bb) {
|
||||
request.cookies?.executeForEachCookie { Cookie cookie ->
|
||||
if (cookieOfAbsentType(cookie)) {
|
||||
return
|
||||
}
|
||||
|
||||
bb.addLine(".cookie(\"${cookie.key}\", \"${cookie.serverValue}\")")
|
||||
}
|
||||
}
|
||||
|
||||
protected void appendRequestWithRequiredResponseContentType(BlockBuilder bb) {
|
||||
String acceptHeader = getHeader("Accept")
|
||||
if (acceptHeader) {
|
||||
@@ -146,6 +158,15 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCookiesBlock(BlockBuilder bb) {
|
||||
response.cookies?.executeForEachCookie { Cookie cookie ->
|
||||
processCookieElement(bb, cookie.key, cookie.serverValue instanceof NotToEscapePattern ?
|
||||
cookie.serverValue :
|
||||
MapConverter.getTestSideValues(cookie.serverValue))
|
||||
}
|
||||
}
|
||||
|
||||
protected String getHeader(String name) {
|
||||
return request.headers?.entries.find { it.name == name }?.serverValue
|
||||
}
|
||||
@@ -185,4 +206,16 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
|
||||
blockBuilder.addLine("${exec.insertValue("response.getHeaderString(\"$property\")")};")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Pattern pattern) {
|
||||
blockBuilder.addLine("assertThat(response.getCookies().get(\"$key\")).isNotNull();")
|
||||
blockBuilder.addLine("assertThat(response.getCookies().get(\"$key\").getValue()).${createCookieComparison(pattern)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, String value) {
|
||||
blockBuilder.addLine("assertThat(response.getCookies().get(\"$key\")).isNotNull();")
|
||||
blockBuilder.addLine("assertThat(response.getCookies().get(\"$key\").getValue()).${createCookieComparison(value)}")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.contract.verifier.builder
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.DslProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
|
||||
@@ -62,6 +63,7 @@ class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequ
|
||||
appendUrlPathAndQueryParameters(bb)
|
||||
appendRequestWithRequiredResponseContentType(bb)
|
||||
appendHeaders(bb)
|
||||
appendCookies(bb)
|
||||
appendMethodAndBody(bb)
|
||||
|
||||
bb.unindent()
|
||||
@@ -128,6 +130,16 @@ class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequ
|
||||
}
|
||||
}
|
||||
|
||||
protected appendCookies(BlockBuilder bb) {
|
||||
request.cookies?.executeForEachCookie { Cookie cookie ->
|
||||
if (cookieOfAbsentType(cookie)) {
|
||||
return
|
||||
}
|
||||
|
||||
bb.addLine(".cookie('${cookie.key}', '${cookie.serverValue}')")
|
||||
}
|
||||
}
|
||||
|
||||
protected String getHeader(String name) {
|
||||
return request.headers?.entries?.find { it.name == name }?.serverValue
|
||||
}
|
||||
@@ -146,6 +158,15 @@ class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequ
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCookiesBlock(BlockBuilder bb) {
|
||||
response.cookies?.executeForEachCookie { Cookie cookie ->
|
||||
processCookieElement(bb, cookie.key, cookie.serverValue instanceof NotToEscapePattern ?
|
||||
cookie.serverValue :
|
||||
MapConverter.getTestSideValues(cookie.serverValue))
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseAsString() {
|
||||
return 'responseAsString'
|
||||
@@ -181,6 +202,18 @@ class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequ
|
||||
blockBuilder.addLine("response.getHeaderString('$property') ${convertHeaderComparison(value)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Pattern pattern) {
|
||||
blockBuilder.addLine("response.getCookies().get('$key') != null")
|
||||
blockBuilder.addLine("response.getCookies().get('$key').getValue() ${convertCookieComparison(pattern)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, String value) {
|
||||
blockBuilder.addLine("response.getCookies().get('$key') != null")
|
||||
blockBuilder.addLine("response.getCookies().get('$key').getValue() ${convertCookieComparison(value)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String postProcessJsonPathCall(String jsonPath) {
|
||||
if (templateProcessor.containsTemplateEntry(jsonPath)) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.contract.verifier.builder
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import com.jayway.jsonpath.DocumentContext
|
||||
@@ -98,6 +100,11 @@ abstract class MethodBodyBuilder {
|
||||
*/
|
||||
protected abstract void validateResponseHeadersBlock(BlockBuilder bb)
|
||||
|
||||
/**
|
||||
* Builds the response cookies validation code block
|
||||
*/
|
||||
protected abstract void validateResponseCookiesBlock(BlockBuilder bb)
|
||||
|
||||
/**
|
||||
* Builds the code that returns response in the string format
|
||||
*/
|
||||
@@ -172,6 +179,21 @@ abstract class MethodBodyBuilder {
|
||||
*/
|
||||
protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, Number value)
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the assertion for the given cookie path
|
||||
*/
|
||||
protected abstract void processCookieElement(BlockBuilder blockBuilder, String key, Pattern pattern)
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the assertion for the given cookie path
|
||||
*/
|
||||
protected abstract void processCookieElement(BlockBuilder blockBuilder, String key, String value)
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the assertion for the given cookie path
|
||||
*/
|
||||
protected abstract void processCookieElement(BlockBuilder blockBuilder, String key, GString value)
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the code to retrieve a value for a property
|
||||
* from the list with the given index
|
||||
@@ -201,6 +223,11 @@ abstract class MethodBodyBuilder {
|
||||
*/
|
||||
protected abstract String getHeaderString(Header header)
|
||||
|
||||
/**
|
||||
* Builds the code to append a cookie to the request / message
|
||||
*/
|
||||
protected abstract String getCookieString(Cookie cookie)
|
||||
|
||||
/**
|
||||
* Builds the code to append body to the request / message
|
||||
*/
|
||||
@@ -596,6 +623,12 @@ abstract class MethodBodyBuilder {
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Object value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the assertion for the given cookie
|
||||
*/
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Object value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the assertion for the given body element
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.contract.verifier.builder
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
|
||||
@@ -53,6 +54,15 @@ class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestP
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCookiesBlock(BlockBuilder bb) {
|
||||
response.cookies?.executeForEachCookie { Cookie cookie ->
|
||||
processCookieElement(bb, cookie.key, cookie.serverValue instanceof NotToEscapePattern ?
|
||||
cookie.serverValue :
|
||||
MapConverter.getTestSideValues(cookie.serverValue))
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseAsString() {
|
||||
return 'response.body.asString()'
|
||||
@@ -69,6 +79,16 @@ class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestP
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Object value) {
|
||||
if (value instanceof NotToEscapePattern) {
|
||||
blockBuilder.addLine("response.cookie('$key') " +
|
||||
"${patternComparison(((NotToEscapePattern) value).serverValue.pattern().replace("\\", "\\\\"))}")
|
||||
} else {
|
||||
processCookieElement(blockBuilder, key, value.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Number number) {
|
||||
blockBuilder.addLine("response.header('$property') == ${number}")
|
||||
@@ -89,6 +109,18 @@ class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestP
|
||||
blockBuilder.addLine("response.header('$property') ${convertHeaderComparison(value)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Pattern pattern) {
|
||||
blockBuilder.addLine("response.cookie('$key') != null")
|
||||
blockBuilder.addLine("response.cookie('$key') ${convertCookieComparison(pattern)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, String value) {
|
||||
blockBuilder.addLine("response.cookie('$key') != null")
|
||||
blockBuilder.addLine("response.cookie('$key') ${convertCookieComparison(value)}")
|
||||
}
|
||||
|
||||
// #273 - should escape $ for Groovy since it will try to make it a GString
|
||||
@Override
|
||||
protected String postProcessJsonPathCall(String jsonPath) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import groovy.transform.TypeChecked
|
||||
import groovy.transform.TypeCheckingMode
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.MatchingStrategy
|
||||
@@ -100,6 +101,14 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder {
|
||||
}
|
||||
bb.addLine(getHeaderString(header))
|
||||
}
|
||||
|
||||
request.cookies?.executeForEachCookie { Cookie cookie ->
|
||||
if (cookieOfAbsentType(cookie)) {
|
||||
return
|
||||
}
|
||||
bb.addLine(getCookieString(cookie))
|
||||
}
|
||||
|
||||
if (request.body) {
|
||||
Object body = request.body?.serverValue instanceof ExecutionProperty ?
|
||||
request.body?.serverValue : bodyAsString
|
||||
@@ -115,6 +124,11 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder {
|
||||
((MatchingStrategy) header.serverValue).type == MatchingStrategy.Type.ABSENT
|
||||
}
|
||||
|
||||
protected boolean cookieOfAbsentType(Cookie cookie) {
|
||||
return cookie.serverValue instanceof MatchingStrategy &&
|
||||
((MatchingStrategy) cookie.serverValue).type == MatchingStrategy.Type.ABSENT
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void when(BlockBuilder bb) {
|
||||
bb.addLine(getInputString(request))
|
||||
@@ -168,6 +182,9 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder {
|
||||
if (response.headers) {
|
||||
validateResponseHeadersBlock(bb)
|
||||
}
|
||||
if (response.cookies) {
|
||||
validateResponseCookiesBlock(bb)
|
||||
}
|
||||
if (response.body) {
|
||||
bb.endBlock()
|
||||
bb.addLine(addCommentSignIfRequired('and:')).startBlock()
|
||||
@@ -188,6 +205,12 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder {
|
||||
processHeaderElement(blockBuilder, property, gstringValue)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, GString value) {
|
||||
String gStringValue = ContentUtils.extractValueForGString(value, ContentUtils.GET_TEST_SIDE).toString()
|
||||
processCookieElement(blockBuilder, key, gStringValue)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContentType getResponseContentType() {
|
||||
ContentType contentType = recognizeContentTypeFromHeader(response.headers)
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.contract.verifier.builder
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
|
||||
@@ -55,6 +56,15 @@ class RestAssuredJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCookiesBlock(BlockBuilder bb) {
|
||||
response.cookies?.executeForEachCookie { Cookie cookie ->
|
||||
processCookieElement(bb, cookie.key, cookie.serverValue instanceof NotToEscapePattern ?
|
||||
cookie.serverValue :
|
||||
MapConverter.getTestSideValues(cookie.serverValue))
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseBodyPropertyComparisonString(String property, Object value) {
|
||||
return null
|
||||
@@ -96,4 +106,15 @@ class RestAssuredJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder {
|
||||
blockBuilder.addLine("${exec.insertValue("response.header(\"$property\")")};")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Pattern pattern) {
|
||||
blockBuilder.addLine("assertThat(response.getCookie(\"$key\")).isNotNull();")
|
||||
blockBuilder.addLine("assertThat(response.getCookie(\"$key\")).${createCookieComparison(pattern)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, String value) {
|
||||
blockBuilder.addLine("assertThat(response.getCookie(\"$key\")).isNotNull();")
|
||||
blockBuilder.addLine("assertThat(response.getCookie(\"$key\")).${createCookieComparison(value)}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import groovy.json.StringEscapeUtils
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.Input
|
||||
@@ -96,6 +97,18 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
blockBuilder.addLine("response.getHeader('$property')?.toString() ${convertHeaderComparison(value)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, Pattern pattern) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, String value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, GString value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCodeBlock(BlockBuilder bb) {
|
||||
if (outputMessage) {
|
||||
@@ -122,6 +135,10 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCookiesBlock(BlockBuilder bb) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseAsString() {
|
||||
return 'contractVerifierObjectMapper.writeValueAsString(response.payload)'
|
||||
@@ -187,6 +204,11 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
return "${getTestSideValue(header.name)}: ${getTestSideValue(header.serverValue)}"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCookieString(Cookie cookie) {
|
||||
return ''
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBodyString(Object body) {
|
||||
return ''
|
||||
|
||||
@@ -20,6 +20,7 @@ import groovy.json.StringEscapeUtils
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Request
|
||||
@@ -122,6 +123,11 @@ abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessing
|
||||
return ".header(${getTestSideValue(header.name)}, ${getTestSideValue(header.serverValue)})"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCookieString(Cookie cookie) {
|
||||
return ".cookie(${getTestSideValue(cookie.key)}, ${getTestSideValue(cookie.serverValue)})"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBodyString(Object body) {
|
||||
String value
|
||||
@@ -149,6 +155,12 @@ abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessing
|
||||
processHeaderElement(blockBuilder, property, gstringValue)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processCookieElement(BlockBuilder blockBuilder, String key, GString value) {
|
||||
String gStringValue = ContentUtils.extractValueForGString(value, ContentUtils.GET_TEST_SIDE).toString()
|
||||
processCookieElement(blockBuilder, key, gStringValue)
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(String headerValue) {
|
||||
return " == '$headerValue'"
|
||||
}
|
||||
@@ -157,6 +169,14 @@ abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessing
|
||||
return patternComparison(headerValue)
|
||||
}
|
||||
|
||||
protected String convertCookieComparison(String cookieValue) {
|
||||
return "== '$cookieValue'"
|
||||
}
|
||||
|
||||
protected String convertCookieComparison(Pattern cookieValue) {
|
||||
return patternComparison(cookieValue)
|
||||
}
|
||||
|
||||
protected String patternComparison(Pattern pattern) {
|
||||
return patternComparison(pattern.toString())
|
||||
}
|
||||
|
||||
@@ -34,6 +34,56 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
|
||||
@Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(assertJsonSize: true)
|
||||
|
||||
@Shared
|
||||
// tag::contract_with_cookies[]
|
||||
Contract contractDslWithCookiesValue = Contract.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "/foo"
|
||||
headers {
|
||||
header 'Accept': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': 'cookie-value'
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': 'new-cookie-value'
|
||||
}
|
||||
body([status: 'OK'])
|
||||
}
|
||||
}
|
||||
// end::contract_with_cookies[]
|
||||
|
||||
@Shared
|
||||
Contract contractDslWithCookiesPattern = Contract.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "/foo"
|
||||
headers {
|
||||
header 'Accept': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': regex('[A-Za-z]+')
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': regex('[A-Za-z]+')
|
||||
}
|
||||
body([status: 'OK'])
|
||||
}
|
||||
}
|
||||
|
||||
def "should generate assertions for simple response body with #methodBuilderName"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
@@ -1205,4 +1255,56 @@ DATA
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
|
||||
}
|
||||
|
||||
def "should generate test for cookies with string value in JAX-RS JUnit test"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new JaxRsClientJUnitMethodBodyBuilder(contractDslWithCookiesValue, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "cookie-value")''')
|
||||
test.contains('''assertThat(response.getCookies().get("cookie-key")).isNotNull();''')
|
||||
test.contains('''assertThat(response.getCookies().get("cookie-key").getValue()).isEqualTo("new-cookie-value");''')
|
||||
}
|
||||
|
||||
def "should generate test for cookies with pattern in JAX-RS JUnit test"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new JaxRsClientJUnitMethodBodyBuilder(contractDslWithCookiesPattern, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
test.contains('''assertThat(response.getCookies().get("cookie-key")).isNotNull();''')
|
||||
test.contains('''assertThat(response.getCookies().get("cookie-key").getValue()).matches("[A-Za-z]+");''')
|
||||
}
|
||||
|
||||
def "should generate test for cookies with string value in JAX-RS Spock test"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new JaxRsClientSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesValue, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie('cookie-key', 'cookie-value')''')
|
||||
test.contains('''response.getCookies().get('cookie-key') != null''')
|
||||
test.contains("response.getCookies().get('cookie-key').getValue() == 'new-cookie-value'")
|
||||
}
|
||||
|
||||
def "should generate test for cookies with pattern in JAX-RS Spock test"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new JaxRsClientSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesPattern, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie('cookie-key', '[A-Za-z]+')''')
|
||||
test.contains('''response.getCookies().get('cookie-key') != null''')
|
||||
test.contains('''response.getCookies().get('cookie-key').getValue() ==~ java.util.regex.Pattern.compile('[A-Za-z]+')''')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,54 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
assertJsonSize: true
|
||||
)
|
||||
|
||||
@Shared
|
||||
Contract contractDslWithCookiesValue = Contract.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "/foo"
|
||||
headers {
|
||||
header 'Accept': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': 'cookie-value'
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': 'new-cookie-value'
|
||||
}
|
||||
body([status: 'OK'])
|
||||
}
|
||||
}
|
||||
|
||||
@Shared
|
||||
Contract contractDslWithCookiesPattern = Contract.make {
|
||||
request {
|
||||
method "GET"
|
||||
url "/foo"
|
||||
headers {
|
||||
header 'Accept': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': regex('[A-Za-z]+')
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
headers {
|
||||
header 'Content-Type': 'application/json'
|
||||
}
|
||||
cookies {
|
||||
cookie 'cookie-key': regex('[A-Za-z]+')
|
||||
}
|
||||
body([status: 'OK'])
|
||||
}
|
||||
}
|
||||
|
||||
@Shared
|
||||
// tag::contract_with_regex[]
|
||||
Contract dslWithOptionalsInString = Contract.make {
|
||||
@@ -2412,4 +2460,57 @@ DocumentContext parsedJson = JsonPath.parse(json);
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String body -> body.contains("response.getHeaderString('Authorization') == 'foo secret bar'") }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String body -> body.contains('assertThat(response.getHeaderString("Authorization")).isEqualTo("foo secret bar");') }
|
||||
}
|
||||
|
||||
def "should generate JUnit assertions with cookies"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDslWithCookiesValue, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "cookie-value")''')
|
||||
test.contains('''assertThat(response.getCookie("cookie-key")).isNotNull();''')
|
||||
test.contains('''assertThat(response.getCookie("cookie-key")).isEqualTo("new-cookie-value");''')
|
||||
}
|
||||
|
||||
def "should generate JUnit assertions with cookies pattern"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDslWithCookiesPattern, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
test.contains('''assertThat(response.getCookie("cookie-key")).isNotNull();''')
|
||||
test.contains('''assertThat(response.getCookie("cookie-key")).matches("[A-Za-z]+");''')
|
||||
}
|
||||
|
||||
def "should generate spock assertions with cookies"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesValue, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "cookie-value")''')
|
||||
test.contains('''response.cookie('cookie-key') != null''')
|
||||
test.contains('''response.cookie('cookie-key') == 'new-cookie-value''')
|
||||
}
|
||||
|
||||
def "should generate spock assertions with cookies pattern"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDslWithCookiesPattern, properties)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
test.contains('''response.cookie('cookie-key') != null''')
|
||||
test.contains('''response.cookie('cookie-key') ==~ java.util.regex.Pattern.compile('[A-Za-z]+')''')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user