diff --git a/lib/domain_test.ts b/lib/domain_test.ts index 00ff2d4..97d1931 100644 --- a/lib/domain_test.ts +++ b/lib/domain_test.ts @@ -1,18 +1,31 @@ -import { restaurantDecider, restaurantView } from "./domain.ts"; import { + orderDecider, + orderView, + restaurantDecider, + restaurantView, +} from "./domain.ts"; +import { + orderCommandSchema, + orderEventSchema, restaurantCommandSchema, restaurantEventSchema, } from "./api_schema.ts"; import { ViewSpecification } from "../test_specification.ts"; import { DeciderSpecification } from "../test_specification.ts"; -import type { RestaurantCommand, RestaurantEvent } from "./api.ts"; +import type { + OrderCommand, + OrderEvent, + RestaurantCommand, + RestaurantEvent, +} from "./api.ts"; +// ######################################################################### // A convinient testing specififcation for the Decider - GIVEN / WHEN / THEN +// ######################################################################### // Json representation of the command const createRestaurantCommandJson = ` { - "commandId": "691490bb-c4d3-45b8-99d0-efcf20e353ag", "decider": "Restaurant", "kind": "CreateRestaurantCommand", "id": "691490bb-c4d3-45b8-99d0-efcf20e353ao", @@ -52,7 +65,6 @@ const restaurantCreatedEventJson = ` // Json representation of the command const changeRestaurantMenuCommandJson = ` { - "commandId": "691490bb-c4d3-45b8-99d0-efcf20e353ag", "decider": "Restaurant", "kind": "ChangeRestaurantMenuCommand", "id": "691490bb-c4d3-45b8-99d0-efcf20e353ao", @@ -70,7 +82,6 @@ const changeRestaurantMenuCommandJson = ` const placeOrderCommandJson = ` { - "commandId": "691490bb-c4d3-45b8-99d0-efcf20e353ag", "decider": "Restaurant", "kind": "PlaceOrderCommand", "id": "691490bb-c4d3-45b8-99d0-efcf20e353ao", @@ -83,6 +94,28 @@ const placeOrderCommandJson = ` } `; +const createOrderCommandJson = ` + { + "decider": "Order", + "kind": "CreateOrderCommand", + "restaurantId": "691490bb-c4d3-45b8-99d0-efcf20e353ao", + "id": "691490bb-c4d3-45b8-99d0-efcf20e353ag", + "menuItems": [ + {"menuItemId": "1", "name": "Salad2", "price": "18.59"}, + {"menuItemId": "2", "name": "Soup2", "price": "16.94"}, + {"menuItemId": "3", "name": "Steak2", "price": "19.89"} + ] + } + `; + +const markOrderAsPreparedCommandJson = ` + { + "decider": "Order", + "kind": "MarkOrderAsPreparedCommand", + "id": "691490bb-c4d3-45b8-99d0-efcf20e353ag" + } + `; + // Json representation of the expected event(s) const restaurantMenuChangedEventJson = ` { @@ -110,7 +143,7 @@ const restaurantOrderPlacedEventJson = ` "kind": "RestaurantOrderPlacedEvent", "id": "691490bb-c4d3-45b8-99d0-efcf20e353ao", "orderId": "691490bb-c4d3-45b8-99d0-efcf20e353ag", - "menuItems": [ + "menuItems": [ {"menuItemId": "1", "name": "Salad2", "price": "18.59"}, {"menuItemId": "2", "name": "Soup2", "price": "16.94"}, {"menuItemId": "3", "name": "Steak2", "price": "19.89"} @@ -135,6 +168,32 @@ const restaurantOrderNotPlacedEventJson = ` } `; +const orderCreatedEventJson = ` + { + "version": 1, + "decider": "Order", + "kind": "OrderCreatedEvent", + "restaurantId": "691490bb-c4d3-45b8-99d0-efcf20e353ao", + "id": "691490bb-c4d3-45b8-99d0-efcf20e353ag", + "menuItems": [ + {"menuItemId": "1", "name": "Salad2", "price": "18.59"}, + {"menuItemId": "2", "name": "Soup2", "price": "16.94"}, + {"menuItemId": "3", "name": "Steak2", "price": "19.89"} + ], + "final": false + } + `; + +const orderPreparedEventJson = ` + { + "version": 1, + "decider": "Order", + "kind": "OrderPreparedEvent", + "id": "691490bb-c4d3-45b8-99d0-efcf20e353ag", + "final": false + } + `; + // The Decider test for the restaurant create command Deno.test(function createRestaurantDeciderTest() { // Parse the restaurant command from the request / Zod validation/parsing @@ -176,7 +235,7 @@ Deno.test(function changeRestaurantMenuDeciderTest() { JSON.parse(restaurantMenuChangedEventJson), ); - // Run the second test specification for the restaurant decider + // Run the test specification for the restaurant decider DeciderSpecification.for(restaurantDecider) .given([restaurantCreatedEvent]) .when(changeRestaurantMenuCommand) @@ -203,7 +262,7 @@ Deno.test(function placeOrderAtRestaurantDeciderTest() { JSON.parse(restaurantOrderPlacedEventJson), ); - // Run the second test specification for the restaurant decider + // Run the test specification for the restaurant decider DeciderSpecification.for(restaurantDecider) .given([restaurantCreatedEvent]) .when(placeOrderCommand) @@ -224,7 +283,7 @@ Deno.test(function placeOrderAtRestaurantWithErrorDeciderTest() { JSON.parse(restaurantOrderNotPlacedEventJson), ); - // Run the second test specification for the restaurant decider + // Run the test specification for the restaurant decider DeciderSpecification.for(restaurantDecider) // Given NO restaurant previously created!!! .given([]) @@ -232,6 +291,57 @@ Deno.test(function placeOrderAtRestaurantWithErrorDeciderTest() { .then([restaurantOrderNotPlacedEvent]); }); +// The Decider test for the create order command +Deno.test(function createOrderDeciderTest() { + // Parse the order command from the request / Zod validation/parsing + const createOrderCommand: OrderCommand = orderCommandSchema + .parse( + JSON.parse(createOrderCommandJson), + ); + + // Parse the order event. + const orderCreatedEvent: OrderEvent = orderEventSchema + .parse( + JSON.parse(orderCreatedEventJson), + ); + + // Run the test specification for the order decider + DeciderSpecification.for(orderDecider) + .given([]) + .when(createOrderCommand) + .then([orderCreatedEvent]); +}); + +// The Decider test for the create order command +Deno.test(function markOrderAsPeparedDeciderTest() { + // Parse the order command from the request / Zod validation/parsing + const markOrderAsPreparedCommand: OrderCommand = orderCommandSchema + .parse( + JSON.parse(markOrderAsPreparedCommandJson), + ); + + // Parse the order event. + const orderCreatedEvent: OrderEvent = orderEventSchema + .parse( + JSON.parse(orderCreatedEventJson), + ); + // Parse the order event. + const orderPreparedEvent: OrderEvent = orderEventSchema + .parse( + JSON.parse(orderPreparedEventJson), + ); + + // Run the test specification for the order decider + DeciderSpecification.for(orderDecider) + .given([orderCreatedEvent]) + .when(markOrderAsPreparedCommand) + .then([orderPreparedEvent]); +}); + +// ############################################################### +// A convinient testing specififcation for the View - GIVEN / THEN +// ############################################################### + Deno.test(function reastaurantCreatedViewTest() { // Parse the restaurant event. const restaurantCreatedEvent: RestaurantEvent = restaurantEventSchema @@ -286,4 +396,29 @@ Deno.test(function restaurantMenuChangedViewTest() { }); }); +Deno.test(function orderPreparedViewTest() { + // Parse the order event. + const orderCreatedEvent: OrderEvent = orderEventSchema + .parse( + JSON.parse(orderCreatedEventJson), + ); + const orderPreparedEvent: OrderEvent = orderEventSchema + .parse( + JSON.parse(orderPreparedEventJson), + ); + + ViewSpecification.for(orderView) + .given([orderCreatedEvent, orderPreparedEvent]) + .then({ + orderId: "691490bb-c4d3-45b8-99d0-efcf20e353ag", + restaurantId: "691490bb-c4d3-45b8-99d0-efcf20e353ao", + menuItems: [ + { menuItemId: "1", name: "Salad2", price: "18.59" }, + { menuItemId: "2", name: "Soup2", price: "16.94" }, + { menuItemId: "3", name: "Steak2", price: "19.89" }, + ], + status: "PREPARED", + }); +}); + // Run the tests: `deno test`