Skip to content

Commit c8798a5

Browse files
fix: added tests for #2367; fixes gh-2368
Signed-off-by: Marcin Grzejszczak <[email protected]>
1 parent 51972ef commit c8798a5

File tree

13 files changed

+2259
-4
lines changed

13 files changed

+2259
-4
lines changed

spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<plexus-archiver.version>4.10.4</plexus-archiver.version>
3939
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>
4040
<maven-site-plugin.version>3.21.0</maven-site-plugin.version>
41-
<maven-plugin-testing-harness.version>4.0.0-beta-4</maven-plugin-testing-harness.version>
41+
<maven-plugin-testing-harness.version>3.4.0</maven-plugin-testing-harness.version>
4242
<maven-shared-incremental.version>1.1</maven-shared-incremental.version>
4343
<slf4j-api.version>2.0.17</slf4j-api.version>
4444
<plexus-utils.version>4.0.2</plexus-utils.version> <!-- If not set the provided version is 3.0.x and MethodMissing is thrown -->

spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/ConvertMojo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ private File contractsDslDir(File contractsDirectory) {
297297
}
298298

299299
private boolean isInsideProject() {
300-
return this.mavenSession.getRequest().isProjectPresent();
300+
return this.session.getRequest().isProjectPresent();
301301
}
302302

303303
}

spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/CopyContracts.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ public void copy(File contractsDirectory, File outputDirectory) throws MojoExecu
8282
execution.setOverwrite(true);
8383
execution.setIncludeEmptyDirs(false);
8484
execution.setFilterFilenames(false);
85-
execution.setFilters(Collections.<String>emptyList());
86-
execution.setNonFilteredFileExtensions(Collections.<String>emptyList());
85+
execution.setFilters(Collections.emptyList());
86+
execution.setNonFilteredFileExtensions(Collections.emptyList());
8787
try {
8888
this.mavenResourcesFiltering.filterResources(execution);
8989
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright 2013-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.contract.maven.verifier;
18+
19+
import java.io.File;
20+
import java.nio.file.Files;
21+
import java.nio.file.Path;
22+
import java.util.List;
23+
import java.util.stream.Stream;
24+
25+
import org.apache.maven.api.plugin.testing.MojoExtension;
26+
import org.apache.maven.api.plugin.testing.MojoTest;
27+
import org.apache.maven.execution.DefaultMavenExecutionRequest;
28+
import org.apache.maven.execution.DefaultMavenExecutionResult;
29+
import org.apache.maven.execution.MavenExecutionRequest;
30+
import org.apache.maven.execution.MavenSession;
31+
import org.apache.maven.model.Build;
32+
import org.apache.maven.model.Model;
33+
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
34+
import org.apache.maven.plugin.AbstractMojo;
35+
import org.apache.maven.project.MavenProject;
36+
import org.junit.jupiter.api.extension.ExtendWith;
37+
38+
@MojoTest
39+
@ExtendWith(MojoExtension.class)
40+
abstract class AbstractMojoIntegrationTests {
41+
42+
void deleteDirectoryIfExists(Path targetDir) throws Exception {
43+
if (!Files.exists(targetDir)) {
44+
return;
45+
}
46+
try (Stream<Path> paths = Files.walk(targetDir)) {
47+
paths.sorted((a, b) -> -a.compareTo(b)).map(Path::toFile).forEach(File::delete);
48+
}
49+
}
50+
51+
void setupBuildPaths(AbstractMojo mojo, Path targetDir) throws Exception {
52+
Path projectDir = targetDir.getParent();
53+
MavenXpp3Reader reader = new MavenXpp3Reader();
54+
Model model = reader.read(Files.newBufferedReader(projectDir.resolve("pom.xml")));
55+
MavenProject project = new MavenProject(model);
56+
project.setFile(projectDir.resolve("pom.xml").toFile());
57+
MojoExtension.setVariableValueToObject(project, "basedir", projectDir.toFile());
58+
Build build = project.getBuild();
59+
if (build == null) {
60+
build = new Build();
61+
}
62+
build.setDirectory(targetDir.toString());
63+
build.setOutputDirectory(targetDir.resolve("classes").toString());
64+
build.setTestOutputDirectory(targetDir.resolve("test-classes").toString());
65+
build.setSourceDirectory(projectDir(project).resolve("src/main/java").toString());
66+
build.setTestSourceDirectory(projectDir(project).resolve("src/test/java").toString());
67+
project.setBuild(build);
68+
project.getProperties().setProperty("project.build.directory", targetDir.toString());
69+
MavenExecutionRequest request = new DefaultMavenExecutionRequest();
70+
request.setBaseDirectory(project.getBasedir());
71+
request.setProjectPresent(true);
72+
MavenSession session = new StubMavenSession(request, project);
73+
MojoExtension.setVariableValueToObject(mojo, "project", project);
74+
MavenProject sessionProject = session.getCurrentProject();
75+
if (sessionProject == null) {
76+
sessionProject = project;
77+
session.setCurrentProject(project);
78+
}
79+
sessionProject.setBuild(build);
80+
session.setProjects(List.of(sessionProject));
81+
MojoExtension.setVariableValueToObject(mojo, "session", session);
82+
}
83+
84+
private Path projectDir(MavenProject project) {
85+
return project.getBasedir().toPath();
86+
}
87+
88+
private static final class StubMavenSession extends MavenSession {
89+
90+
private MavenProject current;
91+
92+
StubMavenSession(MavenExecutionRequest request, MavenProject project) {
93+
super(null, request, new DefaultMavenExecutionResult(), List.of(project));
94+
this.current = project;
95+
}
96+
97+
@Override
98+
public MavenProject getCurrentProject() {
99+
return this.current;
100+
}
101+
102+
@Override
103+
public void setCurrentProject(MavenProject currentProject) {
104+
this.current = currentProject;
105+
}
106+
107+
}
108+
109+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2013-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.contract.maven.verifier;
18+
19+
import java.nio.file.Files;
20+
import java.nio.file.Path;
21+
import java.util.List;
22+
import java.util.stream.Stream;
23+
24+
import org.apache.maven.api.plugin.testing.Basedir;
25+
import org.apache.maven.api.plugin.testing.InjectMojo;
26+
import org.apache.maven.api.plugin.testing.MojoExtension;
27+
import org.junit.jupiter.api.Test;
28+
29+
import static org.assertj.core.api.BDDAssertions.then;
30+
31+
class ConvertMojoIntegrationTests extends AbstractMojoIntegrationTests {
32+
33+
@Test
34+
@InjectMojo(goal = "convert", pom = "pom.xml")
35+
@Basedir("src/test/projects/basic")
36+
void shouldConvertContractsToWiremockStubs(ConvertMojo mojo) throws Exception {
37+
// given
38+
Path projectDir = Path.of(MojoExtension.getBasedir());
39+
Path targetDir = projectDir.resolve("target");
40+
deleteDirectoryIfExists(targetDir);
41+
Files.createDirectories(targetDir);
42+
setupBuildPaths(mojo, targetDir);
43+
MojoExtension.setVariableValueToObject(mojo, "stubsDirectory", targetDir.resolve("stubs").toFile());
44+
MojoExtension.setVariableValueToObject(mojo, "incrementalContractStubs", false);
45+
46+
// when
47+
mojo.execute();
48+
49+
// then
50+
Path stubsRoot = targetDir.resolve("stubs");
51+
then(Files.exists(stubsRoot)).isTrue();
52+
List<Path> stubs;
53+
try (Stream<Path> paths = Files.walk(stubsRoot)) {
54+
stubs = paths.filter(path -> path.toString().endsWith(".json")).toList();
55+
}
56+
then(stubs).isNotEmpty();
57+
String stubContents = Files.readString(stubs.get(0));
58+
then(stubContents).contains("/users").contains("\"response\"");
59+
}
60+
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2013-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.contract.maven.verifier;
18+
19+
import java.nio.file.Files;
20+
import java.nio.file.Path;
21+
import java.util.List;
22+
import java.util.stream.Stream;
23+
24+
import org.apache.maven.api.plugin.testing.Basedir;
25+
import org.apache.maven.api.plugin.testing.InjectMojo;
26+
import org.apache.maven.api.plugin.testing.MojoExtension;
27+
import org.apache.maven.project.MavenProject;
28+
import org.junit.jupiter.api.Test;
29+
30+
import static org.assertj.core.api.BDDAssertions.then;
31+
32+
class GenerateTestsMojoIntegrationTests extends AbstractMojoIntegrationTests {
33+
34+
@Test
35+
@InjectMojo(goal = "generateTests", pom = "pom.xml")
36+
@Basedir("src/test/projects/basic")
37+
void shouldGenerateTestsFromContracts(GenerateTestsMojo mojo) throws Exception {
38+
// given
39+
Path projectDir = Path.of(MojoExtension.getBasedir());
40+
Path targetDir = projectDir.resolve("target");
41+
deleteDirectoryIfExists(targetDir);
42+
Files.createDirectories(targetDir);
43+
Path generatedSources = targetDir.resolve("generated-test-sources/contracts");
44+
Path generatedResources = targetDir.resolve("generated-test-resources/contracts");
45+
setupBuildPaths(mojo, targetDir);
46+
MojoExtension.setVariableValueToObject(mojo, "generatedTestSourcesDir", generatedSources.toFile());
47+
MojoExtension.setVariableValueToObject(mojo, "generatedTestResourcesDir", generatedResources.toFile());
48+
MojoExtension.setVariableValueToObject(mojo, "incrementalContractTests", false);
49+
50+
// when
51+
mojo.execute();
52+
53+
// then
54+
then(Files.exists(generatedSources)).isTrue();
55+
then(Files.exists(generatedResources)).isTrue();
56+
List<Path> generatedJava;
57+
try (Stream<Path> paths = Files.walk(generatedSources)) {
58+
generatedJava = paths.filter(path -> path.toString().endsWith(".java")).toList();
59+
}
60+
then(generatedJava).isNotEmpty();
61+
String generatedContent = Files.readString(generatedJava.get(0));
62+
then(generatedContent).contains("/users");
63+
MavenProject project = (MavenProject) MojoExtension.getVariableValueFromObject(mojo, "project");
64+
then(project.getTestCompileSourceRoots()).contains(generatedSources.toString());
65+
}
66+
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
description: null
3+
ignored: false
4+
inProgress: false
5+
input:
6+
assertThat: null
7+
triggeredBy: "hashCode()"
8+
label: "some_label"
9+
metadata: {}
10+
name: "Messaging"
11+
outputMessage:
12+
assertThat: null
13+
body:
14+
bookName: "foo"
15+
bodyFromFile: null
16+
bodyFromFileAsBytes: null
17+
headers:
18+
BOOK-NAME: "foo"
19+
matchers:
20+
body: []
21+
cookies: []
22+
headers: []
23+
sentTo: "jms:output"
24+
priority: null
25+
request: null
26+
response: null
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package org.springframework.cloud.contract.verifier.tests;
2+
3+
import com.jayway.jsonpath.DocumentContext;
4+
import com.jayway.jsonpath.JsonPath;
5+
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.api.extension.ExtendWith;
7+
import org.junit.jupiter.api.Disabled;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierObjectMapper;
10+
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessage;
11+
import org.springframework.cloud.contract.verifier.messaging.internal.ContractVerifierMessaging;
12+
import io.restassured.module.mockmvc.specification.MockMvcRequestSpecification;
13+
import io.restassured.response.ResponseOptions;
14+
15+
import static org.springframework.cloud.contract.verifier.assertion.SpringCloudContractAssertions.assertThat;
16+
import static org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.*;
17+
import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson;
18+
import static org.springframework.cloud.contract.verifier.messaging.util.ContractVerifierMessagingUtil.headers;
19+
import static org.springframework.cloud.contract.verifier.util.ContractVerifierUtil.fileToBytes;
20+
import static io.restassured.module.mockmvc.RestAssuredMockMvc.*;
21+
22+
@SuppressWarnings("rawtypes")
23+
public class ContractVerifierTest {
24+
@Autowired ContractVerifierMessaging contractVerifierMessaging;
25+
@Autowired ContractVerifierObjectMapper contractVerifierObjectMapper;
26+
27+
@Test
28+
public void validate_messaging() throws Exception {
29+
// when:
30+
hashCode();
31+
32+
// then:
33+
ContractVerifierMessage response = contractVerifierMessaging.receive("jms:output",
34+
contract(this, "messaging.yml"));
35+
assertThat(response).isNotNull();
36+
37+
// and:
38+
assertThat(response.getHeader("BOOK-NAME")).isNotNull();
39+
assertThat(response.getHeader("BOOK-NAME").toString()).isEqualTo("foo");
40+
41+
// and:
42+
DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload()));
43+
assertThatJson(parsedJson).field("['bookName']").isEqualTo("foo");
44+
}
45+
46+
@Test
47+
public void validate_sample() throws Exception {
48+
// given:
49+
MockMvcRequestSpecification request = given()
50+
.header("Content-Type", "application/json")
51+
.body("{\"login\":\"john\",\"name\":\"John The Contract\"}");
52+
53+
// when:
54+
ResponseOptions response = given().spec(request)
55+
.post("/users");
56+
57+
// then:
58+
assertThat(response.statusCode()).isEqualTo(200);
59+
assertThat(response.header("Location")).isEqualTo("/users/john");
60+
}
61+
62+
@Test
63+
@Disabled
64+
public void validate_withList() throws Exception {
65+
// given:
66+
MockMvcRequestSpecification request = given()
67+
.header("Content-Type", "application/json");
68+
69+
// when:
70+
ResponseOptions response = given().spec(request)
71+
.post("/users");
72+
73+
// then:
74+
assertThat(response.statusCode()).isEqualTo(200);
75+
assertThat(response.header("Location")).isEqualTo("/users/john");
76+
77+
// and:
78+
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
79+
assertThatJson(parsedJson).array("['list']").arrayField().isEqualTo("login").value();
80+
assertThatJson(parsedJson).array("['list']").arrayField().isEqualTo("john").value();
81+
assertThatJson(parsedJson).array("['list']").arrayField().isEqualTo("name").value();
82+
assertThatJson(parsedJson).array("['list']").arrayField().isEqualTo("John The Contract").value();
83+
}
84+
85+
}

0 commit comments

Comments
 (0)