summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavsad <david.sadlier@est.tech>2021-06-08 07:17:07 +0100
committerMichael Morris <michael.morris@est.tech>2021-10-06 11:31:51 +0000
commita03a1059f8e4b8b46ab662e9a865b3ae6bb77b53 (patch)
tree13f488a090b3ec57c07ee04584aa24b9a47080c7
parent7b60bd7a745d38fd9e51630b6245c2f227abe830 (diff)
Adding type safety to the service dependency editor.
Issue-ID: SDC-3725 Signed-off-by: davsad <david.sadlier@est.tech> Change-Id: I63d77837fb0df24f5ee12baa5b852a76ce5f55e3
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html19
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less6
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts47
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts4
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/ServiceDependencyProperty.java4
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java14
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesPage.java20
-rw-r--r--integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java62
8 files changed, 143 insertions, 33 deletions
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
index 4b23568a06..f84214e4ce 100644
--- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
@@ -24,18 +24,29 @@
<label class="i-sdc-form-label required" >Source</label>
<ui-element-dropdown class="i-sdc-form-select" data-tests-id="sourceType" [values]="sourceTypes" [(value)]="currentRule.sourceName" (change)="onSelectSourceType($event)"></ui-element-dropdown>
</div>
-
- <div class="rule-input-field assigned-value-field">
+ <div [ngClass]="isComplexListMapType() && isStaticSource() ? 'complex-input-field' : ''"
+ class="rule-input-field assigned-value-field">
<label class="i-sdc-form-label required" >{{assignedValueLabel}}</label>
+ <dynamic-property
+ *ngIf="isStaticSource() && isComplexListMapType()"
+ [selectedPropertyId]="selectedPropertyObj.uniqueId"
+ [property]="selectedPropertyObj"
+ [expandedChildId]="selectedPropertyObj.expandedChildPropertyId ?
+ selectedPropertyObj.expandedChildPropertyId : selectedPropertyObj.name"
+ [canBeDeclared]="true"
+ (propertyChanged)="updateComplexListMapTypeRuleValue()"
+ [rootProperty]="selectedPropertyObj"
+ (expandChild)="selectedPropertyObj.updateExpandedChildPropertyId($event)">
+ </dynamic-property>
<dynamic-element
- *ngIf="currentRule.sourceType === SOURCE_TYPES.STATIC.value"
+ *ngIf="isStaticSource() && !isComplexListMapType()"
[(value)]="currentRule.value"
class="rule-assigned-value"
data-tests-id="ruleAssignedValue"
(elementChanged)="onValueChange($event.isValid)"
[type]="selectedPropertyObj ? selectedPropertyObj.type : 'string'">
</dynamic-element>
- <ui-element-dropdown *ngIf="currentRule.sourceType !== SOURCE_TYPES.STATIC.value"
+ <ui-element-dropdown *ngIf="!isStaticSource()"
class="rule-assigned-value"
data-tests-id="ruleAssignedValue"
[(value)]="currentRule.value"
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less
index e03b73c8c0..b475ed2847 100644
--- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.less
@@ -21,6 +21,7 @@
.rule-builder-content {
display: flex;
align-items: flex-end;
+ flex-wrap: wrap;
.rule-input-field {
flex: 1;
&:not(:last-of-type) {
@@ -38,6 +39,9 @@
height: 30px;
}
}
-
+ .complex-input-field {
+ flex-basis: 100%;
+ display: block;
+ }
}
} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
index 084ab32b5c..cb3e87c8d1 100644
--- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
@@ -14,7 +14,7 @@
* permissions and limitations under the License.
*/
import {Component} from '@angular/core';
-import {InputBEModel, PropertyBEModel} from 'app/models';
+import {InputBEModel, PropertyBEModel, PropertyFEModel} from 'app/models';
import {
ConstraintObjectUI,
OPERATOR_TYPES
@@ -23,6 +23,7 @@ import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-e
import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service';
import {PROPERTY_DATA} from 'app/utils';
import {ServiceInstanceObject} from '../../../models/service-instance-properties-and-interfaces';
+import { PropertiesUtils } from '../properties-assignment/services/properties.utils';
export class UIDropDownSourceTypesElement extends DropdownValue {
options: any[];
@@ -61,7 +62,7 @@ export class ServiceDependenciesEditorComponent {
};
currentServiceName: string;
selectedServiceProperties: PropertyBEModel[];
- selectedPropertyObj: PropertyBEModel;
+ selectedPropertyObj: PropertyFEModel;
ddValueSelectedServicePropertiesNames: DropdownValue[];
operatorTypes: DropdownValue[];
sourceTypes: UIDropDownSourceTypesElement[] = [];
@@ -77,6 +78,8 @@ export class ServiceDependenciesEditorComponent {
SERVICE_PROPERTY: {label: 'Service Property', value: 'property'}
};
+ constructor(private propertiesUtils: PropertiesUtils) {}
+
ngOnInit() {
this.currentIndex = this.input.serviceRuleIndex;
this.serviceRulesList = this.input.serviceRules;
@@ -124,10 +127,11 @@ export class ServiceDependenciesEditorComponent {
}
syncRuleData() {
- if (!this.currentRule.sourceName && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) {
+ if (!this.currentRule.sourceName || this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) {
this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value;
+ this.currentRule.sourceType = this.SOURCE_TYPES.STATIC.value;
}
- this.selectedPropertyObj = _.find(this.selectedServiceProperties, (prop) => prop.name === this.currentRule.servicePropertyName);
+ this.updateSelectedPropertyObj();
this.updateOperatorTypesList();
this.updateSourceTypesRelatedValues();
}
@@ -154,7 +158,7 @@ export class ServiceDependenciesEditorComponent {
}
}
- onChangePage(newIndex) {
+ onChangePage(newIndex:any) {
if (newIndex >= 0 && newIndex < this.input.serviceRules.length) {
this.currentIndex = newIndex;
this.currentRule = this.serviceRulesList[newIndex];
@@ -163,18 +167,18 @@ export class ServiceDependenciesEditorComponent {
}
onServicePropertyChanged() {
- this.selectedPropertyObj = _.find(this.selectedServiceProperties, (prop) => prop.name === this.currentRule.servicePropertyName);
+ this.currentRule.value = '';
+ this.updateSelectedPropertyObj();
this.updateOperatorTypesList();
this.filterOptionsByType();
- this.currentRule.value = '';
}
onSelectSourceType() {
+ this.currentRule.value = '';
this.currentRule.sourceType = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value ?
this.SOURCE_TYPES.STATIC.value :
this.SOURCE_TYPES.SERVICE_PROPERTY.value;
this.updateSourceTypesRelatedValues();
- this.currentRule.value = '';
}
filterOptionsByType() {
@@ -190,7 +194,7 @@ export class ServiceDependenciesEditorComponent {
}, []);
}
- onValueChange(isValidValue) {
+ onValueChange(isValidValue:any) {
this.currentRule.updateValidity(isValidValue);
}
@@ -202,4 +206,29 @@ export class ServiceDependenciesEditorComponent {
// for update all rules
return this.serviceRulesList.every((rule) => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value));
}
+
+ updateSelectedPropertyObj(): void {
+ this.selectedPropertyObj = null;
+ if (this.currentRule.servicePropertyName) {
+ let newProp = new PropertyFEModel(_.find(this.selectedServiceProperties, (prop) => prop.name === this.currentRule.servicePropertyName));
+ newProp.value = JSON.stringify(this.currentRule.value);
+ this.propertiesUtils.initValueObjectRef(newProp);
+ console.log("TEST" + newProp.value);
+ setTimeout(() => {this.selectedPropertyObj = newProp})
+ }
+ }
+
+ isStaticSource(): boolean {
+ return this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value
+ }
+
+ isComplexListMapType(): boolean {
+ return this.selectedPropertyObj && this.selectedPropertyObj.derivedDataType > 0;
+ }
+
+ updateComplexListMapTypeRuleValue(): void {
+ let value = PropertyFEModel.cleanValueObj(this.selectedPropertyObj.valueObj);
+ this.currentRule.value = JSON.stringify(value);
+ this.onValueChange(this.selectedPropertyObj.valueObjIsValid);
+ }
}
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts
index 7b128f4468..cfa466ffa3 100644
--- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.module.ts
@@ -4,6 +4,7 @@ import { FormsModule } from '@angular/forms';
import { FormElementsModule } from 'app/ng2/components/ui/form-components/form-elements.module';
import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module';
import { ServiceDependenciesEditorComponent } from './service-dependencies-editor.component';
+import { PropertyTableModule } from 'app/ng2/components/logic/properties-table/property-table.module';
@NgModule({
declarations: [
@@ -13,7 +14,8 @@ import { ServiceDependenciesEditorComponent } from './service-dependencies-edito
CommonModule,
FormsModule,
FormElementsModule,
- UiElementsModule
+ UiElementsModule,
+ PropertyTableModule
],
exports: [],
entryComponents: [
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/ServiceDependencyProperty.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/ServiceDependencyProperty.java
index 6afbdc244a..47b8df26ad 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/ServiceDependencyProperty.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/datatypes/ServiceDependencyProperty.java
@@ -32,12 +32,14 @@ public class ServiceDependencyProperty {
private final String name;
private final String value;
private final String source;
+ private final String type;
private final LogicalOperator logicalOperator;
- public ServiceDependencyProperty(String name, String value, LogicalOperator logicalOperator) {
+ public ServiceDependencyProperty(String name, String type, String value, LogicalOperator logicalOperator) {
this.name = name;
this.value = value;
this.source = "Static";
+ this.type = type;
this.logicalOperator = logicalOperator;
}
}
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
index e944ab329a..8bec8353ef 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
@@ -284,8 +284,10 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
componentPage.isLoaded();
final ResourcePropertiesPage vfcPropertiesPage = componentPage.goToProperties();
vfcPropertiesPage.isLoaded();
- final List<String> propertyNames = vfcPropertiesPage.getPropertyNames();
- final ServiceDependencyProperty serviceDependencyProperty = new ServiceDependencyProperty(propertyNames.get(0), value, operator);
+ final Map<String, String> propertyNamesAndTypes = vfcPropertiesPage.getPropertyNamesAndTypes();
+ final List<String> propertyNames = propertyNamesAndTypes.keySet().stream().collect(Collectors.toList());
+ final ServiceDependencyProperty serviceDependencyProperty =
+ new ServiceDependencyProperty(propertyNames.get(0), propertyNamesAndTypes.get(propertyNames.get(0)), value, operator);
homePage.getTopNavComponent().clickOnHome();
homePage.isLoaded();
@@ -881,7 +883,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
assertThat(String.format("The Component '%s' should have properties", vfResourceCreateData.getName()), propertyNamesAndTypes,
not(anEmptyMap()));
propertyNamesAndTypes.forEach((name, type)
- -> substitutionFilterProperties.add(new ServiceDependencyProperty(name, getPropertyValueByType(type), LogicalOperator.EQUALS)));
+ -> substitutionFilterProperties.add(new ServiceDependencyProperty(name, type, getPropertyValueByType(type), LogicalOperator.EQUALS)));
}
private String getPropertyValueByType(final String type) {
@@ -895,9 +897,9 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
case "boolean":
return "TRUE";
case "list":
- return "[value1, value2]";
+ return "[\"value1\", \"value2\"]";
case "map":
- return "MyKey: MyValue";
+ return "{\"MyKey\": \"MyValue\"}";
default:
throw new UnsupportedOperationException("Not yet implemented for " + type);
}
@@ -925,7 +927,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
substitutionFilterMap.containsKey(substitutionFilterProperty.getName()));
final Map<?, ?> substitutionFilterValue = (Map<?, ?>) ((List<?>) substitutionFilterMap.get(substitutionFilterProperty.getName())).get(0);
assertThat("Substitution Filter Value should not be empty", substitutionFilterMap, not(anEmptyMap()));
- final String expectedSubstitutionPropertyValue = substitutionFilterProperty.getValue();
+ final String expectedSubstitutionPropertyValue = substitutionFilterProperty.getValue().replaceAll("[\"{}]", "");
final String actualSubstitutionPropertyValue = substitutionFilterValue.values().stream().findFirst().get() instanceof Map
? substitutionFilterValue.values().stream().findFirst().get().toString().replace("=", ": ")
.replaceAll("\\{(.*?)\\}", "$1").trim()
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesPage.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesPage.java
index ace3041577..2d45c7c22a 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesPage.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesPage.java
@@ -19,11 +19,13 @@
package org.onap.sdc.frontend.ci.tests.pages;
+import java.util.HashMap;
import java.util.List;
-import java.util.stream.Collectors;
+import java.util.Map;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -52,13 +54,19 @@ public class ResourcePropertiesPage extends AbstractPageObject {
}
/**
- * Returns a list based on property names
- * @return list of names from the properties table
+ * Creates a map based on property names and data types
*/
- public List<String> getPropertyNames() {
+ public Map<String, String> getPropertyNamesAndTypes() {
waitPropertiesToLoad();
- return findElements(By.xpath(XpathSelector.PROPERTY_NAMES.getXpath())).stream()
- .map(ele -> ele.getAttribute("innerText")).collect(Collectors.toList());
+ final Map<String, String> namesAndTypes = new HashMap<>();
+ final List<WebElement> names = findElements(By.xpath(XpathSelector.PROPERTY_NAMES.getXpath()));
+ final List<WebElement> types = findElements(By.xpath(XpathSelector.PROPERTY_TYPES.getXpath()));
+
+ for (int i = 0;i < names.size();i++) {
+ namesAndTypes.put(names.get(i).getAttribute("innerText"), types.get(i).getAttribute("innerText"));
+ }
+
+ return namesAndTypes;
}
@AllArgsConstructor
diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java
index cc3e28448c..969854b214 100644
--- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java
+++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java
@@ -19,7 +19,11 @@
package org.onap.sdc.frontend.ci.tests.pages;
+import static org.junit.jupiter.api.Assertions.fail;
+
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.onap.sdc.frontend.ci.tests.datatypes.ServiceDependencyProperty;
@@ -28,6 +32,8 @@ import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
+import com.fasterxml.jackson.databind.json.JsonMapper;
+
import lombok.AllArgsConstructor;
import lombok.Getter;
@@ -61,16 +67,56 @@ public class ServiceDependenciesEditor extends AbstractPageObject {
logicalOperator.selectByVisibleText(property.getLogicalOperator().getOperator());
final Select sourceType = new Select(webDriver.findElement(By.xpath(XpathSelector.SOURCE_TYPE.xPath)));
sourceType.selectByVisibleText(property.getSource());
- addRuleAssignedValue(webDriver.findElement(
- By.xpath(XpathSelector.RULE_ASSIGNED_VALUE.xPath)), property.getValue());
+ try {
+ addRuleAssignedValue(property);
+ } catch (Exception e) {
+ fail("Failed to add property due to exception while adding rule value :: {}", e);
+ }
webDriver.findElement(By.xpath(XpathSelector.CREATE_BUTTON.xPath)).click();
}
- private void addRuleAssignedValue(final WebElement element, final String value) {
+ private void addRuleAssignedValue(final ServiceDependencyProperty property) throws Exception {
+ final var type = property.getType();
+ final var value = property.getValue();
+ switch (type) {
+ case "list":
+ addListInput(property.getName(), value);
+ break;
+ case "map":
+ addMapInput(property.getName(), value);
+ break;
+ default:
+ addStringInput(waitForElementVisibility(By.xpath(XpathSelector.RULE_ASSIGNED_VALUE.xPath)), value);
+ break;
+ }
+ }
+
+ private void addStringInput(WebElement element, Object value) {
if ("select".equals(element.getTagName())) {
- new Select(element).selectByVisibleText(value);
+ new Select(element).selectByVisibleText(value.toString());
} else {
- element.sendKeys(value);
+ element.sendKeys(value.toString());
+ }
+ }
+
+ private void addListInput(final String name, final String value) throws Exception {
+ final List<?> values = new JsonMapper().readValue(value, List.class);
+ final WebElement addToListElement = waitForElementVisibility(By.xpath(XpathSelector.RULE_ASSIGNED_VALUE_ADD_TO_LIST.formatXpath(name)));
+ for (int i=0;i<values.size();i++) {
+ addToListElement.click();
+ addStringInput(waitForElementVisibility(By.xpath(XpathSelector.RULE_ASSIGNED_LIST_VALUE.formatXpath(name, i))), values.get((i)));
+ }
+ }
+
+ private void addMapInput(final String name, final String value) throws Exception {
+ final Map<?, ?> values = new JsonMapper().readValue(value, Map.class);
+ int i = 0;
+ final WebElement addToListElement = waitForElementVisibility(By.xpath(XpathSelector.RULE_ASSIGNED_VALUE_ADD_TO_LIST.formatXpath(name)));
+ for(Entry<?, ?> entry : values.entrySet()) {
+ addToListElement.click();
+ final List<WebElement> KeyValueInputs = waitForAllElementsVisibility(By.xpath(XpathSelector.RULE_ASSIGNED_MAP_KEY_VALUE.formatXpath(name, i++)));
+ addStringInput(KeyValueInputs.get(0), entry.getKey());
+ addStringInput(KeyValueInputs.get(1), entry.getValue());
}
}
@@ -82,9 +128,15 @@ public class ServiceDependenciesEditor extends AbstractPageObject {
CONSTRAINT_OPERATOR("//*[@data-tests-id='constraintOperator']/select"),
SOURCE_TYPE("//*[@data-tests-id='sourceType']/select"),
RULE_ASSIGNED_VALUE("//*[@data-tests-id='ruleAssignedValue']//*[self::input or self::select]"),
+ RULE_ASSIGNED_VALUE_ADD_TO_LIST("//a[@data-tests-id = 'add-to-list-%s']"),
+ RULE_ASSIGNED_LIST_VALUE("//*[@data-tests-id='value-prop-%s.%d']"),
+ RULE_ASSIGNED_MAP_KEY_VALUE("//*[contains(@data-tests-id, 'value-prop') and contains(@data-tests-id, '%s.%d')]"),
CREATE_BUTTON("//button[text()='Create']");
private final String xPath;
+ public String formatXpath(Object... values) {
+ return String.format(xPath, values);
+ }
}
}