blob: 66974bf33c69514853ad67ebd68cd74d6446ed0d [file] [log] [blame]
/*
* Copyright 2011 Marc Grue.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zest.sample.dcicargo.sample_a.context.shipping.booking;
import java.util.Date;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.apache.zest.api.unitofwork.UnitOfWork;
import org.apache.zest.sample.dcicargo.sample_a.bootstrap.test.TestApplication;
import org.apache.zest.sample.dcicargo.sample_a.context.support.FoundNoRoutesException;
import org.apache.zest.sample.dcicargo.sample_a.data.entity.CargosEntity;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.cargo.Cargo;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.cargo.Cargos;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.cargo.TrackingId;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.delivery.Delivery;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.delivery.RoutingStatus;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.delivery.TransportStatus;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.handling.HandlingEventType;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.itinerary.Itinerary;
import org.apache.zest.sample.dcicargo.sample_a.data.shipping.location.Location;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
/**
* Test of Book New Cargo use case.
*
* This is a test suite where all steps and deviations in the use case are tested.
* Some data will carry over from one test to another (all tests run within the same UnitOfWork).
*
* Test method names describe the test purpose. The prefix refers to the step in the use case.
*/
public class BookNewCargoTest
extends TestApplication
{
private static final Date TODAY = new Date();
@Before
public void prepareTest()
throws Exception
{
super.prepareTest();
}
@Test( expected = RouteException.class )
public void deviation2a_OriginAndDestinationSame() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
new BookNewCargo( CARGOS, HONGKONG, HONGKONG, day( 17 ) ).book();
}
@Test( expected = RouteException.class )
public void deviation_2b_1_DeadlineInThePastNotAccepted() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Location STOCKHOLM = uow.get( Location.class, SESTO.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( -1 ) ).book();
}
@Test( expected = RouteException.class )
public void deviation_2b_2_DeadlineTodayIsTooEarly() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Location STOCKHOLM = uow.get( Location.class, SESTO.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 0 ) ).book();
}
@Test
public void deviation_2b_3_DeadlineTomorrowIsOkay() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Location STOCKHOLM = uow.get( Location.class, SESTO.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 1 ) ).book();
}
@Test
public void step_2_CreateNewCargo() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Location STOCKHOLM = uow.get( Location.class, SESTO.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
// Create cargo with valid input from customer
TrackingId trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 17 ) ).book();
// Retrieve created cargo from store
Cargo cargo = uow.get( Cargo.class, trackingId.id().get() );
// Test cargo data
assertThat( cargo.trackingId().get(), is( equalTo( trackingId ) ) );
assertThat( cargo.origin().get(), is( equalTo( HONGKONG ) ) );
// Test route specification
assertThat( cargo.routeSpecification().get().destination().get(), is( equalTo( STOCKHOLM ) ) );
// day(17) here is calculated a few milliseconds after initial day(17), so it will be later...
assertThat( cargo.routeSpecification().get().arrivalDeadline().get(), equalTo( day( 17 ) ));
// (Itinerary is not assigned yet)
// Test derived delivery snapshot
Delivery delivery = cargo.delivery().get();
assertThat( delivery.timestamp().get().after( TODAY ), is( equalTo( true ) ) ); // TODAY is set first
assertThat( delivery.routingStatus().get(), is( equalTo( RoutingStatus.NOT_ROUTED ) ) );
assertThat( delivery.transportStatus().get(), is( equalTo( TransportStatus.NOT_RECEIVED ) ) );
assertThat( delivery.nextExpectedHandlingEvent().get().handlingEventType().get(), is( equalTo( HandlingEventType.RECEIVE ) ) );
assertThat( delivery.nextExpectedHandlingEvent().get().location().get(), is( equalTo( HONGKONG ) ) );
assertThat( delivery.nextExpectedHandlingEvent().get().voyage().get(), is( equalTo( null ) ) );
assertThat( delivery.lastHandlingEvent().get(), is( equalTo( null ) ) );
assertThat( delivery.lastKnownLocation().get(), is( equalTo( null ) ) );
assertThat( delivery.currentVoyage().get(), is( equalTo( null ) ) );
assertThat( delivery.eta().get(), is( equalTo( null ) ) ); // Is set when itinerary is assigned
assertThat( delivery.isMisdirected().get(), is( equalTo( false ) ) );
assertThat( delivery.isUnloadedAtDestination().get(), is( equalTo( false ) ) );
}
@Test( expected = FoundNoRoutesException.class )
public void deviation_3a_NoRoutesCanBeThatFast() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Location STOCKHOLM = uow.get( Location.class, SESTO.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
TrackingId trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 1 ) ).book();
Cargo cargo = uow.get( Cargo.class, trackingId.id().get() );
// No routes will be found
new BookNewCargo( cargo ).routeCandidates();
}
@Test
public void step_3_CalculatePossibleRoutes() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Location STOCKHOLM = uow.get( Location.class, SESTO.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
// Create valid cargo
TrackingId trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 30 ) ).book();
Cargo cargo = uow.get( Cargo.class, trackingId.id().get() );
// Step 3 - Find possible routes
List<Itinerary> routeCandidates = new BookNewCargo( cargo ).routeCandidates();
// Check possible routes
for (Itinerary itinerary : routeCandidates)
{
assertThat( "First load location equals origin location.",
itinerary.firstLeg().loadLocation().get(),
is( equalTo( cargo.routeSpecification().get().origin().get() ) ) );
assertThat( "Last unload location equals destination location.",
itinerary.lastLeg().unloadLocation().get(),
is( equalTo( cargo.routeSpecification().get().destination().get() ) ) );
assertThat( "Cargo will be delivered in time.",
itinerary.finalArrivalDate().before( cargo.routeSpecification().get().arrivalDeadline().get() ),
is( equalTo( true ) ) );
}
}
@Test
public void step_5_AssignCargoToRoute() throws Exception
{
UnitOfWork uow = module.currentUnitOfWork();
Location HONGKONG = uow.get( Location.class, CNHKG.code().get() );
Location STOCKHOLM = uow.get( Location.class, SESTO.code().get() );
Cargos CARGOS = uow.get( Cargos.class, CargosEntity.CARGOS_ID );
// Create valid cargo
Date deadline = day( 30 );
TrackingId trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, deadline ).book();
Cargo cargo = uow.get( Cargo.class, trackingId.id().get() );
List<Itinerary> routeCandidates = new BookNewCargo( cargo ).routeCandidates();
// Get first route found
// Would normally be found with an Itinerary id from customer selection
Itinerary itinerary = routeCandidates.get( 0 );
// Use case step 5 - System assigns cargo to route
new BookNewCargo( cargo, itinerary ).assignCargoToRoute();
assertThat( "Itinerary has been assigned to cargo.", itinerary, is( equalTo( cargo.itinerary().get() ) ) );
// BuildDeliverySnapshot will check if itinerary is valid. No need to check it here.
// Check values set in new delivery snapshot
Delivery delivery = cargo.delivery().get();
assertThat( delivery.routingStatus().get(), is( equalTo( RoutingStatus.ROUTED ) ) );
// ETA (= Unload time of last Leg) is before Deadline (set in previous test)
assertTrue( delivery.eta().get().before( deadline ) );
}
}