/* * 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.qi4j.sample.dcicargo.sample_a.context.shipping.booking; import org.junit.Test; import org.qi4j.sample.dcicargo.sample_a.bootstrap.test.TestApplication; import org.qi4j.sample.dcicargo.sample_a.context.support.FoundNoRoutesException; import org.qi4j.sample.dcicargo.sample_a.data.entity.CargoEntity; import org.qi4j.sample.dcicargo.sample_a.data.shipping.cargo.Cargo; import org.qi4j.sample.dcicargo.sample_a.data.shipping.delivery.RoutingStatus; import org.qi4j.sample.dcicargo.sample_a.data.shipping.delivery.TransportStatus; import org.qi4j.sample.dcicargo.sample_a.data.shipping.handling.HandlingEventType; import org.qi4j.sample.dcicargo.sample_a.data.shipping.itinerary.Itinerary; 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 { @Test( expected = Exception.class ) public void deviation2a_OriginAndDestinationSame() throws Exception { new BookNewCargo( CARGOS, HONGKONG, HONGKONG, day( 17 ) ).book(); } @Test( expected = Exception.class ) public void deviation_2b_1_DeadlineInThePastNotAccepted() throws Exception { new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( -1 ) ).book(); } @Test( expected = Exception.class ) public void deviation_2b_2_DeadlineTodayIsTooEarly() throws Exception { new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 0 ) ).book(); } @Test public void deviation_2b_3_DeadlineTomorrowIsOkay() throws Exception { new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 1 ) ).book(); } @Test public void step_2_CreateNewCargo() throws Exception { // Create cargo with valid input from customer trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 17 ) ).book(); // Retrieve created cargo from store cargo = uow.get( CargoEntity.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... assertTrue( cargo.routeSpecification().get().arrivalDeadline().get().before( day( 17 ) ) ); // (Itinerary is not assigned yet) // Test derived delivery snapshot 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 { trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, day( 1 ) ).book(); 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 { // Create valid cargo trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, deadline = day( 30 ) ).book(); cargo = uow.get( Cargo.class, trackingId.id().get() ); // Step 3 - Find possible routes 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 { // Create valid cargo trackingId = new BookNewCargo( CARGOS, HONGKONG, STOCKHOLM, deadline = day( 30 ) ).book(); cargo = uow.get( Cargo.class, trackingId.id().get() ); routeCandidates = new BookNewCargo( cargo ).routeCandidates(); // Get first route found // Would normally be found with an Itinerary id from customer selection 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 = 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 ) ); } }