1import * as AWS from "@/AWS";
2import { NamedQuery } from "@/AWS/Athena/NamedQuery.ts";
3import * as Test from "@/Test/Alchemy";
4import * as athena from "@distilled.cloud/aws/athena";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7
8const { test } = Test.make({ providers: AWS.providers() });
9
10const getNamedQuery = (id: string) =>
11 athena.getNamedQuery({ NamedQueryId: id }).pipe(
12 Effect.map((res) => res.NamedQuery),
13 Effect.catchTag("NamedQueryNotFound", () => Effect.succeed(undefined)),
14 );
15
16test.provider(
17 "lifecycle: create, update in place, replace on database change, destroy",
18 (stack) =>
19 Effect.gen(function* () {
20 yield* stack.destroy();
21
22 // Create — saved against the always-present `primary` workgroup.
23 const created = yield* stack.deploy(
24 Effect.gen(function* () {
25 return yield* NamedQuery("LifecycleNQ", {
26 name: "alchemy-test-named-query",
27 database: "default",
28 queryString: "SELECT 1",
29 description: "initial",
30 });
31 }),
32 );
33 expect(created.namedQueryId).toBeTruthy();
34 expect(created.workGroup).toBe("primary");
35
36 const observed = yield* getNamedQuery(created.namedQueryId);
37 expect(observed?.Name).toBe("alchemy-test-named-query");
38 expect(observed?.QueryString).toBe("SELECT 1");
39 expect(observed?.Description).toBe("initial");
40
41 // Update in place — name/description/queryString mutate, id is stable.
42 const updated = yield* stack.deploy(
43 Effect.gen(function* () {
44 return yield* NamedQuery("LifecycleNQ", {
45 name: "alchemy-test-named-query-v2",
46 database: "default",
47 queryString: "SELECT 2",
48 description: "updated",
49 });
50 }),
51 );
52 expect(updated.namedQueryId).toBe(created.namedQueryId);
53 const observedUpdated = yield* getNamedQuery(created.namedQueryId);
54 expect(observedUpdated?.Name).toBe("alchemy-test-named-query-v2");
55 expect(observedUpdated?.QueryString).toBe("SELECT 2");
56
57 // Replace — changing `database` mints a new NamedQueryId.
58 const replaced = yield* stack.deploy(
59 Effect.gen(function* () {
60 return yield* NamedQuery("LifecycleNQ", {
61 name: "alchemy-test-named-query-v2",
62 database: "information_schema",
63 queryString: "SELECT 2",
64 description: "updated",
65 });
66 }),
67 );
68 expect(replaced.namedQueryId).not.toBe(created.namedQueryId);
69 // Old one is deleted as part of replacement.
70 const oldGone = yield* getNamedQuery(created.namedQueryId);
71 expect(oldGone).toBeUndefined();
72
73 // Destroy — the saved query is removed.
74 yield* stack.destroy();
75 const after = yield* getNamedQuery(replaced.namedQueryId);
76 expect(after).toBeUndefined();
77 }),
78 { tags: ["provider:aws", "provider:aws:athena", "live"], timeout: 180_000 },
79);