@reventlessdev/online-shop-aggregates-ordering 3.0.0-alpha.249 → 3.0.0-alpha.251
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/lib/bs/.compiler.log +2 -2
- package/lib/bs/OrderingPlugin.cmi +0 -0
- package/lib/bs/OrderingPlugin.cmt +0 -0
- package/lib/bs/OrderingPlugin.mlmap +1 -0
- package/lib/bs/compiler-info.json +1 -1
- package/lib/bs/src/CatalogProduct/Aggregate/CatalogProduct_Behavior-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/CatalogProduct/Aggregate/CatalogProduct_Behavior-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Customer/Aggregate/Customer_Behavior-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Customer/Aggregate/Customer_Behavior-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Customer/ReadModel/Customers_Projections-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Customer/ReadModel/Customers_Projections-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Extension/Products_Extension-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Extension/Products_Extension-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/ExtensionPoint/Orders_ExtensionPointMapping-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/ExtensionPoint/Orders_ExtensionPointMapping-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Order/Aggregate/Order-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Order/Aggregate/Order-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Order/Aggregate/Order_Behavior-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Order/Aggregate/Order_Behavior-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Order/Aggregate/Order_Mappings-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Order/Aggregate/Order_Mappings-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Order/ReadModel/Orders_Projections-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Order/ReadModel/Orders_Projections-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Order/SideEffect/Order_EmailNotification-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Order/SideEffect/Order_EmailNotification-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Plugin-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Plugin-OrderingPlugin.cmt +0 -0
- package/lib/bs/src/Task/OrderNotifications-OrderingPlugin.cmi +0 -0
- package/lib/bs/src/Task/OrderNotifications-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.ast +0 -0
- package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res +11 -5
- package/lib/bs/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res.mjs +6 -5
- package/lib/bs/tests/CatalogProduct/ReadModel/AvailableProducts_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/CatalogProduct/ReadModel/AvailableProducts_GWT.ast +0 -0
- package/lib/bs/tests/CatalogProduct/ReadModel/AvailableProducts_GWT.res +2 -0
- package/lib/bs/tests/Customer/Aggregate/Customer_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Customer/Aggregate/Customer_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Customer/Aggregate/Customer_GWT.ast +0 -0
- package/lib/bs/tests/Customer/Aggregate/Customer_GWT.res +32 -17
- package/lib/bs/tests/Customer/Aggregate/Customer_GWT.res.mjs +31 -30
- package/lib/bs/tests/Customer/ReadModel/Customers_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Customer/ReadModel/Customers_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Customer/ReadModel/Customers_GWT.ast +0 -0
- package/lib/bs/tests/Customer/ReadModel/Customers_GWT.res +4 -0
- package/lib/bs/tests/Extension/Products_Extension_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Extension/Products_Extension_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Extension/Products_Extension_GWT.ast +0 -0
- package/lib/bs/tests/Extension/Products_Extension_GWT.res +3 -2
- package/lib/bs/tests/Extension/Products_Extension_GWT.res.mjs +3 -5
- package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.ast +0 -0
- package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res +5 -3
- package/lib/bs/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res.mjs +6 -16
- package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT.ast +0 -0
- package/lib/bs/tests/Order/Aggregate/OrderMappings_GWT.res +4 -0
- package/lib/bs/tests/Order/Aggregate/Order_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Order/Aggregate/Order_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Order/Aggregate/Order_GWT.ast +0 -0
- package/lib/bs/tests/Order/Aggregate/Order_GWT.res +24 -5
- package/lib/bs/tests/Order/Aggregate/Order_GWT.res.mjs +6 -5
- package/lib/bs/tests/Order/ReadModel/Orders_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Order/ReadModel/Orders_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Order/ReadModel/Orders_GWT.ast +0 -0
- package/lib/bs/tests/Order/ReadModel/Orders_GWT.res +4 -0
- package/lib/bs/tests/Order/SideEffect/Order_EmailNotification_GWT-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Order/SideEffect/Order_EmailNotification_GWT-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Ordering_Examples-OrderingPlugin.cmi +0 -0
- package/lib/bs/tests/Ordering_Examples-OrderingPlugin.cmj +0 -0
- package/lib/bs/tests/Ordering_Examples-OrderingPlugin.cmt +0 -0
- package/lib/bs/tests/Ordering_Examples.ast +0 -0
- package/lib/bs/tests/Ordering_Examples.res +13 -0
- package/lib/bs/tests/Ordering_Examples.res.mjs +35 -0
- package/lib/ocaml/.compiler.log +2 -2
- package/lib/ocaml/AvailableProducts_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/AvailableProducts_GWT.ast +0 -0
- package/lib/ocaml/AvailableProducts_GWT.res +2 -0
- package/lib/ocaml/CatalogProduct_Behavior-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/CatalogProduct_Behavior-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/CatalogProduct_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/CatalogProduct_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/CatalogProduct_GWT.ast +0 -0
- package/lib/ocaml/CatalogProduct_GWT.res +11 -5
- package/lib/ocaml/Customer_Behavior-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Customer_Behavior-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Customer_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Customer_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Customer_GWT.ast +0 -0
- package/lib/ocaml/Customer_GWT.res +32 -17
- package/lib/ocaml/Customers_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Customers_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Customers_GWT.ast +0 -0
- package/lib/ocaml/Customers_GWT.res +4 -0
- package/lib/ocaml/Customers_Projections-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Customers_Projections-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Order-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Order-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/OrderMappings_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/OrderMappings_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/OrderMappings_GWT.ast +0 -0
- package/lib/ocaml/OrderMappings_GWT.res +4 -0
- package/lib/ocaml/OrderNotifications-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/OrderNotifications-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Order_Behavior-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Order_Behavior-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Order_EmailNotification-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Order_EmailNotification-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Order_EmailNotification_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Order_EmailNotification_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Order_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Order_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Order_GWT.ast +0 -0
- package/lib/ocaml/Order_GWT.res +24 -5
- package/lib/ocaml/Order_Mappings-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Order_Mappings-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/OrderingPlugin.cmi +0 -0
- package/lib/ocaml/OrderingPlugin.cmt +0 -0
- package/lib/ocaml/OrderingPlugin.mlmap +1 -0
- package/lib/ocaml/Ordering_Examples-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Ordering_Examples-OrderingPlugin.cmj +0 -0
- package/lib/ocaml/Ordering_Examples-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Ordering_Examples.ast +0 -0
- package/lib/ocaml/Ordering_Examples.res +13 -0
- package/lib/ocaml/Orders_ExtensionPointMapping-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Orders_ExtensionPointMapping-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Orders_ExtensionPointMapping_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Orders_ExtensionPointMapping_GWT.ast +0 -0
- package/lib/ocaml/Orders_ExtensionPointMapping_GWT.res +5 -3
- package/lib/ocaml/Orders_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Orders_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Orders_GWT.ast +0 -0
- package/lib/ocaml/Orders_GWT.res +4 -0
- package/lib/ocaml/Orders_Projections-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Orders_Projections-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Plugin-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Plugin-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Products_Extension-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Products_Extension-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Products_Extension_GWT-OrderingPlugin.cmi +0 -0
- package/lib/ocaml/Products_Extension_GWT-OrderingPlugin.cmt +0 -0
- package/lib/ocaml/Products_Extension_GWT.ast +0 -0
- package/lib/ocaml/Products_Extension_GWT.res +3 -2
- package/package.json +8 -8
- package/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res +11 -5
- package/tests/CatalogProduct/Aggregate/CatalogProduct_GWT.res.mjs +6 -5
- package/tests/CatalogProduct/ReadModel/AvailableProducts_GWT.res +2 -0
- package/tests/Customer/Aggregate/Customer_GWT.res +32 -17
- package/tests/Customer/Aggregate/Customer_GWT.res.mjs +31 -30
- package/tests/Customer/ReadModel/Customers_GWT.res +4 -0
- package/tests/Extension/Products_Extension_GWT.res +3 -2
- package/tests/Extension/Products_Extension_GWT.res.mjs +3 -5
- package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res +5 -3
- package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res.mjs +6 -16
- package/tests/Order/Aggregate/OrderMappings_GWT.res +4 -0
- package/tests/Order/Aggregate/Order_GWT.res +24 -5
- package/tests/Order/Aggregate/Order_GWT.res.mjs +6 -5
- package/tests/Order/ReadModel/Orders_GWT.res +4 -0
- package/tests/Ordering_Examples.res +13 -0
- package/tests/Ordering_Examples.res.mjs +35 -0
|
Binary file
|
|
Binary file
|
|
@@ -22,6 +22,7 @@ let prod1 = CatalogSpec.ProductId.make("prod-1")
|
|
|
22
22
|
let placedEvent = Order.Placed({customerId: cust1, productIds: [prod1]})
|
|
23
23
|
|
|
24
24
|
describe("Order auto-ship mapping (Placed → Ship)", () => {
|
|
25
|
+
// scenario-id: 2fd227c7-248e-47be-939a-467bceeb8796
|
|
25
26
|
test("Place → AutoShipMapping issues Ship → target emits Shipped", () =>
|
|
26
27
|
givenSourceEvents([])
|
|
27
28
|
->andTargetEvents([("order-1", [placedEvent])])
|
|
@@ -29,6 +30,7 @@ describe("Order auto-ship mapping (Placed → Ship)", () => {
|
|
|
29
30
|
->thenTargetEvent("order-1", Order.Shipped)
|
|
30
31
|
)
|
|
31
32
|
|
|
33
|
+
// scenario-id: 366966a9-f65a-44cf-9bd2-4df7ef7bced4
|
|
32
34
|
test("Ship command does not fire the mapping (only Placed events do)", () =>
|
|
33
35
|
givenSourceEvents([placedEvent])
|
|
34
36
|
->andTargetEvents([("order-1", [placedEvent])])
|
|
@@ -36,6 +38,7 @@ describe("Order auto-ship mapping (Placed → Ship)", () => {
|
|
|
36
38
|
->thenNoTargetEvent
|
|
37
39
|
)
|
|
38
40
|
|
|
41
|
+
// scenario-id: c6203367-d2ff-4903-b1a2-8cc259ec62ee
|
|
39
42
|
test("Cancel command does not fire the mapping", () =>
|
|
40
43
|
givenSourceEvents([placedEvent])
|
|
41
44
|
->andTargetEvents([("order-1", [placedEvent])])
|
|
@@ -43,6 +46,7 @@ describe("Order auto-ship mapping (Placed → Ship)", () => {
|
|
|
43
46
|
->thenNoTargetEvent
|
|
44
47
|
)
|
|
45
48
|
|
|
49
|
+
// scenario-id: d20d610d-7ec8-4767-8d88-4556c1bf7059
|
|
46
50
|
test("Refund command does not fire the mapping (only Placed events do)", () =>
|
|
47
51
|
givenSourceEvents([placedEvent, Order.Cancelled({productIds: [prod1]})])
|
|
48
52
|
->andTargetEvents([("order-1", [placedEvent, Order.Cancelled({productIds: [prod1]})])])
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/ocaml/Order_GWT.ast
CHANGED
|
Binary file
|
package/lib/ocaml/Order_GWT.res
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
@@reventless.gwt
|
|
2
2
|
|
|
3
|
+
open Ordering_Examples
|
|
4
|
+
|
|
3
5
|
// Ids are typed; the literals are made once, here.
|
|
4
6
|
let cust1 = CustomerId.make("cust-1")
|
|
5
7
|
let prod1 = CatalogSpec.ProductId.make("prod-1")
|
|
6
8
|
let prod2 = CatalogSpec.ProductId.make("prod-2")
|
|
7
9
|
|
|
8
10
|
describe("Order Behavior", () => {
|
|
11
|
+
// scenario-id: 4f723805-10e2-4b72-b40a-6cf71e91c375
|
|
9
12
|
test("Place on new aggregate produces Placed", () =>
|
|
10
13
|
givenEvents([])
|
|
11
14
|
->whenCmd(Place({customerId: cust1, productIds: [prod1, prod2]}))
|
|
12
15
|
->thenEvent(Placed({customerId: cust1, productIds: [prod1, prod2]}))
|
|
13
16
|
)
|
|
14
17
|
|
|
18
|
+
// scenario-id: 061fb189-7195-474f-8010-0a0339d7cf11
|
|
15
19
|
test("Place on existing order returns OrderAlreadyPlaced", () =>
|
|
16
20
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
|
|
17
21
|
->whenCmd(Place({customerId: cust1, productIds: [prod1]}))
|
|
18
22
|
->thenError(OrderAlreadyPlaced)
|
|
19
23
|
)
|
|
20
24
|
|
|
25
|
+
// scenario-id: 3cb519a2-53ba-4f66-938f-2d5e4a3b736b
|
|
21
26
|
test("Place on shipped order returns OrderAlreadyShipped", () =>
|
|
22
27
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
|
|
23
28
|
->whenCmd(Place({customerId: cust1, productIds: [prod1]}))
|
|
24
29
|
->thenError(OrderAlreadyShipped)
|
|
25
30
|
)
|
|
26
31
|
|
|
32
|
+
// scenario-id: e74bad7c-abe6-4313-9290-b20f75897285
|
|
27
33
|
test("Place on cancelled order returns OrderAlreadyCancelled", () =>
|
|
28
34
|
givenEvents([
|
|
29
35
|
Placed({customerId: cust1, productIds: [prod1]}),
|
|
@@ -33,24 +39,28 @@ describe("Order Behavior", () => {
|
|
|
33
39
|
->thenError(OrderAlreadyCancelled)
|
|
34
40
|
)
|
|
35
41
|
|
|
42
|
+
// scenario-id: 1e97733f-32dd-473a-86e9-6c2cfec8f813
|
|
36
43
|
test("Ship on non-existent order returns OrderNotFound", () =>
|
|
37
44
|
givenEvents([])
|
|
38
45
|
->whenCmd(Ship)
|
|
39
46
|
->thenError(OrderNotFound)
|
|
40
47
|
)
|
|
41
48
|
|
|
49
|
+
// scenario-id: 54073db7-f835-4d89-a648-71b6dc4869c2
|
|
42
50
|
test("Ship on placed order produces Shipped", () =>
|
|
43
51
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
|
|
44
52
|
->whenCmd(Ship)
|
|
45
53
|
->thenEvent(Shipped)
|
|
46
54
|
)
|
|
47
55
|
|
|
56
|
+
// scenario-id: 2d4c200e-ece6-40c4-a67d-460f5beca59e
|
|
48
57
|
test("Ship on shipped order produces no events (idempotent)", () =>
|
|
49
58
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
|
|
50
59
|
->whenCmd(Ship)
|
|
51
60
|
->thenNoEvent
|
|
52
61
|
)
|
|
53
62
|
|
|
63
|
+
// scenario-id: 08783980-65d7-4114-b4ef-f0f95b0b3fc5
|
|
54
64
|
test("Ship on cancelled order returns OrderAlreadyCancelled", () =>
|
|
55
65
|
givenEvents([
|
|
56
66
|
Placed({customerId: cust1, productIds: [prod1]}),
|
|
@@ -60,24 +70,28 @@ describe("Order Behavior", () => {
|
|
|
60
70
|
->thenError(OrderAlreadyCancelled)
|
|
61
71
|
)
|
|
62
72
|
|
|
73
|
+
// scenario-id: 2104ec68-2de0-464b-b8f8-379f47b03db9
|
|
63
74
|
test("Cancel on non-existent order returns OrderNotFound", () =>
|
|
64
75
|
givenEvents([])
|
|
65
76
|
->whenCmd(Cancel)
|
|
66
77
|
->thenError(OrderNotFound)
|
|
67
78
|
)
|
|
68
79
|
|
|
80
|
+
// scenario-id: 3d974a23-5eb6-4463-9824-e61b0fa5a278
|
|
69
81
|
test("Cancel on placed order produces Cancelled", () =>
|
|
70
82
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
|
|
71
83
|
->whenCmd(Cancel)
|
|
72
84
|
->thenEvent(Cancelled({productIds: [prod1]}))
|
|
73
85
|
)
|
|
74
86
|
|
|
87
|
+
// scenario-id: 6144fcb7-d768-4237-9e67-e530c736210d
|
|
75
88
|
test("Cancel on shipped order returns OrderAlreadyShipped", () =>
|
|
76
89
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
|
|
77
90
|
->whenCmd(Cancel)
|
|
78
91
|
->thenError(OrderAlreadyShipped)
|
|
79
92
|
)
|
|
80
93
|
|
|
94
|
+
// scenario-id: 07679806-2e68-4cdb-b8c0-8cc67bd65fa7
|
|
81
95
|
test("Cancel on cancelled order produces no events (idempotent)", () =>
|
|
82
96
|
givenEvents([
|
|
83
97
|
Placed({customerId: cust1, productIds: [prod1]}),
|
|
@@ -87,40 +101,45 @@ describe("Order Behavior", () => {
|
|
|
87
101
|
->thenNoEvent
|
|
88
102
|
)
|
|
89
103
|
|
|
104
|
+
// scenario-id: aa624dbf-659b-4685-8695-4203e23a855f
|
|
90
105
|
test("Refund on non-existent order returns OrderNotFound", () =>
|
|
91
106
|
givenEvents([])
|
|
92
107
|
->whenCmd(Refund({reason: "lost-in-transit"}))
|
|
93
108
|
->thenError(OrderNotFound)
|
|
94
109
|
)
|
|
95
110
|
|
|
111
|
+
// scenario-id: cf56897b-1cf0-4768-8ada-eae11c069d95
|
|
96
112
|
test("Refund on placed order returns OrderNotCancelled", () =>
|
|
97
113
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]})])
|
|
98
|
-
->whenCmd(Refund({reason:
|
|
114
|
+
->whenCmd(Refund({reason: changedMind}))
|
|
99
115
|
->thenError(OrderNotCancelled)
|
|
100
116
|
)
|
|
101
117
|
|
|
118
|
+
// scenario-id: 802fb4a7-3768-4c6d-8a54-444f44891515
|
|
102
119
|
test("Refund on shipped order returns OrderNotCancelled", () =>
|
|
103
120
|
givenEvents([Placed({customerId: cust1, productIds: [prod1]}), Shipped])
|
|
104
121
|
->whenCmd(Refund({reason: "delivered-damaged"}))
|
|
105
122
|
->thenError(OrderNotCancelled)
|
|
106
123
|
)
|
|
107
124
|
|
|
125
|
+
// scenario-id: d9f7692d-4d64-41d9-b845-f5958fe95bc0
|
|
108
126
|
test("Refund on cancelled order produces Refunded", () =>
|
|
109
127
|
givenEvents([
|
|
110
128
|
Placed({customerId: cust1, productIds: [prod1]}),
|
|
111
129
|
Cancelled({productIds: [prod1]}),
|
|
112
130
|
])
|
|
113
|
-
->whenCmd(Refund({reason:
|
|
114
|
-
->thenEvent(Refunded({reason:
|
|
131
|
+
->whenCmd(Refund({reason: changedMind}))
|
|
132
|
+
->thenEvent(Refunded({reason: changedMind}))
|
|
115
133
|
)
|
|
116
134
|
|
|
135
|
+
// scenario-id: 4ced8701-2214-4f05-89ed-057b130979ad
|
|
117
136
|
test("Refund on already-refunded order produces no events (idempotent)", () =>
|
|
118
137
|
givenEvents([
|
|
119
138
|
Placed({customerId: cust1, productIds: [prod1]}),
|
|
120
139
|
Cancelled({productIds: [prod1]}),
|
|
121
|
-
Refunded({reason:
|
|
140
|
+
Refunded({reason: changedMind}),
|
|
122
141
|
])
|
|
123
|
-
->whenCmd(Refund({reason:
|
|
142
|
+
->whenCmd(Refund({reason: changedMind}))
|
|
124
143
|
->thenNoEvent
|
|
125
144
|
)
|
|
126
145
|
})
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@@reventless.examples
|
|
2
|
+
|
|
3
|
+
let p1: CatalogSpec.ProductId.t = CatalogSpec.ProductId.makeFromString("p1")
|
|
4
|
+
let p2: CatalogSpec.ProductId.t = CatalogSpec.ProductId.makeFromString("p2")
|
|
5
|
+
|
|
6
|
+
let c1: CustomerId.t = CustomerId.makeFromString("c1")
|
|
7
|
+
|
|
8
|
+
let aliceEmail: string = "alice@example.com"
|
|
9
|
+
let bobEmail: string = "bob@example.com"
|
|
10
|
+
let changedMind: string = "customer-changed-mind"
|
|
11
|
+
let laptop: string = "Laptop"
|
|
12
|
+
let mainStreet: string = "123 Main St"
|
|
13
|
+
let oakAvenue: string = "456 Oak Ave"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
// into one public per-product event each (one-to-many fan-out).
|
|
3
3
|
@@reventless.gwt
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
let p1 = CatalogSpec.ProductId.make("p1")
|
|
7
|
-
let p2 = CatalogSpec.ProductId.make("p2")
|
|
5
|
+
open Ordering_Examples
|
|
8
6
|
|
|
9
7
|
describe("Orders ExtensionPoint mapping — per-product fan-out", () => {
|
|
8
|
+
// scenario-id: b3fe53fe-84bd-4bb7-aca3-a0f9db5a186f
|
|
10
9
|
test("Placed fans out to one ItemOrdered per product", () =>
|
|
11
10
|
whenDelegateEvent(
|
|
12
11
|
Delegate.Placed({customerId: c1, productIds: [p1, p2]}),
|
|
@@ -16,6 +15,7 @@ describe("Orders ExtensionPoint mapping — per-product fan-out", () => {
|
|
|
16
15
|
])
|
|
17
16
|
)
|
|
18
17
|
|
|
18
|
+
// scenario-id: c916b814-2006-4d62-9fff-60bb99ddcfd3
|
|
19
19
|
test("Cancelled fans out to one ItemOrderCancelled per product", () =>
|
|
20
20
|
whenDelegateEvent(Delegate.Cancelled({productIds: [p1, p2]}))->thenPublishesEvents([
|
|
21
21
|
("p1", ExtensionPoint.ItemOrderCancelled({productId: "p1", orderId: "gwt-id"})),
|
|
@@ -23,8 +23,10 @@ describe("Orders ExtensionPoint mapping — per-product fan-out", () => {
|
|
|
23
23
|
])
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
+
// scenario-id: 3647a0be-51ed-4d6d-83b3-9fa53a596e49
|
|
26
27
|
test("Shipped publishes nothing", () => whenDelegateEvent(Delegate.Shipped)->thenPublishesNothing)
|
|
27
28
|
|
|
29
|
+
// scenario-id: 0ac71311-60e6-4373-b078-96cfaf91724d
|
|
28
30
|
test("Refunded publishes nothing", () =>
|
|
29
31
|
whenDelegateEvent(Delegate.Refunded({reason: "customer-changed-mind"}))->thenPublishesNothing
|
|
30
32
|
)
|
|
Binary file
|
|
Binary file
|
package/lib/ocaml/Orders_GWT.ast
CHANGED
|
Binary file
|
package/lib/ocaml/Orders_GWT.res
CHANGED
|
@@ -6,6 +6,7 @@ let prod1 = CatalogSpec.ProductId.make("prod-1")
|
|
|
6
6
|
let prod2 = CatalogSpec.ProductId.make("prod-2")
|
|
7
7
|
|
|
8
8
|
describe("Orders ReadModel ← Order", () => {
|
|
9
|
+
// scenario-id: 94f5938c-adf9-42c2-8986-1204e0aa0710
|
|
9
10
|
test("Placed sets initial read model state", () =>
|
|
10
11
|
givenEvents([])
|
|
11
12
|
->whenEvent(Order.Placed({customerId: cust1, productIds: [prod1, prod2]}))
|
|
@@ -16,6 +17,7 @@ describe("Orders ReadModel ← Order", () => {
|
|
|
16
17
|
})
|
|
17
18
|
)
|
|
18
19
|
|
|
20
|
+
// scenario-id: 4b7e916e-e7db-4c00-9337-9e2fe4104c93
|
|
19
21
|
test("Shipped updates status", () =>
|
|
20
22
|
givenEvents([Order.Placed({customerId: cust1, productIds: [prod1]})])
|
|
21
23
|
->whenEvent(Order.Shipped)
|
|
@@ -26,6 +28,7 @@ describe("Orders ReadModel ← Order", () => {
|
|
|
26
28
|
})
|
|
27
29
|
)
|
|
28
30
|
|
|
31
|
+
// scenario-id: a56314fa-907f-425a-80e6-a7ea1a27d6c9
|
|
29
32
|
test("Cancelled updates status", () =>
|
|
30
33
|
givenEvents([Order.Placed({customerId: cust1, productIds: [prod1]})])
|
|
31
34
|
->whenEvent(Order.Cancelled({productIds: [prod1]}))
|
|
@@ -36,6 +39,7 @@ describe("Orders ReadModel ← Order", () => {
|
|
|
36
39
|
})
|
|
37
40
|
)
|
|
38
41
|
|
|
42
|
+
// scenario-id: 96902cd1-2eae-4a35-b5c6-6d28dc9acda7
|
|
39
43
|
test("Refunded updates status", () =>
|
|
40
44
|
givenEvents([
|
|
41
45
|
Order.Placed({customerId: cust1, productIds: [prod1]}),
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -5,16 +5,17 @@
|
|
|
5
5
|
// `Mapping` is brought into scope by the PPX `open Products_Extension`; opening
|
|
6
6
|
// it surfaces the extension point's events and the delegate's commands.
|
|
7
7
|
open Mapping
|
|
8
|
-
|
|
9
|
-
let p1 = CatalogSpec.ProductId.make("p1")
|
|
8
|
+
open Ordering_Examples
|
|
10
9
|
|
|
11
10
|
describe("Products Extension delegate", () => {
|
|
11
|
+
// scenario-id: 4c14eb06-02b8-41ae-b0b8-cf33ef430e93
|
|
12
12
|
test("ProductBecameAvailable issues Sync", () =>
|
|
13
13
|
whenIncomingEvent(
|
|
14
14
|
ExtensionPoint.ProductBecameAvailable({productId: p1, name: "Book", price: 9.99}),
|
|
15
15
|
)->thenPublishesAggregateCommand("p1", Delegate.Sync({name: "Book", price: 9.99}))
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
+
// scenario-id: d3760e9e-c4f6-4a2f-bb5a-8e57a965ba68
|
|
18
19
|
test("ProductPriceChanged issues UpdatePrice", () =>
|
|
19
20
|
whenIncomingEvent(
|
|
20
21
|
ExtensionPoint.ProductPriceChanged({productId: p1, price: 7.5}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/online-shop-aggregates-ordering",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.251",
|
|
4
4
|
"description": "Online Shop example — Ordering plugin (Customer & Order aggregates)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -21,18 +21,18 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"sury": "11.0.0",
|
|
24
|
-
"@reventlessdev/online-shop-aggregates-ordering-spec": "3.0.0-alpha.141",
|
|
25
|
-
"@reventlessdev/online-shop-aggregates-catalog-spec": "3.0.0-alpha.141",
|
|
26
24
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.22",
|
|
27
|
-
"@reventlessdev/
|
|
28
|
-
"@reventlessdev/reventless-gwt": "1.0.0-alpha.
|
|
29
|
-
"@reventlessdev/reventless-
|
|
30
|
-
"@reventlessdev/
|
|
25
|
+
"@reventlessdev/online-shop-aggregates-catalog-spec": "3.0.0-alpha.142",
|
|
26
|
+
"@reventlessdev/reventless-gwt": "1.0.0-alpha.218",
|
|
27
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.171",
|
|
28
|
+
"@reventlessdev/online-shop-aggregates-ordering-spec": "3.0.0-alpha.142",
|
|
29
|
+
"@reventlessdev/reventless-local": "3.0.0-alpha.261",
|
|
30
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.143"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"rescript": "12.3.1",
|
|
34
34
|
"sury-ppx": "11.0.0",
|
|
35
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
35
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.89"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"rescript": "^12.3.1"
|
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
@@reventless.gwt
|
|
2
2
|
|
|
3
|
+
open Ordering_Examples
|
|
4
|
+
|
|
3
5
|
describe("CatalogProduct Behavior", () => {
|
|
6
|
+
// scenario-id: e0d3dd62-1687-4920-a1ad-d61733936926
|
|
4
7
|
test("Sync on new aggregate produces Synced", () =>
|
|
5
8
|
givenEvents([])
|
|
6
|
-
->whenCmd(Sync({name:
|
|
7
|
-
->thenEvent(Synced({name:
|
|
9
|
+
->whenCmd(Sync({name: laptop, price: 999.99}))
|
|
10
|
+
->thenEvent(Synced({name: laptop, price: 999.99}))
|
|
8
11
|
)
|
|
9
12
|
|
|
13
|
+
// scenario-id: aa7ebc46-2b74-440d-92b1-d5b6262de254
|
|
10
14
|
test("Sync on already-synced aggregate produces no events (idempotent)", () =>
|
|
11
|
-
givenEvents([Synced({name:
|
|
12
|
-
->whenCmd(Sync({name:
|
|
15
|
+
givenEvents([Synced({name: laptop, price: 999.99})])
|
|
16
|
+
->whenCmd(Sync({name: laptop, price: 999.99}))
|
|
13
17
|
->thenNoEvent
|
|
14
18
|
)
|
|
15
19
|
|
|
20
|
+
// scenario-id: 69fe9b40-3a62-497d-b39b-098173ef8cd5
|
|
16
21
|
test("UpdatePrice on never-synced aggregate produces no events (idempotent)", () =>
|
|
17
22
|
givenEvents([])
|
|
18
23
|
->whenCmd(UpdatePrice({price: 1.0}))
|
|
19
24
|
->thenNoEvent
|
|
20
25
|
)
|
|
21
26
|
|
|
27
|
+
// scenario-id: fef61ceb-02a6-4d0c-a1e9-297c99a4d7d9
|
|
22
28
|
test("UpdatePrice on synced aggregate produces PriceUpdated", () =>
|
|
23
|
-
givenEvents([Synced({name:
|
|
29
|
+
givenEvents([Synced({name: laptop, price: 999.99})])
|
|
24
30
|
->whenCmd(UpdatePrice({price: 899.99}))
|
|
25
31
|
->thenEvent(PriceUpdated({price: 899.99}))
|
|
26
32
|
)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Behavior_GWT$ReventlessGwt from "@reventlessdev/reventless-gwt/src/Behavior_GWT.res.mjs";
|
|
4
4
|
import * as CatalogProduct$OrderingPlugin from "../../../src/CatalogProduct/Aggregate/CatalogProduct.res.mjs";
|
|
5
|
+
import * as Ordering_Examples$OrderingPlugin from "../../Ordering_Examples.res.mjs";
|
|
5
6
|
import * as CatalogProduct_Behavior$OrderingPlugin from "../../../src/CatalogProduct/Aggregate/CatalogProduct_Behavior.res.mjs";
|
|
6
7
|
|
|
7
8
|
let include = Behavior_GWT$ReventlessGwt.MakeFromAggregate({
|
|
@@ -38,20 +39,20 @@ let thenNoEvent = include.thenNoEvent;
|
|
|
38
39
|
describe("CatalogProduct Behavior", () => {
|
|
39
40
|
test("Sync on new aggregate produces Synced", () => thenEvent(whenCmd(givenEvents([]), {
|
|
40
41
|
TAG: "Sync",
|
|
41
|
-
name:
|
|
42
|
+
name: Ordering_Examples$OrderingPlugin.laptop,
|
|
42
43
|
price: 999.99
|
|
43
44
|
}), {
|
|
44
45
|
TAG: "Synced",
|
|
45
|
-
name:
|
|
46
|
+
name: Ordering_Examples$OrderingPlugin.laptop,
|
|
46
47
|
price: 999.99
|
|
47
48
|
}));
|
|
48
49
|
test("Sync on already-synced aggregate produces no events (idempotent)", () => thenNoEvent(whenCmd(givenEvents([{
|
|
49
50
|
TAG: "Synced",
|
|
50
|
-
name:
|
|
51
|
+
name: Ordering_Examples$OrderingPlugin.laptop,
|
|
51
52
|
price: 999.99
|
|
52
53
|
}]), {
|
|
53
54
|
TAG: "Sync",
|
|
54
|
-
name:
|
|
55
|
+
name: Ordering_Examples$OrderingPlugin.laptop,
|
|
55
56
|
price: 999.99
|
|
56
57
|
})));
|
|
57
58
|
test("UpdatePrice on never-synced aggregate produces no events (idempotent)", () => thenNoEvent(whenCmd(givenEvents([]), {
|
|
@@ -60,7 +61,7 @@ describe("CatalogProduct Behavior", () => {
|
|
|
60
61
|
})));
|
|
61
62
|
test("UpdatePrice on synced aggregate produces PriceUpdated", () => thenEvent(whenCmd(givenEvents([{
|
|
62
63
|
TAG: "Synced",
|
|
63
|
-
name:
|
|
64
|
+
name: Ordering_Examples$OrderingPlugin.laptop,
|
|
64
65
|
price: 999.99
|
|
65
66
|
}]), {
|
|
66
67
|
TAG: "UpdatePrice",
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
@@reventless.gwt(AvailableProducts_Projections.CatalogProductMapping)
|
|
2
2
|
|
|
3
3
|
describe("AvailableProducts ReadModel ← CatalogProduct", () => {
|
|
4
|
+
// scenario-id: 845f7b2c-e29b-469f-a497-654927750d09
|
|
4
5
|
test("Synced sets initial read model state", () =>
|
|
5
6
|
givenEvents([])
|
|
6
7
|
->whenEvent(CatalogProduct.Synced({name: "Laptop", price: 999.99}))
|
|
7
8
|
->thenState({AvailableProducts.name: "Laptop", price: 999.99})
|
|
8
9
|
)
|
|
9
10
|
|
|
11
|
+
// scenario-id: 272d70a8-20d7-4f33-bca1-ec101bd5f702
|
|
10
12
|
test("PriceUpdated updates the price", () =>
|
|
11
13
|
givenEvents([CatalogProduct.Synced({name: "Laptop", price: 999.99})])
|
|
12
14
|
->whenEvent(CatalogProduct.PriceUpdated({price: 899.99}))
|
|
@@ -1,80 +1,95 @@
|
|
|
1
1
|
@@reventless.gwt
|
|
2
2
|
|
|
3
|
+
open Ordering_Examples
|
|
4
|
+
|
|
3
5
|
describe("Customer Behavior", () => {
|
|
6
|
+
// scenario-id: 5936d064-3500-474f-ac41-619765828d32
|
|
4
7
|
test("Register on new aggregate produces Registered", () =>
|
|
5
8
|
givenEvents([])
|
|
6
|
-
->whenCmd(Register({email:
|
|
7
|
-
->thenEvent(Registered({email:
|
|
9
|
+
->whenCmd(Register({email: aliceEmail, address: mainStreet}))
|
|
10
|
+
->thenEvent(Registered({email: aliceEmail, address: mainStreet}))
|
|
8
11
|
)
|
|
9
12
|
|
|
13
|
+
// scenario-id: 93201f16-17d6-4f94-a096-2dbec3c4306c
|
|
10
14
|
test("Register on existing aggregate returns CustomerAlreadyRegistered", () =>
|
|
11
|
-
givenEvents([Registered({email:
|
|
12
|
-
->whenCmd(Register({email:
|
|
15
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet})])
|
|
16
|
+
->whenCmd(Register({email: bobEmail, address: oakAvenue}))
|
|
13
17
|
->thenError(CustomerAlreadyRegistered)
|
|
14
18
|
)
|
|
15
19
|
|
|
20
|
+
// scenario-id: fcbc5972-10f0-43ae-a402-21fa7e398e2b
|
|
16
21
|
test("Register on deactivated aggregate returns CustomerAlreadyDeactivated", () =>
|
|
17
|
-
givenEvents([Registered({email:
|
|
18
|
-
->whenCmd(Register({email:
|
|
22
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet}), Deactivated])
|
|
23
|
+
->whenCmd(Register({email: bobEmail, address: oakAvenue}))
|
|
19
24
|
->thenError(CustomerAlreadyDeactivated)
|
|
20
25
|
)
|
|
21
26
|
|
|
27
|
+
// scenario-id: eb52c72f-448a-47f6-b6dc-1454fb0976a6
|
|
22
28
|
test("UpdateEmail on non-existent aggregate returns CustomerNotFound", () =>
|
|
23
29
|
givenEvents([])
|
|
24
|
-
->whenCmd(UpdateEmail({email:
|
|
30
|
+
->whenCmd(UpdateEmail({email: bobEmail}))
|
|
25
31
|
->thenError(CustomerNotFound)
|
|
26
32
|
)
|
|
27
33
|
|
|
34
|
+
// scenario-id: 0da39fef-7112-4f6b-93d6-f1479d8d384b
|
|
28
35
|
test("UpdateEmail on active customer produces EmailUpdated", () =>
|
|
29
|
-
givenEvents([Registered({email:
|
|
36
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet})])
|
|
30
37
|
->whenCmd(UpdateEmail({email: "alice2@example.com"}))
|
|
31
38
|
->thenEvent(EmailUpdated({email: "alice2@example.com"}))
|
|
32
39
|
)
|
|
33
40
|
|
|
41
|
+
// scenario-id: 27d8e526-daa8-4b11-be68-c1107394f75d
|
|
34
42
|
test("UpdateEmail to same email produces no events (idempotent)", () =>
|
|
35
|
-
givenEvents([Registered({email:
|
|
36
|
-
->whenCmd(UpdateEmail({email:
|
|
43
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet})])
|
|
44
|
+
->whenCmd(UpdateEmail({email: aliceEmail}))
|
|
37
45
|
->thenNoEvent
|
|
38
46
|
)
|
|
39
47
|
|
|
48
|
+
// scenario-id: f95d0cde-1011-4566-975b-ef086015d811
|
|
40
49
|
test("UpdateEmail on deactivated customer returns CustomerAlreadyDeactivated", () =>
|
|
41
|
-
givenEvents([Registered({email:
|
|
42
|
-
->whenCmd(UpdateEmail({email:
|
|
50
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet}), Deactivated])
|
|
51
|
+
->whenCmd(UpdateEmail({email: bobEmail}))
|
|
43
52
|
->thenError(CustomerAlreadyDeactivated)
|
|
44
53
|
)
|
|
45
54
|
|
|
55
|
+
// scenario-id: 856f318e-b0da-4ae8-98bd-0a27c32cfb68
|
|
46
56
|
test("UpdateAddress on non-existent aggregate returns CustomerNotFound", () =>
|
|
47
57
|
givenEvents([])
|
|
48
58
|
->whenCmd(UpdateAddress({address: "x"}))
|
|
49
59
|
->thenError(CustomerNotFound)
|
|
50
60
|
)
|
|
51
61
|
|
|
62
|
+
// scenario-id: 2f4959d6-b687-4659-b5a6-282a6463d1d8
|
|
52
63
|
test("UpdateAddress on active customer produces AddressUpdated", () =>
|
|
53
|
-
givenEvents([Registered({email:
|
|
64
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet})])
|
|
54
65
|
->whenCmd(UpdateAddress({address: "789 Pine Rd"}))
|
|
55
66
|
->thenEvent(AddressUpdated({address: "789 Pine Rd"}))
|
|
56
67
|
)
|
|
57
68
|
|
|
69
|
+
// scenario-id: 004ce506-1231-43d7-a659-263af800b815
|
|
58
70
|
test("UpdateAddress to same address produces no events (idempotent)", () =>
|
|
59
|
-
givenEvents([Registered({email:
|
|
60
|
-
->whenCmd(UpdateAddress({address:
|
|
71
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet})])
|
|
72
|
+
->whenCmd(UpdateAddress({address: mainStreet}))
|
|
61
73
|
->thenNoEvent
|
|
62
74
|
)
|
|
63
75
|
|
|
76
|
+
// scenario-id: 8c84e2c8-e77c-497d-bad0-70db6643c3de
|
|
64
77
|
test("Deactivate on non-existent aggregate returns CustomerNotFound", () =>
|
|
65
78
|
givenEvents([])
|
|
66
79
|
->whenCmd(Deactivate)
|
|
67
80
|
->thenError(CustomerNotFound)
|
|
68
81
|
)
|
|
69
82
|
|
|
83
|
+
// scenario-id: 54c0ec8c-f937-41b7-bed0-963c54702564
|
|
70
84
|
test("Deactivate on active customer produces Deactivated", () =>
|
|
71
|
-
givenEvents([Registered({email:
|
|
85
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet})])
|
|
72
86
|
->whenCmd(Deactivate)
|
|
73
87
|
->thenEvent(Deactivated)
|
|
74
88
|
)
|
|
75
89
|
|
|
90
|
+
// scenario-id: 083c8024-7e68-44d6-b9ff-61a3250202bf
|
|
76
91
|
test("Deactivate on deactivated customer produces no events (idempotent)", () =>
|
|
77
|
-
givenEvents([Registered({email:
|
|
92
|
+
givenEvents([Registered({email: aliceEmail, address: mainStreet}), Deactivated])
|
|
78
93
|
->whenCmd(Deactivate)
|
|
79
94
|
->thenNoEvent
|
|
80
95
|
)
|