const core = require('@actions/core');
const assert = require('assert');
const aws = require('aws-sdk');
const run = require('./index.js');

jest.mock('@actions/core');

const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID';
const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY';
const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN';
const FAKE_STS_ACCESS_KEY_ID = 'STS-AWS-ACCESS-KEY-ID';
const FAKE_STS_SECRET_ACCESS_KEY = 'STS-AWS-SECRET-ACCESS-KEY';
const FAKE_STS_SESSION_TOKEN = 'STS-AWS-SESSION-TOKEN';
const FAKE_REGION = 'fake-region-1';
const FAKE_ACCOUNT_ID = '123456789012';
const FAKE_ROLE_ACCOUNT_ID = '111111111111';
const ROLE_NAME = 'MY-ROLE';
const ROLE_ARN = 'arn:aws:iam::111111111111:role/MY-ROLE';
const ENVIRONMENT_VARIABLE_OVERRIDES = {
    SHOW_STACK_TRACE: 'true',
    GITHUB_REPOSITORY: 'MY-REPOSITORY-NAME',
    GITHUB_WORKFLOW: 'MY-WORKFLOW-ID',
    GITHUB_ACTION: 'MY-ACTION-NAME',
    GITHUB_ACTOR: 'MY-USERNAME[bot]',
    GITHUB_SHA: 'MY-COMMIT-ID',
    GITHUB_REF: 'MY-BRANCH',
};
const GITHUB_ACTOR_SANITIZED = 'MY-USERNAME_bot_'

function mockGetInput(requestResponse) {
    return function (name, options) { // eslint-disable-line no-unused-vars
        return requestResponse[name]
    }
}
const CREDS_INPUTS = {
    'aws-access-key-id': FAKE_ACCESS_KEY_ID,
    'aws-secret-access-key': FAKE_SECRET_ACCESS_KEY
};
const DEFAULT_INPUTS = {
    ...CREDS_INPUTS,
    'aws-session-token': FAKE_SESSION_TOKEN,
    'aws-region': FAKE_REGION,
    'mask-aws-account-id': 'TRUE'
};
const ASSUME_ROLE_INPUTS = {...CREDS_INPUTS, 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION};

const mockStsCallerIdentity = jest.fn();
const mockStsAssumeRole = jest.fn();

jest.mock('aws-sdk', () => {
    return {
        config: {
            getCredentials: jest.fn()
        },
        STS: jest.fn(() => ({
            getCallerIdentity: mockStsCallerIdentity,
            assumeRole: mockStsAssumeRole,
        }))
    };
});

