Merge pull request #5 from michal-michaluk/feature/shortage-prediction-integration-test

Feature/shortage prediction integration test
This commit is contained in:
Michał Michaluk
2018-03-11 21:55:03 +01:00
committed by GitHub
4 changed files with 111 additions and 5 deletions

View File

@@ -22,10 +22,11 @@ import java.time.LocalDate
import java.time.ZoneId
import static java.time.Instant.from
import static java.time.ZoneId.systemDefault
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT
@IntegrationTest
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = AppConfiguration)
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = [AppConfiguration, TestConfiguration])
class CallOffDocumentIntegrationSpec extends Specification implements ProductTrait {
public static final String PRODUCT_REF_NO = "3009000"
@@ -80,7 +81,7 @@ class CallOffDocumentIntegrationSpec extends Specification implements ProductTra
@Bean
Clock clock() {
return Clock.fixed(from(ANY_DATE), ZoneId.systemDefault())
return Clock.fixed(from(ANY_DATE.atStartOfDay().atZone(systemDefault())), systemDefault())
}
}
}

View File

@@ -2,6 +2,7 @@ package pl.com.bottega.factory.integration
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@@ -25,10 +26,11 @@ import java.time.LocalDate
import java.time.ZoneId
import static java.time.Instant.from
import static java.time.ZoneId.systemDefault
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT
@IntegrationTest
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = AppConfiguration)
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = [AppConfiguration, TestConfiguration])
class DemandAdjustmentIntegrationSpec extends Specification implements ProductTrait {
public static final String PRODUCT_REF_NO = "3009001"
@@ -93,7 +95,7 @@ class DemandAdjustmentIntegrationSpec extends Specification implements ProductTr
@Bean
Clock clock() {
return Clock.fixed(from(ANY_DATE), ZoneId.systemDefault())
return Clock.fixed(from(ANY_DATE.atStartOfDay().atZone(systemDefault())), systemDefault())
}
}
}

View File

@@ -0,0 +1,102 @@
package src.test.groovy.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.context.annotation.Primary
import org.springframework.core.ParameterizedTypeReference
import org.springframework.hateoas.Resource
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.Adjustment
import pl.com.bottega.factory.demand.forecasting.Demand
import pl.com.bottega.factory.demand.forecasting.command.DemandAdjustmentEntity
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.factory.shortages.prediction.calculation.Stock
import pl.com.bottega.factory.shortages.prediction.monitoring.persistence.ShortagesEntity
import pl.com.bottega.factory.warehouse.WarehouseService
import pl.com.bottega.tools.IntegrationTest
import spock.lang.Specification
import java.time.Clock
import java.time.LocalDate
import java.time.ZoneId
import static java.time.Instant.from
import static java.time.ZoneId.systemDefault
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT
@IntegrationTest
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = [AppConfiguration, TestConfiguration])
class ShortageIntegrationSpec extends Specification implements ProductTrait {
public static final String PRODUCT_REF_NO = "3009003"
public static final LocalDate ANY_DATE = LocalDate.now()
public static final int PRODUCT_STOCK_LEVEL = 100
@Autowired TestRestTemplate restTemplate
def 'adjustment that exceeds current stock level should result in shortage'() {
given:
productDescriptionIsSuccessfullyCreated(PRODUCT_REF_NO)
when:
callOffDocumentIsSuccessfullyRequested(PRODUCT_REF_NO, ANY_DATE, PRODUCT_STOCK_LEVEL)
and:
adjustmentIsSuccessfullyRequested(ANY_DATE.plusDays(1), 200)
then:
thereIsShortage(PRODUCT_REF_NO, ANY_DATE.plusDays(1), 200)
}
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()
}
void adjustmentIsSuccessfullyRequested(LocalDate date, long levelExpected) {
Map<LocalDate, Adjustment> adjustments = [:]
adjustments.put(date, new Adjustment(Demand.of(levelExpected), true))
ResponseEntity response = restTemplate
.postForEntity("/demand-adjustments", strongAdjustment(PRODUCT_REF_NO, adjustments), DemandAdjustmentEntity)
assert response.statusCode.is2xxSuccessful()
}
void thereIsShortage(String refNo, LocalDate forDate, long expectedShortage) {
ResponseEntity<Resource<ShortagesEntity>> res = restTemplate
.exchange("/shortages/search/refNos?refNo={refNo}",
HttpMethod.GET,
null,
new ParameterizedTypeReference<Resource<ShortagesEntity>>() {},
["refNo": refNo])
assert res.statusCode.is2xxSuccessful()
}
@Configuration
static class TestConfiguration {
@Bean
Clock clock() {
return Clock.fixed(from(ANY_DATE.atStartOfDay().atZone(systemDefault())), systemDefault())
}
@Bean
WarehouseService warehouseService() {
return { refNo -> new Stock(PRODUCT_STOCK_LEVEL, 0) }
}
}
}

View File

@@ -1,5 +1,6 @@
package pl.com.bottega.factory.shortages.prediction.monitoring.persistence;
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.stereotype.Repository;
@@ -13,7 +14,7 @@ import java.util.Optional;
itemResourceRel = "shortage")
public interface ShortagesDao extends ProjectionRepository<ShortagesEntity, Long> {
@RestResource(path = "refNos", rel = "refNos")
Optional<ShortagesEntity> findByRefNo(String refNo);
Optional<ShortagesEntity> findByRefNo(@Param("refNo") String refNo);
void deleteAllInBatch();
}