@reventlessdev/reventless-aws 3.0.0-alpha.382 → 3.0.0-alpha.383
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 +14 -0
- package/package.json +10 -10
- package/src/Platform.res +9 -2
- package/src/Platform.res.mjs +16 -16
- package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +13 -9
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +227 -1
- package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +185 -7
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +150 -4
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +92 -6
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res +104 -15
- package/src/adapter/ScheduledPublisher/ScheduledPublisher_EventBridgeScheduler_Runtime.res.mjs +122 -34
- package/src/components/AutomationSlice_Builder.res +24 -0
- package/src/components/AutomationSlice_Builder.res.mjs +20 -2
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +1 -1
- package/tests/AutomationSliceEntryPoint_OpsTest.res +91 -0
- package/tests/AutomationSliceEntryPoint_OpsTest.res.mjs +171 -35
- package/tests/ScheduledPublisher_EventBridgeSchedulerTest.res +25 -0
- package/tests/ScheduledPublisher_EventBridgeSchedulerTest.res.mjs +27 -0
|
@@ -224,6 +224,9 @@ describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandler", () =>
|
|
|
224
224
|
steps->Array.push("phase1")
|
|
225
225
|
},
|
|
226
226
|
phase2: async _publish => steps->Array.push("phase2"),
|
|
227
|
+
schedules: Dict.make(),
|
|
228
|
+
takeScheduleChanges: () => [],
|
|
229
|
+
rebuildSchedules: _ => (),
|
|
227
230
|
}
|
|
228
231
|
let context: Reventless.AutomationSlice.context = {
|
|
229
232
|
environment: "test",
|
|
@@ -250,6 +253,50 @@ describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandler", () =>
|
|
|
250
253
|
// the reloaded backlog unprocessed until another invocation.
|
|
251
254
|
expect(steps)->toEqual(["restore", "phase1", "sync", "phase2", "sync"])
|
|
252
255
|
})
|
|
256
|
+
|
|
257
|
+
// The rows are the truth: a platform told before they are stored could hold a
|
|
258
|
+
// schedule no row knows of, if the store write then failed.
|
|
259
|
+
test("stores a changed schedule's rows before telling the platform", async () => {
|
|
260
|
+
let steps = []
|
|
261
|
+
let daily = Reventless.Schedule.Calendar({calendar: Daily({hour: 6, minute: 0})})
|
|
262
|
+
let callback: AutomationSliceEntryPoint_Ops.automationCallback = {
|
|
263
|
+
todoItems: Dict.make(),
|
|
264
|
+
phase1: (_jsons, _ctx) => steps->Array.push("phase1"),
|
|
265
|
+
phase2: async _publish => steps->Array.push("phase2"),
|
|
266
|
+
schedules: Dict.make(),
|
|
267
|
+
takeScheduleChanges: () => [Put({key: "r1", time: daily})],
|
|
268
|
+
rebuildSchedules: _ => (),
|
|
269
|
+
}
|
|
270
|
+
let schedules: AutomationSliceEntryPoint_Ops.schedulesStep = {
|
|
271
|
+
load: async () => steps->Array.push("load schedules"),
|
|
272
|
+
sync: async () => steps->Array.push("sync schedules"),
|
|
273
|
+
platform: {
|
|
274
|
+
put: async (~key, _) => steps->Array.push(`put ${key}`),
|
|
275
|
+
removeName: async name => steps->Array.push(`remove ${name}`),
|
|
276
|
+
names: async () => [],
|
|
277
|
+
nameOf: key => key,
|
|
278
|
+
},
|
|
279
|
+
}
|
|
280
|
+
let handler = AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandler(
|
|
281
|
+
~context={environment: "test", platformName: "P", pluginName: "Pl", sliceName: "S"},
|
|
282
|
+
~callback,
|
|
283
|
+
~publishJsons=noopPublish,
|
|
284
|
+
~syncTodoItems=async () => steps->Array.push("sync"),
|
|
285
|
+
~loadTodoItems=async () => steps->Array.push("restore"),
|
|
286
|
+
~schedules=() => Some(schedules),
|
|
287
|
+
)
|
|
288
|
+
await Stream.fromIterable([str("e")])->handler->Effect.runPromise
|
|
289
|
+
expect(steps)->toEqual([
|
|
290
|
+
"restore",
|
|
291
|
+
"load schedules",
|
|
292
|
+
"phase1",
|
|
293
|
+
"sync",
|
|
294
|
+
"sync schedules",
|
|
295
|
+
"put r1",
|
|
296
|
+
"phase2",
|
|
297
|
+
"sync",
|
|
298
|
+
])
|
|
299
|
+
})
|
|
253
300
|
})
|
|
254
301
|
|
|
255
302
|
describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
@@ -260,6 +307,9 @@ describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
|
260
307
|
registered: dummyRegistered,
|
|
261
308
|
sweep: run,
|
|
262
309
|
comp,
|
|
310
|
+
name: comp,
|
|
311
|
+
tick: None,
|
|
312
|
+
reconcile: None,
|
|
263
313
|
}
|
|
264
314
|
|
|
265
315
|
test("sweeps every slice", async () => {
|
|
@@ -285,6 +335,47 @@ describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
|
285
335
|
})
|
|
286
336
|
})
|
|
287
337
|
|
|
338
|
+
describe("AutomationSliceEntryPoint_Ops.runTick", () => {
|
|
339
|
+
let dummyRegistered: StreamRoutedEntryPoint_Ops.registeredHandler = {
|
|
340
|
+
handler: (_event, _context) => Effect.succeed(),
|
|
341
|
+
}
|
|
342
|
+
let ticks = []
|
|
343
|
+
let slice = (~name, ~tick): AutomationSliceEntryPoint_Ops.builtSlice => {
|
|
344
|
+
registered: dummyRegistered,
|
|
345
|
+
sweep: async () => (),
|
|
346
|
+
comp: name,
|
|
347
|
+
name,
|
|
348
|
+
tick,
|
|
349
|
+
reconcile: None,
|
|
350
|
+
}
|
|
351
|
+
let slices = [
|
|
352
|
+
slice(~name="Outbound", ~tick=None),
|
|
353
|
+
slice(~name="DemandReport", ~tick=Some(async (~key, ~at) => ticks->Array.push((key, at)))),
|
|
354
|
+
]
|
|
355
|
+
|
|
356
|
+
test("delivers the scheduled time to the named slice", async () => {
|
|
357
|
+
await AutomationSliceEntryPoint_Ops.runTick(
|
|
358
|
+
slices,
|
|
359
|
+
{slice: "DemandReport", key: "default", at: "2026-10-16T06:00:00Z"},
|
|
360
|
+
)
|
|
361
|
+
expect(ticks)->toEqual([("default", Date.fromString("2026-10-16T06:00:00Z")->Date.getTime)])
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
// A throw makes the Scheduler retry, and leaves a log line to find.
|
|
365
|
+
test("refuses a slice it does not host, or one that maps no Clock", async () => {
|
|
366
|
+
let refused = async invocation =>
|
|
367
|
+
switch await AutomationSliceEntryPoint_Ops.runTick(slices, invocation) {
|
|
368
|
+
| () => false
|
|
369
|
+
| exception _ => true
|
|
370
|
+
}
|
|
371
|
+
expect(await refused({slice: "Nobody", key: "default", at: "2026-10-16T06:00:00Z"}))->toBe(true)
|
|
372
|
+
expect(await refused({slice: "Outbound", key: "default", at: "2026-10-16T06:00:00Z"}))->toBe(
|
|
373
|
+
true,
|
|
374
|
+
)
|
|
375
|
+
expect(await refused({slice: "DemandReport", key: "default", at: "soon"}))->toBe(true)
|
|
376
|
+
})
|
|
377
|
+
})
|
|
378
|
+
|
|
288
379
|
// Consumed-event fixture for the outbound decode: one consumed variant with a
|
|
289
380
|
// payload, one payload-less, decoded from a source that also emits types this
|
|
290
381
|
// slice does not consume.
|
|
@@ -328,10 +328,16 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandl
|
|
|
328
328
|
let callback_phase2 = async _publish => {
|
|
329
329
|
steps.push("phase2");
|
|
330
330
|
};
|
|
331
|
+
let callback_schedules = {};
|
|
332
|
+
let callback_takeScheduleChanges = () => [];
|
|
333
|
+
let callback_rebuildSchedules = param => {};
|
|
331
334
|
let callback = {
|
|
332
335
|
todoItems: callback_todoItems,
|
|
333
336
|
phase1: callback_phase1,
|
|
334
|
-
phase2: callback_phase2
|
|
337
|
+
phase2: callback_phase2,
|
|
338
|
+
schedules: callback_schedules,
|
|
339
|
+
takeScheduleChanges: callback_takeScheduleChanges,
|
|
340
|
+
rebuildSchedules: callback_rebuildSchedules
|
|
335
341
|
};
|
|
336
342
|
let handler = AutomationSliceEntryPoint_Ops$ReventlessAws.makeAutomationJsonEventsHandler({
|
|
337
343
|
environment: "test",
|
|
@@ -342,7 +348,7 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandl
|
|
|
342
348
|
steps.push("sync");
|
|
343
349
|
}, async () => {
|
|
344
350
|
steps.push("restore");
|
|
345
|
-
});
|
|
351
|
+
}, undefined);
|
|
346
352
|
let envelope = Object.fromEntries([
|
|
347
353
|
[
|
|
348
354
|
"meta",
|
|
@@ -373,6 +379,80 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.makeAutomationJsonEventsHandl
|
|
|
373
379
|
"sync"
|
|
374
380
|
]);
|
|
375
381
|
});
|
|
382
|
+
globalThis.test("stores a changed schedule's rows before telling the platform", async () => {
|
|
383
|
+
let steps = [];
|
|
384
|
+
let callback_todoItems = {};
|
|
385
|
+
let callback_phase1 = (_jsons, _ctx) => {
|
|
386
|
+
steps.push("phase1");
|
|
387
|
+
};
|
|
388
|
+
let callback_phase2 = async _publish => {
|
|
389
|
+
steps.push("phase2");
|
|
390
|
+
};
|
|
391
|
+
let callback_schedules = {};
|
|
392
|
+
let callback_takeScheduleChanges = () => [{
|
|
393
|
+
TAG: "Put",
|
|
394
|
+
key: "r1",
|
|
395
|
+
time: {
|
|
396
|
+
TAG: "Calendar",
|
|
397
|
+
calendar: {
|
|
398
|
+
TAG: "Daily",
|
|
399
|
+
hour: 6,
|
|
400
|
+
minute: 0
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}];
|
|
404
|
+
let callback_rebuildSchedules = param => {};
|
|
405
|
+
let callback = {
|
|
406
|
+
todoItems: callback_todoItems,
|
|
407
|
+
phase1: callback_phase1,
|
|
408
|
+
phase2: callback_phase2,
|
|
409
|
+
schedules: callback_schedules,
|
|
410
|
+
takeScheduleChanges: callback_takeScheduleChanges,
|
|
411
|
+
rebuildSchedules: callback_rebuildSchedules
|
|
412
|
+
};
|
|
413
|
+
let schedules_load = async () => {
|
|
414
|
+
steps.push("load schedules");
|
|
415
|
+
};
|
|
416
|
+
let schedules_sync = async () => {
|
|
417
|
+
steps.push("sync schedules");
|
|
418
|
+
};
|
|
419
|
+
let schedules_platform = {
|
|
420
|
+
put: async (key, param) => {
|
|
421
|
+
steps.push(`put ` + key);
|
|
422
|
+
},
|
|
423
|
+
removeName: async name => {
|
|
424
|
+
steps.push(`remove ` + name);
|
|
425
|
+
},
|
|
426
|
+
names: async () => [],
|
|
427
|
+
nameOf: key => key
|
|
428
|
+
};
|
|
429
|
+
let schedules = {
|
|
430
|
+
load: schedules_load,
|
|
431
|
+
sync: schedules_sync,
|
|
432
|
+
platform: schedules_platform
|
|
433
|
+
};
|
|
434
|
+
let handler = AutomationSliceEntryPoint_Ops$ReventlessAws.makeAutomationJsonEventsHandler({
|
|
435
|
+
environment: "test",
|
|
436
|
+
platformName: "P",
|
|
437
|
+
pluginName: "Pl",
|
|
438
|
+
sliceName: "S"
|
|
439
|
+
}, callback, noopPublish, async () => {
|
|
440
|
+
steps.push("sync");
|
|
441
|
+
}, async () => {
|
|
442
|
+
steps.push("restore");
|
|
443
|
+
}, () => schedules);
|
|
444
|
+
await Effect.runPromise(handler(Stream.fromIterable(["e"])));
|
|
445
|
+
globalThis.expect(steps).toEqual([
|
|
446
|
+
"restore",
|
|
447
|
+
"load schedules",
|
|
448
|
+
"phase1",
|
|
449
|
+
"sync",
|
|
450
|
+
"sync schedules",
|
|
451
|
+
"put r1",
|
|
452
|
+
"phase2",
|
|
453
|
+
"sync"
|
|
454
|
+
]);
|
|
455
|
+
});
|
|
376
456
|
});
|
|
377
457
|
|
|
378
458
|
globalThis.describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
@@ -380,23 +460,23 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
|
380
460
|
let dummyRegistered = {
|
|
381
461
|
handler: dummyRegistered_handler
|
|
382
462
|
};
|
|
463
|
+
let sliceThat = (comp, run) => ({
|
|
464
|
+
registered: dummyRegistered,
|
|
465
|
+
sweep: run,
|
|
466
|
+
comp: comp,
|
|
467
|
+
name: comp,
|
|
468
|
+
tick: undefined,
|
|
469
|
+
reconcile: undefined
|
|
470
|
+
});
|
|
383
471
|
globalThis.test("sweeps every slice", async () => {
|
|
384
472
|
let swept = [];
|
|
385
473
|
await AutomationSliceEntryPoint_Ops$ReventlessAws.runSweeps([
|
|
386
|
-
{
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
registered: dummyRegistered,
|
|
395
|
-
sweep: async () => {
|
|
396
|
-
swept.push("b");
|
|
397
|
-
},
|
|
398
|
-
comp: "B"
|
|
399
|
-
}
|
|
474
|
+
sliceThat("A", async () => {
|
|
475
|
+
swept.push("a");
|
|
476
|
+
}),
|
|
477
|
+
sliceThat("B", async () => {
|
|
478
|
+
swept.push("b");
|
|
479
|
+
})
|
|
400
480
|
]);
|
|
401
481
|
globalThis.expect(swept).toEqual([
|
|
402
482
|
"a",
|
|
@@ -406,25 +486,13 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
|
406
486
|
globalThis.test("a throwing slice does not stop the others", async () => {
|
|
407
487
|
let swept = [];
|
|
408
488
|
await AutomationSliceEntryPoint_Ops$ReventlessAws.runSweeps([
|
|
409
|
-
{
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
{
|
|
417
|
-
registered: dummyRegistered,
|
|
418
|
-
sweep: async () => Stdlib_JsError.throwWithMessage("gateway down"),
|
|
419
|
-
comp: "Boom"
|
|
420
|
-
},
|
|
421
|
-
{
|
|
422
|
-
registered: dummyRegistered,
|
|
423
|
-
sweep: async () => {
|
|
424
|
-
swept.push("c");
|
|
425
|
-
},
|
|
426
|
-
comp: "C"
|
|
427
|
-
}
|
|
489
|
+
sliceThat("A", async () => {
|
|
490
|
+
swept.push("a");
|
|
491
|
+
}),
|
|
492
|
+
sliceThat("Boom", async () => Stdlib_JsError.throwWithMessage("gateway down")),
|
|
493
|
+
sliceThat("C", async () => {
|
|
494
|
+
swept.push("c");
|
|
495
|
+
})
|
|
428
496
|
]);
|
|
429
497
|
globalThis.expect(swept).toEqual([
|
|
430
498
|
"a",
|
|
@@ -433,6 +501,74 @@ globalThis.describe("AutomationSliceEntryPoint_Ops.runSweeps", () => {
|
|
|
433
501
|
});
|
|
434
502
|
});
|
|
435
503
|
|
|
504
|
+
globalThis.describe("AutomationSliceEntryPoint_Ops.runTick", () => {
|
|
505
|
+
let dummyRegistered_handler = (_event, _context) => Effect.succeed();
|
|
506
|
+
let dummyRegistered = {
|
|
507
|
+
handler: dummyRegistered_handler
|
|
508
|
+
};
|
|
509
|
+
let ticks = [];
|
|
510
|
+
let slice = (name, tick) => ({
|
|
511
|
+
registered: dummyRegistered,
|
|
512
|
+
sweep: async () => {},
|
|
513
|
+
comp: name,
|
|
514
|
+
name: name,
|
|
515
|
+
tick: tick,
|
|
516
|
+
reconcile: undefined
|
|
517
|
+
});
|
|
518
|
+
let slices = [
|
|
519
|
+
{
|
|
520
|
+
registered: dummyRegistered,
|
|
521
|
+
sweep: async () => {},
|
|
522
|
+
comp: "Outbound",
|
|
523
|
+
name: "Outbound",
|
|
524
|
+
tick: undefined,
|
|
525
|
+
reconcile: undefined
|
|
526
|
+
},
|
|
527
|
+
slice("DemandReport", async (key, at) => {
|
|
528
|
+
ticks.push([
|
|
529
|
+
key,
|
|
530
|
+
at
|
|
531
|
+
]);
|
|
532
|
+
})
|
|
533
|
+
];
|
|
534
|
+
globalThis.test("delivers the scheduled time to the named slice", async () => {
|
|
535
|
+
await AutomationSliceEntryPoint_Ops$ReventlessAws.runTick(slices, {
|
|
536
|
+
slice: "DemandReport",
|
|
537
|
+
key: "default",
|
|
538
|
+
at: "2026-10-16T06:00:00Z"
|
|
539
|
+
});
|
|
540
|
+
globalThis.expect(ticks).toEqual([[
|
|
541
|
+
"default",
|
|
542
|
+
new Date("2026-10-16T06:00:00Z").getTime()
|
|
543
|
+
]]);
|
|
544
|
+
});
|
|
545
|
+
globalThis.test("refuses a slice it does not host, or one that maps no Clock", async () => {
|
|
546
|
+
let refused = async invocation => {
|
|
547
|
+
try {
|
|
548
|
+
await AutomationSliceEntryPoint_Ops$ReventlessAws.runTick(slices, invocation);
|
|
549
|
+
return false;
|
|
550
|
+
} catch (exn) {
|
|
551
|
+
return true;
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
globalThis.expect(await refused({
|
|
555
|
+
slice: "Nobody",
|
|
556
|
+
key: "default",
|
|
557
|
+
at: "2026-10-16T06:00:00Z"
|
|
558
|
+
})).toBe(true);
|
|
559
|
+
globalThis.expect(await refused({
|
|
560
|
+
slice: "Outbound",
|
|
561
|
+
key: "default",
|
|
562
|
+
at: "2026-10-16T06:00:00Z"
|
|
563
|
+
})).toBe(true);
|
|
564
|
+
globalThis.expect(await refused({
|
|
565
|
+
slice: "DemandReport",
|
|
566
|
+
key: "default",
|
|
567
|
+
at: "soon"
|
|
568
|
+
})).toBe(true);
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
|
|
436
572
|
let outboundEventSchema = Sury.union([
|
|
437
573
|
Sury.$schema(s => ({
|
|
438
574
|
TAG: "OrderPlaced",
|
|
@@ -62,4 +62,29 @@ describe("ScheduledPublisher_EventBridgeScheduler_Runtime", () => {
|
|
|
62
62
|
let tags = Dict.fromArray([("Name", "SchedulerScheduleGroup"), ("reventless:plugin", "")])
|
|
63
63
|
expect(tags->AWS.Tags.withoutEmpty->Dict.toArray)->toEqual([("Name", "SchedulerScheduleGroup")])
|
|
64
64
|
})
|
|
65
|
+
|
|
66
|
+
testSync("names an automation's schedule <slice>.<key>, or hashes a key it would refuse", () => {
|
|
67
|
+
expect(Runtime.tickScheduleName(~slice="MarketingDigest", ~key="r1"))->toBe(
|
|
68
|
+
"MarketingDigest.r1",
|
|
69
|
+
)
|
|
70
|
+
let hashed = Runtime.tickScheduleName(~slice="MarketingDigest", ~key="customer:42")
|
|
71
|
+
expect((hashed->String.startsWith("MarketingDigest."), hashed->String.length))->toEqual((
|
|
72
|
+
true,
|
|
73
|
+
16 + 16,
|
|
74
|
+
))
|
|
75
|
+
let long = "A"->String.repeat(60)
|
|
76
|
+
let cut = Runtime.tickScheduleName(~slice=long, ~key="default")
|
|
77
|
+
expect((cut->String.length, cut->Runtime.isSliceSchedule(~slice=long)))->toEqual((57, true))
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
testSync("tells a slice's schedules from another slice's sharing its prefix", () => {
|
|
81
|
+
expect("Digest.r1"->Runtime.isSliceSchedule(~slice="Digest"))->toBe(true)
|
|
82
|
+
expect("DigestWeekly.r1"->Runtime.isSliceSchedule(~slice="Digest"))->toBe(false)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
testSync("invokes the automation Lambda with the slice, the key and the scheduled time", () => {
|
|
86
|
+
expect(
|
|
87
|
+
Runtime.tickInput(~slice="MarketingDigest", ~key="r1"),
|
|
88
|
+
)->toBe(`{"reventlessTick":{"slice":"MarketingDigest","key":"r1","at":"<aws.scheduler.scheduled-time>"}}`)
|
|
89
|
+
})
|
|
65
90
|
})
|
|
@@ -100,6 +100,33 @@ globalThis.describe("ScheduledPublisher_EventBridgeScheduler_Runtime", () => {
|
|
|
100
100
|
"SchedulerScheduleGroup"
|
|
101
101
|
]]);
|
|
102
102
|
});
|
|
103
|
+
globalThis.test("names an automation's schedule <slice>.<key>, or hashes a key it would refuse", () => {
|
|
104
|
+
globalThis.expect(ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.tickScheduleName("MarketingDigest", "r1")).toBe("MarketingDigest.r1");
|
|
105
|
+
let hashed = ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.tickScheduleName("MarketingDigest", "customer:42");
|
|
106
|
+
globalThis.expect([
|
|
107
|
+
hashed.startsWith("MarketingDigest."),
|
|
108
|
+
hashed.length
|
|
109
|
+
]).toEqual([
|
|
110
|
+
true,
|
|
111
|
+
32
|
|
112
|
+
]);
|
|
113
|
+
let long = "A".repeat(60);
|
|
114
|
+
let cut = ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.tickScheduleName(long, "default");
|
|
115
|
+
globalThis.expect([
|
|
116
|
+
cut.length,
|
|
117
|
+
ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.isSliceSchedule(cut, long)
|
|
118
|
+
]).toEqual([
|
|
119
|
+
57,
|
|
120
|
+
true
|
|
121
|
+
]);
|
|
122
|
+
});
|
|
123
|
+
globalThis.test("tells a slice's schedules from another slice's sharing its prefix", () => {
|
|
124
|
+
globalThis.expect(ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.isSliceSchedule("Digest.r1", "Digest")).toBe(true);
|
|
125
|
+
globalThis.expect(ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.isSliceSchedule("DigestWeekly.r1", "Digest")).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
globalThis.test("invokes the automation Lambda with the slice, the key and the scheduled time", () => {
|
|
128
|
+
globalThis.expect(ScheduledPublisher_EventBridgeScheduler_Runtime$ReventlessAws.tickInput("MarketingDigest", "r1")).toBe(`{"reventlessTick":{"slice":"MarketingDigest","key":"r1","at":"<aws.scheduler.scheduled-time>"}}`);
|
|
129
|
+
});
|
|
103
130
|
});
|
|
104
131
|
|
|
105
132
|
let Runtime;
|