Rename API in line with adjusted approach

Change PlaceOrderCommand/OrderPlacedEvent to
CreateOrderCommand/OrderCreatedEvent. Placed suggests it is already
placed, meaning products cannot be changed. However with the new
OrderLine member and its operations it's no longer correct to state the
order placed upon creation. Furthermore, the OrderedProduct is no longer
 a single product, but contains several. Renaming this to Order is more
 in line with what this query model resembles

#BAEL-4767
This commit is contained in:
Steven van Beelen 2021-03-19 11:35:31 +01:00
parent 70189df008
commit 2b351eda7a
10 changed files with 149 additions and 151 deletions

View File

@ -2,10 +2,10 @@ package com.baeldung.axon.commandmodel.order;
import com.baeldung.axon.coreapi.commands.AddProductCommand; import com.baeldung.axon.coreapi.commands.AddProductCommand;
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand; import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand; import com.baeldung.axon.coreapi.commands.CreateOrderCommand;
import com.baeldung.axon.coreapi.commands.ShipOrderCommand; import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent; import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
import com.baeldung.axon.coreapi.events.OrderPlacedEvent; import com.baeldung.axon.coreapi.events.OrderCreatedEvent;
import com.baeldung.axon.coreapi.events.OrderShippedEvent; import com.baeldung.axon.coreapi.events.OrderShippedEvent;
import com.baeldung.axon.coreapi.events.ProductAddedEvent; import com.baeldung.axon.coreapi.events.ProductAddedEvent;
import com.baeldung.axon.coreapi.events.ProductRemovedEvent; import com.baeldung.axon.coreapi.events.ProductRemovedEvent;
@ -34,8 +34,8 @@ public class OrderAggregate {
private Map<String, OrderLine> orderLines; private Map<String, OrderLine> orderLines;
@CommandHandler @CommandHandler
public OrderAggregate(PlaceOrderCommand command) { public OrderAggregate(CreateOrderCommand command) {
apply(new OrderPlacedEvent(command.getOrderId())); apply(new OrderCreatedEvent(command.getOrderId()));
} }
@CommandHandler @CommandHandler
@ -70,7 +70,7 @@ public class OrderAggregate {
} }
@EventSourcingHandler @EventSourcingHandler
public void on(OrderPlacedEvent event) { public void on(OrderCreatedEvent event) {
this.orderId = event.getOrderId(); this.orderId = event.getOrderId();
this.orderConfirmed = false; this.orderConfirmed = false;
this.orderLines = new HashMap<>(); this.orderLines = new HashMap<>();

View File

@ -4,12 +4,12 @@ import org.axonframework.modelling.command.TargetAggregateIdentifier;
import java.util.Objects; import java.util.Objects;
public class PlaceOrderCommand { public class CreateOrderCommand {
@TargetAggregateIdentifier @TargetAggregateIdentifier
private final String orderId; private final String orderId;
public PlaceOrderCommand(String orderId) { public CreateOrderCommand(String orderId) {
this.orderId = orderId; this.orderId = orderId;
} }
@ -25,7 +25,7 @@ public class PlaceOrderCommand {
if (o == null || getClass() != o.getClass()) { if (o == null || getClass() != o.getClass()) {
return false; return false;
} }
PlaceOrderCommand that = (PlaceOrderCommand) o; CreateOrderCommand that = (CreateOrderCommand) o;
return Objects.equals(orderId, that.orderId); return Objects.equals(orderId, that.orderId);
} }
@ -36,7 +36,7 @@ public class PlaceOrderCommand {
@Override @Override
public String toString() { public String toString() {
return "PlaceOrderCommand{" + return "CreateOrderCommand{" +
"orderId='" + orderId + '\'' + "orderId='" + orderId + '\'' +
'}'; '}';
} }

View File

@ -2,11 +2,11 @@ package com.baeldung.axon.coreapi.events;
import java.util.Objects; import java.util.Objects;
public class OrderPlacedEvent { public class OrderCreatedEvent {
private final String orderId; private final String orderId;
public OrderPlacedEvent(String orderId) { public OrderCreatedEvent(String orderId) {
this.orderId = orderId; this.orderId = orderId;
} }
@ -22,7 +22,7 @@ public class OrderPlacedEvent {
if (o == null || getClass() != o.getClass()) { if (o == null || getClass() != o.getClass()) {
return false; return false;
} }
OrderPlacedEvent that = (OrderPlacedEvent) o; OrderCreatedEvent that = (OrderCreatedEvent) o;
return Objects.equals(orderId, that.orderId); return Objects.equals(orderId, that.orderId);
} }
@ -33,7 +33,7 @@ public class OrderPlacedEvent {
@Override @Override
public String toString() { public String toString() {
return "OrderPlacedEvent{" + return "OrderCreatedEvent{" +
"orderId='" + orderId + '\'' + "orderId='" + orderId + '\'' +
'}'; '}';
} }

View File

@ -4,16 +4,16 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
public class OrderedProduct { public class Order {
private final String orderId; private final String orderId;
private final Map<String, Integer> products; private final Map<String, Integer> products;
private OrderStatus orderStatus; private OrderStatus orderStatus;
public OrderedProduct(String orderId) { public Order(String orderId) {
this.orderId = orderId; this.orderId = orderId;
this.products = new HashMap<>(); this.products = new HashMap<>();
orderStatus = OrderStatus.PLACED; orderStatus = OrderStatus.CREATED;
} }
public String getOrderId() { public String getOrderId() {
@ -61,8 +61,9 @@ public class OrderedProduct {
if (o == null || getClass() != o.getClass()) { if (o == null || getClass() != o.getClass()) {
return false; return false;
} }
OrderedProduct that = (OrderedProduct) o; Order that = (Order) o;
return Objects.equals(orderId, that.orderId) && Objects.equals(products, that.products) return Objects.equals(orderId, that.orderId)
&& Objects.equals(products, that.products)
&& orderStatus == that.orderStatus; && orderStatus == that.orderStatus;
} }
@ -73,7 +74,7 @@ public class OrderedProduct {
@Override @Override
public String toString() { public String toString() {
return "OrderedProduct{" + return "Order{" +
"orderId='" + orderId + '\'' + "orderId='" + orderId + '\'' +
", products=" + products + ", products=" + products +
", orderStatus=" + orderStatus + ", orderStatus=" + orderStatus +

View File

@ -2,6 +2,5 @@ package com.baeldung.axon.coreapi.queries;
public enum OrderStatus { public enum OrderStatus {
PLACED, CONFIRMED, SHIPPED CREATED, CONFIRMED, SHIPPED
} }

View File

@ -2,12 +2,12 @@ package com.baeldung.axon.gui;
import com.baeldung.axon.coreapi.commands.AddProductCommand; import com.baeldung.axon.coreapi.commands.AddProductCommand;
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand; import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
import com.baeldung.axon.coreapi.commands.CreateOrderCommand;
import com.baeldung.axon.coreapi.commands.DecrementProductCountCommand; import com.baeldung.axon.coreapi.commands.DecrementProductCountCommand;
import com.baeldung.axon.coreapi.commands.IncrementProductCountCommand; import com.baeldung.axon.coreapi.commands.IncrementProductCountCommand;
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
import com.baeldung.axon.coreapi.commands.ShipOrderCommand; import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery; import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
import com.baeldung.axon.coreapi.queries.OrderedProduct; import com.baeldung.axon.coreapi.queries.Order;
import org.axonframework.commandhandling.gateway.CommandGateway; import org.axonframework.commandhandling.gateway.CommandGateway;
import org.axonframework.messaging.responsetypes.ResponseTypes; import org.axonframework.messaging.responsetypes.ResponseTypes;
import org.axonframework.queryhandling.QueryGateway; import org.axonframework.queryhandling.QueryGateway;
@ -34,7 +34,7 @@ public class OrderRestEndpoint {
@PostMapping("/ship-order") @PostMapping("/ship-order")
public void shipOrder() { public void shipOrder() {
String orderId = UUID.randomUUID().toString(); String orderId = UUID.randomUUID().toString();
commandGateway.send(new PlaceOrderCommand(orderId)); commandGateway.send(new CreateOrderCommand(orderId));
commandGateway.send(new AddProductCommand(orderId, "Deluxe Chair")); commandGateway.send(new AddProductCommand(orderId, "Deluxe Chair"));
commandGateway.send(new ConfirmOrderCommand(orderId)); commandGateway.send(new ConfirmOrderCommand(orderId));
commandGateway.send(new ShipOrderCommand(orderId)); commandGateway.send(new ShipOrderCommand(orderId));
@ -43,20 +43,20 @@ public class OrderRestEndpoint {
@PostMapping("/ship-unconfirmed-order") @PostMapping("/ship-unconfirmed-order")
public void shipUnconfirmedOrder() { public void shipUnconfirmedOrder() {
String orderId = UUID.randomUUID().toString(); String orderId = UUID.randomUUID().toString();
commandGateway.send(new PlaceOrderCommand(orderId)); commandGateway.send(new CreateOrderCommand(orderId));
commandGateway.send(new AddProductCommand(orderId, "Deluxe Chair")); commandGateway.send(new AddProductCommand(orderId, "Deluxe Chair"));
// This throws an exception, as an Order cannot be shipped if it has not been confirmed yet. // This throws an exception, as an Order cannot be shipped if it has not been confirmed yet.
commandGateway.send(new ShipOrderCommand(orderId)); commandGateway.send(new ShipOrderCommand(orderId));
} }
@PostMapping("/order") @PostMapping("/order")
public CompletableFuture<String> placeOrder() { public CompletableFuture<String> createOrder() {
return placeOrder(UUID.randomUUID().toString()); return createOrder(UUID.randomUUID().toString());
} }
@PostMapping("/order/{order-id}") @PostMapping("/order/{order-id}")
public CompletableFuture<String> placeOrder(@PathVariable("order-id") String orderId) { public CompletableFuture<String> createOrder(@PathVariable("order-id") String orderId) {
return commandGateway.send(new PlaceOrderCommand(orderId)); return commandGateway.send(new CreateOrderCommand(orderId));
} }
@PostMapping("/order/{order-id}/product/{product-id}") @PostMapping("/order/{order-id}/product/{product-id}")
@ -88,9 +88,7 @@ public class OrderRestEndpoint {
} }
@GetMapping("/all-orders") @GetMapping("/all-orders")
public CompletableFuture<List<OrderedProduct>> findAllOrderedProducts() { public CompletableFuture<List<Order>> findAllOrders() {
return queryGateway.query( return queryGateway.query(new FindAllOrderedProductsQuery(), ResponseTypes.multipleInstancesOf(Order.class));
new FindAllOrderedProductsQuery(), ResponseTypes.multipleInstancesOf(OrderedProduct.class)
);
} }
} }

View File

@ -1,86 +0,0 @@
package com.baeldung.axon.querymodel;
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
import com.baeldung.axon.coreapi.events.OrderPlacedEvent;
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
import com.baeldung.axon.coreapi.events.ProductAddedEvent;
import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent;
import com.baeldung.axon.coreapi.events.ProductCountIncrementedEvent;
import com.baeldung.axon.coreapi.events.ProductRemovedEvent;
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
import com.baeldung.axon.coreapi.queries.OrderedProduct;
import org.axonframework.config.ProcessingGroup;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.queryhandling.QueryHandler;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@ProcessingGroup("ordered-products")
public class OrderedProductsEventHandler {
private final Map<String, OrderedProduct> orderedProducts = new HashMap<>();
@EventHandler
public void on(OrderPlacedEvent event) {
String orderId = event.getOrderId();
orderedProducts.put(orderId, new OrderedProduct(orderId));
}
@EventHandler
public void on(ProductAddedEvent event) {
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
orderedProduct.addProduct(event.getProductId());
return orderedProduct;
});
}
@EventHandler
public void on(ProductCountIncrementedEvent event) {
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
orderedProduct.incrementProductInstance(event.getProductId());
return orderedProduct;
});
}
@EventHandler
public void on(ProductCountDecrementedEvent event) {
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
orderedProduct.decrementProductInstance(event.getProductId());
return orderedProduct;
});
}
@EventHandler
public void on(ProductRemovedEvent event) {
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
orderedProduct.removeProduct(event.getProductId());
return orderedProduct;
});
}
@EventHandler
public void on(OrderConfirmedEvent event) {
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
orderedProduct.setOrderConfirmed();
return orderedProduct;
});
}
@EventHandler
public void on(OrderShippedEvent event) {
orderedProducts.computeIfPresent(event.getOrderId(), (orderId, orderedProduct) -> {
orderedProduct.setOrderShipped();
return orderedProduct;
});
}
@QueryHandler
public List<OrderedProduct> handle(FindAllOrderedProductsQuery query) {
return new ArrayList<>(orderedProducts.values());
}
}

View File

@ -0,0 +1,86 @@
package com.baeldung.axon.querymodel;
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
import com.baeldung.axon.coreapi.events.OrderCreatedEvent;
import com.baeldung.axon.coreapi.events.OrderShippedEvent;
import com.baeldung.axon.coreapi.events.ProductAddedEvent;
import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent;
import com.baeldung.axon.coreapi.events.ProductCountIncrementedEvent;
import com.baeldung.axon.coreapi.events.ProductRemovedEvent;
import com.baeldung.axon.coreapi.queries.FindAllOrderedProductsQuery;
import com.baeldung.axon.coreapi.queries.Order;
import org.axonframework.config.ProcessingGroup;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.queryhandling.QueryHandler;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@ProcessingGroup("orders")
public class OrdersEventHandler {
private final Map<String, Order> orders = new HashMap<>();
@EventHandler
public void on(OrderCreatedEvent event) {
String orderId = event.getOrderId();
orders.put(orderId, new Order(orderId));
}
@EventHandler
public void on(ProductAddedEvent event) {
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
order.addProduct(event.getProductId());
return order;
});
}
@EventHandler
public void on(ProductCountIncrementedEvent event) {
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
order.incrementProductInstance(event.getProductId());
return order;
});
}
@EventHandler
public void on(ProductCountDecrementedEvent event) {
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
order.decrementProductInstance(event.getProductId());
return order;
});
}
@EventHandler
public void on(ProductRemovedEvent event) {
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
order.removeProduct(event.getProductId());
return order;
});
}
@EventHandler
public void on(OrderConfirmedEvent event) {
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
order.setOrderConfirmed();
return order;
});
}
@EventHandler
public void on(OrderShippedEvent event) {
orders.computeIfPresent(event.getOrderId(), (orderId, order) -> {
order.setOrderShipped();
return order;
});
}
@QueryHandler
public List<Order> handle(FindAllOrderedProductsQuery query) {
return new ArrayList<>(orders.values());
}
}

