Skip to content

Commit

Permalink
test: add unit tests for mock env vars
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardfoyle committed Feb 12, 2021
1 parent ae1e138 commit c163cdc
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { importModelTableResolver } from '../../CFNParser/import-model-table-resolver';

describe('import model table resolver', () => {
it('replaces matched imports', () => {
expect(importModelTableResolver('1234:GetAtt:MyModelTable:Name', 'dev')).toEqual('MyModel-1234-dev');
});

it('identity function if no match', () => {
expect(importModelTableResolver('not a match', 'dev')).toEqual('not a match');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { stateManager } from 'amplify-cli-core';
import _ from 'lodash';
import { populateCfnParams } from '../../../utils/lambda/populate-cfn-params';

jest.mock('amplify-cli-core');
jest.mock('../../../api/api', () => ({
MOCK_API_PORT: '666',
}));

const stateManager_mock = stateManager as jest.Mocked<typeof stateManager>;

stateManager_mock.getLocalEnvInfo.mockReturnValue({
envName: 'test',
});

const teamProviderParam = {
anotherCfnParam: 'testValue',
};
stateManager_mock.getTeamProviderInfo.mockReturnValue({
test: {
awscloudformation: {
Region: 'test-region',
StackId: 'arn:aws:cloudformation:us-test-1:1234:stack/my-test-stack',
StackName: 'test-stack-name',
},
categories: {
function: {
func1: teamProviderParam,
},
},
},
});

const meta_stub = {
function: {
func1: {
dependsOn: [
{
category: 'storage',
resourceName: 'mytable',
attributes: ['tableName', 'tableArn'],
},
{
category: 'api',
resourceName: 'myApi',
attributes: ['apiName'],
},
],
},
},
storage: {
mytable: {
output: {
tableName: 'testTableName',
tableArn: 'testTableArn',
},
},
},
api: {
myApi: {
output: {
apiName: 'testApiName',
apiEndpoint: 'testApiEndpoint',
},
},
},
};

describe('populate cfn params', () => {
it('includes CFN pseudo parameters', () => {
expect(populateCfnParams({}, undefined)).toMatchObject({
env: 'test',
'AWS::Region': 'test-region',
'AWS::AccountId': '1234',
'AWS::StackId': 'arn:aws:cloudformation:us-test-1:1234:stack/my-test-stack',
'AWS::StackName': 'test-stack-name',
});
});

it('falls back to default pseudo params when not in team provider', () => {
stateManager_mock.getTeamProviderInfo.mockReturnValueOnce({
test: {
awscloudformation: {},
},
});

expect(populateCfnParams({}, undefined)).toMatchObject({
env: 'test',
'AWS::Region': 'us-test-1',
'AWS::AccountId': '12345678910',
'AWS::StackId': 'fake-stack-id',
'AWS::StackName': 'local-testing',
});
});

it('gets dependsOn params from amplify-meta', () => {
stateManager_mock.getMeta.mockReturnValueOnce(meta_stub);
expect(populateCfnParams({}, 'func1')).toMatchObject({
apimyApiapiName: 'testApiName',
storagemytabletableName: 'testTableName',
storagemytabletableArn: 'testTableArn',
});
});

it('overwrites api endpoint url when specified', () => {
const meta_stub_copy = _.cloneDeep(meta_stub);
meta_stub_copy.function.func1.dependsOn[1].attributes.push('GraphQLAPIEndpointOutput');
stateManager_mock.getMeta.mockReturnValueOnce(meta_stub_copy);
expect(populateCfnParams({ warning: jest.fn() }, 'func1', true)).toMatchObject({
apimyApiGraphQLAPIEndpointOutput: `http://localhost:666/graphql`,
});
});

it('prints warning when no value found', () => {
const meta_stub_copy = _.cloneDeep(meta_stub);
meta_stub_copy.function.func1.dependsOn[1].attributes.push('GraphQLAPIEndpointOutput');
stateManager_mock.getMeta.mockReturnValueOnce(meta_stub_copy);
const warningMock = jest.fn();
const result = populateCfnParams({ warning: warningMock }, 'func1');
expect(typeof result).toBe('object');
expect(result.apimyApiGraphQLAPIEndpointOutput).toBeUndefined();
expect(warningMock.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"No output found for attribute 'GraphQLAPIEndpointOutput' on resource 'myApi' in category 'api'",
],
Array [
"This attribute will be undefined in the mock environment until you run \`amplify push\`",
],
]
`);
});

it('includes params from parameters.json', () => {
const expectedMap = {
someOtherParam: 'this is the value',
};
stateManager_mock.getResourceParametersJson.mockReturnValueOnce(expectedMap);
expect(populateCfnParams({}, 'func1')).toMatchObject(expectedMap);
});

it('includes params from team-provider-info.json', () => {
expect(populateCfnParams({}, 'func1')).toMatchObject(teamProviderParam);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { loadConfigurationForEnv } from 'amplify-provider-awscloudformation';
import { ProcessedLambdaFunction } from '../../../CFNParser/stack/types';
import { populateLambdaMockEnvVars } from '../../../utils/lambda/populate-lambda-mock-env-vars';
import { stateManager, pathManager, $TSContext } from 'amplify-cli-core';
import * as path from 'path';
import * as dotenv from 'dotenv';

jest.mock('amplify-provider-awscloudformation');
jest.mock('amplify-cli-core');
jest.mock('dotenv');

const loadConfigurationForEnv_mock = loadConfigurationForEnv as jest.MockedFunction<typeof loadConfigurationForEnv>;
loadConfigurationForEnv_mock.mockResolvedValue({
accessKeyId: 'testaccesskey',
secretAccessKey: 'testsecretaccesskey',
sessionToken: 'testsessiontoken',
region: 'test-region',
});

const stateManager_mock = stateManager as jest.Mocked<typeof stateManager>;
stateManager_mock.getLocalEnvInfo.mockReturnValue({ envName: 'test' });

const pathManager_mock = pathManager as jest.Mocked<typeof pathManager>;
pathManager_mock.getBackendDirPath.mockReturnValue('backend/path');

const dotenv_mock = dotenv as jest.Mocked<typeof dotenv>;

describe('populate labmda mock env vars', () => {
beforeEach(() => jest.clearAllMocks());
it('populates AWS credential variables', async () => {
const processedLambda: ProcessedLambdaFunction = {
cfnExposedAttributes: {},
name: 'testLambda',
handler: 'test.handler',
environment: {},
};

await populateLambdaMockEnvVars({} as $TSContext, processedLambda);
expect(processedLambda.environment).toMatchObject({
AWS_ACCESS_KEY_ID: 'testaccesskey',
AWS_SECRET_ACCESS_KEY: 'testsecretaccesskey',
AWS_SESSION_TOKEN: 'testsessiontoken',
});
});

it('loads dynamic defaults', async () => {
const processedLambda: ProcessedLambdaFunction = {
cfnExposedAttributes: {},
name: 'testLambda',
handler: 'test.handler',
environment: {},
};
stateManager_mock.getTeamProviderInfo.mockReturnValueOnce({
test: {
awscloudformation: {
Region: 'test-region',
},
},
});
const expectedPath = path.join('backend/path', 'function', processedLambda.name);

await populateLambdaMockEnvVars({} as $TSContext, processedLambda);
expect(processedLambda.environment).toMatchObject({
_HANDLER: processedLambda.handler,
AWS_REGION: 'test-region',
AWS_LAMBDA_FUNCTION_NAME: processedLambda.name,
LAMBDA_TASK_ROOT: expectedPath,
LAMBDA_RUNTIME_DIR: expectedPath,
});
});

it('loads dot env values', async () => {
const processedLambda: ProcessedLambdaFunction = {
cfnExposedAttributes: {},
name: 'testLambda',
handler: 'test.handler',
environment: {},
};
const expectedMap = {
CUSTOM_MOCK_ENV_VAR: 'some value',
};
pathManager_mock.getBackendDirPath.mockReturnValueOnce('backend/path');
dotenv_mock.config.mockReturnValueOnce({
parsed: expectedMap,
});

await populateLambdaMockEnvVars({} as $TSContext, processedLambda);
expect(processedLambda.environment).toMatchObject(expectedMap);
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { $TSContext, stateManager } from 'amplify-cli-core';
import aws = require('aws-sdk');
import _ = require('lodash');
import _ from 'lodash';
import { MOCK_API_PORT } from '../../api/api';

/**
Expand All @@ -13,15 +12,15 @@ export const populateCfnParams = (
resourceName: string,
overrideApiToLocal: boolean = false,
): Record<string, string> => {
return [getDefaultParams, getAmplifyMetaParams, getParametersJsonParams, getTeamProviderParams]
return [getCfnPseudoParams, getAmplifyMetaParams, getParametersJsonParams, getTeamProviderParams]
.map(paramProvider => paramProvider(print, resourceName, overrideApiToLocal))
.reduce((acc, it) => ({ ...acc, ...it }), {});
};

const getDefaultParams = (): Record<string, string> => {
const getCfnPseudoParams = (): Record<string, string> => {
const env = stateManager.getLocalEnvInfo().envName;
const teamProvider = stateManager.getTeamProviderInfo();
const region = _.get(teamProvider, [env, 'awscloudformation', 'Region']);
const region = _.get(teamProvider, [env, 'awscloudformation', 'Region'], 'us-test-1');
const stackId = _.get(teamProvider, [env, 'awscloudformation', 'StackId'], 'fake-stack-id');
const stackName = _.get(teamProvider, [env, 'awscloudformation', 'StackName'], 'local-testing');
const accountIdMatcher = /arn:aws:cloudformation:.+:(?<accountId>\d+):stack\/.+/;
Expand Down

0 comments on commit c163cdc

Please sign in to comment.