Skip to content

Commit a8d3e0f

Browse files
committed
test(aws-ssm-util): add test coverage for getParameters batch function
1 parent 138257d commit a8d3e0f

File tree

1 file changed

+89
-1
lines changed

1 file changed

+89
-1
lines changed

lambdas/libs/aws-ssm-util/src/index.test.ts

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
GetParameterCommand,
33
GetParameterCommandOutput,
4+
GetParametersCommand,
45
PutParameterCommand,
56
PutParameterCommandOutput,
67
SSMClient,
@@ -9,7 +10,7 @@ import 'aws-sdk-client-mock-jest/vitest';
910
import { mockClient } from 'aws-sdk-client-mock';
1011
import nock from 'nock';
1112

12-
import { getParameter, putParameter, SSM_ADVANCED_TIER_THRESHOLD } from '.';
13+
import { getParameter, getParameters, putParameter, SSM_ADVANCED_TIER_THRESHOLD } from '.';
1314
import { describe, it, expect, beforeEach, vi } from 'vitest';
1415

1516
const mockSSMClient = mockClient(SSMClient);
@@ -166,3 +167,90 @@ describe('Test getParameter and putParameter', () => {
166167
});
167168
});
168169
});
170+
171+
describe('Test getParameters (batch)', () => {
172+
beforeEach(() => {
173+
mockSSMClient.reset();
174+
});
175+
176+
it('returns multiple parameters in a single call', async () => {
177+
mockSSMClient.on(GetParametersCommand).resolves({
178+
Parameters: [
179+
{ Name: '/app/param1', Value: 'value1' },
180+
{ Name: '/app/param2', Value: 'value2' },
181+
],
182+
});
183+
184+
const result = await getParameters(['/app/param1', '/app/param2']);
185+
186+
expect(result).toEqual(
187+
new Map([
188+
['/app/param1', 'value1'],
189+
['/app/param2', 'value2'],
190+
]),
191+
);
192+
expect(mockSSMClient).toHaveReceivedCommandWith(GetParametersCommand, {
193+
Names: ['/app/param1', '/app/param2'],
194+
WithDecryption: true,
195+
});
196+
});
197+
198+
it('returns empty map for empty input', async () => {
199+
const result = await getParameters([]);
200+
201+
expect(result).toEqual(new Map());
202+
expect(mockSSMClient).not.toHaveReceivedCommand(GetParametersCommand);
203+
});
204+
205+
it('chunks requests when more than 10 parameters', async () => {
206+
const names = Array.from({ length: 12 }, (_, i) => `/app/param${i}`);
207+
208+
mockSSMClient
209+
.on(GetParametersCommand, { Names: names.slice(0, 10), WithDecryption: true })
210+
.resolves({
211+
Parameters: names.slice(0, 10).map((name) => ({ Name: name, Value: `val-${name}` })),
212+
})
213+
.on(GetParametersCommand, { Names: names.slice(10), WithDecryption: true })
214+
.resolves({
215+
Parameters: names.slice(10).map((name) => ({ Name: name, Value: `val-${name}` })),
216+
});
217+
218+
const result = await getParameters(names);
219+
220+
expect(result.size).toBe(12);
221+
expect(mockSSMClient).toHaveReceivedCommandTimes(GetParametersCommand, 2);
222+
for (const name of names) {
223+
expect(result.get(name)).toBe(`val-${name}`);
224+
}
225+
});
226+
227+
it('omits parameters with missing Name or Value', async () => {
228+
mockSSMClient.on(GetParametersCommand).resolves({
229+
Parameters: [
230+
{ Name: '/app/good', Value: 'value' },
231+
{ Name: '/app/no-value', Value: undefined },
232+
{ Name: undefined, Value: 'orphan' },
233+
],
234+
});
235+
236+
const result = await getParameters(['/app/good', '/app/no-value']);
237+
238+
expect(result).toEqual(new Map([['/app/good', 'value']]));
239+
});
240+
241+
it('propagates errors from SSM API', async () => {
242+
mockSSMClient.on(GetParametersCommand).rejects(new Error('AccessDenied'));
243+
244+
await expect(getParameters(['/app/param1'])).rejects.toThrow('AccessDenied');
245+
});
246+
247+
it('handles response with empty Parameters array', async () => {
248+
mockSSMClient.on(GetParametersCommand).resolves({
249+
Parameters: [],
250+
});
251+
252+
const result = await getParameters(['/app/missing']);
253+
254+
expect(result).toEqual(new Map());
255+
});
256+
});

0 commit comments

Comments
 (0)