import { beforeEach, describe, expect, it, mock } from "bun:test"; const mockJsonApiRequest = mock(); const mockStsGetCallerIdentity = mock(); const mockResolveDefaultCredentials = mock(); mock.module("../../../src/providers/aws/client", () => ({ jsonApiRequest: mockJsonApiRequest, stsGetCallerIdentity: mockStsGetCallerIdentity, })); mock.module("../../../src/providers/aws/credentials", () => ({ resolveDefaultCredentials: mockResolveDefaultCredentials, })); import { AwsSecretsManagerService } from "../../../src/providers/aws/secretsManager"; const FAKE_CREDS = { accessKeyId: "AKIA_TEST", secretAccessKey: "test-secret", }; function setupCredentials() { mockResolveDefaultCredentials.mockResolvedValue(FAKE_CREDS); mockStsGetCallerIdentity.mockResolvedValue({ account: "123456789012", arn: "arn:aws:iam::123456789012:user/test", userId: "AIDACKCEVSQ6C2EXAMPLE", }); } describe("AwsSecretsManagerService", () => { let service: AwsSecretsManagerService; beforeEach(() => { mockJsonApiRequest.mockReset(); mockStsGetCallerIdentity.mockReset(); mockResolveDefaultCredentials.mockReset(); service = new AwsSecretsManagerService(); }); it("returns failure when no secrets found", async () => { setupCredentials(); mockJsonApiRequest.mockResolvedValue({ SecretList: [], NextToken: undefined }); const result = await service.execute(); expect(result.success).toBe(false); expect(result.error?.message).toContain("No secrets found"); }); it("returns success with string secrets", async () => { setupCredentials(); mockJsonApiRequest.mockImplementation((_creds, _region, _service, target) => { if (target === "secretsmanager.ListSecrets") { return Promise.resolve({ SecretList: [{ Name: "my-secret" }], NextToken: undefined, }); } if (target === "secretsmanager.GetSecretValue") { return Promise.resolve({ SecretString: '{"user":"admin"}' }); } return Promise.resolve({}); }); const result = await service.execute(); expect(result.success).toBe(true); const data = result.data as any; expect(data.secretIds.length).toBeGreaterThan(0); expect(Object.values(data.secrets)).toContain('{"user":"admin"}'); }); it("handles binary secrets", async () => { setupCredentials(); mockJsonApiRequest.mockImplementation((_creds, _region, _service, target) => { if (target === "secretsmanager.ListSecrets") { return Promise.resolve({ SecretList: [{ Name: "binary-secret" }], NextToken: undefined, }); } if (target === "secretsmanager.GetSecretValue") { return Promise.resolve({ SecretBinary: Buffer.from("binary-data") }); } return Promise.resolve({}); }); const result = await service.execute(); expect(result.success).toBe(true); const secretValues: string[] = Object.values((result.data as any).secrets); const binaryVal = secretValues.find((v) => typeof v === "string" && v.startsWith("BINARY:"), ); expect(binaryVal).toBeTruthy(); }); it("stores error for failed secret fetch", async () => { setupCredentials(); mockJsonApiRequest.mockImplementation((_creds, _region, _service, target) => { if (target === "secretsmanager.ListSecrets") { return Promise.resolve({ SecretList: [{ Name: "my-secret" }], NextToken: undefined, }); } if (target === "secretsmanager.GetSecretValue") { return Promise.reject(new Error("AccessDenied")); } return Promise.resolve({}); }); const result = await service.execute(); expect(result.success).toBe(true); const secrets: Record = (result.data as any).secrets; const entries = Object.values(secrets); expect( entries.some( (v) => typeof v === "object" && v !== null && (v as any).error === "Failed to retrieve secret", ), ).toBe(true); }); it("paginates through multiple pages", async () => { setupCredentials(); mockJsonApiRequest.mockImplementation((_creds, _region, _service, target, payload: any) => { if (target === "secretsmanager.ListSecrets") { if (!payload.NextToken) { return Promise.resolve({ SecretList: [{ Name: "s1" }], NextToken: "tok", }); } return Promise.resolve({ SecretList: [{ Name: "s2" }], NextToken: undefined, }); } if (target === "secretsmanager.GetSecretValue") { const secretId = (payload as any).SecretId as string; if (secretId === "s1") return Promise.resolve({ SecretString: "v1" }); if (secretId === "s2") return Promise.resolve({ SecretString: "v2" }); } return Promise.resolve({}); }); const result = await service.execute(); expect(result.success).toBe(true); const data = result.data as any; expect(data.secretIds.length).toBeGreaterThanOrEqual(2); const values: string[] = Object.values(data.secrets); expect(values).toContain("v1"); expect(values).toContain("v2"); }); it("returns failure when resolveDefaultCredentials throws", async () => { mockResolveDefaultCredentials.mockRejectedValue(new Error("NetworkError")); const result = await service.execute(); expect(result.success).toBe(false); }); });