View File

@ -1,8 +1,8 @@
### Place Order, Add Product, Confirm and Ship Order ### Create Order, Add Product, Confirm and Ship Order
POST http://localhost:8080/ship-order POST http://localhost:8080/ship-order
### Place Order, Add Product and Ship Order ### Create Order, Add Product and Ship Order
POST http://localhost:8080/ship-unconfirmed-order POST http://localhost:8080/ship-unconfirmed-order
@ -10,7 +10,7 @@ POST http://localhost:8080/ship-unconfirmed-order
GET http://localhost:8080/all-orders GET http://localhost:8080/all-orders
### Place Order with id 666a1661-474d-4046-8b12-8b5896312768 ### Create Order with id 666a1661-474d-4046-8b12-8b5896312768
POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768 POST http://localhost:8080/order/666a1661-474d-4046-8b12-8b5896312768

View File

@ -3,12 +3,12 @@ package com.baeldung.axon.commandmodel;
import com.baeldung.axon.commandmodel.order.OrderAggregate; import com.baeldung.axon.commandmodel.order.OrderAggregate;
import com.baeldung.axon.coreapi.commands.AddProductCommand; import com.baeldung.axon.coreapi.commands.AddProductCommand;
import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand; import com.baeldung.axon.coreapi.commands.ConfirmOrderCommand;
import com.baeldung.axon.coreapi.commands.CreateOrderCommand;
import com.baeldung.axon.coreapi.commands.DecrementProductCountCommand; import com.baeldung.axon.coreapi.commands.DecrementProductCountCommand;
import com.baeldung.axon.coreapi.commands.IncrementProductCountCommand; import com.baeldung.axon.coreapi.commands.IncrementProductCountCommand;
import com.baeldung.axon.coreapi.commands.PlaceOrderCommand;
import com.baeldung.axon.coreapi.commands.ShipOrderCommand; import com.baeldung.axon.coreapi.commands.ShipOrderCommand;
import com.baeldung.axon.coreapi.events.OrderConfirmedEvent; import com.baeldung.axon.coreapi.events.OrderConfirmedEvent;
import com.baeldung.axon.coreapi.events.OrderPlacedEvent; import com.baeldung.axon.coreapi.events.OrderCreatedEvent;
import com.baeldung.axon.coreapi.events.OrderShippedEvent; import com.baeldung.axon.coreapi.events.OrderShippedEvent;
import com.baeldung.axon.coreapi.events.ProductAddedEvent; import com.baeldung.axon.coreapi.events.ProductAddedEvent;
import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent; import com.baeldung.axon.coreapi.events.ProductCountDecrementedEvent;
@ -37,37 +37,37 @@ class OrderAggregateUnitTest {
} }
@Test @Test
void giveNoPriorActivity_whenPlaceOrderCommand_thenShouldPublishOrderPlacedEvent() { void giveNoPriorActivity_whenCreateOrderCommand_thenShouldPublishOrderCreatedEvent() {
fixture.givenNoPriorActivity() fixture.givenNoPriorActivity()
.when(new PlaceOrderCommand(ORDER_ID)) .when(new CreateOrderCommand(ORDER_ID))
.expectEvents(new OrderPlacedEvent(ORDER_ID)); .expectEvents(new OrderCreatedEvent(ORDER_ID));
} }
@Test @Test
void givenOrderPlacedEvent_whenAddProductCommand_thenShouldPublishProductAddedEvent() { void givenOrderCreatedEvent_whenAddProductCommand_thenShouldPublishProductAddedEvent() {
fixture.given(new OrderPlacedEvent(ORDER_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID))
.when(new AddProductCommand(ORDER_ID, PRODUCT_ID)) .when(new AddProductCommand(ORDER_ID, PRODUCT_ID))
.expectEvents(new ProductAddedEvent(ORDER_ID, PRODUCT_ID)); .expectEvents(new ProductAddedEvent(ORDER_ID, PRODUCT_ID));
} }
@Test @Test
void givenOrderPlacedEventAndProductAddedEvent_whenAddProductCommandForSameProductId_thenShouldThrowDuplicateOrderLineException() { void givenOrderCreatedEventAndProductAddedEvent_whenAddProductCommandForSameProductId_thenShouldThrowDuplicateOrderLineException() {
fixture.given(new OrderPlacedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID))
.when(new AddProductCommand(ORDER_ID, PRODUCT_ID)) .when(new AddProductCommand(ORDER_ID, PRODUCT_ID))
.expectException(DuplicateOrderLineException.class) .expectException(DuplicateOrderLineException.class)
.expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(PRODUCT_ID))); .expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(PRODUCT_ID)));
} }
@Test @Test
void givenOrderPlacedEventAndProductAddedEvent_whenIncrementProductCountCommand_thenShouldPublishProductCountIncrementedEvent() { void givenOrderCreatedEventAndProductAddedEvent_whenIncrementProductCountCommand_thenShouldPublishProductCountIncrementedEvent() {
fixture.given(new OrderPlacedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID))
.when(new IncrementProductCountCommand(ORDER_ID, PRODUCT_ID)) .when(new IncrementProductCountCommand(ORDER_ID, PRODUCT_ID))
.expectEvents(new ProductCountIncrementedEvent(ORDER_ID, PRODUCT_ID)); .expectEvents(new ProductCountIncrementedEvent(ORDER_ID, PRODUCT_ID));
} }
@Test @Test
void givenOrderPlacedEventProductAddedEventAndProductCountIncrementedEvent_whenDecrementProductCountCommand_thenShouldPublishProductCountDecrementedEvent() { void givenOrderCreatedEventProductAddedEventAndProductCountIncrementedEvent_whenDecrementProductCountCommand_thenShouldPublishProductCountDecrementedEvent() {
fixture.given(new OrderPlacedEvent(ORDER_ID), fixture.given(new OrderCreatedEvent(ORDER_ID),
new ProductAddedEvent(ORDER_ID, PRODUCT_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID),
new ProductCountIncrementedEvent(ORDER_ID, PRODUCT_ID)) new ProductCountIncrementedEvent(ORDER_ID, PRODUCT_ID))
.when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID)) .when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID))
@ -75,51 +75,51 @@ class OrderAggregateUnitTest {
} }
@Test @Test
void givenOrderPlacedEventAndProductAddedEvent_whenDecrementProductCountCommand_thenShouldPublishProductRemovedEvent() { void givenOrderCreatedEventAndProductAddedEvent_whenDecrementProductCountCommand_thenShouldPublishProductRemovedEvent() {
fixture.given(new OrderPlacedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID))
.when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID)) .when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID))
.expectEvents(new ProductRemovedEvent(ORDER_ID, PRODUCT_ID)); .expectEvents(new ProductRemovedEvent(ORDER_ID, PRODUCT_ID));
} }
@Test @Test
void givenOrderPlacedEvent_whenConfirmOrderCommand_thenShouldPublishOrderConfirmedEvent() { void givenOrderCreatedEvent_whenConfirmOrderCommand_thenShouldPublishOrderConfirmedEvent() {
fixture.given(new OrderPlacedEvent(ORDER_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID))
.when(new ConfirmOrderCommand(ORDER_ID)) .when(new ConfirmOrderCommand(ORDER_ID))
.expectEvents(new OrderConfirmedEvent(ORDER_ID)); .expectEvents(new OrderConfirmedEvent(ORDER_ID));
} }
@Test @Test
void givenOrderPlacedEventAndOrderConfirmedEvent_whenConfirmOrderCommand_thenExpectNoEvents() { void givenOrderCreatedEventAndOrderConfirmedEvent_whenConfirmOrderCommand_thenExpectNoEvents() {
fixture.given(new OrderPlacedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID))
.when(new ConfirmOrderCommand(ORDER_ID)) .when(new ConfirmOrderCommand(ORDER_ID))
.expectNoEvents(); .expectNoEvents();
} }
@Test @Test
void givenOrderPlacedEvent_whenShipOrderCommand_thenShouldThrowUnconfirmedOrderException() { void givenOrderCreatedEvent_whenShipOrderCommand_thenShouldThrowUnconfirmedOrderException() {
fixture.given(new OrderPlacedEvent(ORDER_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID))
.when(new ShipOrderCommand(ORDER_ID)) .when(new ShipOrderCommand(ORDER_ID))
.expectException(UnconfirmedOrderException.class); .expectException(UnconfirmedOrderException.class);
} }
@Test @Test
void givenOrderPlacedEventAndOrderConfirmedEvent_whenShipOrderCommand_thenShouldPublishOrderShippedEvent() { void givenOrderCreatedEventAndOrderConfirmedEvent_whenShipOrderCommand_thenShouldPublishOrderShippedEvent() {
fixture.given(new OrderPlacedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID))
.when(new ShipOrderCommand(ORDER_ID)) .when(new ShipOrderCommand(ORDER_ID))
.expectEvents(new OrderShippedEvent(ORDER_ID)); .expectEvents(new OrderShippedEvent(ORDER_ID));
} }
@Test @Test
void givenOrderPlacedEventProductAndOrderConfirmedEvent_whenAddProductCommand_thenShouldThrowOrderAlreadyConfirmedException() { void givenOrderCreatedEventProductAndOrderConfirmedEvent_whenAddProductCommand_thenShouldThrowOrderAlreadyConfirmedException() {
fixture.given(new OrderPlacedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID)) fixture.given(new OrderCreatedEvent(ORDER_ID), new OrderConfirmedEvent(ORDER_ID))
.when(new AddProductCommand(ORDER_ID, PRODUCT_ID)) .when(new AddProductCommand(ORDER_ID, PRODUCT_ID))
.expectException(OrderAlreadyConfirmedException.class) .expectException(OrderAlreadyConfirmedException.class)
.expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(ORDER_ID))); .expectExceptionMessage(Matchers.predicate(message -> ((String) message).contains(ORDER_ID)));
} }
@Test @Test
void givenOrderPlacedEventProductAddedEventAndOrderConfirmedEvent_whenIncrementProductCountCommand_thenShouldThrowOrderAlreadyConfirmedException() { void givenOrderCreatedEventProductAddedEventAndOrderConfirmedEvent_whenIncrementProductCountCommand_thenShouldThrowOrderAlreadyConfirmedException() {
fixture.given(new OrderPlacedEvent(ORDER_ID), fixture.given(new OrderCreatedEvent(ORDER_ID),
new ProductAddedEvent(ORDER_ID, PRODUCT_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID),
new OrderConfirmedEvent(ORDER_ID)) new OrderConfirmedEvent(ORDER_ID))
.when(new IncrementProductCountCommand(ORDER_ID, PRODUCT_ID)) .when(new IncrementProductCountCommand(ORDER_ID, PRODUCT_ID))
@ -128,8 +128,8 @@ class OrderAggregateUnitTest {
} }
@Test @Test
void givenOrderPlacedEventProductAddedEventAndOrderConfirmedEvent_whenDecrementProductCountCommand_thenShouldThrowOrderAlreadyConfirmedException() { void givenOrderCreatedEventProductAddedEventAndOrderConfirmedEvent_whenDecrementProductCountCommand_thenShouldThrowOrderAlreadyConfirmedException() {
fixture.given(new OrderPlacedEvent(ORDER_ID), fixture.given(new OrderCreatedEvent(ORDER_ID),
new ProductAddedEvent(ORDER_ID, PRODUCT_ID), new ProductAddedEvent(ORDER_ID, PRODUCT_ID),
new OrderConfirmedEvent(ORDER_ID)) new OrderConfirmedEvent(ORDER_ID))
.when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID)) .when(new DecrementProductCountCommand(ORDER_ID, PRODUCT_ID))