diff --git a/lib/aws.ts b/lib/aws.ts
index 1e3610e..c6d3d2c 100644
--- a/lib/aws.ts
+++ b/lib/aws.ts
@@ -162,7 +162,7 @@ export class DefaultAwsClient implements IAws {
*
* @see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html#API_AssumeRole_RequestParameters
*/
-export function safeUsername() {
+function safeUsername() {
try {
return os.userInfo().username.replace(/[^\w+=,.@-]/g, '@');
} catch {
diff --git a/test/aws.test.ts b/test/aws.test.ts
index 7e9e7a5..3a9f8f3 100644
--- a/test/aws.test.ts
+++ b/test/aws.test.ts
@@ -1,4 +1,5 @@
-import { DefaultAwsClient, safeUsername } from '../lib';
+import * as os from 'os';
+import { DefaultAwsClient } from '../lib';
afterEach(() => {
jest.requireActual('aws-sdk');
@@ -26,31 +27,37 @@ describe('discoverTargetAccount', () => {
ChainableTemporaryCredentials: jest.fn(),
};
});
-
const aws = new DefaultAwsClient();
-
- await aws.discoverTargetAccount({
- region: 'us-east-1',
- assumeRoleArn: 'arn:aws:iam::123456789012:role/my-role',
- assumeRoleExternalId: 'external-id',
- });
-
- expect(AWS.ChainableTemporaryCredentials).toHaveBeenCalledWith({
- params: {
- ExternalId: 'external-id',
- RoleArn: 'arn:aws:iam::123456789012:role/my-role',
- RoleSessionName: `cdk-assets-${safeUsername()}`,
- },
- stsConfig: {
- customUserAgent: 'cdk-assets',
+ await withMocked(os, 'userInfo', async (userInfo) => {
+ userInfo.mockReturnValue({
+ username: 'foo',
+ uid: 1,
+ gid: 1,
+ homedir: '/here',
+ shell: '/bin/sh',
+ });
+ await aws.discoverTargetAccount({
region: 'us-east-1',
- },
+ assumeRoleArn: 'arn:aws:iam::123456789012:role/my-role',
+ assumeRoleExternalId: 'external-id',
+ });
+ expect(AWS.ChainableTemporaryCredentials).toHaveBeenCalledWith({
+ params: {
+ ExternalId: 'external-id',
+ RoleArn: 'arn:aws:iam::123456789012:role/my-role',
+ RoleSessionName: `cdk-assets-foo`,
+ },
+ stsConfig: {
+ customUserAgent: 'cdk-assets',
+ region: 'us-east-1',
+ },
+ });
});
});
test('returns account information', async () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
- const AWS = require('aws-sdk');
+ require('aws-sdk');
jest.mock('aws-sdk', () => {
return {
@@ -75,3 +82,34 @@ describe('discoverTargetAccount', () => {
});
});
});
+
+export function withMocked(
+ obj: A,
+ key: K,
+ block: (fn: jest.Mocked[K]) => B
+): B {
+ const original = obj[key];
+ const mockFn = jest.fn();
+ (obj as any)[key] = mockFn;
+
+ let asyncFinally: boolean = false;
+ try {
+ const ret = block(mockFn as any);
+ if (!isPromise(ret)) {
+ return ret;
+ }
+
+ asyncFinally = true;
+ return ret.finally(() => {
+ obj[key] = original;
+ }) as any;
+ } finally {
+ if (!asyncFinally) {
+ obj[key] = original;
+ }
+ }
+}
+
+function isPromise(object: any): object is Promise {
+ return Promise.resolve(object) === object;
+}