1import * as AWS from "@/AWS";
2import { LoginProfile, 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";
8import * as Redacted from "effect/Redacted";
9
10const { test } = Test.make({ providers: AWS.providers() });
11
12describe(
13 "AWS.IAM.LoginProfile",
14 { tags: ["provider:aws", "provider:aws:iam", "live"] },
15 () => {
16 // Canonical `list()` test: IAM is a global service and there is no
17 // list-login-profiles API, so the provider enumerates every user first and
18 // then probes `getLoginProfile` per user (skipping users without console
19 // access). Deploy a real user + login profile, resolve the provider from
20 // context with the typed `findProvider`, call `list()`, and assert the
21 // deployed profile appears in the result.
22 test.provider("list enumerates the deployed login profile", (stack) =>
23 Effect.gen(function* () {
24 yield* stack.destroy();
25
26 const deployed = yield* stack.deploy(
27 Effect.gen(function* () {
28 const user = yield* User("LoginProfileListOwner", {});
29 const profile = yield* LoginProfile("LoginProfileListProfile", {
30 userName: user.userName,
31 password: Redacted.make("TempPassword123!"),
32 passwordResetRequired: true,
33 });
34 return { user, profile };
35 }),
36 );
37
38 const provider = yield* Provider.findProvider(LoginProfile);
39 const all = yield* provider.list();
40
41 const found = all.find(
42 (entry) => entry.userName === deployed.user.userName,
43 );
44 expect(found).toBeDefined();
45 expect(found?.userName).toBe(deployed.user.userName);
46
47 yield* stack.destroy();
48
49 // The user (and with it the login profile) is gone.
50 const deletedUser = yield* IAM.getUser({
51 UserName: deployed.user.userName,
52 }).pipe(Effect.option);
53 expect(deletedUser._tag).toBe("None");
54 }),
55 );
56 },
57);