From b01ab6860eb5ab3be5b04427924c1c44b1d0fc66 Mon Sep 17 00:00:00 2001 From: Kai Moritz Date: Sat, 21 May 2022 12:47:16 +0200 Subject: [PATCH] Added a Spring-based consumer * Goal: re-stage the contract with Spring for educational purposes * Generates a totally different contract for now... * Is copied from the code-example for the PactDslJsonBody DSL * See: https://docs.pact.io/implementation_guides/jvm/consumer#building-json-bodies-with-pactdsljsonbody-dsl[example-code] * Added Maven-Builddirectory to .gitignore * Added the generated JSON for comparison --- .gitignore | 1 + spring-consumer/pom.xml | 65 +++++++++++ .../java/de/juplo/demos/pact/Application.java | 14 +++ .../de/juplo/demos/pact/ApplicationTests.java | 14 +++ .../de/juplo/demos/pact/ContractTest.java | 62 +++++++++++ .../SpringConsumer-Siren Order Provider.json | 102 ++++++++++++++++++ 6 files changed, 258 insertions(+) create mode 100644 spring-consumer/pom.xml create mode 100644 spring-consumer/src/main/java/de/juplo/demos/pact/Application.java create mode 100644 spring-consumer/src/test/java/de/juplo/demos/pact/ApplicationTests.java create mode 100644 spring-consumer/src/test/java/de/juplo/demos/pact/ContractTest.java create mode 100644 spring-consumer/target/pacts/SpringConsumer-Siren Order Provider.json diff --git a/.gitignore b/.gitignore index 3c2a5eb..0d1ebd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .gradle build/ node_modules/ +target/ # Ignore Gradle GUI config gradle-app.setting diff --git a/spring-consumer/pom.xml b/spring-consumer/pom.xml new file mode 100644 index 0000000..23844a2 --- /dev/null +++ b/spring-consumer/pom.xml @@ -0,0 +1,65 @@ + + + + + org.springframework.boot + spring-boot-starter-parent + 2.7.0 + + + + 4.0.0 + de.juplo.demos.pact + siren-consumer + 1.0.0-SNAPSHOT + + + 11 + 4.2.2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + au.com.dius.pact.consumer + junit5 + ${pact.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + maven-failsafe-plugin + + + + + diff --git a/spring-consumer/src/main/java/de/juplo/demos/pact/Application.java b/spring-consumer/src/main/java/de/juplo/demos/pact/Application.java new file mode 100644 index 0000000..5dccaa0 --- /dev/null +++ b/spring-consumer/src/main/java/de/juplo/demos/pact/Application.java @@ -0,0 +1,14 @@ +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); + } + +} diff --git a/spring-consumer/src/test/java/de/juplo/demos/pact/ApplicationTests.java b/spring-consumer/src/test/java/de/juplo/demos/pact/ApplicationTests.java new file mode 100644 index 0000000..7c96248 --- /dev/null +++ b/spring-consumer/src/test/java/de/juplo/demos/pact/ApplicationTests.java @@ -0,0 +1,14 @@ +package de.juplo.demos.pact; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ApplicationTests +{ + + @Test + void contextLoads() { + } + +} diff --git a/spring-consumer/src/test/java/de/juplo/demos/pact/ContractTest.java b/spring-consumer/src/test/java/de/juplo/demos/pact/ContractTest.java new file mode 100644 index 0000000..d7358d8 --- /dev/null +++ b/spring-consumer/src/test/java/de/juplo/demos/pact/ContractTest.java @@ -0,0 +1,62 @@ +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); + } + } +} diff --git a/spring-consumer/target/pacts/SpringConsumer-Siren Order Provider.json b/spring-consumer/target/pacts/SpringConsumer-Siren Order Provider.json new file mode 100644 index 0000000..3d6d034 --- /dev/null +++ b/spring-consumer/target/pacts/SpringConsumer-Siren Order Provider.json @@ -0,0 +1,102 @@ +{ + "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" + } +} -- 2.20.1