1import * as AWS from "@/AWS";
2import { AccessKey, User } from "@/AWS/IAM";
3import * as Provider from "@/Provider";
4import * as Test from "@/Test/Alchemy";
5import * as IAM from "@distilled.cloud/aws/iam";
6import { describe, expect } from "alchemy-test";
7import * as Effect from "effect/Effect";
8
9const { test } = Test.make({ providers: AWS.providers() });
10
11describe(
12 "AWS.IAM.AccessKey",
13 { tags: ["provider:aws", "provider:aws:iam", "live"] },
14 () => {
15 // Canonical `list()` test: IAM is a global service and `listAccessKeys`
16 // requires a `UserName`, so the provider enumerates every user first and then
17 // lists keys per user. Deploy a real user + access key, resolve the provider
18 // from context with the typed `findProvider`, call `list()`, and assert the
19 // deployed key appears in the exhaustively-paginated result.
20 test.provider("list enumerates the deployed access key", (stack) =>
21 Effect.gen(function* () {
22 yield* stack.destroy();
23
24 const deployed = yield* stack.deploy(
25 Effect.gen(function* () {
26 const user = yield* User("AccessKeyListOwner", {});
27 const key = yield* AccessKey("AccessKeyListKey", {
28 userName: user.userName,
29 status: "Active",
30 });
31 return { user, key };
32 }),
33 );
34
35 const provider = yield* Provider.findProvider(AccessKey);
36 const all = yield* provider.list();
37
38 const found = all.find(
39 (entry) => entry.accessKeyId === deployed.key.accessKeyId,
40 );
41 expect(found).toBeDefined();
42 expect(found?.userName).toBe(deployed.user.userName);
43 expect(found?.secretAccessKey).toBeUndefined();
44
45 yield* stack.destroy();
46
47 // The user (and with it every access key it owned) is gone.
48 const deletedUser = yield* IAM.getUser({
49 UserName: deployed.user.userName,
50 }).pipe(Effect.option);
51 expect(deletedUser._tag).toBe("None");
52 }),
53 );
54 },
55);