From ac6b4e9519c988ef30edb9739b9cc2afd41bc7c7 Mon Sep 17 00:00:00 2001 From: Jakub Pilimon Date: Sun, 11 Mar 2018 13:00:59 +0100 Subject: [PATCH 1/4] possibility to run the app with in memory h2 database for integration testing --- app-monolith/pom.xml | 6 + .../src/main/resources/schema/commons.sql | 12 -- .../src/main/resources/schema/commons.xml | 11 ++ .../main/resources/schema/db.changelog.xml | 12 +- .../resources/schema/delivery-planning.sql | 17 --- .../resources/schema/delivery-planning.xml | 42 ++++++ .../resources/schema/demand-forecasting.sql | 49 ------- .../resources/schema/demand-forecasting.xml | 134 ++++++++++++++++++ .../resources/schema/product-management.sql | 9 -- .../resources/schema/product-management.xml | 24 ++++ .../resources/schema/production-planning.sql | 22 --- .../resources/schema/production-planning.xml | 60 ++++++++ .../resources/schema/shortages-prediction.sql | 19 --- .../resources/schema/shortages-prediction.xml | 40 ++++++ .../src/test/resources/application.properties | 10 ++ 15 files changed, 333 insertions(+), 134 deletions(-) delete mode 100644 app-monolith/src/main/resources/schema/commons.sql create mode 100644 app-monolith/src/main/resources/schema/commons.xml delete mode 100644 app-monolith/src/main/resources/schema/delivery-planning.sql create mode 100644 app-monolith/src/main/resources/schema/delivery-planning.xml delete mode 100644 app-monolith/src/main/resources/schema/demand-forecasting.sql create mode 100644 app-monolith/src/main/resources/schema/demand-forecasting.xml delete mode 100644 app-monolith/src/main/resources/schema/product-management.sql create mode 100644 app-monolith/src/main/resources/schema/product-management.xml delete mode 100644 app-monolith/src/main/resources/schema/production-planning.sql create mode 100644 app-monolith/src/main/resources/schema/production-planning.xml delete mode 100644 app-monolith/src/main/resources/schema/shortages-prediction.sql create mode 100644 app-monolith/src/main/resources/schema/shortages-prediction.xml create mode 100644 app-monolith/src/test/resources/application.properties diff --git a/app-monolith/pom.xml b/app-monolith/pom.xml index ebef45f..54f1ca7 100644 --- a/app-monolith/pom.xml +++ b/app-monolith/pom.xml @@ -99,6 +99,12 @@ 1.1-groovy-2.4 test + + com.h2database + h2 + 1.4.194 + test + net.bytebuddy byte-buddy diff --git a/app-monolith/src/main/resources/schema/commons.sql b/app-monolith/src/main/resources/schema/commons.sql deleted file mode 100644 index 495f961..0000000 --- a/app-monolith/src/main/resources/schema/commons.sql +++ /dev/null @@ -1,12 +0,0 @@ ---liquibase formatted sql - ---changeset michaluk.michal:1.init - -CREATE SEQUENCE hibernate_sequence - START WITH 1 - INCREMENT BY 1 - NO MINVALUE - NO MAXVALUE - CACHE 1; - -CREATE CAST (character varying AS json) WITH INOUT AS ASSIGNMENT; diff --git a/app-monolith/src/main/resources/schema/commons.xml b/app-monolith/src/main/resources/schema/commons.xml new file mode 100644 index 0000000..2a2b72c --- /dev/null +++ b/app-monolith/src/main/resources/schema/commons.xml @@ -0,0 +1,11 @@ + + + + + + + CREATE CAST (character varying AS jsonb) WITH INOUT AS ASSIGNMENT + + diff --git a/app-monolith/src/main/resources/schema/db.changelog.xml b/app-monolith/src/main/resources/schema/db.changelog.xml index 0e94a27..f5d9b8e 100644 --- a/app-monolith/src/main/resources/schema/db.changelog.xml +++ b/app-monolith/src/main/resources/schema/db.changelog.xml @@ -2,10 +2,10 @@ - - - - - - + + + + + + diff --git a/app-monolith/src/main/resources/schema/delivery-planning.sql b/app-monolith/src/main/resources/schema/delivery-planning.sql deleted file mode 100644 index 0b3e86b..0000000 --- a/app-monolith/src/main/resources/schema/delivery-planning.sql +++ /dev/null @@ -1,17 +0,0 @@ ---liquibase formatted sql - ---changeset michaluk.michal:1.init -CREATE SCHEMA delivery_planning; - -CREATE TABLE delivery_planning.delivery_planner_definition ( - ref_no character varying(64) NOT NULL PRIMARY KEY, - definition json NOT NULL -); - -CREATE TABLE delivery_planning.delivery_forecast ( - id serial NOT NULL PRIMARY KEY, - ref_no character varying(64) NOT NULL, - "time" timestamp without time zone NOT NULL, - "date" timestamp without time zone NOT NULL, - level bigint NOT NULL -); diff --git a/app-monolith/src/main/resources/schema/delivery-planning.xml b/app-monolith/src/main/resources/schema/delivery-planning.xml new file mode 100644 index 0000000..8012ae9 --- /dev/null +++ b/app-monolith/src/main/resources/schema/delivery-planning.xml @@ -0,0 +1,42 @@ + + + + + + + + + + CREATE SCHEMA delivery_planning + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app-monolith/src/main/resources/schema/demand-forecasting.sql b/app-monolith/src/main/resources/schema/demand-forecasting.sql deleted file mode 100644 index ce91d92..0000000 --- a/app-monolith/src/main/resources/schema/demand-forecasting.sql +++ /dev/null @@ -1,49 +0,0 @@ ---liquibase formatted sql - ---changeset michaluk.michal:1.init -CREATE SCHEMA demand_forecasting; - -CREATE TABLE demand_forecasting.product_demand ( - id serial NOT NULL PRIMARY KEY, - version bigint NOT NULL, - ref_no character varying(64) NOT NULL, - UNIQUE(ref_no) -); - -CREATE TABLE demand_forecasting."demand" ( - id serial NOT NULL PRIMARY KEY, - ref_no character varying(64) NOT NULL, - "date" timestamp without time zone NOT NULL, - value json NOT NULL, - UNIQUE(ref_no, "date") -); - -CREATE TABLE demand_forecasting.current_demand ( - id serial NOT NULL PRIMARY KEY, - ref_no character varying(64) NOT NULL, - "date" timestamp without time zone NOT NULL, - level bigint NOT NULL, - "schema" character varying(64) NOT NULL, - UNIQUE(ref_no, "date") -); - -CREATE TABLE demand_forecasting.demand_adjustment ( - id serial NOT NULL PRIMARY KEY, - customer_representative character varying(255) NOT NULL, - note character varying(255) NOT NULL, - adjustment json NOT NULL, - clean_after timestamp without time zone -); - -CREATE TABLE demand_forecasting.demand_review ( - id serial NOT NULL PRIMARY KEY, - ref_no character varying(64) NOT NULL, - "date" timestamp without time zone NOT NULL, - "timestamp" timestamp without time zone NOT NULL, - review json NOT NULL, - decision character varying(64), - clean_after timestamp without time zone -); - ---changeset michaluk.michal:2.rename.review.table -ALTER TABLE demand_forecasting.demand_review RENAME TO required_review; diff --git a/app-monolith/src/main/resources/schema/demand-forecasting.xml b/app-monolith/src/main/resources/schema/demand-forecasting.xml new file mode 100644 index 0000000..18b552a --- /dev/null +++ b/app-monolith/src/main/resources/schema/demand-forecasting.xml @@ -0,0 +1,134 @@ + + + + + + + + + + CREATE SCHEMA demand_forecasting + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app-monolith/src/main/resources/schema/product-management.sql b/app-monolith/src/main/resources/schema/product-management.sql deleted file mode 100644 index f7b66f5..0000000 --- a/app-monolith/src/main/resources/schema/product-management.sql +++ /dev/null @@ -1,9 +0,0 @@ ---liquibase formatted sql - ---changeset michaluk.michal:1.init -CREATE SCHEMA product_management; - -CREATE TABLE product_management.product_description ( - ref_no character varying(64) NOT NULL PRIMARY KEY, - description json NOT NULL -); diff --git a/app-monolith/src/main/resources/schema/product-management.xml b/app-monolith/src/main/resources/schema/product-management.xml new file mode 100644 index 0000000..8761062 --- /dev/null +++ b/app-monolith/src/main/resources/schema/product-management.xml @@ -0,0 +1,24 @@ + + + + + + + + + + CREATE SCHEMA product_management + + + + + + + + + + + + \ No newline at end of file diff --git a/app-monolith/src/main/resources/schema/production-planning.sql b/app-monolith/src/main/resources/schema/production-planning.sql deleted file mode 100644 index 025cf40..0000000 --- a/app-monolith/src/main/resources/schema/production-planning.sql +++ /dev/null @@ -1,22 +0,0 @@ ---liquibase formatted sql - ---changeset michaluk.michal:1.init -CREATE SCHEMA production_planning; - -CREATE TABLE production_planning.production_daily_output ( - id serial NOT NULL PRIMARY KEY, - ref_no character varying(64) NOT NULL, - "date" timestamp without time zone NOT NULL, - output bigint NOT NULL, - UNIQUE(ref_no, "date") -); - -CREATE TABLE production_planning.production_output ( - id serial NOT NULL PRIMARY KEY, - ref_no character varying(64) NOT NULL, - "start" timestamp without time zone NOT NULL, - "end" timestamp without time zone NOT NULL, - duration bigint NOT NULL, - parts_per_minute integer NOT NULL, - total bigint NOT NULL -); diff --git a/app-monolith/src/main/resources/schema/production-planning.xml b/app-monolith/src/main/resources/schema/production-planning.xml new file mode 100644 index 0000000..3e6a323 --- /dev/null +++ b/app-monolith/src/main/resources/schema/production-planning.xml @@ -0,0 +1,60 @@ + + + + + + + + + + CREATE SCHEMA production_planning + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app-monolith/src/main/resources/schema/shortages-prediction.sql b/app-monolith/src/main/resources/schema/shortages-prediction.sql deleted file mode 100644 index 95333f3..0000000 --- a/app-monolith/src/main/resources/schema/shortages-prediction.sql +++ /dev/null @@ -1,19 +0,0 @@ ---liquibase formatted sql - ---changeset michaluk.michal:1.init -CREATE SCHEMA shortages_prediction; - -CREATE TABLE shortages_prediction.shortage ( - id serial NOT NULL PRIMARY KEY, - version bigint NOT NULL, - ref_no character varying(64) NOT NULL, - shortages json NOT NULL, - UNIQUE(ref_no) -); - -CREATE TABLE shortages_prediction.stock_forecast ( - ref_no character varying(64) NOT NULL PRIMARY KEY -); - ---changeset michaluk.michal:2.rename.shortages.column -ALTER TABLE shortages_prediction.shortage RENAME shortages TO shortage; diff --git a/app-monolith/src/main/resources/schema/shortages-prediction.xml b/app-monolith/src/main/resources/schema/shortages-prediction.xml new file mode 100644 index 0000000..6bf377e --- /dev/null +++ b/app-monolith/src/main/resources/schema/shortages-prediction.xml @@ -0,0 +1,40 @@ + + + + + + + + + + CREATE SCHEMA shortages_prediction + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app-monolith/src/test/resources/application.properties b/app-monolith/src/test/resources/application.properties new file mode 100644 index 0000000..5d7b0a5 --- /dev/null +++ b/app-monolith/src/test/resources/application.properties @@ -0,0 +1,10 @@ +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +spring.datasource.username=sa +spring.datasource.password=sa + +spring.main.banner-mode=off +spring.jpa.database=default +spring.jpa.generate-ddl=false + +liquibase.change-log=classpath:/schema/db.changelog.xml From 27f8cbb8fadb87a9b410bfa527cd5567997a7ec6 Mon Sep 17 00:00:00 2001 From: Jakub Pilimon Date: Sun, 11 Mar 2018 13:01:44 +0100 Subject: [PATCH 2/4] possibility to push CALL OFF DOCUMENT via rest endpoint --- .../forecasting/command/CommandsHandler.java | 7 +++ .../forecasting/persistence/DocumentDao.java | 13 +++++ .../persistence/DocumentEntity.java | 49 +++++++++++++++++++ .../factory/demand/forecasting/Document.java | 4 +- 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentDao.java create mode 100644 demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentEntity.java diff --git a/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/command/CommandsHandler.java b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/command/CommandsHandler.java index 2937b16..3cad57b 100644 --- a/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/command/CommandsHandler.java +++ b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/command/CommandsHandler.java @@ -3,6 +3,7 @@ package pl.com.bottega.factory.demand.forecasting.command; import lombok.AllArgsConstructor; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.event.EventListener; +import org.springframework.data.rest.core.annotation.HandleAfterCreate; import org.springframework.data.rest.core.annotation.HandleBeforeCreate; import org.springframework.data.rest.core.annotation.HandleBeforeSave; import org.springframework.data.rest.core.annotation.RepositoryEventHandler; @@ -10,6 +11,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import pl.com.bottega.factory.demand.forecasting.DemandService; +import pl.com.bottega.factory.demand.forecasting.persistence.DocumentEntity; import java.time.Clock; import java.time.LocalDate; @@ -35,6 +37,11 @@ public class CommandsHandler { service.adjust(adjustment.getAdjustment()); } + @HandleAfterCreate + public void process(DocumentEntity document) { + service.process(document.getDocument()); + } + @HandleBeforeSave public void review(RequiredReviewEntity review) { if (review.decisionTaken()) { diff --git a/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentDao.java b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentDao.java new file mode 100644 index 0000000..69a4810 --- /dev/null +++ b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentDao.java @@ -0,0 +1,13 @@ +package pl.com.bottega.factory.demand.forecasting.persistence; + +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import org.springframework.stereotype.Repository; +import pl.com.bottega.tools.CommandRepository; + +@Repository("documentDao") +@RepositoryRestResource(path = "demand-documents", + collectionResourceRel = "demand-documents", + itemResourceRel = "demand-document") +public interface DocumentDao extends CommandRepository { + +} diff --git a/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentEntity.java b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentEntity.java new file mode 100644 index 0000000..67aab6d --- /dev/null +++ b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/persistence/DocumentEntity.java @@ -0,0 +1,49 @@ +package pl.com.bottega.factory.demand.forecasting.persistence; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.LastModifiedDate; +import pl.com.bottega.factory.demand.forecasting.Document; +import pl.com.bottega.tools.JsonConverter; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.Instant; +import java.time.LocalDate; + +@Entity(name = "Document") +@Table(schema = "demand_forecasting") +@Getter +@NoArgsConstructor +public class DocumentEntity implements Serializable { + + @Id + @GeneratedValue + private Long id; + private String refNo; + @LastModifiedDate + private Instant saved; + private String originalUri; + private String storedUri; + @Setter + @Convert(converter = DocumentAsJson.class) + private Document document; + + @Setter + private LocalDate cleanAfter; + + public DocumentEntity(String originalUri, String storedUri, Document document) { + saved = Instant.now(); + this.originalUri = originalUri; + this.storedUri = storedUri; + this.document = document; + this.refNo = document.getRefNo(); + } + + public static class DocumentAsJson extends JsonConverter { + public DocumentAsJson() { + super(Document.class); + } + } +} diff --git a/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java b/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java index 0a4b670..efa1edc 100644 --- a/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java +++ b/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java @@ -1,6 +1,6 @@ package pl.com.bottega.factory.demand.forecasting; -import lombok.AllArgsConstructor; +import lombok.Value; import java.time.Instant; import java.time.LocalDate; @@ -9,7 +9,7 @@ import java.util.SortedMap; import java.util.function.BiFunction; import java.util.stream.Collectors; -@AllArgsConstructor +@Value public class Document { private final Instant created; From 179793cc434a240d7be5da772bd8d29641c39842 Mon Sep 17 00:00:00 2001 From: Jakub Pilimon Date: Sun, 11 Mar 2018 13:02:37 +0100 Subject: [PATCH 3/4] integration test for pushing call of document and requesting current demands --- .../com/bottega/factory/ProductTrait.groovy | 36 ++++++++ .../CallOffDocumentIntegrationSpec.groovy | 89 +++++++++++++++++++ .../projection/CurrentDemandDao.java | 4 +- 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 app-monolith/src/test/pl/com/bottega/factory/ProductTrait.groovy create mode 100644 app-monolith/src/test/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy diff --git a/app-monolith/src/test/pl/com/bottega/factory/ProductTrait.groovy b/app-monolith/src/test/pl/com/bottega/factory/ProductTrait.groovy new file mode 100644 index 0000000..98c67ee --- /dev/null +++ b/app-monolith/src/test/pl/com/bottega/factory/ProductTrait.groovy @@ -0,0 +1,36 @@ +package src.test.pl.com.bottega.factory + +import pl.com.bottega.factory.demand.forecasting.Demand +import pl.com.bottega.factory.demand.forecasting.Document +import pl.com.bottega.factory.demand.forecasting.persistence.DocumentEntity +import pl.com.bottega.factory.product.management.ProductDescription +import pl.com.bottega.factory.product.management.ProductDescriptionEntity + +import java.time.Instant +import java.time.LocalDate +import java.time.OffsetTime +import java.time.ZoneOffset + +trait ProductTrait { + + + DocumentEntity documentFor(String refNo, LocalDate date, long ... levels) { + Document document = document(refNo, date, levels) + return new DocumentEntity("uri", "storedUri", document) + } + + ProductDescriptionEntity productDescription(String refNo) { + ProductDescription desc = new ProductDescription("461952398951", ["PROWAD.POJ.NA JARZ.ESSENT"]) + return new ProductDescriptionEntity(refNo, desc) + } + + Document document(String refNo, LocalDate date, long ... levels) { + Instant created = date.atTime(OffsetTime.of(8, 0, 0, 0, ZoneOffset.UTC)).toInstant() + SortedMap results = new TreeMap<>() + for (long level : levels) { + results.put(date, Demand.of(level)) + date = date.plusDays(1) + } + new Document(created, refNo, results) + } +} diff --git a/app-monolith/src/test/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy b/app-monolith/src/test/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy new file mode 100644 index 0000000..a5a065c --- /dev/null +++ b/app-monolith/src/test/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy @@ -0,0 +1,89 @@ +package src.test.pl.com.bottega.factory.integration + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.web.client.TestRestTemplate +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.core.ParameterizedTypeReference +import org.springframework.hateoas.Resources +import org.springframework.http.HttpMethod +import org.springframework.http.ResponseEntity +import pl.com.bottega.factory.AppConfiguration +import pl.com.bottega.factory.demand.forecasting.persistence.DocumentEntity +import pl.com.bottega.factory.demand.forecasting.projection.CurrentDemandEntity +import pl.com.bottega.factory.product.management.ProductDescriptionEntity +import spock.lang.Specification +import src.test.pl.com.bottega.factory.ProductTrait + +import java.time.Clock +import java.time.LocalDate +import java.time.ZoneId + +import static java.time.Instant.from +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT + +@SpringBootTest(webEnvironment = RANDOM_PORT, classes = AppConfiguration) +class CallOffDocumentIntegrationSpec extends Specification implements ProductTrait { + + public static final String PRODUCT_REF_NO = "refNum" + public static final LocalDate ANY_DATE = LocalDate.of(2019, 1, 1) + + @Autowired TestRestTemplate restTemplate + + def 'receiving call off document should create new product demands for subsequent days'() { + given: + productDescriptionIsSuccessfullyCreated(PRODUCT_REF_NO) + when: + callOffDocumentIsSuccessfullyRequested(PRODUCT_REF_NO, ANY_DATE, 100, 200, 300) + and: + Collection demands = + demandsForProductStartingFromDateAreRequested(PRODUCT_REF_NO, ANY_DATE.minusDays(1)) + then: + demands.size() == 3 + thereIsDemand(demands, ANY_DATE, 100) + thereIsDemand(demands, ANY_DATE.plusDays(1), 200) + thereIsDemand(demands, ANY_DATE.plusDays(2), 300) + + } + + void productDescriptionIsSuccessfullyCreated(String refNo) { + ResponseEntity response = restTemplate + .postForEntity("/product-descriptions", productDescription(refNo), ProductDescriptionEntity) + assert response.statusCode.is2xxSuccessful() + } + + void callOffDocumentIsSuccessfullyRequested(String refNo, LocalDate date, long ... levels) { + ResponseEntity response = restTemplate + .postForEntity("/demand-documents", documentFor(refNo, date, levels), DocumentEntity) + assert response.statusCode.is2xxSuccessful() + } + + Collection demandsForProductStartingFromDateAreRequested(String refNo, LocalDate date) { + ResponseEntity> res = restTemplate + .exchange("/demand-forecasts/search/refNos?refNo={refNo}&date={date}", + HttpMethod.GET, + null, + new ParameterizedTypeReference>() {}, + ["refNo": refNo, "date" : date]) + assert res.statusCode.is2xxSuccessful() + return res.getBody().getContent() + + } + + void thereIsDemand(Collection demands, LocalDate date, long expectedLevel) { + assert demands.find { it.date == date && it.level == expectedLevel } + } + + @Configuration + static class TestConfiguration { + + @Bean + Clock clock() { + return Clock.fixed(from(ANY_DATE), ZoneId.systemDefault()) + + } + + + } +} \ No newline at end of file diff --git a/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/projection/CurrentDemandDao.java b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/projection/CurrentDemandDao.java index cd1a426..85d4fed 100644 --- a/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/projection/CurrentDemandDao.java +++ b/demand-forecasting-adapters/src/main/java/pl/com/bottega/factory/demand/forecasting/projection/CurrentDemandDao.java @@ -1,7 +1,9 @@ package pl.com.bottega.factory.demand.forecasting.projection; +import org.springframework.data.repository.query.Param; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import org.springframework.data.rest.core.annotation.RestResource; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.stereotype.Repository; import pl.com.bottega.tools.ProjectionRepository; @@ -14,7 +16,7 @@ import java.util.List; itemResourceRel = "demand-forecast") public interface CurrentDemandDao extends ProjectionRepository { @RestResource(path = "refNos", rel = "refNos") - List findByRefNoAndDateGreaterThanEqual(String refNo, LocalDate date); + List findByRefNoAndDateGreaterThanEqual(@Param("refNo") String refNo, @Param("date") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date); @RestResource(exported = false) void deleteByRefNoAndDate(String refNo, LocalDate date); From e579cffbac85abdf3095f772b07594f1d8bcdc16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Michaluk?= Date: Sun, 11 Mar 2018 15:26:59 +0100 Subject: [PATCH 4/4] integration test hooked to build --- adapter-commons/pom.xml | 5 ++++ .../pl/com/bottega/tools/IntegrationTest.java | 18 +++++++++++++++ app-monolith/pom.xml | 23 +++++++++++++++++++ .../com/bottega/factory/ProductTrait.groovy | 3 +-- .../CallOffDocumentIntegrationSpec.groovy | 17 ++++++-------- .../resources/application-test.properties | 4 ++++ .../src/test/resources/application.properties | 10 -------- .../factory/demand/forecasting/Document.java | 1 - 8 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 adapter-commons/src/test/java/pl/com/bottega/tools/IntegrationTest.java rename app-monolith/src/test/{ => groovy}/pl/com/bottega/factory/ProductTrait.groovy (96%) rename app-monolith/src/test/{ => groovy}/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy (91%) create mode 100644 app-monolith/src/test/resources/application-test.properties delete mode 100644 app-monolith/src/test/resources/application.properties diff --git a/adapter-commons/pom.xml b/adapter-commons/pom.xml index 3128142..22703c0 100644 --- a/adapter-commons/pom.xml +++ b/adapter-commons/pom.xml @@ -28,6 +28,11 @@ jackson-datatype-jsr310 2.8.5 + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/adapter-commons/src/test/java/pl/com/bottega/tools/IntegrationTest.java b/adapter-commons/src/test/java/pl/com/bottega/tools/IntegrationTest.java new file mode 100644 index 0000000..c9ed86d --- /dev/null +++ b/adapter-commons/src/test/java/pl/com/bottega/tools/IntegrationTest.java @@ -0,0 +1,18 @@ +package pl.com.bottega.tools; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.annotation.AliasFor; +import org.springframework.test.context.ActiveProfiles; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@SpringBootTest +@ActiveProfiles +public @interface IntegrationTest { + @AliasFor(annotation = ActiveProfiles.class, attribute = "profiles") String[] activeProfiles() default {"test"}; +} diff --git a/app-monolith/pom.xml b/app-monolith/pom.xml index 54f1ca7..4d8a205 100644 --- a/app-monolith/pom.xml +++ b/app-monolith/pom.xml @@ -131,6 +131,29 @@ + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.6 + + + + compileTests + + + + + + maven-surefire-plugin + 2.20.1 + + false + + **/*Spec.java + **/*Test.java + + + diff --git a/app-monolith/src/test/pl/com/bottega/factory/ProductTrait.groovy b/app-monolith/src/test/groovy/pl/com/bottega/factory/ProductTrait.groovy similarity index 96% rename from app-monolith/src/test/pl/com/bottega/factory/ProductTrait.groovy rename to app-monolith/src/test/groovy/pl/com/bottega/factory/ProductTrait.groovy index 98c67ee..7ae2b03 100644 --- a/app-monolith/src/test/pl/com/bottega/factory/ProductTrait.groovy +++ b/app-monolith/src/test/groovy/pl/com/bottega/factory/ProductTrait.groovy @@ -1,4 +1,4 @@ -package src.test.pl.com.bottega.factory +package pl.com.bottega.factory import pl.com.bottega.factory.demand.forecasting.Demand import pl.com.bottega.factory.demand.forecasting.Document @@ -13,7 +13,6 @@ import java.time.ZoneOffset trait ProductTrait { - DocumentEntity documentFor(String refNo, LocalDate date, long ... levels) { Document document = document(refNo, date, levels) return new DocumentEntity("uri", "storedUri", document) diff --git a/app-monolith/src/test/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy b/app-monolith/src/test/groovy/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy similarity index 91% rename from app-monolith/src/test/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy rename to app-monolith/src/test/groovy/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy index a5a065c..f897e6c 100644 --- a/app-monolith/src/test/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy +++ b/app-monolith/src/test/groovy/pl/com/bottega/factory/integration/CallOffDocumentIntegrationSpec.groovy @@ -1,4 +1,4 @@ -package src.test.pl.com.bottega.factory.integration +package pl.com.bottega.factory.integration import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -10,11 +10,12 @@ import org.springframework.hateoas.Resources import org.springframework.http.HttpMethod import org.springframework.http.ResponseEntity import pl.com.bottega.factory.AppConfiguration +import pl.com.bottega.factory.ProductTrait import pl.com.bottega.factory.demand.forecasting.persistence.DocumentEntity import pl.com.bottega.factory.demand.forecasting.projection.CurrentDemandEntity import pl.com.bottega.factory.product.management.ProductDescriptionEntity +import pl.com.bottega.tools.IntegrationTest import spock.lang.Specification -import src.test.pl.com.bottega.factory.ProductTrait import java.time.Clock import java.time.LocalDate @@ -23,11 +24,12 @@ import java.time.ZoneId import static java.time.Instant.from import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT +@IntegrationTest @SpringBootTest(webEnvironment = RANDOM_PORT, classes = AppConfiguration) class CallOffDocumentIntegrationSpec extends Specification implements ProductTrait { - public static final String PRODUCT_REF_NO = "refNum" - public static final LocalDate ANY_DATE = LocalDate.of(2019, 1, 1) + public static final String PRODUCT_REF_NO = "3009000" + public static final LocalDate ANY_DATE = LocalDate.now() @Autowired TestRestTemplate restTemplate @@ -44,7 +46,6 @@ class CallOffDocumentIntegrationSpec extends Specification implements ProductTra thereIsDemand(demands, ANY_DATE, 100) thereIsDemand(demands, ANY_DATE.plusDays(1), 200) thereIsDemand(demands, ANY_DATE.plusDays(2), 300) - } void productDescriptionIsSuccessfullyCreated(String refNo) { @@ -65,10 +66,9 @@ class CallOffDocumentIntegrationSpec extends Specification implements ProductTra HttpMethod.GET, null, new ParameterizedTypeReference>() {}, - ["refNo": refNo, "date" : date]) + ["refNo": refNo, "date": date]) assert res.statusCode.is2xxSuccessful() return res.getBody().getContent() - } void thereIsDemand(Collection demands, LocalDate date, long expectedLevel) { @@ -81,9 +81,6 @@ class CallOffDocumentIntegrationSpec extends Specification implements ProductTra @Bean Clock clock() { return Clock.fixed(from(ANY_DATE), ZoneId.systemDefault()) - } - - } } \ No newline at end of file diff --git a/app-monolith/src/test/resources/application-test.properties b/app-monolith/src/test/resources/application-test.properties new file mode 100644 index 0000000..79eedd9 --- /dev/null +++ b/app-monolith/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password=sa +spring.datasource.driver-class-name=org.h2.Driver diff --git a/app-monolith/src/test/resources/application.properties b/app-monolith/src/test/resources/application.properties deleted file mode 100644 index 5d7b0a5..0000000 --- a/app-monolith/src/test/resources/application.properties +++ /dev/null @@ -1,10 +0,0 @@ -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 -spring.datasource.username=sa -spring.datasource.password=sa - -spring.main.banner-mode=off -spring.jpa.database=default -spring.jpa.generate-ddl=false - -liquibase.change-log=classpath:/schema/db.changelog.xml diff --git a/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java b/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java index efa1edc..239a7ee 100644 --- a/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java +++ b/demand-forecasting-model/src/main/java/pl/com/bottega/factory/demand/forecasting/Document.java @@ -27,4 +27,3 @@ public class Document { return refNo; } } -