Added a CUSTOM test mode for test generation
This commit is contained in:
committed by
Marcin Grzejszczak
parent
a629f6ba10
commit
2121b0b1b4
@@ -265,6 +265,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jcl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.resolver</groupId>
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-messaging</artifactId>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
interface CustomModeAcceptor {
|
||||
|
||||
default boolean acceptType(GeneratedClassMetaData generatedClassMetaData,
|
||||
SingleContractMetadata singleContractMetadata) {
|
||||
return generatedClassMetaData.configProperties.getTestMode() == TestMode.CUSTOM
|
||||
&& acceptType(singleContractMetadata);
|
||||
}
|
||||
|
||||
default boolean acceptType(GeneratedClassMetaData generatedClassMetaData) {
|
||||
return generatedClassMetaData.configProperties.getTestMode() == TestMode.CUSTOM
|
||||
&& generatedClassMetaData.isAnyHttp();
|
||||
}
|
||||
|
||||
default boolean acceptType(SingleContractMetadata singleContractMetadata) {
|
||||
return singleContractMetadata.isHttp();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty;
|
||||
import org.springframework.cloud.contract.spec.internal.FromFileProperty;
|
||||
import org.springframework.cloud.contract.spec.internal.Request;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
import org.springframework.cloud.contract.verifier.util.ContentType;
|
||||
|
||||
class CustomModeBodyGiven implements Given {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final BodyReader bodyReader;
|
||||
|
||||
private final BodyParser bodyParser;
|
||||
|
||||
CustomModeBodyGiven(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.bodyReader = new BodyReader(generatedClassMetaData);
|
||||
this.bodyParser = bodyParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
processInput(this.blockBuilder, metadata);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void processInput(BlockBuilder bb, SingleContractMetadata metadata) {
|
||||
Object body;
|
||||
Request request = metadata.getContract().getRequest();
|
||||
Object serverValue = request.getBody().getServerValue();
|
||||
if (serverValue instanceof ExecutionProperty
|
||||
|| serverValue instanceof FromFileProperty) {
|
||||
body = request.getBody().getServerValue();
|
||||
}
|
||||
else {
|
||||
body = this.bodyParser.requestBodyAsString(metadata);
|
||||
}
|
||||
bb.addIndented(getBodyString(metadata, body));
|
||||
}
|
||||
|
||||
private String getBodyString(SingleContractMetadata metadata, Object body) {
|
||||
String value;
|
||||
if (body instanceof ExecutionProperty) {
|
||||
value = body.toString();
|
||||
}
|
||||
else if (body instanceof FromFileProperty) {
|
||||
FromFileProperty fileProperty = (FromFileProperty) body;
|
||||
value = fileProperty.isByte()
|
||||
? this.bodyReader.readBytesFromFileString(metadata, fileProperty,
|
||||
CommunicationType.REQUEST)
|
||||
: this.bodyReader.readStringFromFileString(metadata, fileProperty,
|
||||
CommunicationType.REQUEST);
|
||||
}
|
||||
else {
|
||||
String escaped = escapeRequestSpecialChars(metadata, body.toString());
|
||||
value = this.bodyParser.quotedEscapedLongText(escaped);
|
||||
}
|
||||
return ".body(" + value + ")";
|
||||
}
|
||||
|
||||
private String escapeRequestSpecialChars(SingleContractMetadata metadata,
|
||||
String string) {
|
||||
if (metadata.getInputTestContentType() == ContentType.JSON) {
|
||||
return string.replaceAll("\\\\n", "\\\\\\\\n");
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null && request.getBody() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
interface CustomModeBodyParser extends BodyParser {
|
||||
|
||||
BodyParser INSTANCE = new CustomModeBodyParser() {
|
||||
};
|
||||
|
||||
@Override
|
||||
default String responseAsString() {
|
||||
return "response.getBody().asString()";
|
||||
}
|
||||
|
||||
@Override
|
||||
default String byteArrayString() {
|
||||
return "response.getBody().asByteArray()";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Cookie;
|
||||
import org.springframework.cloud.contract.spec.internal.MatchingStrategy;
|
||||
import org.springframework.cloud.contract.spec.internal.Request;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeCookiesGiven implements Given {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
CustomModeCookiesGiven(BlockBuilder blockBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
processInput(metadata.getContract().getRequest());
|
||||
return this;
|
||||
}
|
||||
|
||||
private void processInput(Request request) {
|
||||
Iterator<Cookie> iterator = request.getCookies().getEntries().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Cookie cookie = iterator.next();
|
||||
if (ofAbsentType(cookie)) {
|
||||
return;
|
||||
}
|
||||
if (iterator.hasNext()) {
|
||||
this.blockBuilder.addLine(string(cookie));
|
||||
}
|
||||
else {
|
||||
this.blockBuilder.addIndented(string(cookie));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String string(Cookie cookie) {
|
||||
return ".cookie(" + ContentHelper.getTestSideForNonBodyValue(cookie.getKey())
|
||||
+ ", " + ContentHelper.getTestSideForNonBodyValue(cookie.getServerValue())
|
||||
+ ")";
|
||||
}
|
||||
|
||||
private boolean ofAbsentType(Cookie cookie) {
|
||||
return cookie.getServerValue() instanceof MatchingStrategy
|
||||
&& MatchingStrategy.Type.ABSENT
|
||||
.equals(((MatchingStrategy) cookie.getServerValue()).getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null && request.getCookies() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Response;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeCookiesThen implements Then, CustomModeAcceptor, CookieElementProcessor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final ComparisonBuilder comparisonBuilder;
|
||||
|
||||
CustomModeCookiesThen(BlockBuilder blockBuilder,
|
||||
ComparisonBuilder comparisonBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.comparisonBuilder = comparisonBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Then> apply(SingleContractMetadata metadata) {
|
||||
processCookies(metadata);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComparisonBuilder comparisonBuilder() {
|
||||
return this.comparisonBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockBuilder blockBuilder() {
|
||||
return this.blockBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String cookieKey(String key) {
|
||||
return "response.cookie(\"" + key + "\")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Response response = metadata.getContract().getResponse();
|
||||
return response.getCookies() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class CustomModeFields implements Field, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
private static final String[] FIELDS = { "@Inject HttpVerifier httpVerifier" };
|
||||
|
||||
CustomModeFields(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field call() {
|
||||
Arrays.stream(FIELDS).forEach(this.blockBuilder::addLineWithEnding);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept() {
|
||||
return acceptType(this.generatedClassMetaData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeGiven implements Given, BodyMethodVisitor, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
private final List<Given> requestGivens = new LinkedList<>();
|
||||
|
||||
private final List<Given> bodyGivens = new LinkedList<>();
|
||||
|
||||
CustomModeGiven(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
this.requestGivens.addAll(Collections.singletonList(
|
||||
new CustomModeRequestGiven(blockBuilder, generatedClassMetaData)));
|
||||
this.bodyGivens.addAll(
|
||||
Arrays.asList(new CustomModeMethodWithUrlGiven(blockBuilder, bodyParser),
|
||||
new CustomModeHeadersGiven(blockBuilder),
|
||||
new CustomModeCookiesGiven(blockBuilder),
|
||||
new CustomModeBodyGiven(blockBuilder, generatedClassMetaData,
|
||||
bodyParser),
|
||||
new CustomMultipartGiven(generatedClassMetaData),
|
||||
new CustomModeRequestBuildGiven(blockBuilder)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata singleContractMetadata) {
|
||||
startBodyBlock(this.blockBuilder, "given:");
|
||||
addRequestGivenLine(singleContractMetadata);
|
||||
indentedBodyBlock(this.blockBuilder, this.bodyGivens, singleContractMetadata);
|
||||
this.blockBuilder.addEmptyLine();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addRequestGivenLine(SingleContractMetadata singleContractMetadata) {
|
||||
this.requestGivens.stream().filter(given -> given.accept(singleContractMetadata))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No matching request building Given implementation for a custom test mode"))
|
||||
.apply(singleContractMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata singleContractMetadata) {
|
||||
return acceptType(generatedClassMetaData, singleContractMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.spec.internal.Headers;
|
||||
import org.springframework.cloud.contract.spec.internal.MatchingStrategy;
|
||||
import org.springframework.cloud.contract.spec.internal.Request;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
|
||||
class CustomModeHeadersGiven implements Given {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
CustomModeHeadersGiven(BlockBuilder blockBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
processInput(this.blockBuilder, metadata.getContract().getRequest().getHeaders());
|
||||
return this;
|
||||
}
|
||||
|
||||
private void processInput(BlockBuilder bb, Headers headers) {
|
||||
Iterator<Header> iterator = headers.getEntries().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Header header = iterator.next();
|
||||
if (ofAbsentType(header)) {
|
||||
return;
|
||||
}
|
||||
if (iterator.hasNext()) {
|
||||
bb.addLine(string(header));
|
||||
}
|
||||
else {
|
||||
bb.addIndented(string(header));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String string(Header header) {
|
||||
return ".header(" + ContentHelper.getTestSideForNonBodyValue(header.getName())
|
||||
+ ", "
|
||||
+ ContentHelper.getTestSideForNonBodyValue(
|
||||
MapConverter.getTestSideValuesForNonBody(header.getServerValue()))
|
||||
+ ")";
|
||||
}
|
||||
|
||||
private boolean ofAbsentType(Header header) {
|
||||
return header.getServerValue() instanceof MatchingStrategy
|
||||
&& MatchingStrategy.Type.ABSENT
|
||||
.equals(((MatchingStrategy) header.getServerValue()).getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null && request.getHeaders() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty;
|
||||
import org.springframework.cloud.contract.spec.internal.Header;
|
||||
import org.springframework.cloud.contract.spec.internal.Headers;
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern;
|
||||
import org.springframework.cloud.contract.spec.internal.Response;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
|
||||
class CustomModeHeadersThen implements Then, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final ComparisonBuilder comparisonBuilder;
|
||||
|
||||
CustomModeHeadersThen(BlockBuilder blockBuilder,
|
||||
ComparisonBuilder comparisonBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.comparisonBuilder = comparisonBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Then> apply(SingleContractMetadata metadata) {
|
||||
Response response = metadata.getContract().getResponse();
|
||||
Headers headers = response.getHeaders();
|
||||
Iterator<Header> iterator = headers.getEntries().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Header header = iterator.next();
|
||||
String text = processHeaderElement(header.getName(),
|
||||
header.getServerValue() instanceof NotToEscapePattern
|
||||
? header.getServerValue()
|
||||
: MapConverter.getTestSideValues(header.getServerValue()));
|
||||
if (iterator.hasNext()) {
|
||||
this.blockBuilder.addLineWithEnding(text);
|
||||
}
|
||||
else {
|
||||
this.blockBuilder.addIndented(text);
|
||||
}
|
||||
}
|
||||
this.blockBuilder.addEndingIfNotPresent();
|
||||
return this;
|
||||
}
|
||||
|
||||
private String processHeaderElement(String property, Object value) {
|
||||
if (value instanceof NotToEscapePattern) {
|
||||
return this.comparisonBuilder
|
||||
.assertThat("response.header(\"" + property + "\")")
|
||||
+ matchesManuallyEscapedPattern((NotToEscapePattern) value);
|
||||
}
|
||||
else if (value instanceof ExecutionProperty) {
|
||||
return ((ExecutionProperty) value)
|
||||
.insertValue("response.header(\"" + property + "\")");
|
||||
|
||||
}
|
||||
return this.comparisonBuilder.assertThat("response.header(\"" + property + "\")",
|
||||
value);
|
||||
}
|
||||
|
||||
private String matchesManuallyEscapedPattern(NotToEscapePattern value) {
|
||||
return this.comparisonBuilder
|
||||
.matchesEscaped(value.getServerValue().pattern().replace("\\", "\\\\"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Response response = metadata.getContract().getResponse();
|
||||
return response.getHeaders() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class CustomModeImports implements Imports, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
private static final String[] IMPORTS = { "javax.inject.Inject",
|
||||
"org.springframework.cloud.contract.verifier.http.HttpVerifier",
|
||||
"org.springframework.cloud.contract.verifier.http.Request",
|
||||
"org.springframework.cloud.contract.verifier.http.Response;" };
|
||||
|
||||
CustomModeImports(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Imports call() {
|
||||
Arrays.stream(IMPORTS)
|
||||
.forEach(s -> this.blockBuilder.addLineWithEnding("import " + s));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept() {
|
||||
return acceptType(this.generatedClassMetaData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty;
|
||||
import org.springframework.cloud.contract.spec.internal.Request;
|
||||
import org.springframework.cloud.contract.spec.internal.Url;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
|
||||
class CustomModeMethodWithUrlGiven implements Given {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final BodyParser bodyParser;
|
||||
|
||||
CustomModeMethodWithUrlGiven(BlockBuilder blockBuilder, BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.bodyParser = bodyParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
addUrl(getUrl(metadata.getContract().getRequest()),
|
||||
metadata.getContract().getRequest());
|
||||
return this;
|
||||
}
|
||||
|
||||
private Url getUrl(Request request) {
|
||||
if (request.getUrl() != null) {
|
||||
return request.getUrl();
|
||||
}
|
||||
if (request.getUrlPath() != null) {
|
||||
return request.getUrlPath();
|
||||
}
|
||||
throw new IllegalStateException("URL is not set!");
|
||||
}
|
||||
|
||||
private void addUrl(Url buildUrl, Request request) {
|
||||
Object testSideUrl = MapConverter.getTestSideValues(buildUrl);
|
||||
String method = request.getMethod().getServerValue().toString().toLowerCase();
|
||||
String url = testSideUrl.toString();
|
||||
if (!(testSideUrl instanceof ExecutionProperty)) {
|
||||
url = this.bodyParser.quotedShortText(testSideUrl.toString());
|
||||
}
|
||||
this.blockBuilder.addIndented("." + method + "(" + url + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Request;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeRequestBuildGiven implements Given {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
CustomModeRequestBuildGiven(BlockBuilder blockBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
this.blockBuilder.addLineWithEnding(".build()");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeRequestGiven implements Given, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
CustomModeRequestGiven(BlockBuilder blockBuilder, GeneratedClassMetaData metaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = metaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
this.blockBuilder.addIndented("Request request = given()");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
return acceptType(this.generatedClassMetaData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeResponseWhen implements When, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
CustomModeResponseWhen(BlockBuilder blockBuilder, GeneratedClassMetaData metaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = metaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<When> apply(SingleContractMetadata metadata) {
|
||||
this.blockBuilder
|
||||
.addLineWithEnding("Response response = httpVerifier.exchange(request)")
|
||||
.endBlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
return acceptType(this.generatedClassMetaData, metadata);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class CustomModeStaticImports implements Imports, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
private static final String[] IMPORTS = {
|
||||
"org.springframework.cloud.contract.verifier.http.Request.given" };
|
||||
|
||||
CustomModeStaticImports(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Imports call() {
|
||||
Arrays.stream(IMPORTS)
|
||||
.forEach(s -> this.blockBuilder.addLineWithEnding("import static " + s));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept() {
|
||||
return acceptType(this.generatedClassMetaData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Response;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeStatusCodeThen implements Then {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final ComparisonBuilder comparisonBuilder;
|
||||
|
||||
CustomModeStatusCodeThen(BlockBuilder blockBuilder,
|
||||
ComparisonBuilder comparisonBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.comparisonBuilder = comparisonBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Then> apply(SingleContractMetadata metadata) {
|
||||
Response response = metadata.getContract().getResponse();
|
||||
this.blockBuilder
|
||||
.addIndented(this.comparisonBuilder.assertThat("response.statusCode()",
|
||||
response.getStatus().getServerValue()))
|
||||
.addEndingIfNotPresent();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeThen implements Then, BodyMethodVisitor, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
private final List<Then> thens = new LinkedList<>();
|
||||
|
||||
CustomModeThen(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser,
|
||||
ComparisonBuilder comparisonBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
this.thens.addAll(Arrays.asList(
|
||||
new CustomModeStatusCodeThen(this.blockBuilder, comparisonBuilder),
|
||||
new CustomModeHeadersThen(this.blockBuilder, comparisonBuilder),
|
||||
new CustomModeCookiesThen(this.blockBuilder, comparisonBuilder),
|
||||
new GenericHttpBodyThen(this.blockBuilder, generatedClassMetaData,
|
||||
bodyParser, comparisonBuilder)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Then> apply(SingleContractMetadata singleContractMetadata) {
|
||||
startBodyBlock(this.blockBuilder, "then:");
|
||||
bodyBlock(this.blockBuilder, this.thens, singleContractMetadata);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata singleContractMetadata) {
|
||||
return acceptType(this.generatedClassMetaData, singleContractMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomModeWhen implements When, BodyMethodVisitor, CustomModeAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
private final List<When> responseWhens = new LinkedList<>();
|
||||
|
||||
CustomModeWhen(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
this.responseWhens.addAll(Arrays.asList(
|
||||
new CustomModeResponseWhen(blockBuilder, this.generatedClassMetaData)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<When> apply(SingleContractMetadata singleContractMetadata) {
|
||||
startBodyBlock(this.blockBuilder, "when:");
|
||||
addResponseWhenLine(singleContractMetadata);
|
||||
this.blockBuilder.addEmptyLine();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addResponseWhenLine(SingleContractMetadata singleContractMetadata) {
|
||||
this.responseWhens.stream().filter(when -> when.accept(singleContractMetadata))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No matching request building When implementation for Rest Assured"))
|
||||
.apply(singleContractMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata singleContractMetadata) {
|
||||
return acceptType(this.generatedClassMetaData, singleContractMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Request;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomMultipartGiven implements Given, CustomModeAcceptor {
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
CustomMultipartGiven(GeneratedClassMetaData generatedClassMetaData) {
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
throw new UnsupportedOperationException("Multipart is not yet supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null && request.getMultipart() != null
|
||||
&& acceptType(this.generatedClassMetaData, metadata);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.Request;
|
||||
import org.springframework.cloud.contract.spec.internal.Url;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class CustomQueryParamsGiven implements Given, CustomModeAcceptor, QueryParamsResolver {
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
throw new UnsupportedOperationException("Query params are not supported");
|
||||
}
|
||||
|
||||
private Url getUrl(Request request) {
|
||||
if (request.getUrl() != null) {
|
||||
return request.getUrl();
|
||||
}
|
||||
if (request.getUrlPath() != null) {
|
||||
return request.getUrlPath();
|
||||
}
|
||||
throw new IllegalStateException("URL is not set!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
Url url = getUrl(request);
|
||||
return url.getQueryParameters() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,6 +35,11 @@ class FieldBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
FieldBuilder customMode() {
|
||||
this.parentBuilder.field(new CustomModeFields(this.builder, this.metaData));
|
||||
return this;
|
||||
}
|
||||
|
||||
ClassBodyBuilder build() {
|
||||
return this.parentBuilder;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,15 @@ class ImportsBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
ImportsBuilder custom() {
|
||||
this.parentBuilder.imports(new CustomImports(builder, metaData));
|
||||
this.parentBuilder.staticImports(new CustomStaticImports(builder, metaData));
|
||||
ImportsBuilder userImports() {
|
||||
this.parentBuilder.imports(new UserImports(builder, metaData));
|
||||
this.parentBuilder.staticImports(new UserStaticImports(builder, metaData));
|
||||
return this;
|
||||
}
|
||||
|
||||
ImportsBuilder customMode() {
|
||||
this.parentBuilder.imports(new CustomModeImports(builder, metaData));
|
||||
this.parentBuilder.staticImports(new CustomModeStaticImports(builder, metaData));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
|
||||
import static org.springframework.cloud.contract.verifier.util.ContentUtils.getJavaMultipartFileParameterContent;
|
||||
|
||||
class MockMvcMultipartGiven implements Given {
|
||||
class JavaMultipartGiven implements Given, RestAssuredAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
@@ -36,8 +36,8 @@ class MockMvcMultipartGiven implements Given {
|
||||
|
||||
private final BodyParser bodyParser;
|
||||
|
||||
MockMvcMultipartGiven(BlockBuilder blockBuilder, GeneratedClassMetaData generatedClassMetaData,
|
||||
BodyParser bodyParser) {
|
||||
JavaMultipartGiven(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.bodyReader = new BodyReader(generatedClassMetaData);
|
||||
this.bodyParser = bodyParser;
|
||||
@@ -46,40 +46,47 @@ class MockMvcMultipartGiven implements Given {
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
getMultipartParameters(metadata).entrySet()
|
||||
.forEach(entry -> this.blockBuilder.addLine(getMultipartParameterLine(metadata, entry)));
|
||||
getMultipartParameters(metadata).entrySet().forEach(entry -> this.blockBuilder
|
||||
.addLine(getMultipartParameterLine(metadata, entry)));
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getMultipartParameterLine(SingleContractMetadata metadata, Map.Entry<String, Object> parameter) {
|
||||
private String getMultipartParameterLine(SingleContractMetadata metadata,
|
||||
Map.Entry<String, Object> parameter) {
|
||||
if (parameter.getValue() instanceof NamedProperty) {
|
||||
return ".multiPart(" + getMultipartFileParameterContent(metadata, parameter.getKey(),
|
||||
(NamedProperty) parameter.getValue()) + ")";
|
||||
return ".multiPart(" + getMultipartFileParameterContent(metadata,
|
||||
parameter.getKey(), (NamedProperty) parameter.getValue()) + ")";
|
||||
}
|
||||
return getParameterString(parameter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getMultipartParameters(SingleContractMetadata metadata) {
|
||||
return (Map<String, Object>) metadata.getContract().getRequest().getMultipart().getServerValue();
|
||||
return (Map<String, Object>) metadata.getContract().getRequest().getMultipart()
|
||||
.getServerValue();
|
||||
}
|
||||
|
||||
private String getMultipartFileParameterContent(SingleContractMetadata metadata, String propertyName,
|
||||
NamedProperty propertyValue) {
|
||||
private String getMultipartFileParameterContent(SingleContractMetadata metadata,
|
||||
String propertyName, NamedProperty propertyValue) {
|
||||
return getJavaMultipartFileParameterContent(propertyName, propertyValue,
|
||||
fileProp -> this.bodyReader.readBytesFromFileString(metadata, fileProp, CommunicationType.REQUEST));
|
||||
fileProp -> this.bodyReader.readBytesFromFileString(metadata, fileProp,
|
||||
CommunicationType.REQUEST));
|
||||
}
|
||||
|
||||
private String getParameterString(Map.Entry<String, Object> parameter) {
|
||||
return ".param(" + this.bodyParser.quotedShortText(parameter.getKey()) + ", "
|
||||
+ this.bodyParser.quotedShortText(MapConverter.getTestSideValuesForNonBody(parameter.getValue())) + ")";
|
||||
+ this.bodyParser.quotedShortText(
|
||||
MapConverter.getTestSideValuesForNonBody(parameter.getValue()))
|
||||
+ ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null && request.getMultipart() != null
|
||||
&& this.generatedClassMetaData.configProperties.getTestFramework() != TestFramework.SPOCK;
|
||||
&& acceptType(this.generatedClassMetaData, metadata)
|
||||
&& this.generatedClassMetaData.configProperties
|
||||
.getTestFramework() != TestFramework.SPOCK;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -66,7 +66,8 @@ public class JavaTestGenerator implements SingleTestGenerator {
|
||||
.build()
|
||||
.imports()
|
||||
.defaultImports()
|
||||
.custom()
|
||||
.userImports()
|
||||
.customMode()
|
||||
.json()
|
||||
.jUnit4()
|
||||
.jUnit5()
|
||||
@@ -93,6 +94,7 @@ public class JavaTestGenerator implements SingleTestGenerator {
|
||||
return ClassBodyBuilder.builder(builder, metaData)
|
||||
.field()
|
||||
.messaging()
|
||||
.customMode()
|
||||
.build()
|
||||
.methodBuilder(methodBuilder);
|
||||
// @formatter:on
|
||||
@@ -112,6 +114,7 @@ public class JavaTestGenerator implements SingleTestGenerator {
|
||||
.spock()
|
||||
.build()
|
||||
.restAssured()
|
||||
.customMode()
|
||||
.jaxRs()
|
||||
.messaging();
|
||||
// @formatter:on
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
interface RestAssuredAcceptor {
|
||||
|
||||
default boolean acceptType(GeneratedClassMetaData generatedClassMetaData,
|
||||
SingleContractMetadata singleContractMetadata) {
|
||||
return generatedClassMetaData.configProperties.getTestMode() != TestMode.CUSTOM
|
||||
&& generatedClassMetaData.configProperties
|
||||
.getTestMode() != TestMode.JAXRSCLIENT
|
||||
&& singleContractMetadata.isHttp();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,7 +19,8 @@ package org.springframework.cloud.contract.verifier.builder;
|
||||
import org.springframework.cloud.contract.spec.internal.Response;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class RestAssuredCookiesThen implements Then, MockMvcAcceptor, CookieElementProcessor {
|
||||
class RestAssuredCookiesThen
|
||||
implements Then, RestAssuredAcceptor, CookieElementProcessor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
|
||||
@@ -20,10 +20,9 @@ import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class RestAssuredGiven implements Given, BodyMethodVisitor {
|
||||
class RestAssuredGiven implements Given, BodyMethodVisitor, RestAssuredAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
@@ -33,18 +32,21 @@ class RestAssuredGiven implements Given, BodyMethodVisitor {
|
||||
|
||||
private final List<Given> bodyGivens = new LinkedList<>();
|
||||
|
||||
RestAssuredGiven(BlockBuilder blockBuilder, GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
RestAssuredGiven(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
this.requestGivens.addAll(Arrays.asList(new MockMvcRequestGiven(blockBuilder, generatedClassMetaData),
|
||||
this.requestGivens.addAll(Arrays.asList(
|
||||
new MockMvcRequestGiven(blockBuilder, generatedClassMetaData),
|
||||
new SpockMockMvcRequestGiven(blockBuilder, generatedClassMetaData),
|
||||
new ExplicitRequestGiven(blockBuilder, generatedClassMetaData),
|
||||
new WebTestClientRequestGiven(blockBuilder, generatedClassMetaData)));
|
||||
this.bodyGivens
|
||||
.addAll(Arrays.asList(new MockMvcHeadersGiven(blockBuilder), new MockMvcCookiesGiven(blockBuilder),
|
||||
new MockMvcBodyGiven(blockBuilder, generatedClassMetaData, bodyParser),
|
||||
new MockMvcMultipartGiven(blockBuilder, generatedClassMetaData, bodyParser),
|
||||
new SpockMockMvcMultipartGiven(blockBuilder, generatedClassMetaData, bodyParser)));
|
||||
this.bodyGivens.addAll(Arrays.asList(new MockMvcHeadersGiven(blockBuilder),
|
||||
new MockMvcCookiesGiven(blockBuilder),
|
||||
new MockMvcBodyGiven(blockBuilder, generatedClassMetaData, bodyParser),
|
||||
new JavaMultipartGiven(blockBuilder, generatedClassMetaData, bodyParser),
|
||||
new SpockMockMvcMultipartGiven(blockBuilder, generatedClassMetaData,
|
||||
bodyParser)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,15 +59,16 @@ class RestAssuredGiven implements Given, BodyMethodVisitor {
|
||||
}
|
||||
|
||||
private void addRequestGivenLine(SingleContractMetadata singleContractMetadata) {
|
||||
this.requestGivens.stream().filter(given -> given.accept(singleContractMetadata)).findFirst().orElseThrow(
|
||||
() -> new IllegalStateException("No matching request building Given implementation for Rest Assured"))
|
||||
this.requestGivens.stream().filter(given -> given.accept(singleContractMetadata))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No matching request building Given implementation for Rest Assured"))
|
||||
.apply(singleContractMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata singleContractMetadata) {
|
||||
return singleContractMetadata.isHttp()
|
||||
&& this.generatedClassMetaData.configProperties.getTestMode() != TestMode.JAXRSCLIENT;
|
||||
return acceptType(this.generatedClassMetaData, singleContractMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.springframework.cloud.contract.spec.internal.Response;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
|
||||
class RestAssuredHeadersThen implements Then, MockMvcAcceptor {
|
||||
class RestAssuredHeadersThen implements Then, RestAssuredAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
|
||||
@@ -20,10 +20,9 @@ import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class RestAssuredThen implements Then, BodyMethodVisitor {
|
||||
class RestAssuredThen implements Then, BodyMethodVisitor, RestAssuredAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
@@ -31,14 +30,17 @@ class RestAssuredThen implements Then, BodyMethodVisitor {
|
||||
|
||||
private final List<Then> thens = new LinkedList<>();
|
||||
|
||||
RestAssuredThen(BlockBuilder blockBuilder, GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser,
|
||||
RestAssuredThen(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser,
|
||||
ComparisonBuilder comparisonBuilder) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
this.thens.addAll(Arrays.asList(new RestAssuredStatusCodeThen(this.blockBuilder, comparisonBuilder),
|
||||
this.thens.addAll(Arrays.asList(
|
||||
new RestAssuredStatusCodeThen(this.blockBuilder, comparisonBuilder),
|
||||
new RestAssuredHeadersThen(this.blockBuilder, comparisonBuilder),
|
||||
new RestAssuredCookiesThen(this.blockBuilder, comparisonBuilder),
|
||||
new GenericHttpBodyThen(this.blockBuilder, generatedClassMetaData, bodyParser, comparisonBuilder)));
|
||||
new GenericHttpBodyThen(this.blockBuilder, generatedClassMetaData,
|
||||
bodyParser, comparisonBuilder)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,8 +52,7 @@ class RestAssuredThen implements Then, BodyMethodVisitor {
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata singleContractMetadata) {
|
||||
return singleContractMetadata.isHttp()
|
||||
&& this.generatedClassMetaData.configProperties.getTestMode() != TestMode.JAXRSCLIENT;
|
||||
return acceptType(this.generatedClassMetaData, singleContractMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,10 +20,9 @@ import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode;
|
||||
import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
|
||||
class RestAssuredWhen implements When, BodyMethodVisitor {
|
||||
class RestAssuredWhen implements When, BodyMethodVisitor, RestAssuredAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
@@ -33,16 +32,21 @@ class RestAssuredWhen implements When, BodyMethodVisitor {
|
||||
|
||||
private final List<When> whens = new LinkedList<>();
|
||||
|
||||
RestAssuredWhen(BlockBuilder blockBuilder, GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
RestAssuredWhen(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
this.responseWhens.addAll(Arrays.asList(new MockMvcResponseWhen(blockBuilder, this.generatedClassMetaData),
|
||||
this.responseWhens.addAll(Arrays.asList(
|
||||
new MockMvcResponseWhen(blockBuilder, this.generatedClassMetaData),
|
||||
new SpockMockMvcResponseWhen(blockBuilder, this.generatedClassMetaData),
|
||||
new ExplicitResponseWhen(blockBuilder, this.generatedClassMetaData),
|
||||
new WebTestClientResponseWhen(blockBuilder, this.generatedClassMetaData)));
|
||||
this.whens.addAll(Arrays.asList(new MockMvcQueryParamsWhen(this.blockBuilder, bodyParser),
|
||||
new MockMvcAsyncWhen(this.blockBuilder, this.generatedClassMetaData),
|
||||
new MockMvcUrlWhen(this.blockBuilder, bodyParser)));
|
||||
new WebTestClientResponseWhen(blockBuilder,
|
||||
this.generatedClassMetaData)));
|
||||
this.whens.addAll(
|
||||
Arrays.asList(new MockMvcQueryParamsWhen(this.blockBuilder, bodyParser),
|
||||
new MockMvcAsyncWhen(this.blockBuilder,
|
||||
this.generatedClassMetaData),
|
||||
new MockMvcUrlWhen(this.blockBuilder, bodyParser)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,15 +59,16 @@ class RestAssuredWhen implements When, BodyMethodVisitor {
|
||||
}
|
||||
|
||||
private void addResponseWhenLine(SingleContractMetadata singleContractMetadata) {
|
||||
this.responseWhens.stream().filter(when -> when.accept(singleContractMetadata)).findFirst().orElseThrow(
|
||||
() -> new IllegalStateException("No matching request building When implementation for Rest Assured"))
|
||||
this.responseWhens.stream().filter(when -> when.accept(singleContractMetadata))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No matching request building When implementation for Rest Assured"))
|
||||
.apply(singleContractMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata singleContractMetadata) {
|
||||
return singleContractMetadata.isHttp()
|
||||
&& this.generatedClassMetaData.configProperties.getTestMode() != TestMode.JAXRSCLIENT;
|
||||
return acceptType(this.generatedClassMetaData, singleContractMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -99,6 +99,20 @@ class SingleMethodBuilder {
|
||||
.methodPostProcessor(new TemplateUpdatingMethodPostProcessor(this.blockBuilder));
|
||||
}
|
||||
|
||||
SingleMethodBuilder customMode() {
|
||||
return given(new CustomModeGiven(this.blockBuilder, this.generatedClassMetaData,
|
||||
CustomModeBodyParser.INSTANCE))
|
||||
.methodPreProcessor(new InProgressContractMethodPreProcessor())
|
||||
.when(new CustomModeWhen(this.blockBuilder,
|
||||
this.generatedClassMetaData))
|
||||
.then(new CustomModeThen(this.blockBuilder,
|
||||
this.generatedClassMetaData,
|
||||
CustomModeBodyParser.INSTANCE,
|
||||
ComparisonBuilder.JAVA_HTTP_INSTANCE))
|
||||
.methodPostProcessor(new TemplateUpdatingMethodPostProcessor(
|
||||
this.blockBuilder));
|
||||
}
|
||||
|
||||
SingleMethodBuilder jaxRs() {
|
||||
return methodPreProcessor(new InProgressContractMethodPreProcessor())
|
||||
.given(new JaxRsGiven(this.generatedClassMetaData))
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.cloud.contract.verifier.file.SingleContractMetadata;
|
||||
import org.springframework.cloud.contract.verifier.util.ContentUtils;
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter;
|
||||
|
||||
class SpockMockMvcMultipartGiven implements Given {
|
||||
class SpockMockMvcMultipartGiven implements Given, MockMvcAcceptor {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
@@ -35,8 +35,8 @@ class SpockMockMvcMultipartGiven implements Given {
|
||||
|
||||
private final BodyParser bodyParser;
|
||||
|
||||
SpockMockMvcMultipartGiven(BlockBuilder blockBuilder, GeneratedClassMetaData generatedClassMetaData,
|
||||
BodyParser bodyParser) {
|
||||
SpockMockMvcMultipartGiven(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData, BodyParser bodyParser) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.bodyReader = new BodyReader(generatedClassMetaData);
|
||||
this.bodyParser = bodyParser;
|
||||
@@ -45,40 +45,48 @@ class SpockMockMvcMultipartGiven implements Given {
|
||||
|
||||
@Override
|
||||
public MethodVisitor<Given> apply(SingleContractMetadata metadata) {
|
||||
getMultipartParameters(metadata).entrySet()
|
||||
.forEach(entry -> this.blockBuilder.addLine(getMultipartParameterLine(metadata, entry)));
|
||||
getMultipartParameters(metadata).entrySet().forEach(entry -> this.blockBuilder
|
||||
.addLine(getMultipartParameterLine(metadata, entry)));
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getMultipartParameterLine(SingleContractMetadata metadata, Map.Entry<String, Object> parameter) {
|
||||
private String getMultipartParameterLine(SingleContractMetadata metadata,
|
||||
Map.Entry<String, Object> parameter) {
|
||||
if (parameter.getValue() instanceof NamedProperty) {
|
||||
return ".multiPart(" + getMultipartFileParameterContent(metadata, parameter.getKey(),
|
||||
(NamedProperty) parameter.getValue()) + ")";
|
||||
return ".multiPart(" + getMultipartFileParameterContent(metadata,
|
||||
parameter.getKey(), (NamedProperty) parameter.getValue()) + ")";
|
||||
}
|
||||
return getParameterString(parameter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getMultipartParameters(SingleContractMetadata metadata) {
|
||||
return (Map<String, Object>) metadata.getContract().getRequest().getMultipart().getServerValue();
|
||||
return (Map<String, Object>) metadata.getContract().getRequest().getMultipart()
|
||||
.getServerValue();
|
||||
}
|
||||
|
||||
private String getMultipartFileParameterContent(SingleContractMetadata metadata, String propertyName,
|
||||
NamedProperty propertyValue) {
|
||||
return ContentUtils.getGroovyMultipartFileParameterContent(propertyName, propertyValue,
|
||||
fileProp -> this.bodyReader.readBytesFromFileString(metadata, fileProp, CommunicationType.REQUEST));
|
||||
private String getMultipartFileParameterContent(SingleContractMetadata metadata,
|
||||
String propertyName, NamedProperty propertyValue) {
|
||||
return ContentUtils.getGroovyMultipartFileParameterContent(propertyName,
|
||||
propertyValue,
|
||||
fileProp -> this.bodyReader.readBytesFromFileString(metadata, fileProp,
|
||||
CommunicationType.REQUEST));
|
||||
}
|
||||
|
||||
private String getParameterString(Map.Entry<String, Object> parameter) {
|
||||
return ".param(" + this.bodyParser.quotedShortText(parameter.getKey()) + ", "
|
||||
+ this.bodyParser.quotedShortText(MapConverter.getTestSideValuesForNonBody(parameter.getValue())) + ")";
|
||||
+ this.bodyParser.quotedShortText(
|
||||
MapConverter.getTestSideValuesForNonBody(parameter.getValue()))
|
||||
+ ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(SingleContractMetadata metadata) {
|
||||
Request request = metadata.getContract().getRequest();
|
||||
return request != null && request.getMultipart() != null
|
||||
&& this.generatedClassMetaData.configProperties.getTestFramework() == TestFramework.SPOCK;
|
||||
&& acceptType(this.generatedClassMetaData, metadata)
|
||||
&& this.generatedClassMetaData.configProperties
|
||||
.getTestFramework() == TestFramework.SPOCK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,13 +18,14 @@ package org.springframework.cloud.contract.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class CustomImports implements Imports {
|
||||
class UserImports implements Imports {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
CustomImports(BlockBuilder blockBuilder, GeneratedClassMetaData generatedClassMetaData) {
|
||||
UserImports(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
}
|
||||
@@ -18,13 +18,14 @@ package org.springframework.cloud.contract.verifier.builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class CustomStaticImports implements Imports {
|
||||
class UserStaticImports implements Imports {
|
||||
|
||||
private final BlockBuilder blockBuilder;
|
||||
|
||||
private final GeneratedClassMetaData generatedClassMetaData;
|
||||
|
||||
CustomStaticImports(BlockBuilder blockBuilder, GeneratedClassMetaData generatedClassMetaData) {
|
||||
UserStaticImports(BlockBuilder blockBuilder,
|
||||
GeneratedClassMetaData generatedClassMetaData) {
|
||||
this.blockBuilder = blockBuilder;
|
||||
this.generatedClassMetaData = generatedClassMetaData;
|
||||
}
|
||||
@@ -39,7 +40,8 @@ class CustomStaticImports implements Imports {
|
||||
@Override
|
||||
public boolean accept() {
|
||||
return this.generatedClassMetaData.configProperties.getStaticImports() != null
|
||||
&& this.generatedClassMetaData.configProperties.getStaticImports().length > 0;
|
||||
&& this.generatedClassMetaData.configProperties
|
||||
.getStaticImports().length > 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder.imports;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.CUSTOM;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT5;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.SPOCK;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.TESTNG;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.TestFramework;
|
||||
|
||||
/**
|
||||
* Provides imports based on test framework.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 2.1.0
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public class BaseImportProvider {
|
||||
|
||||
private static final ImportDefinitions GENERAL_IMPORTS = new ImportDefinitions(emptyList(),
|
||||
Arrays.asList(
|
||||
"org.springframework.cloud.contract.verifier.assertion.SpringCloudContractAssertions.assertThat",
|
||||
"org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.*"));
|
||||
|
||||
private static final Map<TestFramework, String> RULE_IMPORT;
|
||||
|
||||
private static final Map<TestFramework, ImportDefinitions> TEST_FRAMEWORK_SPECIFIC_IMPORTS;
|
||||
|
||||
static {
|
||||
TEST_FRAMEWORK_SPECIFIC_IMPORTS = new HashMap<>(5);
|
||||
TEST_FRAMEWORK_SPECIFIC_IMPORTS.put(JUNIT, new ImportDefinitions(singletonList("org.junit.Test")));
|
||||
TEST_FRAMEWORK_SPECIFIC_IMPORTS.put(JUNIT5, new ImportDefinitions(singletonList("org.junit.jupiter.api.Test")));
|
||||
TEST_FRAMEWORK_SPECIFIC_IMPORTS.put(SPOCK, new ImportDefinitions(emptyList()));
|
||||
TEST_FRAMEWORK_SPECIFIC_IMPORTS.put(TESTNG,
|
||||
new ImportDefinitions(singletonList("org.testng.annotations.Test")));
|
||||
TEST_FRAMEWORK_SPECIFIC_IMPORTS.put(CUSTOM, new ImportDefinitions(emptyList()));
|
||||
|
||||
RULE_IMPORT = new HashMap<>(5);
|
||||
RULE_IMPORT.put(JUNIT, "org.junit.Rule");
|
||||
RULE_IMPORT.put(JUNIT5, "org.junit.jupiter.api.extension.ExtendWith");
|
||||
RULE_IMPORT.put(SPOCK, "org.junit.Rule");
|
||||
RULE_IMPORT.put(TESTNG, "org.junit.Rule");
|
||||
RULE_IMPORT.put(CUSTOM, "org.junit.Rule");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of imports for provided test framework.
|
||||
* @param testFramework
|
||||
* @return list of imports
|
||||
*/
|
||||
public static List<String> getImports(TestFramework testFramework) {
|
||||
List<String> result = new ArrayList<>(GENERAL_IMPORTS.getImports());
|
||||
result.addAll(TEST_FRAMEWORK_SPECIFIC_IMPORTS.get(testFramework).getImports());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param testFramework test framework to pick the static imports for
|
||||
* @return list of static imports for provided test framework.
|
||||
*/
|
||||
public static List<String> getStaticImports(TestFramework testFramework) {
|
||||
List<String> result = new ArrayList<>(GENERAL_IMPORTS.getStaticImports());
|
||||
result.addAll(TEST_FRAMEWORK_SPECIFIC_IMPORTS.get(testFramework).getStaticImports());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String getRuleImport(TestFramework testFramework) {
|
||||
return RULE_IMPORT.get(testFramework);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder.imports;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.CUSTOM;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT5;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.SPOCK;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.TESTNG;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestMode.EXPLICIT;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestMode.JAXRSCLIENT;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestMode.MOCKMVC;
|
||||
import static org.springframework.cloud.contract.verifier.config.TestMode.WEBTESTCLIENT;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.config.TestFramework;
|
||||
import org.springframework.cloud.contract.verifier.config.TestMode;
|
||||
|
||||
/**
|
||||
* Provides imports based on test framework and test mode.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class HttpImportProvider {
|
||||
|
||||
private final Map<Pair<TestFramework, TestMode>, ImportDefinitions> FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS;
|
||||
|
||||
private final Map<TestMode, ImportDefinitions> TEST_MODE_SPECIFIC_IMPORTS;
|
||||
|
||||
public HttpImportProvider(String restAssuredPackage) {
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS = new HashMap<>(20);
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT, JAXRSCLIENT),
|
||||
new ImportDefinitions(singletonList("javax.ws.rs.core.Response")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT5, JAXRSCLIENT),
|
||||
new ImportDefinitions(singletonList("javax.ws.rs.core.Response")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(TESTNG, JAXRSCLIENT),
|
||||
new ImportDefinitions(singletonList("javax.ws.rs.core.Response")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT, MOCKMVC),
|
||||
new ImportDefinitions(
|
||||
Arrays.asList(restAssuredPackage + ".module.mockmvc.specification.MockMvcRequestSpecification",
|
||||
restAssuredPackage + ".response.ResponseOptions")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT, WEBTESTCLIENT),
|
||||
new ImportDefinitions(Arrays.asList(
|
||||
"io.restassured.module.webtestclient.specification.WebTestClientRequestSpecification",
|
||||
"io.restassured.module.webtestclient.response.WebTestClientResponse")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT5, MOCKMVC),
|
||||
new ImportDefinitions(
|
||||
Arrays.asList(restAssuredPackage + ".module.mockmvc.specification.MockMvcRequestSpecification",
|
||||
restAssuredPackage + ".response.ResponseOptions")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT5, WEBTESTCLIENT),
|
||||
new ImportDefinitions(Arrays.asList(
|
||||
"io.restassured.module.webtestclient.specification.WebTestClientRequestSpecification",
|
||||
"io.restassured.module.webtestclient.response.WebTestClientResponse")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(TESTNG, MOCKMVC),
|
||||
new ImportDefinitions(
|
||||
Arrays.asList(restAssuredPackage + ".module.mockmvc.specification.MockMvcRequestSpecification",
|
||||
restAssuredPackage + ".response.ResponseOptions")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(TESTNG, WEBTESTCLIENT),
|
||||
new ImportDefinitions(Arrays.asList(
|
||||
"io.restassured.module.webtestclient.specification.WebTestClientRequestSpecification",
|
||||
"io.restassured.module.webtestclient.response.WebTestClientResponse")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT, EXPLICIT),
|
||||
new ImportDefinitions(Arrays.asList(restAssuredPackage + ".specification.RequestSpecification",
|
||||
restAssuredPackage + ".response.Response")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(JUNIT5, EXPLICIT),
|
||||
new ImportDefinitions(Arrays.asList(restAssuredPackage + ".specification.RequestSpecification",
|
||||
restAssuredPackage + ".response.Response")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(TESTNG, EXPLICIT),
|
||||
new ImportDefinitions(Arrays.asList(restAssuredPackage + ".specification.RequestSpecification",
|
||||
restAssuredPackage + ".response.Response")));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(SPOCK, JAXRSCLIENT), new ImportDefinitions(emptyList()));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(CUSTOM, JAXRSCLIENT), new ImportDefinitions(emptyList()));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(SPOCK, MOCKMVC), new ImportDefinitions(emptyList()));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(CUSTOM, MOCKMVC), new ImportDefinitions(emptyList()));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(SPOCK, EXPLICIT), new ImportDefinitions(emptyList()));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(CUSTOM, EXPLICIT), new ImportDefinitions(emptyList()));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(SPOCK, WEBTESTCLIENT), new ImportDefinitions(emptyList()));
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.put(Pair.of(CUSTOM, WEBTESTCLIENT),
|
||||
new ImportDefinitions(emptyList()));
|
||||
|
||||
TEST_MODE_SPECIFIC_IMPORTS = new HashMap<>(4);
|
||||
TEST_MODE_SPECIFIC_IMPORTS.put(JAXRSCLIENT,
|
||||
new ImportDefinitions(emptyList(), singletonList("javax.ws.rs.client.Entity.*")));
|
||||
TEST_MODE_SPECIFIC_IMPORTS.put(MOCKMVC, new ImportDefinitions(emptyList(),
|
||||
singletonList(restAssuredPackage + ".module.mockmvc.RestAssuredMockMvc.*")));
|
||||
TEST_MODE_SPECIFIC_IMPORTS.put(EXPLICIT,
|
||||
new ImportDefinitions(emptyList(), singletonList(restAssuredPackage + ".RestAssured.*")));
|
||||
TEST_MODE_SPECIFIC_IMPORTS.put(WEBTESTCLIENT, new ImportDefinitions(emptyList(),
|
||||
singletonList("io.restassured.module.webtestclient.RestAssuredWebTestClient.*")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of imports for http test contracts for provided test framework and
|
||||
* test mode.
|
||||
* @param testFramework
|
||||
* @param testMode
|
||||
* @return list of imports
|
||||
*/
|
||||
public List<String> getImports(TestFramework testFramework, TestMode testMode) {
|
||||
List<String> result = new ArrayList<>(TEST_MODE_SPECIFIC_IMPORTS.get(testMode).getImports());
|
||||
result.addAll(FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.get(Pair.of(testFramework, testMode)).getImports());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of static imports for http test contracts for provided test framework
|
||||
* and test mode.
|
||||
* @param testFramework
|
||||
* @param testMode
|
||||
* @return list of static imports
|
||||
*/
|
||||
public List<String> getStaticImports(TestFramework testFramework, TestMode testMode) {
|
||||
List<String> result = new ArrayList<>(TEST_MODE_SPECIFIC_IMPORTS.get(testMode).getStaticImports());
|
||||
result.addAll(
|
||||
FRAMEWORK_AND_TEST_MODE_SPECIFIC_IMPORTS.get(Pair.of(testFramework, testMode)).getStaticImports());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder.imports;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@Deprecated
|
||||
class ImportDefinitions {
|
||||
|
||||
private final List<String> imports;
|
||||
|
||||
private final List<String> staticImports;
|
||||
|
||||
public ImportDefinitions(List<String> imports, List<String> staticImports) {
|
||||
this.imports = imports;
|
||||
this.staticImports = staticImports;
|
||||
}
|
||||
|
||||
public ImportDefinitions(List<String> imports) {
|
||||
this(imports, new ArrayList<>());
|
||||
}
|
||||
|
||||
public final List<String> getImports() {
|
||||
return imports;
|
||||
}
|
||||
|
||||
public final List<String> getStaticImports() {
|
||||
return staticImports;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 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.verifier.builder.imports;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides imports based on test framework and test mode.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class MessagingImportProvider {
|
||||
|
||||
/**
|
||||
* @return list of imports for messaging test contracts.
|
||||
*/
|
||||
public static List<String> getImports() {
|
||||
return Arrays.asList("javax.inject.Inject",
|
||||
"org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper",
|
||||
"org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage",
|
||||
"org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list of static imports for messaging test contracts.
|
||||
*/
|
||||
public static List<String> getStaticImports() {
|
||||
return Arrays.asList(
|
||||
"org.springframework.cloud.contract.verifier.messaging.util.ContractVerifierMessagingUtil.headers",
|
||||
"org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.fileToBytes");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.contract.verifier.config;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.http.HttpVerifier;
|
||||
|
||||
/**
|
||||
* Provides different testing modes.
|
||||
*
|
||||
@@ -25,6 +27,10 @@ package org.springframework.cloud.contract.verifier.config;
|
||||
*/
|
||||
public enum TestMode {
|
||||
|
||||
/**
|
||||
* Requires the user to provide an implementation of the {@link HttpVerifier}.
|
||||
*/
|
||||
CUSTOM,
|
||||
/**
|
||||
* Uses Spring's MockMvc mode.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.verifier.http;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
/**
|
||||
* Abstraction over an HTTP body.
|
||||
*
|
||||
* Warning! This API is experimental and can change in time.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class Body {
|
||||
|
||||
final Object body;
|
||||
|
||||
Body(Object body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return body as byte array
|
||||
*/
|
||||
public byte[] asByteArray() {
|
||||
if (body instanceof byte[]) {
|
||||
return (byte[]) this.body;
|
||||
}
|
||||
return body.toString().getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return body as string
|
||||
*/
|
||||
public String asString() {
|
||||
return asString(Charset.defaultCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param charset to encode the body
|
||||
* @return body as string
|
||||
*/
|
||||
public String asString(Charset charset) {
|
||||
if (body instanceof String) {
|
||||
return (String) body;
|
||||
}
|
||||
else if (body instanceof byte[]) {
|
||||
return new String((byte[]) body, charset);
|
||||
}
|
||||
return body.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.verifier.http;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.contract.verifier.util.MetadataUtil;
|
||||
import org.springframework.cloud.contract.verifier.util.SpringCloudContractMetadata;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Metadata representation of the Contract Verifier's HTTP communication.
|
||||
*
|
||||
* Warning! This API is experimental and can change in time.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class ContractVerifierHttpMetadata implements SpringCloudContractMetadata {
|
||||
|
||||
/**
|
||||
* Metadata entry in the contract.
|
||||
*/
|
||||
public static final String METADATA_KEY = "verifierHttp";
|
||||
|
||||
/**
|
||||
* Scheme used for HTTP communication.
|
||||
*/
|
||||
private Scheme scheme;
|
||||
|
||||
/**
|
||||
* Protocol used for HTTP communication.
|
||||
*/
|
||||
private Protocol protocol;
|
||||
|
||||
@NonNull
|
||||
public static ContractVerifierHttpMetadata fromMetadata(
|
||||
Map<String, Object> metadata) {
|
||||
return MetadataUtil.fromMetadata(metadata, METADATA_KEY,
|
||||
new ContractVerifierHttpMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return METADATA_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Metadata entries used by the framework";
|
||||
}
|
||||
|
||||
public Scheme getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public void setScheme(Scheme scheme) {
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
public void setScheme(String scheme) {
|
||||
this.scheme = Scheme.fromString(scheme);
|
||||
}
|
||||
|
||||
public Protocol getProtocol() {
|
||||
return this.protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(Protocol protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = Protocol.fromString(protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP communication scheme.
|
||||
*/
|
||||
public enum Scheme {
|
||||
|
||||
/**
|
||||
* HTTP scheme.
|
||||
*/
|
||||
HTTP,
|
||||
|
||||
/**
|
||||
* HTTPS scheme.
|
||||
*/
|
||||
HTTPS;
|
||||
|
||||
/**
|
||||
* Builds an enum from string.
|
||||
*/
|
||||
@Nullable
|
||||
public static Scheme fromString(String scheme) {
|
||||
return Arrays.stream(values()).filter(p -> p.name().equalsIgnoreCase(scheme))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Taken from OKHttp's Protocol.
|
||||
*/
|
||||
public enum Protocol {
|
||||
|
||||
/**
|
||||
* An obsolete plaintext framing that does not use persistent sockets by default.
|
||||
*/
|
||||
HTTP_1_0("http/1.0"),
|
||||
|
||||
/**
|
||||
* A plaintext framing that includes persistent connections.
|
||||
*
|
||||
* This version of OkHttp implements [RFC 7230][rfc_7230], and tracks revisions to
|
||||
* that spec.
|
||||
*
|
||||
* [rfc_7230]: https://tools.ietf.org/html/rfc7230
|
||||
*/
|
||||
HTTP_1_1("http/1.1"),
|
||||
|
||||
/**
|
||||
* The IETF's binary-framed protocol that includes header compression,
|
||||
* multiplexing multiple requests on the same socket, and server-push. HTTP/1.1
|
||||
* semantics are layered on HTTP/2.
|
||||
*
|
||||
* HTTP/2 requires deployments of HTTP/2 that use TLS 1.2 support
|
||||
* [CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256], present in Java 8+ and
|
||||
* Android 5+. Servers that enforce this may send an exception message including
|
||||
* the string `INADEQUATE_SECURITY`.
|
||||
*/
|
||||
HTTP_2("h2"),
|
||||
|
||||
/**
|
||||
* Cleartext HTTP/2 with no "upgrade" round trip. This option requires the client
|
||||
* to have prior knowledge that the server supports cleartext HTTP/2.
|
||||
*
|
||||
* See also [Starting HTTP/2 with Prior Knowledge][rfc_7540_34].
|
||||
*
|
||||
* [rfc_7540_34]: https://tools.ietf.org/html/rfc7540.section-3.4
|
||||
*/
|
||||
H2_PRIOR_KNOWLEDGE("h2_prior_knowledge"),
|
||||
|
||||
/**
|
||||
* QUIC (Quick UDP Internet Connection) is a new multiplexed and secure transport
|
||||
* atop UDP, designed from the ground up and optimized for HTTP/2 semantics.
|
||||
* HTTP/1.1 semantics are layered on HTTP/2.
|
||||
*
|
||||
* QUIC is not natively supported by OkHttp, but provided to allow a theoretical
|
||||
* interceptor that provides support.
|
||||
*/
|
||||
QUIC("quic");
|
||||
|
||||
private final String protocol;
|
||||
|
||||
Protocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an enum from string.
|
||||
*/
|
||||
@Nullable
|
||||
public static Protocol fromString(String protocol) {
|
||||
return Arrays.stream(values())
|
||||
.filter(p -> p.protocol.equalsIgnoreCase(protocol)).findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.verifier.http;
|
||||
|
||||
/**
|
||||
* Abstraction over sending and receiving of http messages.
|
||||
*
|
||||
* Warning! This API is experimental and can change in time.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public interface HttpVerifier {
|
||||
|
||||
/**
|
||||
* Sends a request and blocks for the response.
|
||||
* @param request - HTTP request
|
||||
* @return HTTP response
|
||||
*/
|
||||
Response exchange(Request request);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.verifier.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.RequestBody;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* {@link HttpVerifier} implementation that uses {@link OkHttpClient}.
|
||||
* Has an inbuilt support for GRPC.
|
||||
*
|
||||
* Warning! This API is experimental and can change in time.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class OkHttpHttpVerifier implements HttpVerifier {
|
||||
|
||||
private final String url;
|
||||
|
||||
public OkHttpHttpVerifier(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response exchange(Request request) {
|
||||
String requestContentType = request.contentType();
|
||||
// TODO: Resolve protocol and scheme from contract?
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.protocols(protocols(requestContentType)).build();
|
||||
okhttp3.Request req = new okhttp3.Request.Builder()
|
||||
.url(this.url + (request.path().startsWith("/") ? request.path()
|
||||
: "/" + request.path()))
|
||||
.method(request.method().name(), requestBody(request, requestContentType))
|
||||
.headers(Headers.of(stringTyped(request.headers()))) // TODO: Add cookies
|
||||
.build();
|
||||
try (okhttp3.Response res = client.newCall(req).execute()) {
|
||||
return response(res);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Protocol> protocols(String requestContentType) {
|
||||
if (this.url.startsWith("https")) {
|
||||
return Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1);
|
||||
}
|
||||
else if (isGrpc(requestContentType)) {
|
||||
return Collections.singletonList(Protocol.H2_PRIOR_KNOWLEDGE);
|
||||
}
|
||||
return Collections.singletonList(Protocol.HTTP_1_1);
|
||||
}
|
||||
|
||||
private Response response(okhttp3.Response res) throws IOException {
|
||||
byte[] responseBody = responseBody(res);
|
||||
// String contentType = res.headers().get("Content-Type");
|
||||
// TODO: Response body in the test / contract should already be properly encoded
|
||||
// if (contentType != null && isGrpc(contentType) && responseBody != null) {
|
||||
// responseBody = grpcResponseBody(responseBody);
|
||||
// }
|
||||
return Response.builder().body(responseBody).statusCode(res.code())
|
||||
.headers(withSingleHeader(res))
|
||||
// TODO: Add cookies
|
||||
// .cookies(res.headers().values("Set-Cookie").stream().map(s ->
|
||||
// s.split(";")).flatMap(Arrays::stream).collect(Collectors.toMap(o -> o.
|
||||
// , e -> e.getValue().get(0), (a,b) -> a, HashMap::new))))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RequestBody requestBody(Request request, String requestContentType) {
|
||||
if (request.body() == null) {
|
||||
return null;
|
||||
}
|
||||
byte[] bodyArray = request.body().asByteArray();
|
||||
return RequestBody.create(MediaType.parse(requestContentType), bodyArray);
|
||||
}
|
||||
|
||||
private boolean isGrpc(String contentType) {
|
||||
return contentType.startsWith("application/grpc");
|
||||
}
|
||||
|
||||
// the encoded body should already have proper byte values
|
||||
// TODO: This should be removed?
|
||||
private byte[] grpcRequestBody(Request request) {
|
||||
byte[] bodyArray; // TODO: Add compression support
|
||||
byte compressedFlag = 0;
|
||||
byte[] message = request.body().asByteArray();
|
||||
byte[] messageLength = ByteBuffer.allocate(4).putInt(message.length).array();
|
||||
bodyArray = ByteBuffer.allocate(1 + messageLength.length + message.length)
|
||||
.put(compressedFlag).put(messageLength).put(message).array();
|
||||
return bodyArray;
|
||||
}
|
||||
|
||||
// TODO: This should be removed?
|
||||
private byte[] grpcResponseBody(byte[] responseBody) {
|
||||
// 5 value = 4th index
|
||||
// 1 for compression, 4 for message size
|
||||
int actualPayloadSize = responseBody.length - 5;
|
||||
byte[] destination = new byte[actualPayloadSize];
|
||||
System.arraycopy(responseBody, 5, destination, 0, actualPayloadSize);
|
||||
responseBody = destination;
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private byte[] responseBody(okhttp3.Response res) throws IOException {
|
||||
return res.body() != null ? res.body().bytes() : null;
|
||||
}
|
||||
|
||||
private Map<String, Object> withSingleHeader(okhttp3.Response res) {
|
||||
return res.headers().toMultimap().entrySet().stream().collect(Collectors.toMap(
|
||||
Map.Entry::getKey, e -> e.getValue().get(0), (a, b) -> a, HashMap::new));
|
||||
}
|
||||
|
||||
private Map<String, String> stringTyped(Map<String, Object> headers) {
|
||||
return headers.entrySet().stream().collect(
|
||||
Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toString()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.verifier.http;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.HttpMethods;
|
||||
|
||||
/**
|
||||
* Abstraction over a HTTP request.
|
||||
*
|
||||
* Warning! This API is experimental and can change in time.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class Request {
|
||||
|
||||
private final HttpMethods.HttpMethod method;
|
||||
|
||||
private final String path;
|
||||
|
||||
private final Body body;
|
||||
|
||||
private final Map<String, Object> headers;
|
||||
|
||||
private final Map<String, Object> cookies;
|
||||
|
||||
Request(HttpMethods.HttpMethod method, String path, Body body,
|
||||
Map<String, Object> headers, Map<String, Object> cookies) {
|
||||
this.method = method;
|
||||
this.path = path;
|
||||
this.body = body;
|
||||
this.headers = headers == null ? new HashMap<>() : headers;
|
||||
this.cookies = cookies == null ? new HashMap<>() : cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return content type from headers
|
||||
*/
|
||||
public String contentType() {
|
||||
Object value = this.headers.entrySet().stream()
|
||||
.filter(e -> e.getKey().toLowerCase().equals("content-type")).findFirst()
|
||||
.orElse(new AbstractMap.SimpleEntry<>("", null)).getValue();
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTTP method
|
||||
*/
|
||||
public HttpMethods.HttpMethod method() {
|
||||
return this.method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTTP path
|
||||
*/
|
||||
public String path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return request body
|
||||
*/
|
||||
public Body body() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return request headers
|
||||
*/
|
||||
public Map<String, Object> headers() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return request cookies
|
||||
*/
|
||||
public Map<String, Object> cookies() {
|
||||
return this.cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to pick the HTTP method.
|
||||
* @return method builder
|
||||
*/
|
||||
public static Request.MethodBuilder given() {
|
||||
return new Request.MethodBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder over HTTP methods.
|
||||
*/
|
||||
public static class MethodBuilder {
|
||||
|
||||
/**
|
||||
* Factory method for DELETE HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder delete(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.DELETE, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for GET HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder get(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.GET, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for HEAD HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder head(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.HEAD, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for OPTIONS HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder options(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.OPTIONS, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for PATCH HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder patch(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.PATCH, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for POST HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder post(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.POST, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for PUT HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder put(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.PUT, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for TRACE HTTP method.
|
||||
* @param path to call
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder trace(String path) {
|
||||
return new Request.Builder(HttpMethods.HttpMethod.TRACE, path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for a {@link Request}.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
final HttpMethods.HttpMethod method;
|
||||
|
||||
final String path;
|
||||
|
||||
Body body;
|
||||
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
|
||||
Map<String, Object> cookies = new HashMap<>();
|
||||
|
||||
Builder(HttpMethods.HttpMethod method, String path) {
|
||||
this.method = method;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param body HTTP body
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder body(Object body) {
|
||||
this.body = new Body(body);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param headers HTTP headers
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder headers(Map<String, Object> headers) {
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key HTTP key
|
||||
* @param value HTTP value
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder header(String key, Object value) {
|
||||
this.headers.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cookies HTTP cookies
|
||||
* @return builder
|
||||
*/
|
||||
public Request.Builder cookies(Map<String, Object> cookies) {
|
||||
this.cookies = cookies;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return built {@link Request}
|
||||
*/
|
||||
public Request build() {
|
||||
return new Request(this.method, this.path, this.body, this.headers,
|
||||
this.cookies);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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.verifier.http;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Abstraction over a HTTP response.
|
||||
*
|
||||
* Warning! This API is experimental and can change in time.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class Response {
|
||||
|
||||
private final int statusCode;
|
||||
|
||||
private final Body body;
|
||||
|
||||
private final Map<String, Object> headers;
|
||||
|
||||
private final Map<String, Object> cookies;
|
||||
|
||||
Response(int statusCode, Body body, Map<String, Object> headers,
|
||||
Map<String, Object> cookies) {
|
||||
this.statusCode = statusCode;
|
||||
this.body = body;
|
||||
this.headers = headers;
|
||||
this.cookies = cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return numerical representation of a status code
|
||||
*/
|
||||
public int statusCode() {
|
||||
return this.statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key header key
|
||||
* @return header value or null if not present
|
||||
*/
|
||||
public String header(String key) {
|
||||
return this.headers.entrySet().stream()
|
||||
.filter(e -> e.getKey().equalsIgnoreCase(key)).findFirst()
|
||||
.map(e -> e.getValue().toString()).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key cookie key
|
||||
* @return header value or null if not present
|
||||
*/
|
||||
public String cookie(String key) {
|
||||
return this.cookies.entrySet().stream()
|
||||
.filter(e -> e.getKey().equalsIgnoreCase(key)).findFirst()
|
||||
.map(e -> e.getValue().toString()).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response body
|
||||
*/
|
||||
public Body getBody() {
|
||||
return this.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return builder
|
||||
*/
|
||||
public static Response.Builder builder() {
|
||||
return new Response.Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return headers
|
||||
*/
|
||||
public Map<String, Object> headers() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return cookies
|
||||
*/
|
||||
public Map<String, Object> cookies() {
|
||||
return this.cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Response builder.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
int statusCode;
|
||||
|
||||
Body body;
|
||||
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
|
||||
Map<String, Object> cookies = new HashMap<>();
|
||||
|
||||
/**
|
||||
* @param status as int
|
||||
* @return builder
|
||||
*/
|
||||
public Response.Builder statusCode(int status) {
|
||||
this.statusCode = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param body - response body
|
||||
* @return builder
|
||||
*/
|
||||
public Response.Builder body(Object body) {
|
||||
this.body = new Body(body);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param headers - response headers
|
||||
* @return builder
|
||||
*/
|
||||
public Response.Builder headers(Map<String, Object> headers) {
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key header key
|
||||
* @param value header value
|
||||
* @return builder
|
||||
*/
|
||||
public Response.Builder header(String key, Object value) {
|
||||
this.headers.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cookies - response cookies
|
||||
* @return builder
|
||||
*/
|
||||
public Response.Builder cookies(Map<String, Object> cookies) {
|
||||
this.cookies = cookies;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return response
|
||||
*/
|
||||
public Response build() {
|
||||
return new Response(this.statusCode, this.body, this.headers, this.cookies);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -122,6 +122,7 @@ response:
|
||||
methodBuilderName | methodBuilder
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue("#187")
|
||||
@@ -155,6 +156,7 @@ response:
|
||||
methodBuilderName | methodBuilder
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('#79')
|
||||
@@ -190,6 +192,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('#79')
|
||||
@@ -228,6 +231,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('#82')
|
||||
@@ -263,6 +267,9 @@ response:
|
||||
"webclient" | {
|
||||
properties.testMode = TestMode.WEBTESTCLIENT
|
||||
} | '.body("{\\"items\\":[\\"HOP\\"]}")'
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
} | '.body("{\\"items\\":[\\"HOP\\"]}")'
|
||||
}
|
||||
|
||||
@Issue('#88')
|
||||
@@ -292,6 +299,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK } | """.body('''property1=VAL1''')"""
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC } | '.body("property1=VAL1")'
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT } | '.body("property1=VAL1")'
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM } | '.body("property1=VAL1")'
|
||||
}
|
||||
|
||||
@Issue('185')
|
||||
@@ -326,6 +334,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
def 'should generate assertions for array in response body with #methodBuilderName'() {
|
||||
@@ -363,6 +372,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
def 'should generate assertions for array inside response body element with #methodBuilderName'() {
|
||||
@@ -399,6 +409,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
def 'should generate assertions for nested objects in response body with #methodBuilderName'() {
|
||||
@@ -432,6 +443,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
def 'should generate regex assertions for map objects in response body with #methodBuilderName'() {
|
||||
@@ -469,6 +481,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
def "should generate a call with an url path and query parameters with #methodBuilderName"() {
|
||||
@@ -642,6 +655,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK } | ".body('''''')"
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC } | '.body("")'
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT } | '.body("")'
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM } | '.body("")'
|
||||
}
|
||||
|
||||
def 'should generate test for String in response body with #methodBuilderName'() {
|
||||
@@ -678,6 +692,9 @@ response:
|
||||
"webclient" | {
|
||||
properties.testMode = TestMode.WEBTESTCLIENT
|
||||
} | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");'
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
} | 'String responseBody = response.getBody().asString();' | 'assertThat(responseBody).isEqualTo("test");'
|
||||
}
|
||||
|
||||
@Issue('113')
|
||||
@@ -731,6 +748,9 @@ response:
|
||||
"webclient" | {
|
||||
properties.testMode = TestMode.WEBTESTCLIENT
|
||||
} | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");'
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
} | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");'
|
||||
}
|
||||
|
||||
def 'should work with more complex stuff and jsonpaths with #methodBuilderName'() {
|
||||
@@ -777,6 +797,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('72')
|
||||
@@ -822,6 +843,9 @@ response:
|
||||
"webclient" | {
|
||||
properties.testMode = TestMode.WEBTESTCLIENT
|
||||
} | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))''']
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
} | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))''']
|
||||
}
|
||||
|
||||
def "shouldn't generate unicode escape characters with #methodBuilderName"() {
|
||||
@@ -871,6 +895,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('180')
|
||||
@@ -1188,6 +1213,7 @@ response:
|
||||
methodBuilderName | methodBuilder
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('262')
|
||||
@@ -1261,6 +1287,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('266')
|
||||
@@ -1298,6 +1325,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('266')
|
||||
@@ -1330,6 +1358,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('47')
|
||||
@@ -1420,6 +1449,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK }
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC }
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('#273')
|
||||
@@ -1662,6 +1692,9 @@ response:
|
||||
"webclient" | {
|
||||
properties.testMode = TestMode.WEBTESTCLIENT
|
||||
} | { String s -> "response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application.vnd.fraud.v1.json.*')" }
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
} | { String s -> "response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application.vnd.fraud.v1.json.*')" }
|
||||
}
|
||||
|
||||
@Issue('#172')
|
||||
@@ -1699,6 +1732,7 @@ response:
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK } | """responseBody == '''{"a":1}\\n{"a":2}\\n'''"""
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}\\n'''
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}\\n'''
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}\\n'''
|
||||
}
|
||||
|
||||
@Issue('#443')
|
||||
@@ -1747,6 +1781,9 @@ response:
|
||||
"jaxrs" | {
|
||||
properties.testFramework = TestFramework.JUNIT; properties.testMode = TestMode.JAXRSCLIENT
|
||||
} | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") }
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
} | { String testContents -> testContents.contains("""assertThat(responseBody).matches("true|false");""") }
|
||||
}
|
||||
|
||||
@Issue('#169')
|
||||
@@ -1785,6 +1822,7 @@ response:
|
||||
methodBuilderName | methodBuilder | expectedAssertion
|
||||
"spock" | { properties.testFramework = TestFramework.SPOCK } | '''responseBody == "{\\"a\\":1}\\n{\\"a\\":2}"'''
|
||||
"mockmvc" | { properties.testMode = TestMode.MOCKMVC } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}'''
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM } | '''assertThat(responseBody).isEqualTo("{\\"a\\":1}\\n{\\"a\\":2}'''
|
||||
}
|
||||
|
||||
@Issue('#169')
|
||||
@@ -1825,6 +1863,9 @@ response:
|
||||
"jaxrs" | {
|
||||
properties.testFramework = TestFramework.JUNIT; properties.testMode = TestMode.JAXRSCLIENT
|
||||
}
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
}
|
||||
}
|
||||
|
||||
@Issue('#203')
|
||||
@@ -1866,6 +1907,7 @@ response:
|
||||
properties.testFramework = TestFramework.JUNIT; properties.testMode = TestMode.JAXRSCLIENT
|
||||
}
|
||||
"webclient" | { properties.testMode = TestMode.WEBTESTCLIENT }
|
||||
"custom" | { properties.testMode = TestMode.CUSTOM }
|
||||
}
|
||||
|
||||
@Issue('#226')
|
||||
@@ -1909,5 +1951,8 @@ response:
|
||||
"webclient" | {
|
||||
properties.testMode = TestMode.WEBTESTCLIENT
|
||||
} | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') }
|
||||
"custom" | {
|
||||
properties.testMode = TestMode.CUSTOM
|
||||
} | { String body -> body.contains('body("12000")') } | { String body -> body.contains('assertThat(responseBody).isEqualTo("12000");') }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ class SpringCloudContractRequestMatcherTests {
|
||||
}
|
||||
};
|
||||
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class), Parameters.one("tool", "foo"));
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class),
|
||||
Parameters.one("tool", "foo"));
|
||||
|
||||
BDDAssertions.then(result.isExactMatch()).isFalse();
|
||||
}
|
||||
@@ -63,7 +64,8 @@ class SpringCloudContractRequestMatcherTests {
|
||||
}
|
||||
};
|
||||
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class), Parameters.one("contract", "value"));
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class),
|
||||
Parameters.one("contract", "value"));
|
||||
|
||||
BDDAssertions.then(result.isExactMatch()).isFalse();
|
||||
}
|
||||
@@ -80,22 +82,28 @@ class SpringCloudContractRequestMatcherTests {
|
||||
}
|
||||
};
|
||||
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class), Parameters.one("contract", "value"));
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class),
|
||||
Parameters.one("contract", "value"));
|
||||
|
||||
BDDAssertions.then(result.isExactMatch()).isFalse();
|
||||
}
|
||||
|
||||
private static final String PROPER_YAML = "---\n" + "request:\n" + " method: \"POST\"\n" + " url: \"/graphql\"\n"
|
||||
+ " headers:\n" + " Content-Type: \"application/json\"\n" + " body:\n"
|
||||
private static final String PROPER_YAML = "---\n" + "request:\n"
|
||||
+ " method: \"POST\"\n" + " url: \"/graphql\"\n" + " headers:\n"
|
||||
+ " Content-Type: \"application/json\"\n" + " body:\n"
|
||||
+ " query: \"query queryName($personName: String!) { personToCheck(name: $personName)"
|
||||
+ " { name age } }\"\n" + " variables:\n" + " personName: \"Old Enough\"\n"
|
||||
+ " operationName: \"queryName\"\n" + " matchers:\n" + " headers:\n"
|
||||
+ " - key: \"Content-Type\"\n" + " regex: \"application/json.*\"\n"
|
||||
+ " regexType: \"as_string\"\n" + "response:\n" + " status: 200\n" + " headers:\n"
|
||||
+ " Content-Type: \"application/json\"\n" + " body:\n" + " data:\n" + " personToCheck:\n"
|
||||
+ " name: \"Old Enough\"\n" + " age: \"40\"\n" + " matchers:\n" + " headers:\n"
|
||||
+ " - key: \"Content-Type\"\n" + " regex: \"application/json.*\"\n"
|
||||
+ " regexType: \"as_string\"\n" + "name: \"shouldRetrieveOldEnoughPerson\"\n" + "metadata:\n"
|
||||
+ " { name age } }\"\n" + " variables:\n"
|
||||
+ " personName: \"Old Enough\"\n" + " operationName: \"queryName\"\n"
|
||||
+ " matchers:\n" + " headers:\n" + " - key: \"Content-Type\"\n"
|
||||
+ " regex: \"application/json.*\"\n"
|
||||
+ " regexType: \"as_string\"\n" + "response:\n" + " status: 200\n"
|
||||
+ " headers:\n" + " Content-Type: \"application/json\"\n" + " body:\n"
|
||||
+ " data:\n" + " personToCheck:\n" + " name: \"Old Enough\"\n"
|
||||
+ " age: \"40\"\n" + " matchers:\n" + " headers:\n"
|
||||
+ " - key: \"Content-Type\"\n"
|
||||
+ " regex: \"application/json.*\"\n"
|
||||
+ " regexType: \"as_string\"\n"
|
||||
+ "name: \"shouldRetrieveOldEnoughPerson\"\n" + "metadata:\n"
|
||||
+ " verifier:\n" + " tool: \"graphql\"\n";
|
||||
|
||||
@Test
|
||||
@@ -109,8 +117,8 @@ class SpringCloudContractRequestMatcherTests {
|
||||
}
|
||||
};
|
||||
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class),
|
||||
toMap(Tuples.of("tool", "unsupported"), Tuples.of("contract", PROPER_YAML)));
|
||||
MatchResult result = matcher.match(BDDMockito.mock(Request.class), toMap(
|
||||
Tuples.of("tool", "unsupported"), Tuples.of("contract", PROPER_YAML)));
|
||||
|
||||
BDDAssertions.then(result.isExactMatch()).isFalse();
|
||||
}
|
||||
@@ -145,7 +153,8 @@ class SpringCloudContractRequestMatcherTests {
|
||||
class ApplicableRequestMatcher implements RequestMatcher {
|
||||
|
||||
@Override
|
||||
public MatchResult match(List<YamlContract> contracts, Request request, Parameters parameters) {
|
||||
public MatchResult match(List<YamlContract> contracts, Request request,
|
||||
Parameters parameters) {
|
||||
return MatchResult.of(true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user