@reventlessdev/online-shop-hybrid-ordering 1.0.0-alpha.246 → 1.0.0-alpha.248

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/package.json +10 -10
  3. package/tests/CatalogProduct/StateChange/SyncCatalogProduct_GWT.res +35 -32
  4. package/tests/CatalogProduct/StateChange/SyncCatalogProduct_GWT.res.mjs +46 -55
  5. package/tests/CatalogProduct/StateViewStream/AvailableProducts_GWT.res +16 -13
  6. package/tests/CatalogProduct/StateViewStream/AvailableProducts_GWT.res.mjs +29 -37
  7. package/tests/Customer/Aggregate/Customer_GWT.res +60 -36
  8. package/tests/Customer/Aggregate/Customer_GWT.res.mjs +56 -55
  9. package/tests/Customer/OutboundTranslation/GeocodeCustomerAddress_GWT.res +30 -18
  10. package/tests/Customer/OutboundTranslation/GeocodeCustomerAddress_GWT.res.mjs +22 -19
  11. package/tests/Customer/OutboundTranslation/VerifyCustomerEmail_GWT.res +6 -0
  12. package/tests/Customer/ReadModelStream/Customers_GWT.res +24 -15
  13. package/tests/Customer/ReadModelStream/Customers_GWT.res.mjs +17 -24
  14. package/tests/Customer/StateChange/EmailVerificationChallenges_GWT.res +45 -45
  15. package/tests/Customer/StateChange/EmailVerificationChallenges_GWT.res.mjs +42 -47
  16. package/tests/Extension/Products_Extension_GWT.res +23 -6
  17. package/tests/Extension/Products_Extension_GWT.res.mjs +9 -17
  18. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res +7 -7
  19. package/tests/ExtensionPoint/Orders_ExtensionPointMapping_GWT.res.mjs +8 -19
  20. package/tests/Flow/OrderingFlow_GWT.res +29 -30
  21. package/tests/Flow/OrderingFlow_GWT.res.mjs +28 -43
  22. package/tests/Notification/Automation/NotificationIntake_GWT.res +28 -20
  23. package/tests/Notification/Automation/NotificationIntake_GWT.res.mjs +24 -31
  24. package/tests/Notification/OutboundTranslation/SendNotification_GWT.res +18 -10
  25. package/tests/Notification/OutboundTranslation/SendNotification_GWT.res.mjs +13 -12
  26. package/tests/Notification/StateChange/NotificationPreferences_GWT.res +40 -28
  27. package/tests/Notification/StateChange/NotificationPreferences_GWT.res.mjs +33 -32
  28. package/tests/Notification/StateChange/NotificationSourceClaims_GWT.res +10 -3
  29. package/tests/Notification/StateChange/NotificationSourceClaims_GWT.res.mjs +4 -3
  30. package/tests/Notification/StateViewStream/NotificationDeliveries_GWT.res +45 -15
  31. package/tests/Notification/StateViewStream/NotificationDeliveries_GWT.res.mjs +42 -19
  32. package/tests/Order/Automation/AutoShipOrder_GWT.res +17 -10
  33. package/tests/Order/Automation/AutoShipOrder_GWT.res.mjs +10 -13
  34. package/tests/Order/StateChange/CancelOrder_GWT.res +25 -18
  35. package/tests/Order/StateChange/CancelOrder_GWT.res.mjs +20 -27
  36. package/tests/Order/StateChange/PlaceOrder_Examples.res +13 -0
  37. package/tests/Order/StateChange/PlaceOrder_Examples.res.mjs +16 -0
  38. package/tests/Order/StateChange/PlaceOrder_GWT.res +449 -243
  39. package/tests/Order/StateChange/PlaceOrder_GWT.res.mjs +509 -289
  40. package/tests/Order/StateChange/ShipOrder_GWT.res +17 -18
  41. package/tests/Order/StateChange/ShipOrder_GWT.res.mjs +18 -29
  42. package/tests/Order/StateViewStream/Orders_GWT.res +71 -68
  43. package/tests/Order/StateViewStream/Orders_GWT.res.mjs +61 -80
  44. package/tests/Ordering_Examples.res +49 -0
  45. package/tests/Ordering_Examples.res.mjs +103 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 1.0.0-alpha.248 (2026-09-23)
7
+
8
+ **Note:** Version bump only for package @reventlessdev/online-shop-hybrid-ordering
9
+
10
+
11
+
12
+
13
+
14
+ # 1.0.0-alpha.247 (2026-09-22)
15
+
16
+ **Note:** Version bump only for package @reventlessdev/online-shop-hybrid-ordering
17
+
18
+
19
+
20
+
21
+
6
22
  # 1.0.0-alpha.246 (2026-09-21)
