UNPKG

@davidpellerin/accountfactory

Version:

AWS Organizations setup and management tool for creating and managing multi-account setups

196 lines (167 loc) 7.41 kB
import { beforeEach, describe, expect, jest, test } from '@jest/globals'; import { mockClient } from 'aws-sdk-client-mock'; import { STSClient } from '@aws-sdk/client-sts'; import { SecretsManagerClient } from '@aws-sdk/client-secrets-manager'; import { createTestLogger } from '../utils/testLogger.js'; import { DEFAULT_REGION } from '../constants.js'; const stsClientMock = mockClient(STSClient); const secretsManagerClientMock = mockClient(SecretsManagerClient); let testLogger; // Create a mock for child_process.exec const mockExec = jest.fn(); // Mock the child_process module jest.unstable_mockModule('child_process', () => ({ exec: mockExec, })); describe('SetupProfilesService', () => { beforeEach(() => { stsClientMock.reset(); secretsManagerClientMock.reset(); testLogger = createTestLogger(); // Reset the exec mock mockExec.mockClear(); mockExec.mockImplementation((command, callback) => { callback(null, 'success', ''); }); }); describe('constructor', () => { test('should throw error when STSClient is not provided', async () => { const { SetupProfilesService } = await import('./setupProfilesService.js'); expect(() => new SetupProfilesService(null, secretsManagerClientMock)).toThrow( 'STSClient is required' ); }); test('should throw error when SecretsManagerClient is not provided', async () => { const { SetupProfilesService } = await import('./setupProfilesService.js'); expect(() => new SetupProfilesService(stsClientMock, null)).toThrow( 'SecretsManagerClient is required' ); }); test('should create instance when all dependencies are provided', async () => { const { SetupProfilesService } = await import('./setupProfilesService.js'); expect( () => new SetupProfilesService(stsClientMock, secretsManagerClientMock, testLogger) ).not.toThrow(); }); }); describe('setupAwsProfile', () => { const testAccountConfig = { email: 'test@example.com', profileName: 'test-profile', }; const testLiveAccountList = [ { Id: '123456789012', Name: 'Test Account', Email: 'test@example.com', Status: 'ACTIVE', }, ]; const testOptions = { username: 'testuser', }; const testCredentials = { username: 'testuser', password: 'testpassword', access_key_id: 'AKIATEST12345', secret_access_key: 'secretkey12345', account_id: '123456789012', console_url: 'https://123456789012.signin.aws.amazon.com/console', }; test('should throw error when account not found in live account list', async () => { const { SetupProfilesService } = await import('./setupProfilesService.js'); const service = new SetupProfilesService(stsClientMock, secretsManagerClientMock, testLogger); await expect( service.setupAwsProfile( { ...testAccountConfig, email: 'nonexistent@example.com' }, testLiveAccountList, testOptions ) ).rejects.toThrow( 'Could not find AWS Organizations account with email nonexistent@example.com' ); }); test('should throw error when credentials not found in Secrets Manager', async () => { // Create a service with a mocked secretsManagerService const { SetupProfilesService } = await import('./setupProfilesService.js'); const service = new SetupProfilesService(stsClientMock, secretsManagerClientMock, testLogger); // Replace the secretsManagerService with a mock implementation service.secretsManagerService = { getExistingCredentials: jest.fn().mockResolvedValue(null), }; // Call the method and expect it to throw await expect( service.setupAwsProfile(testAccountConfig, testLiveAccountList, testOptions) ).rejects.toThrow(/No credentials found for user testuser in account 123456789012/); }); test('should configure AWS profile successfully when credentials exist', async () => { // Create a service with a mocked secretsManagerService const { SetupProfilesService } = await import('./setupProfilesService.js'); const service = new SetupProfilesService(stsClientMock, secretsManagerClientMock, testLogger); // Replace the secretsManagerService with a mock implementation const mockGetExistingCredentials = jest.fn().mockResolvedValue(testCredentials); service.secretsManagerService = { getExistingCredentials: mockGetExistingCredentials, }; // Call the method await service.setupAwsProfile(testAccountConfig, testLiveAccountList, testOptions); // Verify getExistingCredentials was called with correct parameters expect(mockGetExistingCredentials).toHaveBeenCalledWith('123456789012', 'testuser'); // Verify exec was called 4 times with the correct AWS configure commands expect(mockExec).toHaveBeenCalledTimes(4); expect(mockExec).toHaveBeenCalledWith( `aws configure set aws_access_key_id ${testCredentials.access_key_id} --profile ${testAccountConfig.profileName}`, expect.any(Function) ); expect(mockExec).toHaveBeenCalledWith( `aws configure set aws_secret_access_key ${testCredentials.secret_access_key} --profile ${testAccountConfig.profileName}`, expect.any(Function) ); expect(mockExec).toHaveBeenCalledWith( `aws configure set region ${DEFAULT_REGION} --profile ${testAccountConfig.profileName}`, expect.any(Function) ); expect(mockExec).toHaveBeenCalledWith( `aws configure set output json --profile ${testAccountConfig.profileName}`, expect.any(Function) ); // Verify success log message const logs = testLogger.getLogEntries(); const successLog = logs.find( log => log.level === 'success' && log.message.includes( `Successfully configured AWS profile '${testAccountConfig.profileName}'` ) ); expect(successLog).toBeTruthy(); }); test('should throw error when AWS configure command fails', async () => { // Create a service with a mocked secretsManagerService const { SetupProfilesService } = await import('./setupProfilesService.js'); const service = new SetupProfilesService(stsClientMock, secretsManagerClientMock, testLogger); // Replace the secretsManagerService with a mock implementation service.secretsManagerService = { getExistingCredentials: jest.fn().mockResolvedValue(testCredentials), }; // Mock exec to fail on the second call mockExec .mockImplementationOnce((command, callback) => { callback(null, 'success', ''); }) .mockImplementationOnce((command, callback) => { callback(new Error('Command failed'), '', 'stderr output'); }); // Call the method and expect it to throw await expect( service.setupAwsProfile(testAccountConfig, testLiveAccountList, testOptions) ).rejects.toThrow('Command failed'); // Verify error log message const logs = testLogger.getLogEntries(); const errorLog = logs.find( log => log.level === 'error' && log.message.includes('Failed to set up AWS profile') ); expect(errorLog).toBeTruthy(); }); }); });