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 = [