7
23
 
8
24
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reventlessdev/online-shop-hybrid-ordering",
3
- "version": "1.0.0-alpha.246",
3
+ "version": "1.0.0-alpha.248",
4
4
  "description": "Online Shop Hybrid example — Ordering plugin (Customer aggregate + Order/CatalogProduct DCB)",
5
5
  "license": "Apache-2.0",
6
6
  "jest": {
@@ -21,20 +21,20 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "sury": "11.0.0",
24
- "@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.138",
24
+ "@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.139",
25
+ "@reventlessdev/online-shop-hybrid-ordering-spec": "1.0.0-alpha.138",
26
+ "@reventlessdev/reventless-gwt": "1.0.0-alpha.217",
25
27
  "@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.22",
26
- "@reventlessdev/reventless-gwt": "1.0.0-alpha.216",
27
- "@reventlessdev/reventless-infra": "3.0.0-alpha.169",
28
- "@reventlessdev/online-shop-hybrid-ordering-spec": "1.0.0-alpha.137",
29
- "@reventlessdev/reventless-local": "3.0.0-alpha.259",
30
- "@reventlessdev/trait-address-geocoding": "1.0.0-alpha.18",
31
- "@reventlessdev/trait-notification": "1.0.0-alpha.18",
32
- "@reventlessdev/reventless-spec": "3.0.0-alpha.141"
28
+ "@reventlessdev/reventless-infra": "3.0.0-alpha.170",
29
+ "@reventlessdev/reventless-local": "3.0.0-alpha.260",
30
+ "@reventlessdev/reventless-spec": "3.0.0-alpha.142",
31
+ "@reventlessdev/trait-address-geocoding": "1.0.0-alpha.19",
32
+ "@reventlessdev/trait-notification": "1.0.0-alpha.19"
33
33
  },
