diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..718292e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,33 @@ +name: Maven CI + +on: + push: + branches: + - step4 + pull_request: + branches: + - step4 + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'temurin' + + - name: Consumer - Pact tests + run: ./mvnw verify + working-directory: consumer + + - name: Consumer - Move Contracts to Provider + run: cp consumer/target/pacts/ProductCatalogue-ProductService.json provider/pacts + + - name: Provider - Pact verification + run: ./mvnw verify || true + working-directory: provider \ No newline at end of file diff --git a/.java-version b/.java-version new file mode 100644 index 0000000..03b6389 --- /dev/null +++ b/.java-version @@ -0,0 +1 @@ +17.0 diff --git a/README.md b/README.md index 0167cb2..317dfc4 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,8 @@ If running this as a team workshop format, you may want to take a look through t ## Requirements -- JDK 8 or above -- Maven 3 +- JDK 17+ +- Maven 3+ - Docker for step 11 ## Scenario @@ -126,7 +126,8 @@ You can see the client interface test we created in `consumer/src/test/java/io/p ); Product product = productServiceClient.getProductById(10); - assertThat(product, is(equalTo(new Product(10L, "28 Degrees", "CREDIT_CARD", "v1")))); + assertThat(product, is(equalTo(new Product(10L, "28 Degrees", "CREDIT_CARD", "v1", null)))); + } ``` @@ -146,7 +147,7 @@ consumer ❯ ./mvnw verify [INFO] Building product-catalogue 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] -[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ product-catalogue --- +[INFO] --- maven-resources-plugin:3.3.0:resources (default-resources) @ product-catalogue --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Using 'UTF-8' encoding to copy filtered properties files. [INFO] Copying 1 resource @@ -155,7 +156,7 @@ consumer ❯ ./mvnw verify [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ product-catalogue --- [INFO] Nothing to compile - all classes are up to date [INFO] -[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ product-catalogue --- +[INFO] --- maven-resources-plugin:3.3.0:testResources (default-testResources) @ product-catalogue --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Using 'UTF-8' encoding to copy filtered properties files. [INFO] skip non existing resourceDirectory /home/ronald/Development/Projects/Pact/pact-workshop-Maven-Springboot-JUnit5/consumer/src/test/resources @@ -181,7 +182,7 @@ consumer ❯ ./mvnw verify [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] -[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ product-catalogue --- +[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) @ product-catalogue --- [INFO] [INFO] --- spring-boot-maven-plugin:2.4.3:repackage (repackage) @ product-catalogue --- [INFO] Replacing main artifact with repackaged archive @@ -320,57 +321,59 @@ class ProductServiceClientPactTest { public RequestResponsePact allProducts(PactDslWithProvider builder) { return builder .given("products exists") - .uponReceiving("get all products") - .path("/products") + .uponReceiving("get all products") + .path("/products") .willRespondWith() - .status(200) - .body( - new PactDslJsonBody() - .minArrayLike("products", 1, 2) - .integerType("id", 9L) - .stringType("name", "Gem Visa") - .stringType("type", "CREDIT_CARD") - .closeObject() - .closeArray() - ) + .status(200) + .body( + new PactDslJsonBody() + .minArrayLike("products", 1, 2) + .integerType("id", 9L) + .stringType("name", "Gem Visa") + .stringType("type", "CREDIT_CARD") + .closeObject() + .closeArray() + ) .toPact(); } + @Test + @PactTestFor(pactMethod = "allProducts", pactVersion = PactSpecVersion.V3) + void testAllProducts(MockServer mockServer) { + productServiceClient.setBaseUrl(mockServer.getUrl()); + List products = productServiceClient.fetchProducts().getProducts(); + assertThat(products, hasSize(2)); + assertThat(products.get(0), is(equalTo(new Product(9L, "Gem Visa", "CREDIT_CARD", null, null)))); + } + @Pact(consumer = "ProductCatalogue") public RequestResponsePact singleProduct(PactDslWithProvider builder) { return builder .given("product with ID 10 exists", "id", 10) .uponReceiving("get product with ID 10") - .path("/products/10") + .path("/products/10") .willRespondWith() - .status(200) - .body( - new PactDslJsonBody() - .integerType("id", 10L) - .stringType("name", "28 Degrees") - .stringType("type", "CREDIT_CARD") - .stringType("code", "CC_001") - .stringType("version", "v1") - ) + .status(200) + .body( + new PactDslJsonBody() + .integerType("id", 10L) + .stringType("name", "28 Degrees") + .stringType("type", "CREDIT_CARD") + .stringType("code", "CC_001") + .stringType("version", "v1") + ) .toPact(); } @Test - @PactTestFor(pactMethod = "allProducts", port="9999") - void testAllProducts(MockServer mockServer) throws IOException { + @PactTestFor(pactMethod = "singleProduct", pactVersion = PactSpecVersion.V3) + void testSingleProduct(MockServer mockServer) { productServiceClient.setBaseUrl(mockServer.getUrl()); - List products = productServiceClient.fetchProducts().getProducts(); - assertThat(products, hasSize(2)); - assertThat(products.get(0), is(equalTo(new Product(9L, "Gem Visa", "CREDIT_CARD", null, null)))); - } - - @Test - @PactTestFor(pactMethod = "singleProduct", port="9999") - void testSingleProduct(MockServer mockServer) throws IOException { Product product = productServiceClient.getProductById(10L); assertThat(product, is(equalTo(new Product(10L, "28 Degrees", "CREDIT_CARD", "v1", "CC_001")))); } } + ``` @@ -390,7 +393,7 @@ consumer ❯ ./mvnw verify [INFO] Building product-catalogue 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] -[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ product-catalogue --- +[INFO] --- maven-resources-plugin:3.3.0:resources (default-resources) @ product-catalogue --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Using 'UTF-8' encoding to copy filtered properties files. [INFO] Copying 1 resource @@ -399,7 +402,7 @@ consumer ❯ ./mvnw verify [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ product-catalogue --- [INFO] Nothing to compile - all classes are up to date [INFO] -[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ product-catalogue --- +[INFO] --- maven-resources-plugin:3.3.0:testResources (default-testResources) @ product-catalogue --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Using 'UTF-8' encoding to copy filtered properties files. [INFO] skip non existing resourceDirectory /home/ronald/Development/Projects/Pact/pact-workshop-Maven-Springboot-JUnit5/consumer/src/test/resources @@ -422,7 +425,7 @@ consumer ❯ ./mvnw verify [INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] -[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ product-catalogue --- +[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) @ product-catalogue --- [INFO] Building jar: /home/ronald/Development/Projects/Pact/pact-workshop-Maven-Springboot-JUnit5/consumer/target/product-catalogue-0.0.1-SNAPSHOT.jar [INFO] [INFO] --- spring-boot-maven-plugin:2.4.3:repackage (repackage) @ product-catalogue --- diff --git a/consumer/pom.xml b/consumer/pom.xml index 8582364..bfc42ca 100644 --- a/consumer/pom.xml +++ b/consumer/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.4.3 + 3.1.8 io.pact.workshop @@ -15,9 +15,9 @@ Product Catalogue service for Pact Workshop - 1.8 - 8 - 8 + 17 + 17 + 17 @@ -40,14 +40,14 @@ org.projectlombok lombok - 1.18.16 + 1.18.30 provided - com.github.tomakehurst - wiremock-jre8 - 2.27.2 + org.wiremock + wiremock + 3.0.1 test @@ -68,20 +68,20 @@ au.com.dius.pact.consumer junit5 - 4.1.7 + 4.6.5 test org.apache.commons commons-collections4 - 4.1 + 4.4 com.squareup.okhttp3 okhttp - 4.9.1 + 4.12.0 diff --git a/consumer/src/test/java/io/pact/workshop/product_catalogue/clients/ProductServiceClientPactTest.java b/consumer/src/test/java/io/pact/workshop/product_catalogue/clients/ProductServiceClientPactTest.java index a5143c5..84bc6b5 100644 --- a/consumer/src/test/java/io/pact/workshop/product_catalogue/clients/ProductServiceClientPactTest.java +++ b/consumer/src/test/java/io/pact/workshop/product_catalogue/clients/ProductServiceClientPactTest.java @@ -7,13 +7,13 @@ 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 au.com.dius.pact.core.model.PactSpecVersion; // required for v4.6.x to set pactVersion import io.pact.workshop.product_catalogue.models.Product; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import java.io.IOException; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; @@ -48,6 +48,15 @@ public RequestResponsePact allProducts(PactDslWithProvider builder) { .toPact(); } + @Test + @PactTestFor(pactMethod = "allProducts", pactVersion = PactSpecVersion.V3) + void testAllProducts(MockServer mockServer) { + productServiceClient.setBaseUrl(mockServer.getUrl()); + List products = productServiceClient.fetchProducts().getProducts(); + assertThat(products, hasSize(2)); + assertThat(products.get(0), is(equalTo(new Product(9L, "Gem Visa", "CREDIT_CARD", null, null)))); + } + @Pact(consumer = "ProductCatalogue") public RequestResponsePact singleProduct(PactDslWithProvider builder) { return builder @@ -68,17 +77,9 @@ public RequestResponsePact singleProduct(PactDslWithProvider builder) { } @Test - @PactTestFor(pactMethod = "allProducts", port="9999") - void testAllProducts(MockServer mockServer) throws IOException { + @PactTestFor(pactMethod = "singleProduct", pactVersion = PactSpecVersion.V3) + void testSingleProduct(MockServer mockServer) { productServiceClient.setBaseUrl(mockServer.getUrl()); - List products = productServiceClient.fetchProducts().getProducts(); - assertThat(products, hasSize(2)); - assertThat(products.get(0), is(equalTo(new Product(9L, "Gem Visa", "CREDIT_CARD", null, null)))); - } - - @Test - @PactTestFor(pactMethod = "singleProduct", port="9999") - void testSingleProduct(MockServer mockServer) throws IOException { Product product = productServiceClient.getProductById(10L); assertThat(product, is(equalTo(new Product(10L, "28 Degrees", "CREDIT_CARD", "v1", "CC_001")))); } diff --git a/provider/application.properties b/provider/application.properties new file mode 100644 index 0000000..4d2c43a --- /dev/null +++ b/provider/application.properties @@ -0,0 +1 @@ +spring.jpa.defer-datasource-initialization=true diff --git a/provider/pom.xml b/provider/pom.xml index 46f5c2f..6b784ac 100644 --- a/provider/pom.xml +++ b/provider/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.4.3 + 3.1.8 io.pact.workshop @@ -14,11 +14,12 @@ 1.0-SNAPSHOT Product Service for Pact Workshop - - 1.8 - 8 - 8 - + + 17 + 17 + 17 + + @@ -46,7 +47,7 @@ org.projectlombok lombok - 1.18.16 + 1.18.30 provided @@ -60,13 +61,13 @@ org.apache.commons commons-collections4 - 4.1 + 4.4 au.com.dius.pact.provider junit5spring - 4.1.17 + 4.6.5 test diff --git a/provider/src/main/java/io/pact/workshop/product_service/products/Product.java b/provider/src/main/java/io/pact/workshop/product_service/products/Product.java index 8fe430e..9c8b651 100644 --- a/provider/src/main/java/io/pact/workshop/product_service/products/Product.java +++ b/provider/src/main/java/io/pact/workshop/product_service/products/Product.java @@ -4,8 +4,8 @@ import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Entity; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; @Entity @Data diff --git a/provider/src/main/resources/data.sql b/provider/src/main/resources/data.sql index b795701..eaf2ede 100644 --- a/provider/src/main/resources/data.sql +++ b/provider/src/main/resources/data.sql @@ -1,3 +1,3 @@ -insert into product (id, name, type, version, code) values (1, 'Gem Visa', 'CREDIT_CARD', 'v1', 'CC_01_VISA'); -insert into product (id, name, type, version, code) values (2, '28 Degrees', 'CREDIT_CARD', 'v1', 'CC_02_OTH'); -insert into product (id, name, type, version, code) values (3, 'MyFlexiPay', 'PERSONAL_LOAN', 'v2', 'LN_PERS_01'); +insert into product (id, name, type, version, code) values (9, 'Gem Visa', 'CREDIT_CARD', 'v1', 'CC_01_VISA'); +insert into product (id, name, type, version, code) values (10, '28 Degrees', 'CREDIT_CARD', 'v1', 'CC_02_OTH'); +insert into product (id, name, type, version, code) values (11, 'MyFlexiPay', 'PERSONAL_LOAN', 'v2', 'LN_PERS_01'); diff --git a/provider/src/test/java/io/pact/workshop/product_service/PactVerificationTest.java b/provider/src/test/java/io/pact/workshop/product_service/PactVerificationTest.java index 99654ef..4ffb975 100644 --- a/provider/src/test/java/io/pact/workshop/product_service/PactVerificationTest.java +++ b/provider/src/test/java/io/pact/workshop/product_service/PactVerificationTest.java @@ -12,7 +12,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Provider("ProductService")