1import * as AWS from "@/AWS";
2import { DataCatalog } from "@/AWS/Athena/DataCatalog.ts";
3import * as Provider from "@/Provider";
4import * as Test from "@/Test/Alchemy";
5import * as athena from "@distilled.cloud/aws/athena";
6import { expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8
9const { test } = Test.make({ providers: AWS.providers() });
10
11const catalogName = "alchemy_test_catalog";
12const fnA =
13 "arn:aws:lambda:us-west-2:391965393224:function:alchemy-athena-cat-a";
14const fnB =
15 "arn:aws:lambda:us-west-2:391965393224:function:alchemy-athena-cat-b";
16
17const getCatalog = athena
18 .getDataCatalog({ Name: catalogName, WorkGroup: "primary" })
19 .pipe(
20 Effect.map((res) => res.DataCatalog),
21 Effect.catchTag("DataCatalogNotFound", () => Effect.succeed(undefined)),
22 );
23
24test.provider(
25 "lifecycle: create LAMBDA catalog, update params/description, destroy",
26 (stack) =>
27 Effect.gen(function* () {
28 yield* stack.destroy();
29
30 // Create — a federated LAMBDA connector (a fake function ARN is accepted
31 // at create time; Athena validates lazily at query time).
32 const created = yield* stack.deploy(
33 Effect.gen(function* () {
34 return yield* DataCatalog("LifecycleCat", {
35 name: catalogName,
36 type: "LAMBDA",
37 description: "initial",
38 parameters: { "metadata-function": fnA, "record-function": fnA },
39 tags: { env: "test" },
40 });
41 }),
42 );
43 expect(created.dataCatalogArn).toContain(`datacatalog/${catalogName}`);
44 expect(created.type).toBe("LAMBDA");
45
46 // Out-of-band verification via distilled.
47 const observed = yield* getCatalog;
48 expect(observed?.Type).toBe("LAMBDA");
49 expect(observed?.Parameters?.["metadata-function"]).toBe(fnA);
50 expect(observed?.Description).toBe("initial");
51
52 // Tags applied.
53 const tags = yield* athena.listTagsForResource({
54 ResourceARN: created.dataCatalogArn,
55 });
56 expect(
57 tags.Tags?.some((t) => t.Key === "env" && t.Value === "test"),
58 ).toBe(true);
59
60 // Canonical list() coverage.
61 const provider = yield* Provider.findProvider(DataCatalog);
62 const all = yield* provider.list();
63 expect(all.some((c) => c.name === catalogName)).toBe(true);
64
65 // Update — change the record-function param + description in place.
66 yield* stack.deploy(
67 Effect.gen(function* () {
68 return yield* DataCatalog("LifecycleCat", {
69 name: catalogName,
70 type: "LAMBDA",
71 description: "updated",
72 parameters: { "metadata-function": fnA, "record-function": fnB },
73 });
74 }),
75 );
76 const updated = yield* getCatalog;
77 expect(updated?.Parameters?.["record-function"]).toBe(fnB);
78 expect(updated?.Description).toBe("updated");
79
80 // Destroy — the catalog is removed.
81 yield* stack.destroy();
82 const after = yield* getCatalog;
83 expect(after).toBeUndefined();
84 }),
85 { tags: ["provider:aws", "provider:aws:athena", "live"], timeout: 180_000 },
86);