34
34
  "devDependencies": {
35
35
  "rescript": "12.3.1",
36
36
  "sury-ppx": "11.0.0",
37
- "@reventlessdev/reventless-ppx": "1.0.0-alpha.81"
37
+ "@reventlessdev/reventless-ppx": "1.0.0-alpha.89"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "rescript": "^12.3.1"
@@ -1,86 +1,89 @@
1
1
  @@reventless.gwt
2
2
 
3
- let pid = CatalogSpec.ProductId.make
3
+ open Ordering_Examples
4
4
 
5
5
  // Prices are money, so a test writes the amount a person would say and converts
6
6
  // it once. `ofMajor` scales by the currency's own exponent, which is what keeps
7
7
  // the literal honest: 9.99 EUR is 999 cents, and the same call on a JPY price
8
8
  // would scale by 1.
9
- let eur = amount => Reventless.Money.ofMajor(~amount, ~currency=EUR)
10
9
 
11
10
  describe("SyncCatalogProduct StateChangeSlice", () => {
11
+ // scenario-id: 8dfa1851-7779-4c9d-beeb-674e0664e16a
12
12
  test("SyncNewProduct produces CatalogProductSynced", () =>
13
13
  givenEvents([])
14
- ->whenCmd(SyncNewProduct({productId: pid("p1"), name: "Laptop", price: eur(999.99)}))
15
- ->thenEvent(CatalogProductSynced({productId: pid("p1"), name: "Laptop", price: eur(999.99)}))
14
+ ->whenCmd(SyncNewProduct({productId: p1, name: laptop, price: laptopPrice}))
15
+ ->thenEvent(CatalogProductSynced({productId: p1, name: laptop, price: laptopPrice}))
16
16
  )
17
17
 
18
+ // scenario-id: c160117a-1887-4d22-ae68-49751a19a632
18
19
  test("ChangeSyncedPrice produces CatalogProductPriceChanged", () =>
19
- givenEvents([CatalogProductSynced({name: "Laptop", price: eur(999.99)})])
20
- ->whenCmd(ChangeSyncedPrice({productId: pid("p1"), price: eur(899.99)}))
21
- ->thenEvent(CatalogProductPriceChanged({productId: pid("p1"), price: eur(899.99)}))
20
+ givenEvents([CatalogProductSynced({name: laptop, price: laptopPrice})])
21
+ ->whenCmd(ChangeSyncedPrice({productId: p1, price: laptopChangedPrice}))
22
+ ->thenEvent(CatalogProductPriceChanged({productId: p1, price: laptopChangedPrice}))
22
23
  )
23
24
 
25
+ // scenario-id: 76ba6d75-b136-413c-b225-d8f40b0fda6c
24
26
  test("re-syncing identical product data produces no events (idempotent)", () =>
25
- givenEvents([CatalogProductSynced({name: "Laptop", price: eur(999.99)})])
26
- ->whenCmd(SyncNewProduct({productId: pid("p1"), name: "Laptop", price: eur(999.99)}))
27
+ givenEvents([CatalogProductSynced({name: laptop, price: laptopPrice})])
28
+ ->whenCmd(SyncNewProduct({productId: p1, name: laptop, price: laptopPrice}))
27
29
  ->thenNoEvent
28
30
  )
29
31
 
32
+ // scenario-id: 0ed2ff32-af9f-47b4-88e7-1cea906dca7b
30
33
  test("re-applying the current price produces no events (idempotent)", () =>
31
- givenEvents([CatalogProductSynced({name: "Laptop", price: eur(999.99)})])
32
- ->whenCmd(ChangeSyncedPrice({productId: pid("p1"), price: eur(999.99)}))
34
+ givenEvents([CatalogProductSynced({name: laptop, price: laptopPrice})])
35
+ ->whenCmd(ChangeSyncedPrice({productId: p1, price: laptopPrice}))
33
36
  ->thenNoEvent
34
37
  )
35
38
 
39
+ // scenario-id: beb2c75d-f258-49e9-bf75-949c00297f86
36
40
  test("WithdrawSyncedProduct produces CatalogProductWithdrawn", () =>
37
- givenEvents([CatalogProductSynced({name: "Laptop", price: eur(999.99)})])
38
- ->whenCmd(WithdrawSyncedProduct({productId: pid("p1")}))
39
- ->thenEvent(CatalogProductWithdrawn({productId: pid("p1")}))
41
+ givenEvents([CatalogProductSynced({name: laptop, price: laptopPrice})])
42
+ ->whenCmd(WithdrawSyncedProduct({productId: p1}))
43
+ ->thenEvent(CatalogProductWithdrawn({productId: p1}))
40
44
  )
41
45
 
46
+ // scenario-id: 224a3bf7-0231-4ee4-ad3e-6ace53abdc13
42
47
  test("withdrawing an already-withdrawn product produces no events", () =>
43
- givenEvents([
44
- CatalogProductSynced({name: "Laptop", price: eur(999.99)}),
45
- CatalogProductWithdrawn,
46
- ])
47
- ->whenCmd(WithdrawSyncedProduct({productId: pid("p1")}))
48
+ givenEvents([CatalogProductSynced({name: laptop, price: laptopPrice}), CatalogProductWithdrawn])
49
+ ->whenCmd(WithdrawSyncedProduct({productId: p1}))
48
50
  ->thenNoEvent
49
51
  )
50
52
 
51
53
  // The assertion that pins the shadow as the source. Ordering restores the name
52
54
  // and price it kept through the withdrawal — Catalog's `ProductRelisted` carries
53
55
  // neither, and is never asked to.
56
+ // scenario-id: c475bba4-415d-4461-bbaf-f511e4999b1e
54
57
  test("RelistSyncedProduct restores name and price from the shadow", () =>
55
- givenEvents([
56
- CatalogProductSynced({name: "Laptop", price: eur(999.99)}),
57
- CatalogProductWithdrawn,
58
- ])
59
- ->whenCmd(RelistSyncedProduct({productId: pid("p1")}))
60
- ->thenEvent(CatalogProductRelisted({productId: pid("p1"), name: "Laptop", price: eur(999.99)}))
58
+ givenEvents([CatalogProductSynced({name: laptop, price: laptopPrice}), CatalogProductWithdrawn])
59
+ ->whenCmd(RelistSyncedProduct({productId: p1}))
60
+ ->thenEvent(CatalogProductRelisted({productId: p1, name: laptop, price: laptopPrice}))
61
61
  )
62
62
 
63
63
  // And the latest price, not the one it was first synced at: the shadow keeps
64
64
  // being maintained while the product is off the shelf.
65
+ // scenario-id: e8087d7c-15a7-416b-9662-1f0fc1e12b36
65
66
  test("and restores the price it was last repriced to", () =>
66
67
  givenEvents([
67
- CatalogProductSynced({name: "Laptop", price: eur(999.99)}),
68
- CatalogProductPriceChanged({price: eur(899.99)}),
68
+ CatalogProductSynced({name: laptop, price: laptopPrice}),
69
+ CatalogProductPriceChanged({price: laptopChangedPrice}),
69
70
  CatalogProductWithdrawn,
70
71
  ])
71
- ->whenCmd(RelistSyncedProduct({productId: pid("p1")}))
72
- ->thenEvent(CatalogProductRelisted({productId: pid("p1"), name: "Laptop", price: eur(899.99)}))
72
+ ->whenCmd(RelistSyncedProduct({productId: p1}))
73
+ ->thenEvent(CatalogProductRelisted({productId: p1, name: laptop, price: laptopChangedPrice}))
73
74
  )
74
75
 
76
+ // scenario-id: 832afe90-b0e1-4f59-8ae5-d7ee17eb8f2a
75
77
  test("relisting a product that is not withdrawn produces no events", () =>
76
- givenEvents([CatalogProductSynced({name: "Laptop", price: eur(999.99)})])
77
- ->whenCmd(RelistSyncedProduct({productId: pid("p1")}))
78
+ givenEvents([CatalogProductSynced({name: laptop, price: laptopPrice})])
79
+ ->whenCmd(RelistSyncedProduct({productId: p1}))
78
80
  ->thenNoEvent
79
81
  )
80
82
 
81
83
  // Nothing to restore, so nothing is invented: a row with a made-up name and a
82
84
  // zero price would appear in the shopper's catalog backed by no Catalog product.
85
+ // scenario-id: e44fa5b2-b90c-43cc-bf7b-924ba3582c8a
83
86
  test("relisting a product never synced produces no events", () =>
84
- givenEvents([])->whenCmd(RelistSyncedProduct({productId: pid("p1")}))->thenNoEvent
87
+ givenEvents([])->whenCmd(RelistSyncedProduct({productId: p1}))->thenNoEvent
85
88
  )
86
89
  })
@@ -1,8 +1,7 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
- import * as Money$Reventless from "@reventlessdev/reventless-spec/src/semantic/Money.res.mjs";
4
- import * as ProductId$CatalogSpec from "@reventlessdev/online-shop-hybrid-catalog-spec/src/ProductId.res.mjs";
5
3
  import * as Behavior_GWT$ReventlessGwt from "@reventlessdev/reventless-gwt/src/Behavior_GWT.res.mjs";
4
+ import * as Ordering_Examples$OrderingPlugin from "../../Ordering_Examples.res.mjs";
6
5
  import * as SyncCatalogProduct$OrderingPlugin from "../../../src/CatalogProduct/StateChange/SyncCatalogProduct.res.mjs";
7
6
  import * as SyncCatalogProduct_Behavior$OrderingPlugin from "../../../src/CatalogProduct/StateChange/SyncCatalogProduct_Behavior.res.mjs";
8
7
 
@@ -30,123 +29,119 @@ let thenEvent = include.thenEvent;
30
29
 
31
30
  let thenNoEvent = include.thenNoEvent;
32
31
 
33
- function eur(amount) {
34
- return Money$Reventless.ofMajor(amount, "EUR");
35
- }
36
-
37
32
  describe("SyncCatalogProduct StateChangeSlice", () => {
38
33
  test("SyncNewProduct produces CatalogProductSynced", () => thenEvent(whenCmd(givenEvents([]), {
39
34
  TAG: "SyncNewProduct",
40
- productId: ProductId$CatalogSpec.make("p1"),
41
- name: "Laptop",
42
- price: Money$Reventless.ofMajor(999.99, "EUR")
35
+ productId: Ordering_Examples$OrderingPlugin.p1,
36
+ name: Ordering_Examples$OrderingPlugin.laptop,
37
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
43
38
  }), {
44
39
  TAG: "CatalogProductSynced",
45
- productId: ProductId$CatalogSpec.make("p1"),
46
- name: "Laptop",
47
- price: Money$Reventless.ofMajor(999.99, "EUR")
40
+ productId: Ordering_Examples$OrderingPlugin.p1,
41
+ name: Ordering_Examples$OrderingPlugin.laptop,
42
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
48
43
  }));
49
44
  test("ChangeSyncedPrice produces CatalogProductPriceChanged", () => thenEvent(whenCmd(givenEvents([{
50
45
  TAG: "CatalogProductSynced",
51
- name: "Laptop",
52
- price: Money$Reventless.ofMajor(999.99, "EUR")
46
+ name: Ordering_Examples$OrderingPlugin.laptop,
47
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
53
48
  }]), {
54
49
  TAG: "ChangeSyncedPrice",
55
- productId: ProductId$CatalogSpec.make("p1"),
56
- price: Money$Reventless.ofMajor(899.99, "EUR")
50
+ productId: Ordering_Examples$OrderingPlugin.p1,
51
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
57
52
  }), {
58
53
  TAG: "CatalogProductPriceChanged",
59
- productId: ProductId$CatalogSpec.make("p1"),
60
- price: Money$Reventless.ofMajor(899.99, "EUR")
54
+ productId: Ordering_Examples$OrderingPlugin.p1,
55
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
61
56
  }));
62
57
  test("re-syncing identical product data produces no events (idempotent)", () => thenNoEvent(whenCmd(givenEvents([{
63
58
  TAG: "CatalogProductSynced",
64
- name: "Laptop",
65
- price: Money$Reventless.ofMajor(999.99, "EUR")
59
+ name: Ordering_Examples$OrderingPlugin.laptop,
60
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
66
61
  }]), {
67
62
  TAG: "SyncNewProduct",
68
- productId: ProductId$CatalogSpec.make("p1"),
69
- name: "Laptop",
70
- price: Money$Reventless.ofMajor(999.99, "EUR")
63
+ productId: Ordering_Examples$OrderingPlugin.p1,
64
+ name: Ordering_Examples$OrderingPlugin.laptop,
65
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
71
66
  })));
72
67
  test("re-applying the current price produces no events (idempotent)", () => thenNoEvent(whenCmd(givenEvents([{
73
68
  TAG: "CatalogProductSynced",
74
- name: "Laptop",
75
- price: Money$Reventless.ofMajor(999.99, "EUR")
69
+ name: Ordering_Examples$OrderingPlugin.laptop,
70
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
76
71
  }]), {
77
72
  TAG: "ChangeSyncedPrice",
78
- productId: ProductId$CatalogSpec.make("p1"),
79
- price: Money$Reventless.ofMajor(999.99, "EUR")
73
+ productId: Ordering_Examples$OrderingPlugin.p1,
74
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
80
75
  })));
81
76
  test("WithdrawSyncedProduct produces CatalogProductWithdrawn", () => thenEvent(whenCmd(givenEvents([{
82
77
  TAG: "CatalogProductSynced",
83
- name: "Laptop",
84
- price: Money$Reventless.ofMajor(999.99, "EUR")
78
+ name: Ordering_Examples$OrderingPlugin.laptop,
79
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
85
80
  }]), {
86
81
  TAG: "WithdrawSyncedProduct",
87
- productId: ProductId$CatalogSpec.make("p1")
82
+ productId: Ordering_Examples$OrderingPlugin.p1
88
83
  }), {
89
84
  TAG: "CatalogProductWithdrawn",
90
- productId: ProductId$CatalogSpec.make("p1")
85
+ productId: Ordering_Examples$OrderingPlugin.p1
91
86
  }));
92
87
  test("withdrawing an already-withdrawn product produces no events", () => thenNoEvent(whenCmd(givenEvents([
93
88
  {
94
89
  TAG: "CatalogProductSynced",
95
- name: "Laptop",
96
- price: Money$Reventless.ofMajor(999.99, "EUR")
90
+ name: Ordering_Examples$OrderingPlugin.laptop,
91
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
97
92
  },
98
93
  "CatalogProductWithdrawn"
99
94
  ]), {
100
95
  TAG: "WithdrawSyncedProduct",
101
- productId: ProductId$CatalogSpec.make("p1")
96
+ productId: Ordering_Examples$OrderingPlugin.p1
102
97
  })));
103
98
  test("RelistSyncedProduct restores name and price from the shadow", () => thenEvent(whenCmd(givenEvents([
104
99
  {
105
100
  TAG: "CatalogProductSynced",
106
- name: "Laptop",
107
- price: Money$Reventless.ofMajor(999.99, "EUR")
101
+ name: Ordering_Examples$OrderingPlugin.laptop,
102
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
108
103
  },
109
104
  "CatalogProductWithdrawn"
110
105
  ]), {
111
106
  TAG: "RelistSyncedProduct",
112
- productId: ProductId$CatalogSpec.make("p1")
107
+ productId: Ordering_Examples$OrderingPlugin.p1
113
108
  }), {
114
109
  TAG: "CatalogProductRelisted",
115
- productId: ProductId$CatalogSpec.make("p1"),
116
- name: "Laptop",
117
- price: Money$Reventless.ofMajor(999.99, "EUR")
110
+ productId: Ordering_Examples$OrderingPlugin.p1,
111
+ name: Ordering_Examples$OrderingPlugin.laptop,
112
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
118
113
  }));
119
114
  test("and restores the price it was last repriced to", () => thenEvent(whenCmd(givenEvents([
120
115
  {
121
116
  TAG: "CatalogProductSynced",
122
- name: "Laptop",
123
- price: Money$Reventless.ofMajor(999.99, "EUR")
117
+ name: Ordering_Examples$OrderingPlugin.laptop,
118
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
124
119
  },
125
120
  {
126
121
  TAG: "CatalogProductPriceChanged",
127
- price: Money$Reventless.ofMajor(899.99, "EUR")
122
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
128
123
  },
129
124
  "CatalogProductWithdrawn"
130
125
  ]), {
131
126
  TAG: "RelistSyncedProduct",
132
- productId: ProductId$CatalogSpec.make("p1")
127
+ productId: Ordering_Examples$OrderingPlugin.p1
133
128
  }), {
134
129
  TAG: "CatalogProductRelisted",
135
- productId: ProductId$CatalogSpec.make("p1"),
136
- name: "Laptop",
137
- price: Money$Reventless.ofMajor(899.99, "EUR")
130
+ productId: Ordering_Examples$OrderingPlugin.p1,
131
+ name: Ordering_Examples$OrderingPlugin.laptop,
132
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
138
133
  }));
139
134
  test("relisting a product that is not withdrawn produces no events", () => thenNoEvent(whenCmd(givenEvents([{
140
135
  TAG: "CatalogProductSynced",
141
- name: "Laptop",
142
- price: Money$Reventless.ofMajor(999.99, "EUR")
136
+ name: Ordering_Examples$OrderingPlugin.laptop,
137
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
143
138
  }]), {
144
139
  TAG: "RelistSyncedProduct",
145
- productId: ProductId$CatalogSpec.make("p1")
140
+ productId: Ordering_Examples$OrderingPlugin.p1
146
141
  })));
147
142
  test("relisting a product never synced produces no events", () => thenNoEvent(whenCmd(givenEvents([]), {
148
143
  TAG: "RelistSyncedProduct",
149
- productId: ProductId$CatalogSpec.make("p1")
144
+ productId: Ordering_Examples$OrderingPlugin.p1
150
145
  })));
151
146
  });
152
147
 
@@ -166,8 +161,6 @@ let thenAppendsConditionedOn = include.thenAppendsConditionedOn;
166
161
 
167
162
  let thenAppendsConditionedOnExactly = include.thenAppendsConditionedOnExactly;
168
163
 
169
- let pid = ProductId$CatalogSpec.make;
170
-
171
164
  export {
172
165
  Spec,
173
166
  describe,
@@ -183,7 +176,5 @@ export {
183
176
  thenError,
184
177
  thenAppendsConditionedOn,
185
178
  thenAppendsConditionedOnExactly,
186
- pid,
187
- eur,
188
179
  }
189
180
  /* include Not a pure module */
@@ -1,42 +1,45 @@
1
1
  @@reventless.gwt
2
2
 
3
- let pid = CatalogSpec.ProductId.make
3
+ open Ordering_Examples
4
4
 
5
5
  // Prices are money, so a test writes the amount a person would say and converts
6
6
  // it once. `ofMajor` scales by the currency's own exponent, which is what keeps
7
7
  // the literal honest: 9.99 EUR is 999 cents, and the same call on a JPY price
8
8
  // would scale by 1.
9
- let eur = amount => Reventless.Money.ofMajor(~amount, ~currency=EUR)
10
9
 
11
10
  describe("AvailableProducts StateViewSliceStream", () => {
11
+ // scenario-id: 3296c87a-2296-4561-aafc-078ea72e3613
12
12
  test("CatalogProductSynced creates a row", () =>
13
13
  givenEvents([])
14
- ->whenEvent(CatalogProductSynced({productId: pid("p1"), name: "Laptop", price: eur(999.99)}))
15
- ->thenStateWithId("p1", {productId: pid("p1"), name: "Laptop", price: eur(999.99)})
14
+ ->whenEvent(CatalogProductSynced({productId: p1, name: laptop, price: laptopPrice}))
15
+ ->thenStateWithId("p1", {productId: p1, name: laptop, price: laptopPrice})
16
16
  )
17
17
 
18
+ // scenario-id: dfe57c51-86f7-4536-b5a2-1cbbb9954ac9
18
19
  test("CatalogProductPriceChanged updates the price", () =>
19
- givenEvents([CatalogProductSynced({productId: pid("p1"), name: "Laptop", price: eur(999.99)})])
20
- ->whenEvent(CatalogProductPriceChanged({productId: pid("p1"), price: eur(899.99)}))
21
- ->thenStateWithId("p1", {productId: pid("p1"), name: "Laptop", price: eur(899.99)})
20
+ givenEvents([CatalogProductSynced({productId: p1, name: laptop, price: laptopPrice})])
21
+ ->whenEvent(CatalogProductPriceChanged({productId: p1, price: laptopChangedPrice}))
22
+ ->thenStateWithId("p1", {productId: p1, name: laptop, price: laptopChangedPrice})
22
23
  )
23
24
 
24
25
  // The row leaves the view rather than being marked. This answers "what can I
25
26
  // order", and an operator reading it is elevated — a `@retired` flag here would
26
27
  // hide a withdrawn product from the shopper correctly and show it to the
27
28
  // operator, in the one catalog that is supposed to be the shopper's.
29
+ // scenario-id: c8a6785b-6fe5-4c03-a0e9-ddc5f32ba867
28
30
  test("CatalogProductWithdrawn removes the row", () =>
29
- givenEvents([CatalogProductSynced({productId: pid("p1"), name: "Laptop", price: eur(999.99)})])
30
- ->whenEvent(CatalogProductWithdrawn({productId: pid("p1")}))
31
+ givenEvents([CatalogProductSynced({productId: p1, name: laptop, price: laptopPrice})])
32
+ ->whenEvent(CatalogProductWithdrawn({productId: p1}))
31
33
  ->thenNoState
32
34
  )
33
35
 
36
+ // scenario-id: 8f1acb16-da53-4243-8a09-4af89b226919
34
37
  test("CatalogProductRelisted puts it back with its name and price", () =>
35
38
  givenEvents([
36
- CatalogProductSynced({productId: pid("p1"), name: "Laptop", price: eur(999.99)}),
37
- CatalogProductWithdrawn({productId: pid("p1")}),
39
+ CatalogProductSynced({productId: p1, name: laptop, price: laptopPrice}),
40
+ CatalogProductWithdrawn({productId: p1}),
38
41
  ])
39
- ->whenEvent(CatalogProductRelisted({productId: pid("p1"), name: "Laptop", price: eur(899.99)}))
40
- ->thenStateWithId("p1", {productId: pid("p1"), name: "Laptop", price: eur(899.99)})
42
+ ->whenEvent(CatalogProductRelisted({productId: p1, name: laptop, price: laptopChangedPrice}))
43
+ ->thenStateWithId("p1", {productId: p1, name: laptop, price: laptopChangedPrice})
41
44
  )
42
45
  })
@@ -1,9 +1,9 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
- import * as Money$Reventless from "@reventlessdev/reventless-spec/src/semantic/Money.res.mjs";
4
3
  import * as ProductId$CatalogSpec from "@reventlessdev/online-shop-hybrid-catalog-spec/src/ProductId.res.mjs";
5
4
  import * as Projection_GWT$ReventlessGwt from "@reventlessdev/reventless-gwt/src/Projection_GWT.res.mjs";
6
5
  import * as AvailableProducts$OrderingPlugin from "../../../src/CatalogProduct/StateViewStream/AvailableProducts.res.mjs";
6
+ import * as Ordering_Examples$OrderingPlugin from "../../Ordering_Examples.res.mjs";
7
7
  import * as AvailableProducts_Projection$OrderingPlugin from "../../../src/CatalogProduct/StateViewStream/AvailableProducts_Projection.res.mjs";
8
8
 
9
9
  let include = Projection_GWT$ReventlessGwt.Make({
@@ -28,64 +28,60 @@ let thenStateWithId = include.thenStateWithId;
28
28
 
29
29
  let thenNoState = include.thenNoState;
30
30
 
31
- function eur(amount) {
32
- return Money$Reventless.ofMajor(amount, "EUR");
33
- }
34
-
35
31
  describe("AvailableProducts StateViewSliceStream", () => {
36
32
  test("CatalogProductSynced creates a row", undefined, () => thenStateWithId(whenEvent(givenEvents([]), {
37
33
  TAG: "CatalogProductSynced",
38
- productId: ProductId$CatalogSpec.make("p1"),
39
- name: "Laptop",
40
- price: Money$Reventless.ofMajor(999.99, "EUR")
34
+ productId: Ordering_Examples$OrderingPlugin.p1,
35
+ name: Ordering_Examples$OrderingPlugin.laptop,
36
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
41
37
  }), "p1", {
42
- productId: ProductId$CatalogSpec.make("p1"),
43
- name: "Laptop",
44
- price: Money$Reventless.ofMajor(999.99, "EUR")
38
+ productId: Ordering_Examples$OrderingPlugin.p1,
39
+ name: Ordering_Examples$OrderingPlugin.laptop,
40
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
45
41
  }));
46
42
  test("CatalogProductPriceChanged updates the price", undefined, () => thenStateWithId(whenEvent(givenEvents([{
47
43
  TAG: "CatalogProductSynced",
48
- productId: ProductId$CatalogSpec.make("p1"),
49
- name: "Laptop",
50
- price: Money$Reventless.ofMajor(999.99, "EUR")
44
+ productId: Ordering_Examples$OrderingPlugin.p1,
45
+ name: Ordering_Examples$OrderingPlugin.laptop,
46
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
51
47
  }]), {
52
48
  TAG: "CatalogProductPriceChanged",
53
- productId: ProductId$CatalogSpec.make("p1"),
54
- price: Money$Reventless.ofMajor(899.99, "EUR")
49
+ productId: Ordering_Examples$OrderingPlugin.p1,
50
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
55
51
  }), "p1", {
56
- productId: ProductId$CatalogSpec.make("p1"),
57
- name: "Laptop",
58
- price: Money$Reventless.ofMajor(899.99, "EUR")
52
+ productId: Ordering_Examples$OrderingPlugin.p1,
53
+ name: Ordering_Examples$OrderingPlugin.laptop,
54
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
59
55
  }));
60
56
  test("CatalogProductWithdrawn removes the row", undefined, () => thenNoState(whenEvent(givenEvents([{
61
57
  TAG: "CatalogProductSynced",
62
- productId: ProductId$CatalogSpec.make("p1"),
63
- name: "Laptop",
64
- price: Money$Reventless.ofMajor(999.99, "EUR")
58
+ productId: Ordering_Examples$OrderingPlugin.p1,
59
+ name: Ordering_Examples$OrderingPlugin.laptop,
60
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
65
61
  }]), {
66
62
  TAG: "CatalogProductWithdrawn",
67
- productId: ProductId$CatalogSpec.make("p1")
63
+ productId: Ordering_Examples$OrderingPlugin.p1
68
64
  })));
69
65
  test("CatalogProductRelisted puts it back with its name and price", undefined, () => thenStateWithId(whenEvent(givenEvents([
70
66
  {
71
67
  TAG: "CatalogProductSynced",
72
- productId: ProductId$CatalogSpec.make("p1"),
73
- name: "Laptop",
74
- price: Money$Reventless.ofMajor(999.99, "EUR")
68
+ productId: Ordering_Examples$OrderingPlugin.p1,
69
+ name: Ordering_Examples$OrderingPlugin.laptop,
70
+ price: Ordering_Examples$OrderingPlugin.laptopPrice
75
71
  },
76
72
  {
77
73
  TAG: "CatalogProductWithdrawn",
78
- productId: ProductId$CatalogSpec.make("p1")
74
+ productId: Ordering_Examples$OrderingPlugin.p1
79
75
  }
80
76
  ]), {
81
77
  TAG: "CatalogProductRelisted",
82
- productId: ProductId$CatalogSpec.make("p1"),
83
- name: "Laptop",
84
- price: Money$Reventless.ofMajor(899.99, "EUR")
78
+ productId: Ordering_Examples$OrderingPlugin.p1,
79
+ name: Ordering_Examples$OrderingPlugin.laptop,
80
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
85
81
  }), "p1", {
86
- productId: ProductId$CatalogSpec.make("p1"),
87
- name: "Laptop",
88
- price: Money$Reventless.ofMajor(899.99, "EUR")
82
+ productId: Ordering_Examples$OrderingPlugin.p1,
83
+ name: Ordering_Examples$OrderingPlugin.laptop,
84
+ price: Ordering_Examples$OrderingPlugin.laptopChangedPrice
89
85
  }));
90
86
  });
91
87
 
@@ -109,8 +105,6 @@ let thenThrow = include.thenThrow;
109
105
 
110
106
  let thenFail = include.thenFail;
111
107
 
112
- let pid = ProductId$CatalogSpec.make;
113
-
114
108
  export {
115
109
  Spec,
116
110
  describe,
@@ -128,7 +122,5 @@ export {
128
122
  thenNoState,
129
123
  thenThrow,
130
124
  thenFail,
131
- pid,
132
- eur,
133
125
  }
134
126
  /* include Not a pure module */