Upload files to "tests/providers/aws"
This commit is contained in:
@@ -0,0 +1,165 @@
|
|||||||
|
import { beforeEach, describe, expect, it, mock } from "bun:test";
|
||||||
|
|
||||||
|
const mockStsGetCallerIdentity = mock();
|
||||||
|
const mockFromEnv = mock();
|
||||||
|
const mockFromTokenFile = mock();
|
||||||
|
const mockFromContainerMetadata = mock();
|
||||||
|
const mockFromInstanceMetadata = mock();
|
||||||
|
const mockFromProfile = mock();
|
||||||
|
const mockGetAvailableProfiles = mock();
|
||||||
|
|
||||||
|
mock.module("../../../src/providers/aws/client", () => ({
|
||||||
|
stsGetCallerIdentity: mockStsGetCallerIdentity,
|
||||||
|
}));
|
||||||
|
|
||||||
|
mock.module("../../../src/providers/aws/credentials", () => ({
|
||||||
|
fromEnv: mockFromEnv,
|
||||||
|
fromTokenFile: mockFromTokenFile,
|
||||||
|
fromContainerMetadata: mockFromContainerMetadata,
|
||||||
|
fromInstanceMetadata: mockFromInstanceMetadata,
|
||||||
|
fromProfile: mockFromProfile,
|
||||||
|
getAvailableProfiles: mockGetAvailableProfiles,
|
||||||
|
}));
|
||||||
|
|
||||||
|
import { AwsAccountService } from "../../../src/providers/aws/awsAccount";
|
||||||
|
|
||||||
|
function makeCredentialSource(
|
||||||
|
label: string,
|
||||||
|
resolve: () => Promise<{ accessKeyId: string; secretAccessKey: string; sessionToken?: string }>,
|
||||||
|
) {
|
||||||
|
return { label, resolve };
|
||||||
|
}
|
||||||
|
|
||||||
|
function throwingSource(label: string) {
|
||||||
|
return makeCredentialSource(label, async () => {
|
||||||
|
throw new Error(`No credentials from ${label}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("AwsAccountService", () => {
|
||||||
|
let service: AwsAccountService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockStsGetCallerIdentity.mockReset();
|
||||||
|
mockFromEnv.mockReset();
|
||||||
|
mockFromTokenFile.mockReset();
|
||||||
|
mockFromContainerMetadata.mockReset();
|
||||||
|
mockFromInstanceMetadata.mockReset();
|
||||||
|
mockFromProfile.mockReset();
|
||||||
|
mockGetAvailableProfiles.mockReset();
|
||||||
|
service = new AwsAccountService();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns failure when no credentials found", async () => {
|
||||||
|
mockFromEnv.mockReturnValue(throwingSource("env"));
|
||||||
|
mockFromTokenFile.mockReturnValue(throwingSource("token-file"));
|
||||||
|
mockFromContainerMetadata.mockReturnValue(throwingSource("container-metadata"));
|
||||||
|
mockFromInstanceMetadata.mockReturnValue(throwingSource("instance-metadata"));
|
||||||
|
mockGetAvailableProfiles.mockResolvedValue([]);
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(false);
|
||||||
|
expect(result.error?.message).toContain("No accessible AWS credentials");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns success with env credentials", async () => {
|
||||||
|
mockFromEnv.mockReturnValue(
|
||||||
|
makeCredentialSource("env", async () => ({
|
||||||
|
accessKeyId: "AKIA_TEST",
|
||||||
|
secretAccessKey: "secret",
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
mockFromTokenFile.mockReturnValue(throwingSource("token-file"));
|
||||||
|
mockFromContainerMetadata.mockReturnValue(throwingSource("container-metadata"));
|
||||||
|
mockFromInstanceMetadata.mockReturnValue(throwingSource("instance-metadata"));
|
||||||
|
mockGetAvailableProfiles.mockResolvedValue([]);
|
||||||
|
mockStsGetCallerIdentity.mockResolvedValue({
|
||||||
|
account: "123456789012",
|
||||||
|
arn: "arn:aws:iam::123456789012:user/test",
|
||||||
|
userId: "AIDACKCEVSQ6C2EXAMPLE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect((result.data as any[])[0].source).toBe("env");
|
||||||
|
expect((result.data as any[])[0].account).toBe("123456789012");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns success with profile credentials", async () => {
|
||||||
|
mockFromEnv.mockReturnValue(throwingSource("env"));
|
||||||
|
mockFromTokenFile.mockReturnValue(throwingSource("token-file"));
|
||||||
|
mockFromContainerMetadata.mockReturnValue(throwingSource("container-metadata"));
|
||||||
|
mockFromInstanceMetadata.mockReturnValue(throwingSource("instance-metadata"));
|
||||||
|
mockGetAvailableProfiles.mockResolvedValue(["dev", "prod"]);
|
||||||
|
mockFromProfile.mockImplementation((profile: string) =>
|
||||||
|
makeCredentialSource(`profile:${profile}`, async () => ({
|
||||||
|
accessKeyId: `AKIA_${profile}`,
|
||||||
|
secretAccessKey: "secret",
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
mockStsGetCallerIdentity.mockResolvedValue({
|
||||||
|
account: "123456789012",
|
||||||
|
arn: "arn:aws:iam::123456789012:user/test",
|
||||||
|
userId: "AIDACKCEVSQ6C2EXAMPLE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect((result.data as any[]).length).toBe(2);
|
||||||
|
expect((result.data as any[])[0].source).toBe("profile:dev");
|
||||||
|
expect((result.data as any[])[1].source).toBe("profile:prod");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("continues on profile failure", async () => {
|
||||||
|
mockFromEnv.mockReturnValue(throwingSource("env"));
|
||||||
|
mockFromTokenFile.mockReturnValue(throwingSource("token-file"));
|
||||||
|
mockFromContainerMetadata.mockReturnValue(throwingSource("container-metadata"));
|
||||||
|
mockFromInstanceMetadata.mockReturnValue(throwingSource("instance-metadata"));
|
||||||
|
mockGetAvailableProfiles.mockResolvedValue(["bad", "good"]);
|
||||||
|
mockFromProfile.mockImplementation((profile: string) =>
|
||||||
|
makeCredentialSource(`profile:${profile}`, async () => ({
|
||||||
|
accessKeyId: `AKIA_${profile}`,
|
||||||
|
secretAccessKey: "secret",
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
mockStsGetCallerIdentity
|
||||||
|
.mockRejectedValueOnce(new Error("STS failure"))
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
account: "123456789012",
|
||||||
|
arn: "arn:aws:iam::123456789012:user/test",
|
||||||
|
userId: "AIDACKCEVSQ6C2EXAMPLE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect((result.data as any[]).length).toBe(1);
|
||||||
|
expect((result.data as any[])[0].source).toBe("profile:good");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("detects static credentials", async () => {
|
||||||
|
mockFromEnv.mockReturnValue(
|
||||||
|
makeCredentialSource("env", async () => ({
|
||||||
|
accessKeyId: "AKIA_TEST",
|
||||||
|
secretAccessKey: "secret",
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
mockFromTokenFile.mockReturnValue(throwingSource("token-file"));
|
||||||
|
mockFromContainerMetadata.mockReturnValue(throwingSource("container-metadata"));
|
||||||
|
mockFromInstanceMetadata.mockReturnValue(throwingSource("instance-metadata"));
|
||||||
|
mockGetAvailableProfiles.mockResolvedValue([]);
|
||||||
|
mockStsGetCallerIdentity.mockResolvedValue({
|
||||||
|
account: "123456789012",
|
||||||
|
arn: "arn:aws:iam::123456789012:user/test",
|
||||||
|
userId: "AIDACKCEVSQ6C2EXAMPLE",
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect((result.data as any[])[0].staticCredentials).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
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<string, unknown> = (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);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
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 { AwsSsmService } from "../../../src/providers/aws/ssm";
|
||||||
|
|
||||||
|
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("AwsSsmService", () => {
|
||||||
|
let service: AwsSsmService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockJsonApiRequest.mockReset();
|
||||||
|
mockStsGetCallerIdentity.mockReset();
|
||||||
|
mockResolveDefaultCredentials.mockReset();
|
||||||
|
service = new AwsSsmService();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns failure when no parameters found", async () => {
|
||||||
|
setupCredentials();
|
||||||
|
mockJsonApiRequest.mockResolvedValue({ Parameters: [], NextToken: undefined });
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(false);
|
||||||
|
expect(result.error?.message).toContain("No parameters found");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns success with parameters", async () => {
|
||||||
|
setupCredentials();
|
||||||
|
mockJsonApiRequest.mockImplementation((_creds, _region, _service, target) => {
|
||||||
|
if (target === "AmazonSSM.DescribeParameters") {
|
||||||
|
return Promise.resolve({
|
||||||
|
Parameters: [{ Name: "/app/key" }],
|
||||||
|
NextToken: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target === "AmazonSSM.GetParameters") {
|
||||||
|
return Promise.resolve({
|
||||||
|
Parameters: [{ Name: "/app/key", Value: "secret" }],
|
||||||
|
InvalidParameters: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({});
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
const data = result.data as any;
|
||||||
|
expect(data.parameterNames.length).toBeGreaterThan(0);
|
||||||
|
const values: string[] = Object.values(data.parameters);
|
||||||
|
expect(values).toContain("secret");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("stores error for failed parameter fetch", async () => {
|
||||||
|
setupCredentials();
|
||||||
|
mockJsonApiRequest.mockImplementation((_creds, _region, _service, target) => {
|
||||||
|
if (target === "AmazonSSM.DescribeParameters") {
|
||||||
|
return Promise.resolve({
|
||||||
|
Parameters: [{ Name: "/app/key" }],
|
||||||
|
NextToken: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target === "AmazonSSM.GetParameters") {
|
||||||
|
return Promise.reject(new Error("AccessDenied"));
|
||||||
|
}
|
||||||
|
return Promise.resolve({});
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
const params: Record<string, unknown> = (result.data as any).parameters;
|
||||||
|
expect(
|
||||||
|
Object.values(params).some(
|
||||||
|
(v) =>
|
||||||
|
typeof v === "object" &&
|
||||||
|
v !== null &&
|
||||||
|
(v as any).error === "AccessDenied",
|
||||||
|
),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("retries on throttling errors", async () => {
|
||||||
|
setupCredentials();
|
||||||
|
const throttleError = new Error("ThrottlingException: Rate exceeded");
|
||||||
|
|
||||||
|
mockJsonApiRequest.mockImplementation((_creds, _region, _service, target) => {
|
||||||
|
if (target === "AmazonSSM.DescribeParameters") {
|
||||||
|
return Promise.resolve({
|
||||||
|
Parameters: [{ Name: "/app/key" }],
|
||||||
|
NextToken: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target === "AmazonSSM.GetParameters") {
|
||||||
|
return mockJsonApiRequest.mock.results.length < 2
|
||||||
|
? Promise.reject(throttleError)
|
||||||
|
: Promise.resolve({
|
||||||
|
Parameters: [{ Name: "/app/key", Value: "retried" }],
|
||||||
|
InvalidParameters: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({});
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
const params: Record<string, unknown> = (result.data as any).parameters;
|
||||||
|
expect(Object.values(params)).toContain("retried");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("paginates through multiple pages", async () => {
|
||||||
|
setupCredentials();
|
||||||
|
mockJsonApiRequest.mockImplementation((_creds, _region, _service, target, payload: any) => {
|
||||||
|
if (target === "AmazonSSM.DescribeParameters") {
|
||||||
|
if (!payload.NextToken) {
|
||||||
|
return Promise.resolve({
|
||||||
|
Parameters: [{ Name: "/p1" }],
|
||||||
|
NextToken: "tok",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
Parameters: [{ Name: "/p2" }],
|
||||||
|
NextToken: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target === "AmazonSSM.GetParameters") {
|
||||||
|
const names = (payload as any).Names as string[];
|
||||||
|
const params = names.map((n: string) => ({
|
||||||
|
Name: n,
|
||||||
|
Value: n === "/p1" ? "v1" : "v2",
|
||||||
|
}));
|
||||||
|
return Promise.resolve({
|
||||||
|
Parameters: params,
|
||||||
|
InvalidParameters: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return Promise.resolve({});
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await service.execute();
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
const data = result.data as any;
|
||||||
|
expect(data.parameterNames.length).toBeGreaterThanOrEqual(2);
|
||||||
|
const values: string[] = Object.values(data.parameters);
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user