Add xml support (#855)

* Start working on generating stub requests from Xml.

* Start implementing matching by xpath.

* Handle xml request body matchers.

* Merge branch 'master' into add-xml-support

* Implement analysing xmls and converting nodes to matchers.

* Handle attributes in xml analysis and generate stubs with xml body matchers.

* Make XmlToXPathsConverter statically compiled.

* Start extracting json test generation logic out of the MethodBodyBuilder.

* Fix extracted JsonBodyVerificationBuilder. Fix processing attributes
from xml while generating stubs. Fix and adjust tests to recent changes.

* Merge branch 'master' into add-xml-support

# Conflicts:
#	spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy
#	spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/converter/ContractsToYaml.groovy
#	spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy
#	spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy
#	spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/converter/YamlContractConverterSpec.groovy

* Implement test generation for XML body matchers. Start implementing handling XML lists in assertions.

* Fix generating list element assertions and regex body matcher assertions.
Move XML-assert lib content to project sources. Add tests.

* Fix recognising XML content from String body. Minor refactoring.

* Adjust yaml contracts to new xml handling.

* Add tests for handling XML with yaml contracts. Handle incorrect request
matchers processing.

* Minor refactoring.

* Add docs.

* Fix docs.

* Fixes after code review.

* Switch to apache commons logger in `XmlAsserter`.
This commit is contained in:
Olga Maciaszek-Sharma
2019-01-18 20:16:19 +01:00
committed by GitHub
parent 5d8015aa0f
commit 6c3caddb7b
67 changed files with 4606 additions and 757 deletions

View File

@@ -369,7 +369,7 @@ The WireMock stub is as follows:
[source,json,indent=0]
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy[tags=multipartwiremock,indent=0]
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockGroovyDslSpec.groovy[tags=multipartwiremock,indent=0]
----
=== Response
@@ -1215,6 +1215,59 @@ include::{samples_url}/producer_webflux/src/test/java/com/example/BeerRestBase.j
}
----
=== XML Support for REST
For REST contracts, we also support XML request and response body.
The XML body has to be passed within the `body` element
as a `String` or `GString`. Also body matchers can be provided for
both request and response. In place of the `jsonPath(...)` method, the `org.springframework.cloud.contract.spec.internal.BodyMatchers.xPath`
method should be used, with the desired `xPath` provided as the first argument
and the appropriate `MatchingType` as second. All the body matchers apart from `byType()` are supported.
Here is an example of a Groovy DSL contract with XML response body:
[source,groovy,indent=0]
----
include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/XmlMethodBodyBuilderSpec.groovy[tags=xmlgroovy]
----
And below is an example of a YAML contract with XML request and response bodies:
[source,yaml,indent=0]
----
include::{verifier_core_path}/src/test/resources/yml/contract_rest_xml.yml
----
Here is an example of an automatically generated test for XML response body:
[source,java,indent=0]
----
@Test
public void validate_xmlMatches() throws Exception {
// given:
MockMvcRequestSpecification request = given()
.header("Content-Type", "application/xml");
// when:
ResponseOptions response = given().spec(request).get("/get");
// then:
assertThat(response.statusCode()).isEqualTo(200);
// and:
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document parsedXml = documentBuilder.parse(new InputSource(
new StringReader(response.getBody().asString())));
// and:
assertThat(valueFromXPath(parsedXml, "/test/list/elem/text()")).isEqualTo("abc");
assertThat(valueFromXPath(parsedXml,"/test/list/elem[2]/text()")).isEqualTo("def");
assertThat(valueFromXPath(parsedXml, "/test/duck/text()")).matches("[0-9]{3}");
assertThat(nodeFromXPath(parsedXml, "/test/duck/xxx")).isNull();
assertThat(valueFromXPath(parsedXml, "/test/alpha/text()")).matches("[\\p{L}]*");
assertThat(valueFromXPath(parsedXml, "/test/*/complex/text()")).isEqualTo("foo");
assertThat(valueFromXPath(parsedXml, "/test/duck/@type")).isEqualTo("xtype");
}
----
=== Messaging Top-Level Elements
The DSL for messaging looks a little bit different than the one that focuses on HTTP. The