From 12872a40d178f829cab3666037ebefde5eda02c2 Mon Sep 17 00:00:00 2001 From: John Corser Date: Wed, 21 Jul 2021 14:44:50 -0400 Subject: [PATCH] feat(amplify-category-function): skip unnecessary prompt for 'amplify update function' * feat(amplify-category-function): skip unnecessary prompt for 'amplify update function' * test: remove additional prompt from e2e --- .../utils/determineServiceSelection.ts | 87 +++++++++++++++++++ .../src/commands/function/update.ts | 5 +- .../removeFunctionWalkthrough.ts | 4 + .../utils/determineServiceSelection.ts | 24 +++++ .../src/categories/lambda-function.ts | 6 +- 5 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 packages/amplify-category-function/src/__tests__/provider-utils/awscloudformation/utils/determineServiceSelection.ts create mode 100644 packages/amplify-category-function/src/provider-utils/awscloudformation/utils/determineServiceSelection.ts diff --git a/packages/amplify-category-function/src/__tests__/provider-utils/awscloudformation/utils/determineServiceSelection.ts b/packages/amplify-category-function/src/__tests__/provider-utils/awscloudformation/utils/determineServiceSelection.ts new file mode 100644 index 00000000000..b734100641f --- /dev/null +++ b/packages/amplify-category-function/src/__tests__/provider-utils/awscloudformation/utils/determineServiceSelection.ts @@ -0,0 +1,87 @@ +import { determineServiceSelection } from '../../../../provider-utils/awscloudformation/utils/determineServiceSelection'; +import { ServiceName } from '../../../../provider-utils/awscloudformation/utils/constants'; + +const serviceSelectionPromptMock = jest.fn(); +const mockChooseServiceMessage = 'mockChooseServiceMessage'; +const mockContext = { + amplify: { + getResourceStatus: async () => { + return { allResources: [] }; + }, + serviceSelectionPrompt: serviceSelectionPromptMock, + }, +}; + +describe('determineServiceSelection', () => { + it('returns LambdaFunction when no resources exists', async () => { + const response = await determineServiceSelection(mockContext, mockChooseServiceMessage); + expect(response.service === ServiceName.LambdaFunction); + expect(serviceSelectionPromptMock).toBeCalledTimes(0); + }); + + it('returns LambdaFunction when only LambdaFunction resources exists', async () => { + mockContext.amplify.getResourceStatus = async () => { + return { + allResources: [ + { + service: ServiceName.LambdaFunction, + }, + ], + }; + }; + const response = await determineServiceSelection(mockContext, mockChooseServiceMessage); + expect(response.service === ServiceName.LambdaFunction); + expect(serviceSelectionPromptMock).toBeCalledTimes(0); + }); + + it('returns LambdaLayer when only LambdaLayer resources exists', async () => { + mockContext.amplify.getResourceStatus = async () => { + return { + allResources: [ + { + service: ServiceName.LambdaLayer, + }, + ], + }; + }; + const response = await determineServiceSelection(mockContext, mockChooseServiceMessage); + expect(response.service === ServiceName.LambdaLayer); + expect(serviceSelectionPromptMock).toBeCalledTimes(0); + }); + + it('returns LambdaLayer when existing LambdaFunction resources have mobileHubMigrated', async () => { + mockContext.amplify.getResourceStatus = async () => { + return { + allResources: [ + { + service: ServiceName.LambdaLayer, + }, + { + service: ServiceName.LambdaFunction, + mobileHubMigrated: true, + }, + ], + }; + }; + const response = await determineServiceSelection(mockContext, mockChooseServiceMessage); + expect(response.service === ServiceName.LambdaLayer); + expect(serviceSelectionPromptMock).toBeCalledTimes(0); + }); + + it('prompts for user input when both LambdaFunction and LambdaLayer resources exist', async () => { + mockContext.amplify.getResourceStatus = async () => { + return { + allResources: [ + { + service: ServiceName.LambdaFunction, + }, + { + service: ServiceName.LambdaLayer, + }, + ], + }; + }; + await determineServiceSelection(mockContext, mockChooseServiceMessage); + expect(serviceSelectionPromptMock).toBeCalledTimes(1); + }); +}); diff --git a/packages/amplify-category-function/src/commands/function/update.ts b/packages/amplify-category-function/src/commands/function/update.ts index c13ec660058..bef2a00a9db 100644 --- a/packages/amplify-category-function/src/commands/function/update.ts +++ b/packages/amplify-category-function/src/commands/function/update.ts @@ -1,6 +1,7 @@ import { supportedServices } from '../../provider-utils/supported-services'; import { chooseServiceMessageUpdate } from '../../provider-utils/awscloudformation/utils/constants'; import { categoryName } from '../../constants'; +import { determineServiceSelection } from '../../provider-utils/awscloudformation/utils/determineServiceSelection'; const subcommand = 'update'; @@ -8,10 +9,8 @@ module.exports = { name: subcommand, alias: ['configure'], run: async context => { - const { amplify } = context; const servicesMetadata = supportedServices; - return amplify - .serviceSelectionPrompt(context, categoryName, servicesMetadata, chooseServiceMessageUpdate) + return determineServiceSelection(context, chooseServiceMessageUpdate) .then(result => { const providerController = servicesMetadata[result.service].providerController; if (!providerController) { diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeFunctionWalkthrough.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeFunctionWalkthrough.ts index 6879dd5b8a5..930744ce58c 100644 --- a/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeFunctionWalkthrough.ts +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/service-walkthroughs/removeFunctionWalkthrough.ts @@ -7,6 +7,10 @@ import { ServiceName } from '../utils/constants'; export async function removeResource(resourceName?: string): Promise<$TSAny> { const enabledCategoryResources = getEnabledResources(); + if (enabledCategoryResources.length === 0) { + throw new Error('No Lambda function resource to remove. Use "amplify add function" to create a new function.'); + } + if (resourceName) { const resource = enabledCategoryResources.find(categoryResource => categoryResource.value.resourceName === resourceName); return resource.value; diff --git a/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/determineServiceSelection.ts b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/determineServiceSelection.ts new file mode 100644 index 00000000000..cbcd0be9c54 --- /dev/null +++ b/packages/amplify-category-function/src/provider-utils/awscloudformation/utils/determineServiceSelection.ts @@ -0,0 +1,24 @@ +import { ServiceName } from './constants'; +import { categoryName } from '../../../constants'; +import { supportedServices } from '../../supported-services'; + +export const determineServiceSelection = async (context, chooseServiceMessage) => { + const { allResources } = await context.amplify.getResourceStatus(); + const lambdaLayerExists = allResources.filter(resource => resource.service === ServiceName.LambdaLayer).length > 0; + const lambdaFunctionExists = + allResources.filter(resource => resource.service === ServiceName.LambdaFunction && resource.mobileHubMigrated !== true).length > 0; + + if ((!lambdaFunctionExists && !lambdaLayerExists) || (lambdaFunctionExists && !lambdaLayerExists)) { + return { + service: ServiceName.LambdaFunction, + }; + } + + if (!lambdaFunctionExists && lambdaLayerExists) { + return { + service: ServiceName.LambdaLayer, + }; + } + + return await context.amplify.serviceSelectionPrompt(context, categoryName, supportedServices, chooseServiceMessage); +}; diff --git a/packages/amplify-e2e-core/src/categories/lambda-function.ts b/packages/amplify-e2e-core/src/categories/lambda-function.ts index 28898221275..ef73f2f1548 100644 --- a/packages/amplify-e2e-core/src/categories/lambda-function.ts +++ b/packages/amplify-e2e-core/src/categories/lambda-function.ts @@ -175,11 +175,7 @@ const coreFunction = ( selectTemplate(chain, settings.functionTemplate, runtime); } } else { - chain - .wait('Select which capability you want to update:') - .sendCarriageReturn() // lambda function - .wait('Select the Lambda function you want to update') - .sendCarriageReturn(); // assumes only one function configured in the project + chain.wait('Select the Lambda function you want to update').sendCarriageReturn(); // assumes only one function configured in the project } if (functionConfigCallback) {