From 8ce51b200148108ac869e1a8ae26286b65c94cc1 Mon Sep 17 00:00:00 2001 From: Marianna Ghirardelli <43092418+maghirardelli@users.noreply.github.com> Date: Mon, 30 Aug 2021 14:50:17 -0400 Subject: [PATCH] Feat: Pre-populate variable values in input section of new workspace configuration (#680) feat: prepopulate variables in new workspace config --- .../src/parts/helpers/fields/DropDown.js | 30 +- .../helpers/fields/__tests__/DropDown.test.js | 285 ++++++++++++++++++ .../parts/environment-types/EnvTypeCard.js | 3 +- .../parts/environment-types/EnvTypeEditor.js | 1 + .../AccessControlStep.js | 10 +- .../BaseEnvTypeConfigStep.js | 2 +- .../env-type-config-steps/BasicInfoStep.js | 6 +- .../env-type-config-steps/InputParamsStep.js | 1 + .../env-type-editor-steps/ConfigStep.js | 2 +- main/end-to-end-tests/README.md | 4 +- main/end-to-end-tests/cypress.github.json | 5 + main/end-to-end-tests/cypress.json | 5 + .../cypress/integration/workspaces.spec.js | 2 +- .../integration/workspacetypes.spec.js | 114 +++++++ 14 files changed, 460 insertions(+), 10 deletions(-) create mode 100644 addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/__tests__/DropDown.test.js create mode 100644 main/end-to-end-tests/cypress/integration/workspacetypes.spec.js diff --git a/addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/DropDown.js b/addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/DropDown.js index 4664ec0b16..193f9e96dd 100644 --- a/addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/DropDown.js +++ b/addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/DropDown.js @@ -1,3 +1,4 @@ +/* eslint-disable no-template-curly-in-string */ /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * @@ -63,6 +64,33 @@ class DropDown extends React.Component { this.optionsInState = _.concat({ text: data.value, value: data.value }, this.optionsInState); }; + /** + * Uses the dropdown options to extract the placeholder variable values for the parameters when configuring + * a new workspace configuration. + * @param currentValue: holds the current value of the dropdown + * @param field: the current field to find a default variable for + * @returns either the same currentValue or the variable value default to be displayed + */ + getDefaultValue(currentValue, field) { + // Make a dict of the field values to the proper variables + const fieldToVariableMap = { + EncryptionKeyArn: '${encryptionKeyArn}', + VPC: '${vpcId}', + AccessFromCIDRBlock: '${cidr}', + S3Mounts: '${s3Mounts}', + Namespace: '${namespace}', + KeyName: '${adminKeyPairName}', + IamPolicyDocument: '${iamPolicyDocument}', + EnvironmentInstanceFiles: '${environmentInstanceFiles}', + Subnet: '${subnetId}', + }; + // if current value is empty and the field is a key in the above dict + if (currentValue === '' && field.key in fieldToVariableMap) { + return fieldToVariableMap[field.key]; + } + return currentValue; + } + render() { const { field, @@ -119,7 +147,7 @@ class DropDown extends React.Component { const attrs = { id, - value, + value: this.getDefaultValue(value, field), // applicable only when allowAdditions = true onAddItem: this.onAddItem, diff --git a/addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/__tests__/DropDown.test.js b/addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/__tests__/DropDown.test.js new file mode 100644 index 0000000000..a64c8ebad6 --- /dev/null +++ b/addons/addon-base-ui/packages/base-ui/src/parts/helpers/fields/__tests__/DropDown.test.js @@ -0,0 +1,285 @@ +/* eslint-disable no-template-curly-in-string */ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import React from 'react'; +import { shallow } from 'enzyme'; +import DropDown from '../DropDown'; + +const options = [ + { key: 'awsRegion', value: '${awsRegion}', text: '${awsRegion}' }, + { key: 'namespace', value: '${namespace}', text: '${namespace}' }, + { key: 'envId', value: '${envId}', text: '${envId}' }, + { key: 'envTypeId', value: '${envTypeId}', text: '${envTypeId}' }, + { key: 'envTypeConfigId', value: '${envTypeConfigId}', text: '${envTypeConfigId}' }, + { key: 'name', value: '${name}', text: '${name}' }, + { key: 'description', value: '${description}', text: '${description}' }, + { key: 'adminKeyPairName', value: '${adminKeyPairName}', text: '${adminKeyPairName}' }, + { key: 'accountId', value: '${accountId}', text: '${accountId}' }, + { key: 'projectId', value: '${projectId}', text: '${projectId}' }, + { key: 'indexId', value: '${indexId}', text: '${indexId}' }, + { key: 'cidr', value: '${cidr}', text: '${cidr}' }, + { key: 'vpcId', value: '${vpcId}', text: '${vpcId}' }, + { key: 'subnetId', value: '${subnetId}', text: '${subnetId}' }, + { key: 'encryptionKeyArn', value: '${encryptionKeyArn}', text: '${encryptionKeyArn}' }, + { key: 'xAccEnvMgmtRoleArn', value: '${xAccEnvMgmtRoleArn}', text: '${xAccEnvMgmtRoleArn}' }, + { key: 'externalId', value: '${externalId}', text: '${externalId}' }, + { key: 'studyIds', value: '${studyIds}', text: '${studyIds}' }, + { key: 's3Mounts', value: '${s3Mounts}', text: '${s3Mounts}' }, + { key: 'iamPolicyDocument', value: '${iamPolicyDocument}', text: '${iamPolicyDocument}' }, + { key: 'environmentInstanceFiles', value: '${environmentInstanceFiles}', text: '${environmentInstanceFiles}' }, + { key: 'uid', value: '${uid}', text: '${uid}' }, + { key: 'username', value: '${username}', text: '${username}' }, + { key: 'userNamespace', value: '${userNamespace}', text: '${userNamespace}' }, +]; + +describe('DropDown', () => { + let wrapper = null; + let component = null; + + describe('getDefaultValue', () => { + it('should get Encyption Key ARN', () => { + // BUILD + const field = { key: 'EncryptionKeyArn', value: 'encryptionkeyarn' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${encryptionKeyArn}'); + }); + + it('should get IAM Policy Document', () => { + // BUILD + const field = { key: 'IamPolicyDocument', value: 'iampolicydocument' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${iamPolicyDocument}'); + }); + + it('should get Access From CIDR Block', () => { + // BUILD + const field = { key: 'AccessFromCIDRBlock', value: 'accessfromcidrblock' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${cidr}'); + }); + + it('should get VPC', () => { + // BUILD + const field = { key: 'VPC', value: 'vpc' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${vpcId}'); + }); + + it('should get Environment Instance Files', () => { + // BUILD + const field = { key: 'EnvironmentInstanceFiles', value: 'environmentinstancefiles' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${environmentInstanceFiles}'); + }); + + it('should get Subnet', () => { + // BUILD + const field = { key: 'Subnet', value: 'subnet' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${subnetId}'); + }); + + it('should get S3 Mounts', () => { + // BUILD + const field = { key: 'S3Mounts', value: 's3mounts' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${s3Mounts}'); + }); + + it('should get Namespace', () => { + // BUILD + const field = { key: 'Namespace', value: 'namespace' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${namespace}'); + }); + + it('should get KeyName', () => { + // BUILD + const field = { key: 'KeyName', value: 'keyname' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + + // OPERATE + const defaultValue = component.getDefaultValue('', field); + + // CHECK + expect(defaultValue).toBe('${adminKeyPairName}'); + }); + + it('should not change a custom Namespace', () => { + // BUILD + const field = { key: 'Namespace', value: 'namespace' }; + wrapper = shallow( + , + ); + component = wrapper.instance(); + const myNamespace = 'myNamespace'; + + // OPERATE + const defaultValue = component.getDefaultValue(myNamespace, field); + + // CHECK + expect(defaultValue).not.toBe('${namespace}'); + expect(defaultValue).toBe(myNamespace); + }); + + it('should not prepopulate when the field has no key attribute', () => { + // the method would try to do things to undefined variables if there is no key attribute + // in the field + // BUILD + const field = { name: 'someField', value: 'someFieldValue' }; + wrapper = shallow(); + component = wrapper.instance(); + const someValue = 'someValue'; + + // OPERATE + const defaultValue = component.getDefaultValue(someValue, field); + + // CHECK + expect(defaultValue).toBe(someValue); + }); + + it('should not prepopulate when the field has no key attribute even though value passed is empty', () => { + // the method would try to do things to undefined variables if there is no key attribute + // in the field + // BUILD + const field = { name: 'someField', value: 'someFieldValue' }; + wrapper = shallow(); + component = wrapper.instance(); + const someValue = ''; + + // OPERATE + const defaultValue = component.getDefaultValue(someValue, field); + + // CHECK + expect(defaultValue).toBe(someValue); + }); + + it('should not prepopulate when the options has no key attribute', () => { + // the method would try to do things to undefined variables if there is no key attribute + // in the options list's elements + // BUILD + const field = { key: 'someKey', value: 'someFieldValue' }; + const noKeyOption = [{ name: 'someField' }]; + wrapper = shallow( + , + ); + component = wrapper.instance(); + const someValue = 'someValue'; + + // OPERATE + const defaultValue = component.getDefaultValue(someValue, field); + + // CHECK + expect(defaultValue).toBe(someValue); + }); + + it('should not prepopulate when the options is empty', () => { + // BUILD + const field = { key: 'someKey', value: 'someFieldValue' }; + // const noKeyOption = [{ name: 'someField' }]; + wrapper = shallow(); + component = wrapper.instance(); + const someValue = 'someValue'; + + // OPERATE + const defaultValue = component.getDefaultValue(someValue, field); + + // CHECK + expect(defaultValue).toBe(someValue); + }); + + it('should not prepopulate when the field has a key that does not match the option (i.e. not the config setup)', () => { + // BUILD + const field = { key: 'someKey', value: 'someFieldValue' }; + wrapper = shallow(); + component = wrapper.instance(); + const someValue = 'someValue'; + + // OPERATE + const defaultValue = component.getDefaultValue(someValue, field); + + // CHECK + expect(defaultValue).toBe(someValue); + }); + }); +}); diff --git a/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/EnvTypeCard.js b/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/EnvTypeCard.js index 181927f439..c9df37f386 100644 --- a/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/EnvTypeCard.js +++ b/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/EnvTypeCard.js @@ -50,6 +50,7 @@ class EnvTypeCard extends Component { const defaultMgmtActions = [ diff --git a/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/env-type-config/env-type-config-steps/BasicInfoStep.js b/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/env-type-config/env-type-config-steps/BasicInfoStep.js index 5fb3dbf734..3076becb9c 100644 --- a/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/env-type-config/env-type-config-steps/BasicInfoStep.js +++ b/addons/addon-environment-sc-ui/packages/environment-type-mgmt-ui/src/parts/environment-types/env-type-config/env-type-config-steps/BasicInfoStep.js @@ -30,9 +30,9 @@ class BasicInfoStep extends BaseEnvTypeConfigStep { return ( <> - {!isUpdating && } - -