peter_backlund 17 lat temu
rodzic
commit
062a17bf97
15 zmienionych plików z 312 dodań i 145 usunięć
  1. 6
    4
      dddsample/src/test/java/se/citerus/dddsample/application/BookingServiceTest.java
  2. 22
    23
      dddsample/src/test/java/se/citerus/dddsample/application/HandlingEventServiceTest.java
  3. 2
    2
      dddsample/src/test/java/se/citerus/dddsample/application/RoutingServiceTest.java
  4. 0
    25
      dddsample/src/test/java/se/citerus/dddsample/application/service/InMemTransactionManager.java
  5. 6
    5
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/CargoRepositoryTest.java
  6. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/CargoRepositoryInMem.java
  7. 1
    1
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/HandlingEventRepositoryInMem.java
  8. 2
    2
      dddsample/src/test/java/se/citerus/dddsample/infrastructure/routing/ExternalRoutingServiceTest.java
  9. 4
    8
      dddsample/src/test/java/se/citerus/dddsample/interfaces/booking/facade/dto/assembler/CargoRoutingDTOAssemblerTest.java
  10. 1
    2
      dddsample/src/test/java/se/citerus/dddsample/interfaces/booking/facade/dto/assembler/ItineraryCandidateDTOAssemblerTest.java
  11. 1
    2
      dddsample/src/test/java/se/citerus/dddsample/interfaces/booking/facade/dto/assembler/LocationDTOAssemblerTest.java
  12. 2
    1
      dddsample/src/test/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingViewAdapterTest.java
  13. 262
    0
      dddsample/src/test/java/se/citerus/dddsample/scenario/CargoLifecycleScenarioTest.java
  14. 0
    67
      dddsample/src/test/java/se/citerus/dddsample/scenario/TrackingScenarioTest.java
  15. 2
    2
      dddsample/src/test/resources/handling_events.csv

+ 6
- 4
dddsample/src/test/java/se/citerus/dddsample/application/BookingServiceTest.java Wyświetl plik

@@ -12,9 +12,11 @@ import static se.citerus.dddsample.domain.model.location.SampleLocations.STOCKHO
12 12
 import se.citerus.dddsample.domain.model.location.UnLocode;
13 13
 import se.citerus.dddsample.domain.service.RoutingService;
14 14
 
