1import * as AWS from "@/AWS";
2import * as Test from "@/Test/Alchemy";
3import * as eventbridge from "@distilled.cloud/aws/eventbridge";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import * as Schedule from "effect/Schedule";
7
8const { test } = Test.make({ providers: AWS.providers() });
9
10const ARCHIVE_NAME = "alchemy-test-eb-archive-res";
11
12test.provider(
13 "archive lifecycle: create with Duration retention, update, destroy",
14 (stack) =>
15 Effect.gen(function* () {
16 yield* stack.destroy();
17
18 // Create — retention is a Duration.Input converted to RetentionDays.
19 const { archive } = yield* stack.deploy(
20 Effect.gen(function* () {
21 const bus = yield* AWS.EventBridge.EventBus("ArchiveBus", {
22 name: "alchemy-test-eb-archive-bus",
23 });
24 const archive = yield* AWS.EventBridge.Archive("TestArchive", {
25 name: ARCHIVE_NAME,
26 eventSourceArn: bus.eventBusArn,
27 eventPattern: { source: ["alchemy.test"] },
28 retention: "1 day",
29 });
30 return { archive };
31 }),
32 );
33
34 expect(archive.archiveName).toBe(ARCHIVE_NAME);
35 expect(archive.archiveArn).toContain(`:archive/${ARCHIVE_NAME}`);
36
37 // Out-of-band verify via distilled.
38 const created = yield* eventbridge.describeArchive({
39 ArchiveName: ARCHIVE_NAME,
40 });
41 expect(created.RetentionDays).toBe(1);
42 expect(created.EventPattern).toBeTruthy();
43
44 // Update — retention and description sync in place (no replace).
45 const { archive: updated } = yield* stack.deploy(
46 Effect.gen(function* () {
47 const bus = yield* AWS.EventBridge.EventBus("ArchiveBus", {
48 name: "alchemy-test-eb-archive-bus",
49 });
50 const archive = yield* AWS.EventBridge.Archive("TestArchive", {
51 name: ARCHIVE_NAME,
52 eventSourceArn: bus.eventBusArn,
53 eventPattern: { source: ["alchemy.test"] },
54 retention: "2 days",
55 description: "updated archive",
56 });
57 return { archive };
58 }),
59 );
60 expect(updated.archiveArn).toBe(archive.archiveArn);
61
62 const afterUpdate = yield* eventbridge.describeArchive({
63 ArchiveName: ARCHIVE_NAME,
64 });
65 expect(afterUpdate.RetentionDays).toBe(2);
66 expect(afterUpdate.Description).toBe("updated archive");
67
68 yield* stack.destroy();
69
70 // Typed wait-until-gone.
71 const gone = yield* eventbridge
72 .describeArchive({ ArchiveName: ARCHIVE_NAME })
73 .pipe(
74 Effect.map(() => false),
75 Effect.catchTag("ResourceNotFoundException", () =>
76 Effect.succeed(true),
77 ),
78 Effect.repeat({
79 schedule: Schedule.spaced("2 seconds"),
80 until: (isGone): boolean => isGone,
81 times: 10,
82 }),
83 );
84 expect(gone).toBe(true);
85 }),
86 {
87 tags: ["provider:aws", "provider:aws:eventbridge", "live"],
88 timeout: 120_000,
89 },
90);