Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 110 additions & 109 deletions __tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import * as core from '@actions/core'
import { mockClient } from "aws-sdk-client-mock";
import * as core from '@actions/core';
import {
GetSecretValueCommand, ListSecretsCommand,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update your tab size to 4 spaces and resubmit?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

SecretsManagerClient,
GetSecretValueCommand, ListSecretsCommand,
SecretsManagerClient
} from '@aws-sdk/client-secrets-manager';
import { mockClient } from "aws-sdk-client-mock";
import { run } from "../src";
import { CLEANUP_NAME } from "../src/constants";

const DEFAULT_TEST_ENV = {
AWS_DEFAULT_REGION: 'us-east-1'
AWS_DEFAULT_REGION: 'us-east-1'
};

const smMockClient = mockClient(SecretsManagerClient);
Expand All @@ -34,111 +34,112 @@ const TEST_ARN_INPUT = ENV_NAME_4 + "," + TEST_ARN_1;

// Mock the inputs for Github action
jest.mock('@actions/core', () => {
return {
getMultilineInput: jest.fn((name: string, options?: core.InputOptions) => [TEST_NAME, TEST_INPUT_3, TEST_ARN_INPUT] ),
getBooleanInput: jest.fn((name: string, options?: core.InputOptions) => true),
setFailed: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
exportVariable: jest.fn((name: string, val: string) => process.env[name] = val),
setSecret: jest.fn(),
};
return {
getMultilineInput: jest.fn((name: string, options?: core.InputOptions) => [TEST_NAME, TEST_INPUT_3, TEST_ARN_INPUT]),
getBooleanInput: jest.fn((name: string, options?: core.InputOptions) => true),
setFailed: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
exportVariable: jest.fn((name: string, val: string) => process.env[name] = val),
setSecret: jest.fn(),
getInput: jest.fn((name: string, options?: core.InputOptions) => ""),
};
});

