1import * as AWS from "@/AWS";
2import { EventIntegration } from "@/AWS/AppIntegrations";
3import * as Test from "@/Test/Alchemy";
4import * as appintegrations from "@distilled.cloud/aws/appintegrations";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import * as Schedule from "effect/Schedule";
8
9const { test } = Test.make({ providers: AWS.providers() });
10
11// Ungated typed-error probe: prove the distilled error union carries the
12// not-found tag this provider's read/delete paths depend on.
13test.provider(
14 "getEventIntegration on a nonexistent name fails with ResourceNotFoundException",
15 () =>
16 Effect.gen(function* () {
17 const error = yield* Effect.flip(
18 appintegrations.getEventIntegration({
19 Name: "alchemy-nonexistent-event-integration-probe",
20 }),
21 );
22 expect(error._tag).toBe("ResourceNotFoundException");
23 }),
24 { tags: ["provider:aws", "provider:aws:appintegrations", "live"] },
25);
26
27const assertGone = (name: string) =>
28 appintegrations.getEventIntegration({ Name: name }).pipe(
29 Effect.flatMap(() =>
30 Effect.fail(new Error(`event integration '${name}' still exists`)),
31 ),
32 Effect.catchTag("ResourceNotFoundException", () => Effect.void),
33 Effect.retry({
34 schedule: Schedule.max([
35 Schedule.fixed("2 seconds"),
36 Schedule.recurs(10),
37 ]),
38 }),
39 );
40
41test.provider(
42 "create, update description, replace on source change, delete an event integration",
43 (stack) =>
44 Effect.gen(function* () {
45 yield* stack.destroy();
46
47 const { integration } = yield* stack.deploy(
48 Effect.gen(function* () {
49 const integration = yield* EventIntegration("PartnerEvents", {
50 source: "aws.partner/examplepartner.com",
51 eventBridgeBus: "default",
52 description: "alchemy event integration",
53 tags: { purpose: "alchemy-test" },
54 });
55 return { integration };
56 }),
57 );
58
59 expect(integration.eventIntegrationName).toBeDefined();
60 expect(integration.eventIntegrationArn).toContain(":event-integration/");
61 expect(integration.eventBridgeBus).toBe("default");
62 expect(integration.source).toBe("aws.partner/examplepartner.com");
63
64 // Out-of-band verification via distilled.
65 const observed = yield* appintegrations.getEventIntegration({
66 Name: integration.eventIntegrationName,
67 });
68 expect(observed.Description).toBe("alchemy event integration");
69 expect(observed.EventBridgeBus).toBe("default");
70 expect(observed.EventFilter?.Source).toBe(
71 "aws.partner/examplepartner.com",
72 );
73 expect(observed.Tags?.purpose).toBe("alchemy-test");
74
75 // Update the description in place (name/arn stable).
76 const { integration: updated } = yield* stack.deploy(
77 Effect.gen(function* () {
78 const integration = yield* EventIntegration("PartnerEvents", {
79 source: "aws.partner/examplepartner.com",
80 eventBridgeBus: "default",
81 description: "alchemy event integration v2",
82 tags: { purpose: "alchemy-test", phase: "two" },
83 });
84 return { integration };
85 }),
86 );
87 expect(updated.eventIntegrationName).toBe(
88 integration.eventIntegrationName,
89 );
90 expect(updated.eventIntegrationArn).toBe(integration.eventIntegrationArn);
91
92 const reobserved = yield* appintegrations.getEventIntegration({
93 Name: integration.eventIntegrationName,
94 });
95 expect(reobserved.Description).toBe("alchemy event integration v2");
96 expect(reobserved.Tags?.phase).toBe("two");
97
98 // Changing the source replaces the event integration (new physical
99 // name via a fresh instance id).
100 const { integration: replaced } = yield* stack.deploy(
101 Effect.gen(function* () {
102 const integration = yield* EventIntegration("PartnerEvents", {
103 source: "aws.partner/otherpartner.com",
104 eventBridgeBus: "default",
105 description: "alchemy event integration v2",
106 });
107 return { integration };
108 }),
109 );
110 expect(replaced.source).toBe("aws.partner/otherpartner.com");
111 expect(replaced.eventIntegrationName).not.toBe(
112 integration.eventIntegrationName,
113 );
114
115 // The replaced (old) integration is deleted.
116 yield* assertGone(integration.eventIntegrationName);
117
118 yield* stack.destroy();
119 yield* assertGone(replaced.eventIntegrationName);
120 }),
121 {
122 tags: ["provider:aws", "provider:aws:appintegrations", "live"],
123 timeout: 240_000,
124 },
125);