describe('Configure AWS Credentials', () => {
    const OLD_ENV = process.env;

    beforeEach(() => {
        jest.resetModules();
        process.env = {...OLD_ENV, ...ENVIRONMENT_VARIABLE_OVERRIDES};

        jest.clearAllMocks();

        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(DEFAULT_INPUTS));

        mockStsCallerIdentity.mockReset();
        mockStsCallerIdentity
            .mockReturnValueOnce({
                promise() {
                   return Promise.resolve({ Account: FAKE_ACCOUNT_ID });
                }
            })
            .mockReturnValueOnce({
                promise() {
                   return Promise.resolve({ Account: FAKE_ROLE_ACCOUNT_ID });
                }
            });

        aws.config.getCredentials.mockReset();
        aws.config.getCredentials
            .mockImplementationOnce(callback => {
                if (!aws.config.credentials) {
                    aws.config.credentials = {
                        accessKeyId: FAKE_ACCESS_KEY_ID,
                        secretAccessKey: FAKE_SECRET_ACCESS_KEY
                    }
                }
                callback(null);
            })
            .mockImplementationOnce(callback => {
                if (!aws.config.credentials) {
                    aws.config.credentials = {
                        accessKeyId: FAKE_STS_ACCESS_KEY_ID,
                        secretAccessKey: FAKE_STS_SECRET_ACCESS_KEY
                    }
                }
                callback(null);
            });

        mockStsAssumeRole.mockImplementation(() => {
            return {
                promise() {
                    return Promise.resolve({
                        Credentials: {
                            AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
                            SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
                            SessionToken: FAKE_STS_SESSION_TOKEN
                        }
                    });
                }
            }
        });
    });

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

    test('exports env vars', async () => {
        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
        expect(core.exportVariable).toHaveBeenCalledTimes(5);
        expect(core.setSecret).toHaveBeenCalledTimes(4);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', FAKE_SESSION_TOKEN);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_SESSION_TOKEN);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
        expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
    });

    test('action fails when github env vars are not set', async () => {
        process.env.SHOW_STACK_TRACE = 'false';
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
        delete process.env.GITHUB_SHA;

        await run();
        expect(core.setFailed).toHaveBeenCalledWith('Missing required environment value. Are you running in GitHub Actions?');
    });

    test('action does not require GITHUB_REF env var', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
        delete process.env.GITHUB_REF;

        await run();
    });

    test('hosted runners can pull creds from a self-hosted environment', async () => {
        const mockInputs = {'aws-region': FAKE_REGION};
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(mockInputs));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
        expect(core.exportVariable).toHaveBeenCalledTimes(2);
        expect(core.setSecret).toHaveBeenCalledTimes(1);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
        expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
    });

    test('action with no accessible credentials fails', async () => {
        process.env.SHOW_STACK_TRACE = 'false';
        const mockInputs = {'aws-region': FAKE_REGION};
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(mockInputs));
        aws.config.getCredentials.mockReset();
        aws.config.getCredentials.mockImplementation(callback => {
            callback(new Error('No credentials to load'));
        });

        await run();

        expect(core.setFailed).toHaveBeenCalledWith("Credentials could not be loaded, please check your action inputs: No credentials to load");
    });

    test('action with empty credentials fails', async () => {
        process.env.SHOW_STACK_TRACE = 'false';
        const mockInputs = {'aws-region': FAKE_REGION};
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(mockInputs));
        aws.config.getCredentials.mockReset();
        aws.config.getCredentials.mockImplementation(callback => {
            aws.config.credentials = {
                accessKeyId: ''
            }
            callback(null);
        });

        await run();

        expect(core.setFailed).toHaveBeenCalledWith("Credentials could not be loaded, please check your action inputs: Access key ID empty after loading credentials");
    });

    test('action fails when credentials are not set in the SDK correctly', async () => {
        process.env.SHOW_STACK_TRACE = 'false';
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
        aws.config.getCredentials.mockReset();
        aws.config.getCredentials.mockImplementation(callback => {
            aws.config.credentials = {
                accessKeyId: FAKE_ACCESS_KEY_ID
            }
            callback(null);
        });

        await run();

        expect(core.setFailed).toHaveBeenCalledWith("Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action");
    });

    test('session token is optional', async () => {
        const mockInputs = {...CREDS_INPUTS, 'aws-region': 'eu-west-1'};
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(mockInputs));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
        expect(core.exportVariable).toHaveBeenCalledTimes(4);
        expect(core.setSecret).toHaveBeenCalledTimes(3);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
        expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
    });

    test('existing env var creds are cleared', async () => {
        const mockInputs = {...CREDS_INPUTS, 'aws-region': 'eu-west-1'};
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(mockInputs));
        process.env.AWS_ACCESS_KEY_ID = 'foo';
        process.env.AWS_SECRET_ACCESS_KEY = 'bar';
        process.env.AWS_SESSION_TOKEN = 'helloworld';
        aws.config.credentials = {
            accessKeyId: 'foo',
            secretAccessKey: 'bar',
            sessionToken: 'helloworld'
        };

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
        expect(core.exportVariable).toHaveBeenCalledTimes(5);
        expect(core.setSecret).toHaveBeenCalledTimes(3);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
        expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
        expect(aws.config.credentials.accessKeyId).toBe(FAKE_ACCESS_KEY_ID);
        expect(aws.config.credentials.secretAccessKey).toBe(FAKE_SECRET_ACCESS_KEY);
        expect(aws.config.credentials.sessionToken).toBeUndefined();
    });

    test('validates region name', async () => {
        process.env.SHOW_STACK_TRACE = 'false';

        const mockInputs = {...CREDS_INPUTS, 'aws-region': '$AWS_REGION'};
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(mockInputs));

        await run();

        expect(core.setFailed).toHaveBeenCalledWith('Region is not valid: $AWS_REGION');
    });

    test('throws error if access key id exists but missing secret access key', async () => {
        process.env.SHOW_STACK_TRACE = 'false';
        const inputsWIthoutSecretKey = {...ASSUME_ROLE_INPUTS}
        inputsWIthoutSecretKey["aws-secret-access-key"] = undefined
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(inputsWIthoutSecretKey));

        await run();
        expect(core.setFailed).toHaveBeenCalledWith("'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided");

    });

    test('can opt out of masking account ID', async () => {
        const mockInputs = {...CREDS_INPUTS, 'aws-region': 'us-east-1', 'mask-aws-account-id': 'false'};
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(mockInputs));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
        expect(core.exportVariable).toHaveBeenCalledTimes(4);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
        expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-1');
        expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-1');
        expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
        expect(core.setSecret).toHaveBeenCalledTimes(2);
    });

    test('error is caught by core.setFailed and caught', async () => {
        process.env.SHOW_STACK_TRACE = 'false';

        mockStsCallerIdentity.mockReset();
        mockStsCallerIdentity.mockImplementation(() => {
            throw new Error();
        });

        await run();

        expect(core.setFailed).toBeCalled();
    });

    test('error is caught by core.setFailed and passed', async () => {

        mockStsCallerIdentity.mockReset();
        mockStsCallerIdentity.mockImplementation(() => {
            throw new Error();
        });

        await assert.rejects(() => run());

        expect(core.setFailed).toBeCalled();
    });

    test('basic role assumption exports', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledTimes(1);
        expect(core.exportVariable).toHaveBeenCalledTimes(7);
        expect(core.setSecret).toHaveBeenCalledTimes(7);
        expect(core.setOutput).toHaveBeenCalledTimes(2);

        // first the source credentials are exported and masked
        expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_ACCESS_KEY_ID);
        expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_SECRET_ACCESS_KEY);
        expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_ACCOUNT_ID);

        expect(core.exportVariable).toHaveBeenNthCalledWith(1, 'AWS_DEFAULT_REGION', FAKE_REGION);
        expect(core.exportVariable).toHaveBeenNthCalledWith(2, 'AWS_REGION', FAKE_REGION);
        expect(core.exportVariable).toHaveBeenNthCalledWith(3, 'AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
        expect(core.exportVariable).toHaveBeenNthCalledWith(4, 'AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);

        expect(core.setOutput).toHaveBeenNthCalledWith(1, 'aws-account-id', FAKE_ACCOUNT_ID);

        // then the role credentials are exported and masked
        expect(core.setSecret).toHaveBeenNthCalledWith(4, FAKE_STS_ACCESS_KEY_ID);
        expect(core.setSecret).toHaveBeenNthCalledWith(5, FAKE_STS_SECRET_ACCESS_KEY);
        expect(core.setSecret).toHaveBeenNthCalledWith(6, FAKE_STS_SESSION_TOKEN);
        expect(core.setSecret).toHaveBeenNthCalledWith(7, FAKE_ROLE_ACCOUNT_ID);

        expect(core.exportVariable).toHaveBeenNthCalledWith(5, 'AWS_ACCESS_KEY_ID', FAKE_STS_ACCESS_KEY_ID);
        expect(core.exportVariable).toHaveBeenNthCalledWith(6, 'AWS_SECRET_ACCESS_KEY', FAKE_STS_SECRET_ACCESS_KEY);
        expect(core.exportVariable).toHaveBeenNthCalledWith(7, 'AWS_SESSION_TOKEN', FAKE_STS_SESSION_TOKEN);

        expect(core.setOutput).toHaveBeenNthCalledWith(2, 'aws-account-id', FAKE_ROLE_ACCOUNT_ID);
    });

    test('assume role can pull source credentials from self-hosted environment', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledTimes(1);
        expect(core.exportVariable).toHaveBeenCalledTimes(5);
        expect(core.setSecret).toHaveBeenCalledTimes(5);
        expect(core.setOutput).toHaveBeenCalledTimes(2);

        // first the source account is exported and masked
        expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_ACCOUNT_ID);
        expect(core.exportVariable).toHaveBeenNthCalledWith(1, 'AWS_DEFAULT_REGION', FAKE_REGION);
        expect(core.exportVariable).toHaveBeenNthCalledWith(2, 'AWS_REGION', FAKE_REGION);
        expect(core.setOutput).toHaveBeenNthCalledWith(1, 'aws-account-id', FAKE_ACCOUNT_ID);

        // then the role credentials are exported and masked
        expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_STS_ACCESS_KEY_ID);
        expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SECRET_ACCESS_KEY);
        expect(core.setSecret).toHaveBeenNthCalledWith(4, FAKE_STS_SESSION_TOKEN);
        expect(core.setSecret).toHaveBeenNthCalledWith(5, FAKE_ROLE_ACCOUNT_ID);

        expect(core.exportVariable).toHaveBeenNthCalledWith(3, 'AWS_ACCESS_KEY_ID', FAKE_STS_ACCESS_KEY_ID);
        expect(core.exportVariable).toHaveBeenNthCalledWith(4, 'AWS_SECRET_ACCESS_KEY', FAKE_STS_SECRET_ACCESS_KEY);
        expect(core.exportVariable).toHaveBeenNthCalledWith(5, 'AWS_SESSION_TOKEN', FAKE_STS_SESSION_TOKEN);

        expect(core.setOutput).toHaveBeenNthCalledWith(2, 'aws-account-id', FAKE_ROLE_ACCOUNT_ID);
    });

    test('role assumption tags', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 6 * 3600,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ]
        })
    });

    test('role assumption duration provided', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-duration-seconds': 5}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 5,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ]
        })
    });

    test('role assumption session name provided', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-session-name': 'MySessionName'}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'MySessionName',
            DurationSeconds: 6 * 3600,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ]
        })
    });

    test('role name provided instead of ARN', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({...CREDS_INPUTS, 'role-to-assume': ROLE_NAME, 'aws-region': FAKE_REGION}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: 'arn:aws:iam::123456789012:role/MY-ROLE',
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 6 * 3600,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ]
        })
    });

    test('role external ID provided', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-external-id': 'abcdef'}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 6 * 3600,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ],
            ExternalId: 'abcdef'
        })
    });

    test('workflow name sanitized in role assumption tags', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));

        process.env = {...process.env, GITHUB_WORKFLOW: 'Workflow!"#$%&\'()*+, -./:;<=>?@[]^_`{|}~🙂💥🍌1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZai9D2AN2RlWCxtMqChNtxuxjqeqhoQZo0oaq39sjcRZgAAAAAAA'};

        const sanitizedWorkflowName = 'Workflow__________+_ -./:;<=>?@____________1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZa'

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 6 * 3600,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: sanitizedWorkflowName},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ]
        })
    });

    test('skip tagging provided as true', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': true}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 21600,
            Tags: undefined
        })
    });

    test('skip tagging provided as false', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': false}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 21600,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ]
        })
    });

    test('skip tagging not provided', async () => {
        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS}));

        await run();
        expect(mockStsAssumeRole).toHaveBeenCalledWith({
            RoleArn: ROLE_ARN,
            RoleSessionName: 'GitHubActions',
            DurationSeconds: 21600,
            Tags: [
                {Key: 'GitHub', Value: 'Actions'},
                {Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
                {Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
                {Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
                {Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
                {Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
                {Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
            ]
        })
    });

    test('masks variables before exporting', async () => {
        let maskedValues = [];
        const publicFields = ['AWS_REGION', 'AWS_DEFAULT_REGION'];
        core.setSecret.mockReset();
        core.setSecret.mockImplementation((secret) => {
            maskedValues.push(secret);
        });

        core.exportVariable.mockReset();
        core.exportVariable.mockImplementation((name, value) => {
            if (!maskedValues.includes(value) && !publicFields.includes(name)) {
                throw new Error(value + " for variable " + name + " is not masked yet!");
            }
        });

        core.getInput = jest
            .fn()
            .mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));

        await run();
    });

});
