@reventlessdev/online-shop-hybrid-ordering 1.0.0-alpha.304 → 1.0.0-alpha.306
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 +15 -0
- package/package.json +9 -9
- package/src/Customer/Aggregate/Customer.res +5 -3
- package/src/Customer/Aggregate/Customer.res.mjs +16 -5
- package/src/Customer/ReadModelStream/Customers_Projections.res.mjs +1 -1
- package/src/Plugin.res.mjs +2 -2
- package/src/capabilities.json +3 -0
- package/tests/Customer/AddressGeocodingConformance_GWT.res.mjs +2 -0
- package/tests/Customer/Aggregate/Customer_GWT.res +112 -0
- package/tests/Customer/Aggregate/Customer_GWT.res.mjs +179 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
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.306 (2026-10-31)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @reventlessdev/online-shop-hybrid-ordering
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# 1.0.0-alpha.305 (2026-10-30)
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* **spec:** an aggregate keyed by its owner's id refuses other callers ([e05f287](https://github.com/ReventlessDev/reventless-core/commit/e05f287eee959d26190af494691c4fa472797cad))
|
|
19
|
+
|
|
20
|
+
|
|
6
21
|
# 1.0.0-alpha.304 (2026-10-30)
|
|
7
22
|
|
|
8
23
|
**Note:** Version bump only for package @reventlessdev/online-shop-hybrid-ordering
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/online-shop-hybrid-ordering",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.306",
|
|
4
4
|
"description": "Online Shop Hybrid example — Ordering plugin (Customer aggregate + Order/CatalogProduct DCB)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"sury": "11.0.0",
|
|
24
|
-
"@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.
|
|
25
|
-
"@reventlessdev/
|
|
24
|
+
"@reventlessdev/online-shop-hybrid-catalog-spec": "1.0.0-alpha.188",
|
|
25
|
+
"@reventlessdev/reventless-gwt": "1.0.0-alpha.274",
|
|
26
26
|
"@reventlessdev/rescript-pulumi-pulumi": "3.0.0-alpha.0",
|
|
27
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.
|
|
28
|
-
"@reventlessdev/
|
|
29
|
-
"@reventlessdev/reventless-
|
|
30
|
-
"@reventlessdev/trait-
|
|
31
|
-
"@reventlessdev/trait-
|
|
32
|
-
"@reventlessdev/reventless-
|
|
27
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.220",
|
|
28
|
+
"@reventlessdev/online-shop-hybrid-ordering-spec": "1.0.0-alpha.187",
|
|
29
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.191",
|
|
30
|
+
"@reventlessdev/trait-notification": "1.0.0-alpha.76",
|
|
31
|
+
"@reventlessdev/trait-address-geocoding": "1.0.0-alpha.76",
|
|
32
|
+
"@reventlessdev/reventless-local": "3.0.0-alpha.317"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"rescript": "12.3.1",
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
@@reventless.spec
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// The customer is the shopper whose account id keys them: only they, or an
|
|
7
|
+
// elevated caller, may act on this aggregate.
|
|
8
|
+
module Id = Reventless.Id.Owned(CustomerId)
|
|
7
9
|
|
|
8
10
|
// A map coordinate carried by location commands/events. `GeoPoint.t` rather than
|
|
9
11
|
// a local `{lat, lng}` record: the wire shape is identical — so every event
|
|
@@ -55,12 +57,12 @@ type command =
|
|
|
55
57
|
// Carries the address it is a verdict about, so a verdict for an address the
|
|
56
58
|
// customer has since changed can be dropped rather than applied.
|
|
57
59
|
| @noApi MarkEmailVerified({@pii email: string})
|
|
58
|
-
| Deactivate
|
|
60
|
+
| @authorize(AllowRoles([Admin])) Deactivate
|
|
59
61
|
// The way back. Deactivation withdraws a customer from ordinary use; it does
|
|
60
62
|
// not erase them, so restoring one needs no payload — the profile is still in
|
|
61
63
|
// the state, and asking a caller to re-supply an email they never changed
|
|
62
64
|
// would be a second chance to get it wrong.
|
|
63
|
-
| Reactivate
|
|
65
|
+
| @authorize(AllowRoles([Admin])) Reactivate
|
|
64
66
|
|
|
65
67
|
@schema
|
|
66
68
|
type event =
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Sury from "sury";
|
|
4
|
+
import * as Id$Reventless from "@reventlessdev/reventless-spec/src/types/Id.res.mjs";
|
|
4
5
|
import * as Pii$Reventless from "@reventlessdev/reventless-spec/src/components/Pii.res.mjs";
|
|
5
6
|
import * as Api$ReventlessInfra from "@reventlessdev/reventless-infra/src/components/Api.res.mjs";
|
|
7
|
+
import * as CustomerId$OrderingPlugin from "../CustomerId.res.mjs";
|
|
6
8
|
import * as AddressGeocoding$TraitAddressGeocoding from "@reventlessdev/trait-address-geocoding/src/AddressGeocoding.res.mjs";
|
|
7
9
|
|
|
10
|
+
let Id = Id$Reventless.Owned(CustomerId$OrderingPlugin);
|
|
11
|
+
|
|
8
12
|
let commandSchema = Sury.union([
|
|
9
13
|
Sury.$schema(s => ({
|
|
10
14
|
TAG: "Register",
|
|
@@ -85,14 +89,21 @@ let traits = [AddressGeocoding$TraitAddressGeocoding.declaration];
|
|
|
85
89
|
|
|
86
90
|
let commandSchema$1 = Api$ReventlessInfra.markNoApiVariants(commandSchema, ["MarkEmailVerified"]);
|
|
87
91
|
|
|
88
|
-
function authorizationOf(
|
|
89
|
-
|
|
92
|
+
function authorizationOf(name) {
|
|
93
|
+
switch (name) {
|
|
94
|
+
case "Deactivate" :
|
|
95
|
+
case "Reactivate" :
|
|
96
|
+
return {
|
|
97
|
+
TAG: "AllowRoles",
|
|
98
|
+
_0: ["Admin"]
|
|
99
|
+
};
|
|
100
|
+
default:
|
|
101
|
+
return "AllowAuthenticated";
|
|
102
|
+
}
|
|
90
103
|
}
|
|
91
104
|
|
|
92
105
|
let name = "Customer";
|
|
93
106
|
|
|
94
|
-
let Id;
|
|
95
|
-
|
|
96
107
|
let moduleUrl = "@reventlessdev/online-shop-hybrid-ordering/src/Customer/Aggregate/Customer.res.mjs";
|
|
97
108
|
|
|
98
109
|
export {
|
|
@@ -106,4 +117,4 @@ export {
|
|
|
106
117
|
moduleUrl,
|
|
107
118
|
authorizationOf,
|
|
108
119
|
}
|
|
109
|
-
/*
|
|
120
|
+
/* Id Not a pure module */
|
|
@@ -169,7 +169,7 @@ function project(param) {
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
let CustomerMapping = Projection$Reventless.Mapping.Make({
|
|
172
|
-
Id:
|
|
172
|
+
Id: Customer$OrderingPlugin.Id,
|
|
173
173
|
name: Customer$OrderingPlugin.name,
|
|
174
174
|
eventSchema: Customer$OrderingPlugin.eventSchema
|
|
175
175
|
})({
|
package/src/Plugin.res.mjs
CHANGED
|
@@ -423,7 +423,7 @@ function Make(Platform) {
|
|
|
423
423
|
moduleUrl: VerifyCustomerEmail_Translation$OrderingPlugin.moduleUrl
|
|
424
424
|
});
|
|
425
425
|
let CustomerAggregate = Platform.Aggregate.Make({
|
|
426
|
-
Id:
|
|
426
|
+
Id: Customer$OrderingPlugin.Id,
|
|
427
427
|
name: Customer$OrderingPlugin.name,
|
|
428
428
|
eventSchema: Customer$OrderingPlugin.eventSchema,
|
|
429
429
|
errorSchema: Customer$OrderingPlugin.errorSchema,
|
|
@@ -440,7 +440,7 @@ function Make(Platform) {
|
|
|
440
440
|
moduleUrl: Customer_Decision$OrderingPlugin.moduleUrl
|
|
441
441
|
})(NoEventMappings$ReventlessInfra.Make({
|
|
442
442
|
name: Customer$OrderingPlugin.name,
|
|
443
|
-
Id:
|
|
443
|
+
Id: Customer$OrderingPlugin.Id,
|
|
444
444
|
commandSchema: Customer$OrderingPlugin.commandSchema
|
|
445
445
|
}));
|
|
446
446
|
let CustomersReadModel = Platform.ReadModelStream.Make({
|
package/src/capabilities.json
CHANGED
|
@@ -170,6 +170,7 @@ let Conformance = AddressGeocoding_Conformance$TraitAddressGeocoding.Make({
|
|
|
170
170
|
subjectB: subjectB,
|
|
171
171
|
posture: "WritesBack",
|
|
172
172
|
Spec: {
|
|
173
|
+
Id: Customer$OrderingPlugin.Id,
|
|
173
174
|
name: Customer$OrderingPlugin.name,
|
|
174
175
|
commandSchema: Customer$OrderingPlugin.commandSchema,
|
|
175
176
|
eventSchema: Customer$OrderingPlugin.eventSchema,
|
|
@@ -178,6 +179,7 @@ let Conformance = AddressGeocoding_Conformance$TraitAddressGeocoding.Make({
|
|
|
178
179
|
},
|
|
179
180
|
Decision: {
|
|
180
181
|
Spec: {
|
|
182
|
+
Id: Customer$OrderingPlugin.Id,
|
|
181
183
|
name: Customer$OrderingPlugin.name,
|
|
182
184
|
commandSchema: Customer$OrderingPlugin.commandSchema,
|
|
183
185
|
eventSchema: Customer$OrderingPlugin.eventSchema,
|
|
@@ -194,3 +194,115 @@ describe("Customer email verification", () => {
|
|
|
194
194
|
->thenError(CustomerNotFound)
|
|
195
195
|
)
|
|
196
196
|
})
|
|
197
|
+
|
|
198
|
+
// A customer is the shopper their id names: they, or an administrator, change
|
|
199
|
+
// their profile. Taking a customer out of use, or back, is an administrator's.
|
|
200
|
+
describe("Who may act on a Customer", () => {
|
|
201
|
+
// scenario-id: 6dc19620-bd20-4e98-a67b-a78aa39083ca
|
|
202
|
+
test("a customer may register themself", () =>
|
|
203
|
+
givenEvents([])
|
|
204
|
+
->onId(c1)
|
|
205
|
+
->asCaller(Caller.owner(c1))
|
|
206
|
+
->whenCmd(Register({email: aliceEmail, address: mainStreet}))
|
|
207
|
+
->thenEvent(Registered({email: Value(aliceEmail), address: Value(mainStreet)}))
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
// scenario-id: ded81926-2cd1-4b9b-8fbf-2683e23e8114
|
|
211
|
+
test("a customer may not register someone else", () =>
|
|
212
|
+
givenEvents([])
|
|
213
|
+
->onId(c1)
|
|
214
|
+
->asCaller(Caller.owner(c2))
|
|
215
|
+
->whenCmd(Register({email: aliceEmail, address: mainStreet}))
|
|
216
|
+
->thenForbidden
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
// scenario-id: f9cd0f95-17f7-477b-be54-8a60c3010bbd
|
|
220
|
+
test("a customer may change their own email", () =>
|
|
221
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
222
|
+
->onId(c1)
|
|
223
|
+
->asCaller(Caller.owner(c1))
|
|
224
|
+
->whenCmd(UpdateEmail({email: aliceNewEmail}))
|
|
225
|
+
->thenEvent(EmailUpdated({email: Value(aliceNewEmail)}))
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
// scenario-id: 786b0aa7-aef7-4e2a-8889-f603c78098ca
|
|
229
|
+
test("another customer may not change the email", () =>
|
|
230
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
231
|
+
->onId(c1)
|
|
232
|
+
->asCaller(Caller.owner(c2))
|
|
233
|
+
->whenCmd(UpdateEmail({email: aliceNewEmail}))
|
|
234
|
+
->thenForbidden
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
// scenario-id: 5e8240aa-2a3c-49c1-ae4a-ffb29a97d138
|
|
238
|
+
test("another customer may not change the address", () =>
|
|
239
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
240
|
+
->onId(c1)
|
|
241
|
+
->asCaller(Caller.owner(c2))
|
|
242
|
+
->whenCmd(UpdateAddress({address: "789 Pine"}))
|
|
243
|
+
->thenForbidden
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
// scenario-id: 46bfc29e-4cfc-42d8-b2f6-296b28609001
|
|
247
|
+
test("an administrator may change any customer's email", () =>
|
|
248
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
249
|
+
->onId(c1)
|
|
250
|
+
->asCaller(Caller.operatorIn([Admin]))
|
|
251
|
+
->whenCmd(UpdateEmail({email: aliceNewEmail}))
|
|
252
|
+
->thenEvent(EmailUpdated({email: Value(aliceNewEmail)}))
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
// scenario-id: 019e2283-a3b3-4972-8fdf-b470320b5ce3
|
|
256
|
+
test("a caller who is not signed in may not change the email", () =>
|
|
257
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
258
|
+
->onId(c1)
|
|
259
|
+
->asCaller(Caller.anonymous)
|
|
260
|
+
->whenCmd(UpdateEmail({email: aliceNewEmail}))
|
|
261
|
+
->thenForbidden
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
// scenario-id: 69dbc4f8-4009-4caa-9e14-f1dd248d7a2a
|
|
265
|
+
test("a customer may not deactivate themself", () =>
|
|
266
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
267
|
+
->onId(c1)
|
|
268
|
+
->asCaller(Caller.owner(c1))
|
|
269
|
+
->whenCmd(Deactivate)
|
|
270
|
+
->thenForbidden
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
// scenario-id: 7d4c5293-934e-4fb5-81d2-b3b8f96c3e5e
|
|
274
|
+
test("an operator who is not an administrator may not deactivate a customer", () =>
|
|
275
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
276
|
+
->onId(c1)
|
|
277
|
+
->asCaller(Caller.operatorIn([Fulfilment]))
|
|
278
|
+
->whenCmd(Deactivate)
|
|
279
|
+
->thenForbidden
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
// scenario-id: 13f06620-a184-4099-be1c-fc727e74788b
|
|
283
|
+
test("an administrator may deactivate a customer", () =>
|
|
284
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)})])
|
|
285
|
+
->onId(c1)
|
|
286
|
+
->asCaller(Caller.operatorIn([Admin]))
|
|
287
|
+
->whenCmd(Deactivate)
|
|
288
|
+
->thenEvent(Deactivated)
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
// scenario-id: c5375866-bf51-47fe-8633-b1b2887e2ab2
|
|
292
|
+
test("a customer may not reactivate themself", () =>
|
|
293
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)}), Deactivated])
|
|
294
|
+
->onId(c1)
|
|
295
|
+
->asCaller(Caller.owner(c1))
|
|
296
|
+
->whenCmd(Reactivate)
|
|
297
|
+
->thenForbidden
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
// scenario-id: f2696c97-6582-4ee7-a403-ee5aed6d8c19
|
|
301
|
+
test("an administrator may reactivate a customer", () =>
|
|
302
|
+
givenEvents([Registered({email: Value(aliceEmail), address: Value(mainStreet)}), Deactivated])
|
|
303
|
+
->onId(c1)
|
|
304
|
+
->asCaller(Caller.operatorIn([Admin]))
|
|
305
|
+
->whenCmd(Reactivate)
|
|
306
|
+
->thenEvent(Reactivated)
|
|
307
|
+
)
|
|
308
|
+
})
|
|
@@ -6,6 +6,7 @@ import * as Customer_Decision$OrderingPlugin from "../../../src/Customer/Aggrega
|
|
|
6
6
|
import * as Ordering_Examples$OrderingPlugin from "../../Ordering_Examples.res.mjs";
|
|
7
7
|
|
|
8
8
|
let include = Decision_GWT$ReventlessGwt.MakeFromAggregate({
|
|
9
|
+
Id: Customer$OrderingPlugin.Id,
|
|
9
10
|
name: Customer$OrderingPlugin.name,
|
|
10
11
|
commandSchema: Customer$OrderingPlugin.commandSchema,
|
|
11
12
|
eventSchema: Customer$OrderingPlugin.eventSchema,
|
|
@@ -13,6 +14,7 @@ let include = Decision_GWT$ReventlessGwt.MakeFromAggregate({
|
|
|
13
14
|
authorizationOf: Customer$OrderingPlugin.authorizationOf
|
|
14
15
|
})({
|
|
15
16
|
Spec: {
|
|
17
|
+
Id: Customer$OrderingPlugin.Id,
|
|
16
18
|
name: Customer$OrderingPlugin.name,
|
|
17
19
|
commandSchema: Customer$OrderingPlugin.commandSchema,
|
|
18
20
|
eventSchema: Customer$OrderingPlugin.eventSchema,
|
|
@@ -32,6 +34,12 @@ let test = include.test;
|
|
|
32
34
|
|
|
33
35
|
let givenEvents = include.givenEvents;
|
|
34
36
|
|
|
37
|
+
let Caller = include.Caller;
|
|
38
|
+
|
|
39
|
+
let asCaller = include.asCaller;
|
|
40
|
+
|
|
41
|
+
let onId = include.onId;
|
|
42
|
+
|
|
35
43
|
let whenCmd = include.whenCmd;
|
|
36
44
|
|
|
37
45
|
let thenEvent = include.thenEvent;
|
|
@@ -40,6 +48,8 @@ let thenNoEvent = include.thenNoEvent;
|
|
|
40
48
|
|
|
41
49
|
let thenError = include.thenError;
|
|
42
50
|
|
|
51
|
+
let thenForbidden = include.thenForbidden;
|
|
52
|
+
|
|
43
53
|
describe("Customer Decision", () => {
|
|
44
54
|
test("Register on new aggregate produces Registered", () => thenEvent(whenCmd(givenEvents([]), {
|
|
45
55
|
TAG: "Register",
|
|
@@ -419,11 +429,175 @@ describe("Customer email verification", () => {
|
|
|
419
429
|
}), "CustomerNotFound"));
|
|
420
430
|
});
|
|
421
431
|
|
|
422
|
-
|
|
432
|
+
describe("Who may act on a Customer", () => {
|
|
433
|
+
test("a customer may register themself", () => thenEvent(whenCmd(asCaller(onId(givenEvents([]), Ordering_Examples$OrderingPlugin.c1), Caller.owner(Ordering_Examples$OrderingPlugin.c1, undefined)), {
|
|
434
|
+
TAG: "Register",
|
|
435
|
+
email: Ordering_Examples$OrderingPlugin.aliceEmail,
|
|
436
|
+
address: Ordering_Examples$OrderingPlugin.mainStreet
|
|
437
|
+
}), {
|
|
438
|
+
TAG: "Registered",
|
|
439
|
+
email: {
|
|
440
|
+
TAG: "Value",
|
|
441
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
442
|
+
},
|
|
443
|
+
address: {
|
|
444
|
+
TAG: "Value",
|
|
445
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
446
|
+
}
|
|
447
|
+
}));
|
|
448
|
+
test("a customer may not register someone else", () => thenForbidden(whenCmd(asCaller(onId(givenEvents([]), Ordering_Examples$OrderingPlugin.c1), Caller.owner(Ordering_Examples$OrderingPlugin.c2, undefined)), {
|
|
449
|
+
TAG: "Register",
|
|
450
|
+
email: Ordering_Examples$OrderingPlugin.aliceEmail,
|
|
451
|
+
address: Ordering_Examples$OrderingPlugin.mainStreet
|
|
452
|
+
})));
|
|
453
|
+
test("a customer may change their own email", () => thenEvent(whenCmd(asCaller(onId(givenEvents([{
|
|
454
|
+
TAG: "Registered",
|
|
455
|
+
email: {
|
|
456
|
+
TAG: "Value",
|
|
457
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
458
|
+
},
|
|
459
|
+
address: {
|
|
460
|
+
TAG: "Value",
|
|
461
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
462
|
+
}
|
|
463
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.owner(Ordering_Examples$OrderingPlugin.c1, undefined)), {
|
|
464
|
+
TAG: "UpdateEmail",
|
|
465
|
+
email: Ordering_Examples$OrderingPlugin.aliceNewEmail
|
|
466
|
+
}), {
|
|
467
|
+
TAG: "EmailUpdated",
|
|
468
|
+
email: {
|
|
469
|
+
TAG: "Value",
|
|
470
|
+
_0: Ordering_Examples$OrderingPlugin.aliceNewEmail
|
|
471
|
+
}
|
|
472
|
+
}));
|
|
473
|
+
test("another customer may not change the email", () => thenForbidden(whenCmd(asCaller(onId(givenEvents([{
|
|
474
|
+
TAG: "Registered",
|
|
475
|
+
email: {
|
|
476
|
+
TAG: "Value",
|
|
477
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
478
|
+
},
|
|
479
|
+
address: {
|
|
480
|
+
TAG: "Value",
|
|
481
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
482
|
+
}
|
|
483
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.owner(Ordering_Examples$OrderingPlugin.c2, undefined)), {
|
|
484
|
+
TAG: "UpdateEmail",
|
|
485
|
+
email: Ordering_Examples$OrderingPlugin.aliceNewEmail
|
|
486
|
+
})));
|
|
487
|
+
test("another customer may not change the address", () => thenForbidden(whenCmd(asCaller(onId(givenEvents([{
|
|
488
|
+
TAG: "Registered",
|
|
489
|
+
email: {
|
|
490
|
+
TAG: "Value",
|
|
491
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
492
|
+
},
|
|
493
|
+
address: {
|
|
494
|
+
TAG: "Value",
|
|
495
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
496
|
+
}
|
|
497
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.owner(Ordering_Examples$OrderingPlugin.c2, undefined)), {
|
|
498
|
+
TAG: "UpdateAddress",
|
|
499
|
+
address: "789 Pine"
|
|
500
|
+
})));
|
|
501
|
+
test("an administrator may change any customer's email", () => thenEvent(whenCmd(asCaller(onId(givenEvents([{
|
|
502
|
+
TAG: "Registered",
|
|
503
|
+
email: {
|
|
504
|
+
TAG: "Value",
|
|
505
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
506
|
+
},
|
|
507
|
+
address: {
|
|
508
|
+
TAG: "Value",
|
|
509
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
510
|
+
}
|
|
511
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.operatorIn(["Admin"])), {
|
|
512
|
+
TAG: "UpdateEmail",
|
|
513
|
+
email: Ordering_Examples$OrderingPlugin.aliceNewEmail
|
|
514
|
+
}), {
|
|
515
|
+
TAG: "EmailUpdated",
|
|
516
|
+
email: {
|
|
517
|
+
TAG: "Value",
|
|
518
|
+
_0: Ordering_Examples$OrderingPlugin.aliceNewEmail
|
|
519
|
+
}
|
|
520
|
+
}));
|
|
521
|
+
test("a caller who is not signed in may not change the email", () => thenForbidden(whenCmd(asCaller(onId(givenEvents([{
|
|
522
|
+
TAG: "Registered",
|
|
523
|
+
email: {
|
|
524
|
+
TAG: "Value",
|
|
525
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
526
|
+
},
|
|
527
|
+
address: {
|
|
528
|
+
TAG: "Value",
|
|
529
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
530
|
+
}
|
|
531
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.anonymous), {
|
|
532
|
+
TAG: "UpdateEmail",
|
|
533
|
+
email: Ordering_Examples$OrderingPlugin.aliceNewEmail
|
|
534
|
+
})));
|
|
535
|
+
test("a customer may not deactivate themself", () => thenForbidden(whenCmd(asCaller(onId(givenEvents([{
|
|
536
|
+
TAG: "Registered",
|
|
537
|
+
email: {
|
|
538
|
+
TAG: "Value",
|
|
539
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
540
|
+
},
|
|
541
|
+
address: {
|
|
542
|
+
TAG: "Value",
|
|
543
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
544
|
+
}
|
|
545
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.owner(Ordering_Examples$OrderingPlugin.c1, undefined)), "Deactivate")));
|
|
546
|
+
test("an operator who is not an administrator may not deactivate a customer", () => thenForbidden(whenCmd(asCaller(onId(givenEvents([{
|
|
547
|
+
TAG: "Registered",
|
|
548
|
+
email: {
|
|
549
|
+
TAG: "Value",
|
|
550
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
551
|
+
},
|
|
552
|
+
address: {
|
|
553
|
+
TAG: "Value",
|
|
554
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
555
|
+
}
|
|
556
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.operatorIn(["Fulfilment"])), "Deactivate")));
|
|
557
|
+
test("an administrator may deactivate a customer", () => thenEvent(whenCmd(asCaller(onId(givenEvents([{
|
|
558
|
+
TAG: "Registered",
|
|
559
|
+
email: {
|
|
560
|
+
TAG: "Value",
|
|
561
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
562
|
+
},
|
|
563
|
+
address: {
|
|
564
|
+
TAG: "Value",
|
|
565
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
566
|
+
}
|
|
567
|
+
}]), Ordering_Examples$OrderingPlugin.c1), Caller.operatorIn(["Admin"])), "Deactivate"), "Deactivated"));
|
|
568
|
+
test("a customer may not reactivate themself", () => thenForbidden(whenCmd(asCaller(onId(givenEvents([
|
|
569
|
+
{
|
|
570
|
+
TAG: "Registered",
|
|
571
|
+
email: {
|
|
572
|
+
TAG: "Value",
|
|
573
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
574
|
+
},
|
|
575
|
+
address: {
|
|
576
|
+
TAG: "Value",
|
|
577
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
"Deactivated"
|
|
581
|
+
]), Ordering_Examples$OrderingPlugin.c1), Caller.owner(Ordering_Examples$OrderingPlugin.c1, undefined)), "Reactivate")));
|
|
582
|
+
test("an administrator may reactivate a customer", () => thenEvent(whenCmd(asCaller(onId(givenEvents([
|
|
583
|
+
{
|
|
584
|
+
TAG: "Registered",
|
|
585
|
+
email: {
|
|
586
|
+
TAG: "Value",
|
|
587
|
+
_0: Ordering_Examples$OrderingPlugin.aliceEmail
|
|
588
|
+
},
|
|
589
|
+
address: {
|
|
590
|
+
TAG: "Value",
|
|
591
|
+
_0: Ordering_Examples$OrderingPlugin.mainStreet
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
"Deactivated"
|
|
595
|
+
]), Ordering_Examples$OrderingPlugin.c1), Caller.operatorIn(["Admin"])), "Reactivate"), "Reactivated"));
|
|
596
|
+
});
|
|
423
597
|
|
|
424
|
-
let
|
|
598
|
+
let Spec = include.Spec;
|
|
425
599
|
|
|
426
|
-
let
|
|
600
|
+
let todo = include.todo;
|
|
427
601
|
|
|
428
602
|
let thenCompareEvent = include.thenCompareEvent;
|
|
429
603
|
|
|
@@ -435,15 +609,15 @@ let thenCompareEvents = include.thenCompareEvents;
|
|
|
435
609
|
|
|
436
610
|
let thenEventsWithError = include.thenEventsWithError;
|
|
437
611
|
|
|
438
|
-
let thenForbidden = include.thenForbidden;
|
|
439
|
-
|
|
440
612
|
export {
|
|
441
613
|
Spec,
|
|
442
614
|
describe,
|
|
615
|
+
todo,
|
|
443
616
|
test,
|
|
444
617
|
givenEvents,
|
|
445
618
|
Caller,
|
|
446
619
|
asCaller,
|
|
620
|
+
onId,
|
|
447
621
|
whenCmd,
|
|
448
622
|
thenEvent,
|
|
449
623
|
thenCompareEvent,
|