15
+import java.util.Date;
16
+
15 17
 public class BookingServiceTest extends TestCase {
16 18
 
17
-  BookingServiceImpl cargoService;
19
+  BookingServiceImpl bookingService;
18 20
   CargoRepository cargoRepository;
19 21
   LocationRepository locationRepository;
20 22
   RoutingService routingService;
@@ -23,7 +25,7 @@ public class BookingServiceTest extends TestCase {
23 25
     cargoRepository = createMock(CargoRepository.class);
24 26
     locationRepository = createMock(LocationRepository.class);
25 27
     routingService = createMock(RoutingService.class);
26
-    cargoService = new BookingServiceImpl(cargoRepository, locationRepository, routingService);
28
+    bookingService = new BookingServiceImpl(cargoRepository, locationRepository, routingService);
27 29
   }
28 30
 
29 31
   public void testRegisterNew() {
@@ -39,14 +41,14 @@ public class BookingServiceTest extends TestCase {
39 41
 
40 42
     replay(cargoRepository, locationRepository);
41 43
 
42
-    TrackingId trackingId = cargoService.bookNewCargo(fromUnlocode, toUnlocode);
44
+    TrackingId trackingId = bookingService.bookNewCargo(fromUnlocode, toUnlocode, new Date());
43 45
     assertEquals(expectedTrackingId, trackingId);
44 46
   }
45 47
 
46 48
   public void testRegisterNewNullArguments() {
47 49
     replay(cargoRepository, locationRepository);
48 50
     try {
49
-      cargoService.bookNewCargo(null, null);
51
+      bookingService.bookNewCargo(null, null, null);
50 52
       fail("Null arguments should not be allowed");
51 53
     } catch (IllegalArgumentException expected) {}
52 54
   }

+ 22
- 23
dddsample/src/test/java/se/citerus/dddsample/application/HandlingEventServiceTest.java Wyświetl plik

@@ -22,29 +22,28 @@ import java.util.Date;
22 22
 
23 23
 public class HandlingEventServiceTest extends TestCase {
24 24
   private HandlingEventServiceImpl service;
25
-  private SystemEvents systemEvents;
25
+  private ApplicationEvents applicationEvents;
26 26
   private CargoRepository cargoRepository;
27 27
   private VoyageRepository voyageRepository;
28 28
   private HandlingEventRepository handlingEventRepository;
29 29
   private LocationRepository locationRepository;
30 30
   private HandlingEventFactory handlingEventFactory;
31 31
 
32
-  private final Cargo cargoABC = new Cargo(new TrackingId("ABC"), new RouteSpecification(HAMBURG, TOKYO, new Date()));
33
-
34
-  private final Cargo cargoXYZ = new Cargo(new TrackingId("XYZ"), new RouteSpecification(HONGKONG, HELSINKI, new Date()));
32
+  private final Cargo cargoABC = new Cargo(new TrackingId("ABC"), HAMBURG, new RouteSpecification(HAMBURG, TOKYO, new Date()));
33
+  private final Cargo cargoXYZ = new Cargo(new TrackingId("XYZ"), HONGKONG, new RouteSpecification(HONGKONG, HELSINKI, new Date()));
35 34
 
36 35
   protected void setUp() throws Exception{
37 36
     cargoRepository = createMock(CargoRepository.class);
38 37
     voyageRepository = createMock(VoyageRepository.class);
39 38
     handlingEventRepository = createMock(HandlingEventRepository.class);
40 39
     locationRepository = createMock(LocationRepository.class);
41
-    systemEvents = createMock(SystemEvents.class);
40
+    applicationEvents = createMock(ApplicationEvents.class);
42 41
     handlingEventFactory = new HandlingEventFactory(cargoRepository, voyageRepository, locationRepository);
43
-    service = new HandlingEventServiceImpl(handlingEventRepository, systemEvents, handlingEventFactory);
42
+    service = new HandlingEventServiceImpl(handlingEventRepository, applicationEvents, handlingEventFactory);
44 43
   }
45 44
 
46 45
   protected void tearDown() throws Exception {
47
-    verify(cargoRepository, voyageRepository, handlingEventRepository, systemEvents);
46
+    verify(cargoRepository, voyageRepository, handlingEventRepository, applicationEvents);
48 47
   }
49 48
 
50 49
   public void testRegisterEvent() throws Exception {
@@ -59,11 +58,11 @@ public class HandlingEventServiceTest extends TestCase {
59 58
 
60 59
     // TODO: does not inspect the handling event instance in a sufficient way
61 60
     handlingEventRepository.save(isA(HandlingEvent.class));
62
-    systemEvents.cargoWasHandled(isA(HandlingEvent.class));
61
+    applicationEvents.cargoWasHandled(isA(HandlingEvent.class));
63 62
 
64
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
63
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, applicationEvents);
65 64
 
66
-    service.register(new HandlingEventRegistrationAttempt(
65
+    service.registerHandlingEvent(new HandlingEventRegistrationAttempt(
67 66
       new Date(), new Date(), trackingId, voyageNumber, HandlingEvent.Type.LOAD, unLocode
68 67
     ));
69 68
   }
@@ -73,13 +72,13 @@ public class HandlingEventServiceTest extends TestCase {
73 72
     expect(cargoRepository.find(trackingId)).andReturn(cargoABC);
74 73
 
75 74
     handlingEventRepository.save(isA(HandlingEvent.class));
76
-    systemEvents.cargoWasHandled(isA(HandlingEvent.class));
75
+    applicationEvents.cargoWasHandled(isA(HandlingEvent.class));
77 76
 
78 77
     expect(locationRepository.find(STOCKHOLM.unLocode())).andReturn(STOCKHOLM);
79 78
 
80
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
79
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, applicationEvents);
81 80
 
82
-    service.register(new HandlingEventRegistrationAttempt(
81
+    service.registerHandlingEvent(new HandlingEventRegistrationAttempt(
83 82
       new Date(), new Date(), trackingId, null, HandlingEvent.Type.RECEIVE, STOCKHOLM.unLocode()
84 83
     ));
85 84
   }
@@ -90,15 +89,15 @@ public class HandlingEventServiceTest extends TestCase {
90 89
     expect(voyageRepository.find(voyageNumber)).andReturn(null);
91 90
 
92 91
     final TrackingId trackingId = new TrackingId("XYZ");
93
-    expect(cargoRepository.find(trackingId)).andReturn(new Cargo(trackingId, CHICAGO, STOCKHOLM));
92
+    expect(cargoRepository.find(trackingId)).andReturn(new Cargo(trackingId, CHICAGO, new RouteSpecification(CHICAGO, STOCKHOLM, new Date())));
94 93
 
95 94
     expect(locationRepository.find(MELBOURNE.unLocode())).andReturn(MELBOURNE);
96 95
 
97
-    systemEvents.rejectHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
96
+    applicationEvents.rejectedHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
98 97
 
99
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
98
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, applicationEvents);
100 99
     
101
-    service.register(new HandlingEventRegistrationAttempt(
100
+    service.registerHandlingEvent(new HandlingEventRegistrationAttempt(
102 101
       new Date(), new Date(), trackingId, voyageNumber, HandlingEvent.Type.UNLOAD, MELBOURNE.unLocode()
103 102
     ));
104 103
   }
@@ -109,11 +108,11 @@ public class HandlingEventServiceTest extends TestCase {
109 108
 
110 109
     expect(locationRepository.find(HONGKONG.unLocode())).andReturn(HONGKONG);
111 110
 
112
-    systemEvents.rejectHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
111
+    applicationEvents.rejectedHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
113 112
 
114
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
113
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, applicationEvents);
115 114
     
116
-      service.register(new HandlingEventRegistrationAttempt(
115
+      service.registerHandlingEvent(new HandlingEventRegistrationAttempt(
117 116
         new Date(), new Date(), trackingId, new VoyageNumber("V001"), HandlingEvent.Type.CLAIM, HONGKONG.unLocode()
118 117
       ));
119 118
   }
@@ -124,11 +123,11 @@ public class HandlingEventServiceTest extends TestCase {
124 123
     UnLocode wayOff = new UnLocode("XXYYY");
125 124
     expect(locationRepository.find(wayOff)).andReturn(null);
126 125
 
127
-    systemEvents.rejectHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
126
+    applicationEvents.rejectedHandlingEventRegistrationAttempt(isA(HandlingEventRegistrationAttempt.class), isA(CannotCreateHandlingEventException.class));
128 127
 
129
-    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, systemEvents);
128
+    replay(cargoRepository, voyageRepository, handlingEventRepository, locationRepository, applicationEvents);
130 129
     
131
-    service.register(new HandlingEventRegistrationAttempt(
130
+    service.registerHandlingEvent(new HandlingEventRegistrationAttempt(
132 131
       new Date(), new Date(), trackingId, null, HandlingEvent.Type.CLAIM, wayOff
133 132
     ));
134 133
   }

+ 2
- 2
dddsample/src/test/java/se/citerus/dddsample/application/RoutingServiceTest.java Wyświetl plik

@@ -47,7 +47,7 @@ public class RoutingServiceTest extends TestCase {
47 47
   public void testCalculatePossibleRoutes() {
48 48
     TrackingId trackingId = new TrackingId("ABC");
49 49
     RouteSpecification routeSpecification = new RouteSpecification(HONGKONG, HELSINKI, new Date());
50
-    Cargo cargo = new Cargo(trackingId, routeSpecification);
50
+    Cargo cargo = new Cargo(trackingId, HONGKONG, routeSpecification);
51 51
 
52 52
     expect(voyageRepository.find(isA(VoyageNumber.class))).andStubReturn(SampleVoyages.CM002);
53 53
     
@@ -66,7 +66,7 @@ public class RoutingServiceTest extends TestCase {
66 66
 
67 67
       // Cargo final destination and last leg stop should match
68 68
       Location lastLegStop = legs.get(legs.size() - 1).unloadLocation();
69
-      assertEquals(cargo.destination(), lastLegStop);
69
+      assertEquals(cargo.routeSpecification().destination(), lastLegStop);
70 70
 
71 71
       for (int i = 0; i < legs.size() - 1; i++) {
72 72
         // Assert that all legs are conencted

+ 0
- 25
dddsample/src/test/java/se/citerus/dddsample/application/service/InMemTransactionManager.java Wyświetl plik

@@ -1,25 +0,0 @@
1
-package se.citerus.dddsample.application.service;
2
-
3
-import org.springframework.transaction.PlatformTransactionManager;
4
-import org.springframework.transaction.TransactionDefinition;
5
-import org.springframework.transaction.TransactionException;
6
-import org.springframework.transaction.TransactionStatus;
7
-import org.springframework.transaction.support.SimpleTransactionStatus;
8
-
9
-/**
10
- * Simple no-op transaction manager to allow for in-memory "persistence"
11
- * implementation to be plugged in transparently.
12
- */
13
-public class InMemTransactionManager implements PlatformTransactionManager {
14
-
15
-  public TransactionStatus getTransaction(TransactionDefinition transactionDefinition) throws TransactionException {
16
-    return new SimpleTransactionStatus();
17
-  }
18
-
19
-  public void commit(TransactionStatus transactionStatus) throws TransactionException {
20
-  }
21
-
22
-  public void rollback(TransactionStatus transactionStatus) throws TransactionException {
23
-  }
24
-
25
-}

+ 6
- 5
dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/hibernate/CargoRepositoryTest.java Wyświetl plik

@@ -39,8 +39,9 @@ public class CargoRepositoryTest extends AbstractRepositoryTest {
39 39
 
40 40
   public void testFindByCargoId() {
41 41
     Cargo cargo = cargoRepository.find(new TrackingId("FGH"));
42
-    assertEquals(HONGKONG, cargo.origin());
43
-    assertEquals(HELSINKI, cargo.destination());
42
+    assertEquals(STOCKHOLM, cargo.origin());
43
+    assertEquals(HONGKONG, cargo.routeSpecification().origin());
44
+    assertEquals(HELSINKI, cargo.routeSpecification().destination());
44 45
 
45 46
     assertNotNull(cargo.delivery());
46 47
 
@@ -103,7 +104,7 @@ public class CargoRepositoryTest extends AbstractRepositoryTest {
103 104
     Location origin = locationRepository.find(STOCKHOLM.unLocode());
104 105
     Location destination = locationRepository.find(MELBOURNE.unLocode());
105 106
 
106
-    Cargo cargo = new Cargo(trackingId, origin, destination);
107
+    Cargo cargo = new Cargo(trackingId, origin, new RouteSpecification(origin, destination, new Date()));
107 108
     cargoRepository.save(cargo);
108 109
 
109 110
     flush();
@@ -114,10 +115,10 @@ public class CargoRepositoryTest extends AbstractRepositoryTest {
114 115
     assertEquals("AAA", map.get("TRACKING_ID"));
115 116
 
116 117
     Long originId = getLongId(origin);
117
-    assertEquals(originId, map.get("ORIGIN_ID"));
118
+    assertEquals(originId, map.get("SPEC_ORIGIN_ID"));
118 119
 
119 120
     Long destinationId = getLongId(destination);
120
-    assertEquals(destinationId, map.get("DESTINATION_ID"));
121
+    assertEquals(destinationId, map.get("SPEC_DESTINATION_ID"));
121 122
   }
122 123
 
123 124
   public void testReplaceItinerary() {

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/CargoRepositoryInMem.java Wyświetl plik

@@ -40,7 +40,7 @@ public class CargoRepositoryInMem implements CargoRepository {
40 40
   }
41 41
 
42 42
   public void save(final Cargo cargo) {
43
-    //No need to save anything with InMem
43
+    cargoDb.put(cargo.trackingId().idString(), cargo);
44 44
   }
45 45
 
46 46
   public TrackingId nextTrackingId() {

+ 1
- 1
dddsample/src/test/java/se/citerus/dddsample/infrastructure/persistence/inmemory/HandlingEventRepositoryInMem.java Wyświetl plik

@@ -73,7 +73,7 @@ public class HandlingEventRepositoryInMem implements HandlingEventRepository {
73 73
 
74 74
   private void registerEvent(Cargo cargo, String date, HandlingEvent.Type type, CarrierMovement carrierMovement) throws ParseException {
75 75
     /*
76
-    HandlingEvent event = new HandlingEvent(cargo, getDate(date), new Date(), type, null, carrierMovement);
76
+    HandlingEvent event = new HandlingEvent(cargo, getCompletionTime(date), new Date(), type, null, carrierMovement);
77 77
     String id = cargo.trackingId() + "_" + type + "_" + date;
78 78
 
79 79
     logger.debug("Adding event " + id + "(" + event + ")");

+ 2
- 2
dddsample/src/test/java/se/citerus/dddsample/infrastructure/routing/ExternalRoutingServiceTest.java Wyświetl plik

@@ -46,7 +46,7 @@ public class ExternalRoutingServiceTest extends TestCase {
46 46
   public void testCalculatePossibleRoutes() {
47 47
     TrackingId trackingId = new TrackingId("ABC");
48 48
     RouteSpecification routeSpecification = new RouteSpecification(HONGKONG, HELSINKI, new Date());
49
-    Cargo cargo = new Cargo(trackingId, routeSpecification);
49
+    Cargo cargo = new Cargo(trackingId, HONGKONG, routeSpecification);
50 50
 
51 51
     expect(voyageRepository.find(isA(VoyageNumber.class))).andStubReturn(SampleVoyages.CM002);
52 52
     
@@ -65,7 +65,7 @@ public class ExternalRoutingServiceTest extends TestCase {
65 65
 
66 66
       // Cargo final destination and last leg stop should match
67 67
       Location lastLegStop = legs.get(legs.size() - 1).unloadLocation();
68
-      assertEquals(cargo.destination(), lastLegStop);
68
+      assertEquals(cargo.routeSpecification().destination(), lastLegStop);
69 69
 
70 70
       for (int i = 0; i < legs.size() - 1; i++) {
71 71
         // Assert that all legs are connected

dddsample/src/test/java/se/citerus/dddsample/application/service/dto/assembler/CargoRoutingDTOAssemblerTest.java → dddsample/src/test/java/se/citerus/dddsample/interfaces/booking/facade/dto/assembler/CargoRoutingDTOAssemblerTest.java Wyświetl plik

@@ -1,16 +1,12 @@
1
-package se.citerus.dddsample.application.service.dto.assembler;
1
+package se.citerus.dddsample.interfaces.booking.facade.dto.assembler;
2 2
 
3 3
 import junit.framework.TestCase;
4
-import se.citerus.dddsample.domain.model.cargo.Cargo;
5
-import se.citerus.dddsample.domain.model.cargo.Itinerary;
6
-import se.citerus.dddsample.domain.model.cargo.Leg;
7
-import se.citerus.dddsample.domain.model.cargo.TrackingId;
4
+import se.citerus.dddsample.domain.model.cargo.*;
8 5
 import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.CM001;
9 6
 import se.citerus.dddsample.domain.model.location.Location;
10 7
 import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
11 8
 import se.citerus.dddsample.interfaces.booking.facade.dto.CargoRoutingDTO;
12 9
 import se.citerus.dddsample.interfaces.booking.facade.dto.LegDTO;
13
-import se.citerus.dddsample.interfaces.booking.facade.dto.assembler.CargoRoutingDTOAssembler;
14 10
 
15 11
 import java.util.Arrays;
16 12
 import java.util.Date;
@@ -22,7 +18,7 @@ public class CargoRoutingDTOAssemblerTest extends TestCase {
22 18
 
23 19
     final Location origin = STOCKHOLM;
24 20
     final Location destination = MELBOURNE;
25
-    final Cargo cargo = new Cargo(new TrackingId("XYZ"), origin, destination);
21
+    final Cargo cargo = new Cargo(new TrackingId("XYZ"), origin, new RouteSpecification(origin, destination, new Date()));
26 22
 
27 23
     final Itinerary itinerary = new Itinerary(
28 24
       Arrays.asList(
@@ -51,7 +47,7 @@ public class CargoRoutingDTOAssemblerTest extends TestCase {
51 47
   public void testToDTO_NoItinerary() throws Exception {
52 48
     final CargoRoutingDTOAssembler assembler = new CargoRoutingDTOAssembler();
53 49
 
54
-    final Cargo cargo = new Cargo(new TrackingId("XYZ"), STOCKHOLM, MELBOURNE);
50
+    final Cargo cargo = new Cargo(new TrackingId("XYZ"), STOCKHOLM, new RouteSpecification(STOCKHOLM, MELBOURNE, new Date()));
55 51
     final CargoRoutingDTO dto = assembler.toDTO(cargo);
56 52
 
57 53
     assertEquals("XYZ", dto.getTrackingId());

dddsample/src/test/java/se/citerus/dddsample/application/service/dto/assembler/ItineraryCandidateDTOAssemblerTest.java → dddsample/src/test/java/se/citerus/dddsample/interfaces/booking/facade/dto/assembler/ItineraryCandidateDTOAssemblerTest.java Wyświetl plik

@@ -1,4 +1,4 @@
1
-package se.citerus.dddsample.application.service.dto.assembler;
1
+package se.citerus.dddsample.interfaces.booking.facade.dto.assembler;
2 2
 
3 3
 import junit.framework.TestCase;
4 4
 import static org.easymock.EasyMock.*;
@@ -13,7 +13,6 @@ import se.citerus.dddsample.domain.model.location.UnLocode;
13 13
 import se.citerus.dddsample.infrastructure.persistence.inmemory.VoyageRepositoryInMem;
14 14
 import se.citerus.dddsample.interfaces.booking.facade.dto.ItineraryCandidateDTO;
15 15
 import se.citerus.dddsample.interfaces.booking.facade.dto.LegDTO;
16
-import se.citerus.dddsample.interfaces.booking.facade.dto.assembler.ItineraryCandidateDTOAssembler;
17 16
 
18 17
 import java.util.ArrayList;
19 18
 import java.util.Arrays;

dddsample/src/test/java/se/citerus/dddsample/application/service/dto/assembler/LocationDTOAssemblerTest.java → dddsample/src/test/java/se/citerus/dddsample/interfaces/booking/facade/dto/assembler/LocationDTOAssemblerTest.java Wyświetl plik

@@ -1,11 +1,10 @@
1
-package se.citerus.dddsample.application.service.dto.assembler;
1
+package se.citerus.dddsample.interfaces.booking.facade.dto.assembler;
2 2
 
3 3
 import junit.framework.TestCase;
4 4
 import se.citerus.dddsample.domain.model.location.Location;
5 5
 import static se.citerus.dddsample.domain.model.location.SampleLocations.HAMBURG;
6 6
 import static se.citerus.dddsample.domain.model.location.SampleLocations.STOCKHOLM;
7 7
 import se.citerus.dddsample.interfaces.booking.facade.dto.LocationDTO;
8
-import se.citerus.dddsample.interfaces.booking.facade.dto.assembler.LocationDTOAssembler;
9 8
 
10 9
 import java.util.Arrays;
11 10
 import java.util.List;

+ 2
- 1
dddsample/src/test/java/se/citerus/dddsample/interfaces/tracking/CargoTrackingViewAdapterTest.java Wyświetl plik

@@ -4,6 +4,7 @@ import junit.framework.TestCase;
4 4
 import org.springframework.context.support.StaticApplicationContext;
5 5
 import se.citerus.dddsample.domain.model.cargo.Cargo;
6 6
 import se.citerus.dddsample.domain.model.cargo.CargoTestHelper;
7
+import se.citerus.dddsample.domain.model.cargo.RouteSpecification;
7 8
 import se.citerus.dddsample.domain.model.cargo.TrackingId;
8 9
 import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.CM001;
9 10
 import se.citerus.dddsample.domain.model.handling.HandlingEvent;
@@ -15,7 +16,7 @@ import java.util.*;
15 16
 public class CargoTrackingViewAdapterTest extends TestCase {
16 17
 
17 18
   public void testCreate() {
18
-    Cargo cargo = new Cargo(new TrackingId("XYZ"), HANGZOU, HELSINKI);
19
+    Cargo cargo = new Cargo(new TrackingId("XYZ"), HANGZOU, new RouteSpecification(HANGZOU, HELSINKI, new Date()));
19 20
 
20 21
     List<HandlingEvent> events = new ArrayList<HandlingEvent>();
21 22
     events.add(new HandlingEvent(cargo, new Date(1), new Date(2), HandlingEvent.Type.RECEIVE, HANGZOU));

+ 262
- 0
dddsample/src/test/java/se/citerus/dddsample/scenario/CargoLifecycleScenarioTest.java Wyświetl plik

@@ -0,0 +1,262 @@
1
+package se.citerus.dddsample.scenario;
2
+
3
+import junit.framework.TestCase;
4
+import se.citerus.dddsample.application.*;
5
+import se.citerus.dddsample.application.impl.BookingServiceImpl;
6
+import se.citerus.dddsample.application.impl.HandlingEventServiceImpl;
7
+import se.citerus.dddsample.application.impl.TrackingServiceImpl;
8
+import se.citerus.dddsample.domain.model.cargo.*;
9
+import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.*;
10
+import se.citerus.dddsample.domain.model.carrier.Voyage;
11
+import se.citerus.dddsample.domain.model.carrier.VoyageNumber;
12
+import se.citerus.dddsample.domain.model.carrier.VoyageRepository;
13
+import se.citerus.dddsample.domain.model.handling.CannotCreateHandlingEventException;
14
+import se.citerus.dddsample.domain.model.handling.HandlingEvent;
15
+import static se.citerus.dddsample.domain.model.handling.HandlingEvent.Type.*;
16
+import se.citerus.dddsample.domain.model.handling.HandlingEventFactory;
17
+import se.citerus.dddsample.domain.model.handling.HandlingEventRepository;
18
+import se.citerus.dddsample.domain.model.location.Location;
19
+import se.citerus.dddsample.domain.model.location.LocationRepository;
20
+import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
21
+import se.citerus.dddsample.domain.model.location.UnLocode;
22
+import se.citerus.dddsample.domain.service.RoutingService;
23
+import se.citerus.dddsample.infrastructure.persistence.inmemory.CargoRepositoryInMem;
24
+import se.citerus.dddsample.infrastructure.persistence.inmemory.LocationRepositoryInMem;
25
+import se.citerus.dddsample.infrastructure.persistence.inmemory.VoyageRepositoryInMem;
26
+
27
+import java.util.*;
28
+
29
+/**
30
+ * Cargo scenarios.
31
+ */
32
+public class CargoLifecycleScenarioTest extends TestCase {
33
+
34
+  HandlingEventFactory handlingEventFactory;
35
+
36
+  ApplicationEvents applicationEvents;
37
+
38
+  BookingService bookingService;
39
+  HandlingEventService handlingEventService;
40
+  TrackingService trackingService;
41
+  RoutingService routingService;
42
+
43
+  HandlingEventRepository handlingEventRepository;
44
+  CargoRepository cargoRepository;
45
+  LocationRepository locationRepository;
46
+  VoyageRepository voyageRepository;
47
+
48
+  public void testCargoFromHongkongToStockholm() throws Exception {
49
+    /* Test setup: A cargo should be shipped from Hongkong to Stockholm,
50
+       and it should arrive in no more than two weeks. */
51
+    Location origin = HONGKONG;
52
+    Location destination = STOCKHOLM;
53
+    Date arrivalDeadline = inTwoWeeks();
54
+
55
+    /* Use case 1: booking
56
+
57
+       A new cargo is booked, and the unique tracking id is returned. */
58
+    TrackingId trackingId = bookingService.bookNewCargo(
59
+      origin.unLocode(), destination.unLocode(), arrivalDeadline
60
+    );
61
+
62
+    /* The tracking id can be used to lookup the cargo in the repository.
63
+
64
+       Important: The cargo, and thus the domain model, is responsible for determining
65
+       the status of the cargo, whether it is on the right track or not and so on.
66
+       This is core domain logic.
67
+
68
+       Tracking the cargo basically amounts to presenting information extracted from
69
+       the cargo aggregate in a suitable way. */
70
+    Cargo cargo = cargoRepository.find(trackingId);
71
+    assertNotNull(cargo);
72
+    assertEquals(TransportStatus.NOT_RECEIVED, cargo.delivery().transportStatus());
73
+    assertEquals(RoutingStatus.NOT_ROUTED, cargo.routingStatus());
74
+    assertFalse(cargo.isMisdirected());
75
+
76
+
77
+    /* Use case 2: routing
78
+
79
+       A number of possible routes for this cargo is requested and may be
80
+       presented to the customer in some way for him/her to choose from.
81
+       Selection could be affected by things like price and time of delivery,
82
+       but this test simply uses an arbitrary selection to mimic that process.
83
+
84
+       The cargo is then assigned to the selected route, described by an itinerary. */
85
+    List<Itinerary> itineraries = bookingService.requestPossibleRoutesForCargo(trackingId);
86
+    Itinerary itinerary = selectPreferedItinerary(itineraries);
87
+    cargo.assignToRoute(itinerary);
88
+
89
+    assertEquals(RoutingStatus.ROUTED, cargo.routingStatus());
90
+
91
+    /*
92
+      Use case 3: handling
93
+
94
+      A handling event registration attempt will be formed from parsing
95
+      the data coming in as a handling report either via
96
+      the web service interface or as an uploaded CSV file.
97
+
98
+      The handling event factory tries to create a HandlingEvent from the attempt,
99
+      and if the factory decides that this is a plausible handling event, it is stored.
100
+      If the attempt is invalid, for example if no cargo exists for the specfied tracking id,
101
+      the attempt is rejected.
102
+
103
+      Handling begins: cargo is received in Hongkong.
104
+      */
105
+    HandlingEventRegistrationAttempt attempt1 = new HandlingEventRegistrationAttempt(
106
+      new Date(), new Date(), trackingId, null, RECEIVE, HONGKONG.unLocode()
107
+    );
108
+    handlingEventService.registerHandlingEvent(attempt1);
109
+
110
+    // Next event: Load onto voyage CM003 in Hongkong
111
+    handlingEventService.registerHandlingEvent(new HandlingEventRegistrationAttempt(
112
+      new Date(), new Date(), trackingId, CM003.voyageNumber(), LOAD, HONGKONG.unLocode()
113
+    ));
114
+
115
+    // Check current state - should be ok
116
+    assertEquals(CM003, cargo.delivery().currentVoyage());
117
+    assertEquals(HONGKONG, cargo.delivery().lastKnownLocation());
118
+    assertEquals(TransportStatus.ONBOARD_CARRIER, cargo.delivery().transportStatus());
119
+    assertFalse(cargo.isMisdirected());
120
+
121
+    /*
122
+      Here's an attempt to register a handling event that's not valid
123
+      because there is no voyage with the specified voyage number,
124
+      and there's no location with the specified UN Locode either.
125
+
126
+      This attempt will be rejected and will not affet the cargo delivery in any way.
127
+     */
128
+    VoyageNumber noSuchVoyageNumber = new VoyageNumber("XX000");
129
+    UnLocode noSuchUnLocode = new UnLocode("ZZZZZ");
130
+    HandlingEventRegistrationAttempt failedAttempt = new HandlingEventRegistrationAttempt(
131
+      new Date(), new Date(), trackingId, noSuchVoyageNumber, LOAD, noSuchUnLocode
132
+    );
133
+    handlingEventService.registerHandlingEvent(failedAttempt);
134
+
135
+
136
+    // Cargo is now (incorrectly) unloaded in Tokyo
137
+    handlingEventService.registerHandlingEvent(new HandlingEventRegistrationAttempt(
138
+      new Date(), new Date(), trackingId, CM003.voyageNumber(), UNLOAD, TOKYO.unLocode()
139
+    ));
140
+
141
+    // Check current state - cargo is misdirected!
142
+    assertEquals(Voyage.NONE, cargo.delivery().currentVoyage());
143
+    assertEquals(TOKYO, cargo.delivery().lastKnownLocation());
144
+    assertEquals(TransportStatus.IN_PORT, cargo.delivery().transportStatus());
145
+    assertTrue(cargo.isMisdirected());
146
+
147
+    // Specify a new route, this time from Tokyo (where it was incorrectly unloaded) to Stockholm
148
+    RouteSpecification fromTokyo = new RouteSpecification(TOKYO, STOCKHOLM, arrivalDeadline);
149
+    cargo.specifyRoute(fromTokyo);
150
+
151
+    // The old itinerary does not satisfy the new specification
152
+    // TODO won't work until .isSatisfied() is implemented 
153
+    //assertEquals(RoutingStatus.MISROUTED, cargo.routingStatus());
154
+
155
+    // Repeat procedure of selecting one out of a number of possible routes satisfying the route spec
156
+    List<Itinerary> newItineraries = bookingService.requestPossibleRoutesForCargo(cargo.trackingId());
157
+    Itinerary newItinerary = selectPreferedItinerary(newItineraries);
158
+    cargo.assignToRoute(newItinerary);
159
+
160
+    // New itinerary should satisfy new route
161
+    assertEquals(RoutingStatus.ROUTED, cargo.routingStatus());
162
+
163
+    
164
+    // TODO handling from Tokyo to Stockholm
165
+  }
166
+
167
+  /*
168
+  * Utility stubs below.
169
+  */
170
+
171
+  private Date inTwoWeeks() {
172
+    return new Date(new Date().getTime() + 1000 * 60 * 60 * 24 * 14);
173
+  }
174
+
175
+  private Itinerary selectPreferedItinerary(List<Itinerary> itineraries) {
176
+    return itineraries.get(0);
177
+  }
178
+
179
+  protected void setUp() throws Exception {
180
+    // Stub
181
+    // TODO new voyages
182
+    routingService = new RoutingService() {
183
+      public List<Itinerary> fetchRoutesForSpecification(RouteSpecification routeSpecification) {
184
+        if (routeSpecification.origin().equals(HONGKONG)) {
185
+          // Hongkong - NYC - Chicago - Stockholm, initial routing
186
+          return Arrays.asList(
187
+            new Itinerary(Arrays.asList(
188
+              new Leg(CM003, HONGKONG, NEWYORK, new Date(), new Date()),
189
+              new Leg(CM004, NEWYORK, CHICAGO, new Date(), new Date()),
190
+              new Leg(CM005, CHICAGO, STOCKHOLM, new Date(), new Date())
191
+            ))
192
+          );
193
+        } else {
194
+          // Tokyo - Hamburg - Stockholm, rerouting
195
+          return Arrays.asList(
196
+            new Itinerary(Arrays.asList(
197
+              new Leg(CM003, TOKYO, HAMBURG, new Date(), new Date()),
198
+              new Leg(CM005, HAMBURG, STOCKHOLM, new Date(), new Date())
199
+            ))
200
+          );
201
+        }
202
+      }
203
+    };
204
+
205
+
206
+    applicationEvents = new SynchronousApplicationEventsStub();
207
+
208
+    // Stub
209
+    // TODO move functionality to in-mem impl
210
+    handlingEventRepository = new HandlingEventRepository() {
211
+      public void save(HandlingEvent event) {
212
+        Cargo cargo = event.cargo();
213
+        Set<HandlingEvent> events = new HashSet<HandlingEvent>(cargo.delivery().history());
214
+        events.add(event);
215
+        CargoTestHelper.setDeliveryHistory(cargo, events);
216
+      }
217
+
218
+      public List<HandlingEvent> findEventsForCargo(TrackingId trackingId) {
219
+        return null;
220
+      }
221
+    };
222
+
223
+    // In-memory implementations
224
+    cargoRepository = new CargoRepositoryInMem();
225
+    locationRepository = new LocationRepositoryInMem();
226
+    voyageRepository = new VoyageRepositoryInMem();
227
+
228
+    // Actual factories and application services, wired with stubbed or in-memory infrastructure
229
+    trackingService = new TrackingServiceImpl(applicationEvents, cargoRepository);
230
+    handlingEventFactory = new HandlingEventFactory(cargoRepository, voyageRepository, locationRepository);
231
+    handlingEventService = new HandlingEventServiceImpl(handlingEventRepository, applicationEvents, handlingEventFactory);
232
+    bookingService = new BookingServiceImpl(cargoRepository, locationRepository, routingService);
233
+  }
234
+
235
+  private class SynchronousApplicationEventsStub implements ApplicationEvents {
236
+    @Override
237
+    public void cargoWasHandled(HandlingEvent event) {
238
+      System.out.println("EVENT: cargo was handled: " + event);
239
+      trackingService.inspectCargo(event.cargo().trackingId());
240
+    }
241
+
242
+    @Override
243
+    public void cargoWasMisdirected(Cargo cargo) {
244
+      System.out.println("EVENT: cargo was misdirected");
245
+    }
246
+
247
+    @Override
248
+    public void cargoHasArrived(Cargo cargo) {
249
+      System.out.println("EVENT: cargo has arrived: " + cargo.trackingId().idString());
250
+    }
251
+
252
+    @Override
253
+    public void rejectedHandlingEventRegistrationAttempt(HandlingEventRegistrationAttempt attempt, CannotCreateHandlingEventException problem) {
254
+      System.out.println("EVENT: rejected handling event registration attempt: " + problem);
255
+    }
256
+
257
+    @Override
258
+    public void receivedHandlingEventRegistrationAttempt(HandlingEventRegistrationAttempt attempt) {
259
+      System.out.println("EVENT: received handling event registration attempt");
260
+    }
261
+  }
262
+}

+ 0
- 67
dddsample/src/test/java/se/citerus/dddsample/scenario/TrackingScenarioTest.java Wyświetl plik

@@ -1,67 +0,0 @@
1
-package se.citerus.dddsample.scenario;
2
-
3
-import junit.framework.TestCase;
4
-import se.citerus.dddsample.domain.model.cargo.*;
5
-import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.CM001;
6
-import static se.citerus.dddsample.domain.model.carrier.SampleVoyages.CM002;
7
-import se.citerus.dddsample.domain.model.handling.HandlingEvent;
8
-import static se.citerus.dddsample.domain.model.handling.HandlingEvent.Type.LOAD;
9
-import static se.citerus.dddsample.domain.model.handling.HandlingEvent.Type.UNLOAD;
10
-import static se.citerus.dddsample.domain.model.location.SampleLocations.*;
11
-
12
-import java.text.DateFormat;
13
-import java.text.ParseException;
14
-import java.text.SimpleDateFormat;
15
-import java.util.Arrays;
16
-import java.util.Date;
17
-import java.util.List;
18
-
19
-public class TrackingScenarioTest extends TestCase {
20
-
21
-  public void testTrackingScenarioStage1() throws Exception {
22
-
23
-    Cargo cargo = populateCargo();
24
-
25
-    Delivery delivery = cargo.delivery();
26
-
27
-    List<HandlingEvent> handlingEvents = delivery.history();
28
-
29
-    assertEquals(4, handlingEvents.size());
30
-    final HandlingEvent event = delivery.lastEvent();
31
-
32
-    assertEquals(UNLOAD, event.type());
33
-
34
-//    assertFalse(cargo.atFinalDestiation());
35
-//    assertEquals("CNHKG", cargo.currentLocation().unlocode());
36
-
37
-  }
38
-
39
-  private Cargo populateCargo() throws Exception {
40
-    final TrackingId trackingId = new TrackingId("XYZ");
41
-    final RouteSpecification routeSpecification = new RouteSpecification(STOCKHOLM, MELBOURNE, new Date());
42
-    final Cargo cargo = new Cargo(trackingId, routeSpecification);
43
-
44
-    final List<HandlingEvent> handlingEventList = Arrays.asList(
45
-      new HandlingEvent(cargo, getDate("2007-12-01"), new Date(), LOAD, STOCKHOLM, CM001),
46
-      new HandlingEvent(cargo, getDate("2007-12-02"), new Date(), UNLOAD, HAMBURG, CM001),
47
-      new HandlingEvent(cargo, getDate("2007-12-03"), new Date(), LOAD, HAMBURG, CM002),
48
-      new HandlingEvent(cargo, getDate("2007-12-05"), new Date(), UNLOAD, HONGKONG, CM002)
49
-    );
50
-    CargoTestHelper.setDeliveryHistory(cargo, handlingEventList);
51
-
52
-    return cargo;
53
-  }
54
-
55
-  /**
56
-   * Parse an ISO 8601 (YYYY-MM-DD) String to Date
57
-   *
58
-   * @param isoFormat String to parse.
59
-   * @return Created date instance.
60
-   * @throws ParseException Thrown if parsing fails.
61
-   */
62
-  private Date getDate(String isoFormat) throws ParseException {
63
-    final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
64
-    return dateFormat.parse(isoFormat);
65
-  }
66
-
67
-}

+ 2
- 2
dddsample/src/test/resources/handling_events.csv Wyświetl plik

@@ -1,3 +1,3 @@
1
-2008-10-29 12:30:00.000	ZYX	V100	SESTO	LOAD
2
-2008-10-31 04:00:00.000	ZYX	V100	HELSINKI	UNLOAD
1
+2008-10-29 12:30:00.000	ZYX	0202	SESTO	LOAD
2
+2008-10-31 04:00:00.000	ZYX	V100	FIHEL	UNLOAD
3 3
 2008-10-31 08:12:00.000	ZYX	HELSINKI	UNLOAD