.gradle
build/
node_modules/
+target/
# Ignore Gradle GUI config
gradle-app.setting
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-parent</artifactId>
+ <version>2.7.0</version>
+ <relativePath/> <!-- lookup parent from repository -->
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>de.juplo.demos.pact</groupId>
+ <artifactId>siren-consumer</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+
+ <properties>
+ <java.version>11</java.version>
+ <pact.version>4.2.2</pact.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>au.com.dius.pact.consumer</groupId>
+ <artifactId>junit5</artifactId>
+ <version>${pact.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ </exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /dev/null
+package de.juplo.demos.pact;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application
+{
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
--- /dev/null
+package de.juplo.demos.pact;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class ApplicationTests
+{
+
+ @Test
+ void contextLoads() {
+ }
+
+}
--- /dev/null
+package de.juplo.demos.pact;
+
+import au.com.dius.pact.consumer.MockServer;
+import au.com.dius.pact.consumer.dsl.PactDslJsonBody;
+import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
+import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
+import au.com.dius.pact.consumer.junit5.PactTestFor;
+import au.com.dius.pact.core.model.RequestResponsePact;
+import au.com.dius.pact.core.model.annotations.Pact;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.fail;
+
+
+@ExtendWith(PactConsumerTestExt.class)
+@PactTestFor(providerName = "Siren Order Provider")
+public class ContractTest
+{
+ @Pact(consumer="SpringConsumer")
+ public RequestResponsePact getOrders(PactDslWithProvider builder)
+ {
+ PactDslJsonBody body = new PactDslJsonBody()
+ .stringType("name")
+ .booleanType("happy")
+ .hexValue("hexCode")
+ .id()
+ .ipAddress("localAddress")
+ .numberValue("age", 100);
+ return builder
+ .uponReceiving("get all orders")
+ .path("/orders")
+ .method("GET")
+ .willRespondWith()
+ .status(200)
+ .headers(Map.of("Content-Type", "application/vnd.siren+json"))
+ .body(body)
+ .toPact();
+ }
+
+ @Test
+ @PactTestFor(pactMethod = "getOrders")
+ public void testGetExistingUserByEmail(MockServer mockServer)
+ {
+ RestTemplate restTemplate =
+ new RestTemplateBuilder()
+ .rootUri(mockServer.getUrl())
+ .build();
+ try
+ {
+ restTemplate.getForEntity("/orders", String.class);
+ }
+ catch (Exception e)
+ {
+ fail("Unexpected exception", e);
+ }
+ }
+}
--- /dev/null
+{
+ "consumer": {
+ "name": "SpringConsumer"
+ },
+ "interactions": [
+ {
+ "description": "get all orders",
+ "request": {
+ "method": "GET",
+ "path": "/orders"
+ },
+ "response": {
+ "body": {
+ "age": 100,
+ "happy": true,
+ "hexCode": "1234a",
+ "id": 1234567890,
+ "localAddress": "127.0.0.1",
+ "name": "string"
+ },
+ "generators": {
+ "body": {
+ "$.hexCode": {
+ "digits": 10,
+ "type": "RandomHexadecimal"
+ },
+ "$.id": {
+ "max": 2147483647,
+ "min": 0,
+ "type": "RandomInt"
+ },
+ "$.name": {
+ "size": 20,
+ "type": "RandomString"
+ }
+ }
+ },
+ "headers": {
+ "Content-Type": "application/vnd.siren+json"
+ },
+ "matchingRules": {
+ "body": {
+ "$.happy": {
+ "combine": "AND",
+ "matchers": [
+ {
+ "match": "type"
+ }
+ ]
+ },
+ "$.hexCode": {
+ "combine": "AND",
+ "matchers": [
+ {
+ "match": "regex",
+ "regex": "[0-9a-fA-F]+"
+ }
+ ]
+ },
+ "$.id": {
+ "combine": "AND",
+ "matchers": [
+ {
+ "match": "type"
+ }
+ ]
+ },
+ "$.localAddress": {
+ "combine": "AND",
+ "matchers": [
+ {
+ "match": "regex",
+ "regex": "(\\d{1,3}\\.)+\\d{1,3}"
+ }
+ ]
+ },
+ "$.name": {
+ "combine": "AND",
+ "matchers": [
+ {
+ "match": "type"
+ }
+ ]
+ }
+ }
+ },
+ "status": 200
+ }
+ }
+ ],
+ "metadata": {
+ "pact-jvm": {
+ "version": "4.2.2"
+ },
+ "pactSpecification": {
+ "version": "3.0.0"
+ }
+ },
+ "provider": {
+ "name": "Siren Order Provider"
+ }
+}