describe('Test main action', () => {
const OLD_ENV = process.env;

beforeEach(() => {
jest.clearAllMocks();
smMockClient.reset();
process.env = {...OLD_ENV, ...DEFAULT_TEST_ENV};
});

afterEach(() => {
process.env = OLD_ENV;
});

test('Retrieves and sets the requested secrets as environment variables, parsing JSON', async () => {
// Mock all Secrets Manager calls
smMockClient
.on(GetSecretValueCommand, { SecretId: TEST_NAME_1})
.resolves({ Name: TEST_NAME_1, SecretString: SECRET_1 })
.on(GetSecretValueCommand, {SecretId: TEST_NAME_2 })
.resolves({ Name: TEST_NAME_2, SecretString: SECRET_2 })
.on(GetSecretValueCommand, { SecretId: TEST_NAME_3 })
.resolves({ Name: TEST_NAME_3, SecretString: SECRET_3 })
.on(GetSecretValueCommand, { // Retrieve arn secret
SecretId: TEST_ARN_1,
})
.resolves({
Name: TEST_NAME_4,
SecretString: SECRET_4
})
.on(ListSecretsCommand)
.resolves({
SecretList: [
{
Name: TEST_NAME_1
},
{
Name: TEST_NAME_2
}
]
});

await run();
expect(core.exportVariable).toHaveBeenCalledTimes(7);
expect(core.setFailed).not.toHaveBeenCalled();

// JSON secrets should be parsed
expect(core.exportVariable).toHaveBeenCalledWith('TEST_ONE_USER', 'admin');
expect(core.exportVariable).toHaveBeenCalledWith('TEST_ONE_PASSWORD', 'adminpw');
expect(core.exportVariable).toHaveBeenCalledWith('TEST_TWO_USER', 'integ');
expect(core.exportVariable).toHaveBeenCalledWith('TEST_TWO_PASSWORD', 'integpw');

expect(core.exportVariable).toHaveBeenCalledWith(ENV_NAME_3, SECRET_3);
expect(core.exportVariable).toHaveBeenCalledWith(ENV_NAME_4, SECRET_4);

expect(core.exportVariable).toHaveBeenCalledWith(CLEANUP_NAME, JSON.stringify(['TEST_ONE_USER', 'TEST_ONE_PASSWORD', 'TEST_TWO_USER', 'TEST_TWO_PASSWORD', ENV_NAME_3, ENV_NAME_4]));
});

test('Fails the action when an error occurs in Secrets Manager', async () => {
smMockClient.onAnyCommand().resolves({});

await run();
expect(core.setFailed).toHaveBeenCalledTimes(1);
});

test('Fails the action when multiple secrets exported the same variable name', async () => {
smMockClient
.on(GetSecretValueCommand, { SecretId: TEST_NAME_1})
.resolves({ Name: TEST_NAME_1, SecretString: SECRET_1 })
.on(GetSecretValueCommand, {SecretId: TEST_NAME_2 })
.resolves({ Name: TEST_NAME_2, SecretString: SECRET_2 })
.on(GetSecretValueCommand, { SecretId: TEST_NAME_3 })
.resolves({ Name: TEST_NAME_3, SecretString: SECRET_3 })
.on(GetSecretValueCommand, { // Retrieve arn secret
SecretId: TEST_ARN_1,
})
.resolves({
Name: TEST_NAME_4,
SecretString: SECRET_4
})
.on(GetSecretValueCommand) // default
.resolves({Name: "DefaultName", SecretString: "Default"})
.on(ListSecretsCommand)
.resolves({
SecretList: [
{
Name: "TEST/SECRET/2"
},
{
Name: "TEST/SECRET@2"
}
]
});

await run();
expect(core.setFailed).toHaveBeenCalledTimes(1);
});
const OLD_ENV = process.env;

beforeEach(() => {
jest.clearAllMocks();
smMockClient.reset();
process.env = { ...OLD_ENV, ...DEFAULT_TEST_ENV };
});

afterEach(() => {
process.env = OLD_ENV;
});

test('Retrieves and sets the requested secrets as environment variables, parsing JSON', async () => {
// Mock all Secrets Manager calls
smMockClient
.on(GetSecretValueCommand, { SecretId: TEST_NAME_1 })
.resolves({ Name: TEST_NAME_1, SecretString: SECRET_1 })
.on(GetSecretValueCommand, { SecretId: TEST_NAME_2 })
.resolves({ Name: TEST_NAME_2, SecretString: SECRET_2 })
.on(GetSecretValueCommand, { SecretId: TEST_NAME_3 })
.resolves({ Name: TEST_NAME_3, SecretString: SECRET_3 })
.on(GetSecretValueCommand, { // Retrieve arn secret
SecretId: TEST_ARN_1,
})
.resolves({
Name: TEST_NAME_4,
SecretString: SECRET_4
})
.on(ListSecretsCommand)
.resolves({
SecretList: [
{
Name: TEST_NAME_1
},
{
Name: TEST_NAME_2
}
]
});

await run();
expect(core.exportVariable).toHaveBeenCalledTimes(7);
expect(core.setFailed).not.toHaveBeenCalled();

// JSON secrets should be parsed
expect(core.exportVariable).toHaveBeenCalledWith('TEST_ONE_USER', 'admin');
expect(core.exportVariable).toHaveBeenCalledWith('TEST_ONE_PASSWORD', 'adminpw');
expect(core.exportVariable).toHaveBeenCalledWith('TEST_TWO_USER', 'integ');
expect(core.exportVariable).toHaveBeenCalledWith('TEST_TWO_PASSWORD', 'integpw');

expect(core.exportVariable).toHaveBeenCalledWith(ENV_NAME_3, SECRET_3);
expect(core.exportVariable).toHaveBeenCalledWith(ENV_NAME_4, SECRET_4);

expect(core.exportVariable).toHaveBeenCalledWith(CLEANUP_NAME, JSON.stringify(['TEST_ONE_USER', 'TEST_ONE_PASSWORD', 'TEST_TWO_USER', 'TEST_TWO_PASSWORD', ENV_NAME_3, ENV_NAME_4]));
});

test('Fails the action when an error occurs in Secrets Manager', async () => {
smMockClient.onAnyCommand().resolves({});

await run();
expect(core.setFailed).toHaveBeenCalledTimes(1);
});

test('Fails the action when multiple secrets exported the same variable name', async () => {
smMockClient
.on(GetSecretValueCommand, { SecretId: TEST_NAME_1 })
.resolves({ Name: TEST_NAME_1, SecretString: SECRET_1 })
.on(GetSecretValueCommand, { SecretId: TEST_NAME_2 })
.resolves({ Name: TEST_NAME_2, SecretString: SECRET_2 })
.on(GetSecretValueCommand, { SecretId: TEST_NAME_3 })
.resolves({ Name: TEST_NAME_3, SecretString: SECRET_3 })
.on(GetSecretValueCommand, { // Retrieve arn secret
SecretId: TEST_ARN_1,
})
.resolves({
Name: TEST_NAME_4,
SecretString: SECRET_4
})
.on(GetSecretValueCommand) // default
.resolves({ Name: "DefaultName", SecretString: "Default" })
.on(ListSecretsCommand)
.resolves({
SecretList: [
{
Name: "TEST/SECRET/2"
},
{
Name: "TEST/SECRET@2"
}
]
});

await run();
expect(core.setFailed).toHaveBeenCalledTimes(1);
});
});
Loading