List of Input Parameters for VSP: FE 77/82577/3
authorVodafone <onap@vodafone.com>
Mon, 18 Mar 2019 10:16:53 +0000 (15:46 +0530)
committerOren Kleks <orenkle@amdocs.com>
Mon, 25 Mar 2019 06:35:11 +0000 (06:35 +0000)
Change-Id: I17697b5646c1a201678dbab11fef28a7483fbf8c
Issue-ID: SDC-2049
Co-authored-by: rahul.ghugikar@vodafone.com, soumyarup.paul@vodafone.com
Signed-off-by: Vodafone <onap@vodafone.com>
36 files changed:
openecomp-ui/package.json
openecomp-ui/resources/scss/_modules.scss
openecomp-ui/resources/scss/modules/_softwareProductValidationPage.scss [new file with mode: 0644]
openecomp-ui/resources/scss/modules/_softwareProductValidationResultsPage.scss [new file with mode: 0644]
openecomp-ui/src/nfvo-components/input/validation/Input.jsx
openecomp-ui/src/nfvo-utils/i18n/en.json
openecomp-ui/src/nfvo-utils/unCamelCaseString.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/common/helpers/ConfigHelper.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/common/helpers/ScreensHelper.js
openecomp-ui/src/sdc-app/config/config.json
openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
openecomp-ui/src/sdc-app/onboarding/OnboardingConstants.js
openecomp-ui/src/sdc-app/onboarding/OnboardingPunchOut.jsx
openecomp-ui/src/sdc-app/onboarding/OnboardingView.jsx
openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProduct.js
openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationConstants.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationReducer.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputs.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputsView.jsx [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetup.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetupView.jsx [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js [new file with mode: 0644]
openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsView.jsx [new file with mode: 0644]
openecomp-ui/src/sdc-app/punch-outs.js
openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductFactory.js
openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js [new file with mode: 0644]
openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js [new file with mode: 0644]
openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationActionHelper.test.js [new file with mode: 0644]
openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationInputView.test.js [new file with mode: 0644]
openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationView.test.js [new file with mode: 0644]
openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsView.test.js [new file with mode: 0644]
openecomp-ui/webpack.config.js

index 57a3d2b..4ce2c77 100644 (file)
@@ -47,7 +47,8 @@
         "redux": "^3.7.2",
         "sdc-ui": "1.6.62",
         "uuid-js": "^0.7.5",
-        "validator": "^4.3.0"
+        "validator": "^4.3.0",
+        "react-checkbox-tree": "1.4.1"
     },
     "devDependencies": {
         "babel-core": "^6.24.0",
index ad33275..6668f4c 100644 (file)
@@ -27,3 +27,5 @@
 @import 'modules/softwareProductDeployment';
 @import 'modules/versionsPage';
 @import 'modules/mergeEditor';
+@import "modules/_softwareProductValidationPage";
+@import "modules/_softwareProductValidationResultsPage";
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductValidationPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductValidationPage.scss
new file mode 100644 (file)
index 0000000..3f94405
--- /dev/null
@@ -0,0 +1,80 @@
+
+.vsp-validation-view {
+  position: relative;
+  .validation-tabs {
+    .sdc-tabs-list {
+      padding-left: 28px;
+      background-color: $tlv-gray;
+      box-shadow: none;
+      border-bottom: 1px solid $light-gray;
+      .sdc-tab {
+          @extend .heading-2;
+        padding-top: 10px;
+        margin-top: 0;
+        &.sdc-tab-active {
+          color: $blue;
+          font-weight: bold;
+        }
+      }
+    }
+    .sdc-tab-content {
+      margin-top: 0;
+    }
+  }
+
+  .validation-view-title {
+    padding-bottom: 5px;
+    font-size: 16px;
+  }
+
+  .validation-view-tab {
+    padding: 30px 60px 70px 60px;
+  }
+
+  .validation-setup-checkbox-tree-section {
+    //height: 260px;
+    clear: both;
+  }
+
+  .validation-setup-selected-tests {
+    height: 160px;
+    width: 100%;
+    border: solid;
+  }
+
+  .validation-setup-available-tests-section {
+    height: 160px;
+    width: 100%;
+    overflow: auto;
+    clear: both;
+    border: solid;
+  }
+
+  .validation-setup-available-tests-section::-webkit-scrollbar {
+    height: 8px;
+    width: 14px;
+  }
+
+  .div-clear-both {
+    clear: both;
+  }
+
+  .validation-view-controllers {
+    position: absolute;
+    right: 40px;
+    top: 10px;
+    display: flex;
+
+    .proceed-to-validation-results-btn {
+      margin-right: 30px;
+    }
+    .change-tabs-btn {
+      width: 191px;
+      margin-right: 36px;
+      height: 36px;
+    }
+  }
+  .validation-setup-checkbox-tree-section label {
+    margin-bottom: 0px;
+  }
+}
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductValidationResultsPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductValidationResultsPage.scss
new file mode 100644 (file)
index 0000000..9ff3696
--- /dev/null
@@ -0,0 +1,4 @@
+
+.validation-results-test-result-label {
+  padding-left: 10px
+}
index f3279b0..b27ba1d 100644 (file)
@@ -89,6 +89,7 @@ class Input extends React.Component {
                             inputRef={input => (this.input = input)}
                             type={type}
                             data-test-id={this.props['data-test-id']}
+                            placeholder={this.props.placeholder || ''}
                         />
                     )}
                     {type === 'number' && (
index 4634c37..1ad23b7 100644 (file)
   "VNF Header Vendor" : "Vendor",
   "VNF Header Desc" : "Description",
   "VNF Header Action" : "Action",
-  
-  "GENERIC_ERROR": "An error has occurred. Please contact your System Administrator for further assistance."
+
+  "GENERIC_ERROR": "An error has occurred. Please contact your System Administrator for further assistance.",
+
+  "VSP ID" : "VSP ID",
+  "VSP Version" : "VSP Version",
+  "BACK" : "BACK",
+  "NEXT" : "NEXT",
+  "Validation Results" : "Validation Results",
+  "Validation" : "Validation",
+  "Setup": "Setup",
+  "Inputs": "Inputs",
+  "Certifications Query": "Certifications Query",
+  "No Certifications Query are Available": "No Certifications Query are Available",
+  "Selected Certifications Query": "Selected Certifications Query",
+  "Compliance Checks": "Compliance Checks",
+  "No Compliance Checks are Available": "No Compliance Checks are Available",
+  "Selected Compliance Tests": "Selected Compliance Tests",
+  "Value Should Be Minimum of {minLength} characters and a Maximum of {maxLength} characters": "Value Should Be Minimum of {minLength} characters and a Maximum of {maxLength} characters",
+  "{title} Inputs :": "{title} Inputs :",
+  "Scenario: {scenario} | Status: {status}": "Scenario: {scenario} | Status: {status}",
+  "{title} results are not available": "{title} results are not available",
+  "Test Results": "Test Results",
+  "No Validation Checks Performed": "No Validation Checks Performed"
 }
diff --git a/openecomp-ui/src/nfvo-utils/unCamelCaseString.js b/openecomp-ui/src/nfvo-utils/unCamelCaseString.js
new file mode 100644 (file)
index 0000000..656f65f
--- /dev/null
@@ -0,0 +1,29 @@
+/*!
+ * Copyright (C) 2019 Vodafone Group.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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.
+ */
+function unCamelCaseString(message) {
+    return message
+        .replace(/([a-z])([A-Z])/g, '$1 $2')
+        .replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
+        .replace(/^./, function(str) {
+            return str.toUpperCase();
+        });
+}
+
+let unCamelCasedString = str => {
+    return unCamelCaseString(str);
+};
+
+export default unCamelCasedString;
diff --git a/openecomp-ui/src/sdc-app/common/helpers/ConfigHelper.js b/openecomp-ui/src/sdc-app/common/helpers/ConfigHelper.js
new file mode 100644 (file)
index 0000000..3e09ffe
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+
+const restPrefix = Configuration.get('defaultRestOnboardingPrefix');
+
+const ConfigHelper = {
+    fetchVspConfig() {
+        return RestAPIUtil.get(`${restPrefix}/v1.0/externaltesting/config`);
+    }
+};
+
+export default ConfigHelper;
index fbf0239..58f4795 100644 (file)
@@ -197,6 +197,18 @@ const ScreensHelper = {
                             vspProps
                         );
                         break;
+                    case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION:
+                        OnboardingActionHelper.navigateToSoftwareProductValidation(
+                            dispatch,
+                            vspProps
+                        );
+                        break;
+                    case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS:
+                        OnboardingActionHelper.navigateToSoftwareProductValidationResults(
+                            dispatch,
+                            vspProps
+                        );
+                        break;
                     case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
                         OnboardingActionHelper.navigateToSoftwareProductDependencies(
                             dispatch,
index 2e94d86..784f19a 100644 (file)
@@ -5,6 +5,7 @@
     "appContextPath": "/onboarding",
     "defaultRestPrefix": "/onboarding-api",
     "defaultRestCatalogPrefix": "/sdc1/feProxy/rest",
+    "defaultRestOnboardingPrefix": "/sdc1/feProxy/onboarding-api",
     "defaultWebsocketProtocol": "wss",
     "defaultWebsocketPort": "8181",
     "defaultDebugWebsocketPort": "9000",
index c3cf8b2..8385da7 100644 (file)
@@ -48,6 +48,8 @@ import { actionTypes as filterActionTypes } from './onboard/filter/FilterConstan
 import FeaturesActionHelper from 'sdc-app/features/FeaturesActionHelper.js';
 import { notificationActions } from 'nfvo-components/notification/NotificationsConstants.js';
 import i18n from 'nfvo-utils/i18n/i18n.js';
+import SoftwareProductValidationActionHelper from './softwareProduct/validation/SoftwareProductValidationActionHelper.js';
+import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
 
 function setCurrentScreen(dispatch, screen, props = {}) {
     dispatch({
@@ -88,6 +90,13 @@ const OnboardingActionHelper = {
         });
     },
 
+    saveIsValidationDisabled(dispatch, { isValidationDisabled }) {
+        SoftwareProductValidationActionHelper.setIsVspValidationDisabled(
+            dispatch,
+            { isValidationDisabled }
+        );
+    },
+
     autoSaveBeforeNavigate(
         dispatch,
         { softwareProductId, version, vspComponentId, dataToSave }
@@ -381,6 +390,53 @@ const OnboardingActionHelper = {
         });
     },
 
+    navigateToSoftwareProductValidation(
+        dispatch,
+        { softwareProductId, version, status }
+    ) {
+        SoftwareProductValidationActionHelper.fetchVspChecks(dispatch)
+            .then(() => {
+                SoftwareProductValidationActionHelper.setCertificationChecked(
+                    dispatch,
+                    []
+                );
+                SoftwareProductValidationActionHelper.setComplianceChecked(
+                    dispatch,
+                    []
+                );
+                setCurrentScreen(
+                    dispatch,
+                    enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION,
+                    {
+                        softwareProductId,
+                        version,
+                        status
+                    }
+                );
+            })
+            .catch(error => {
+                dispatch({
+                    type: modalActionTypes.GLOBAL_MODAL_ERROR,
+                    data: {
+                        title: 'ERROR',
+                        msg: error.responseJSON.message,
+                        cancelButtonText: i18n('OK')
+                    }
+                });
+            });
+    },
+
+    navigateToSoftwareProductValidationResults(
+        dispatch,
+        { softwareProductId, version, status }
+    ) {
+        setCurrentScreen(
+            dispatch,
+            enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
+            { softwareProductId, version, status }
+        );
+    },
+
     navigateToSoftwareProductDependencies(
         dispatch,
         { softwareProductId, version, status }
index 97e82ef..cf8ff12 100644 (file)
@@ -53,6 +53,8 @@ const breadcrumbsEnum = {
     SOFTWARE_PRODUCT_PROCESSES: 'SOFTWARE_PRODUCT_PROCESSES',
     SOFTWARE_PRODUCT_DEPLOYMENT: 'SOFTWARE_PRODUCT_DEPLOYMENT',
     SOFTWARE_PRODUCT_NETWORKS: 'SOFTWARE_PRODUCT_NETWORKS',
+    SOFTWARE_PRODUCT_VALIDATION: 'SOFTWARE_PRODUCT_VALIDATION',
+    SOFTWARE_PRODUCT_VALIDATION_RESULTS: 'SOFTWARE_PRODUCT_VALIDATION_RESULTS',
     SOFTWARE_PRODUCT_DEPENDENCIES: 'SOFTWARE_PRODUCT_DEPENDENCIES',
     SOFTWARE_PRODUCT_ACTIVITY_LOG: 'SOFTWARE_PRODUCT_ACTIVITY_LOG',
     SOFTWARE_PRODUCT_COMPONENTS: 'SOFTWARE_PRODUCT_COMPONENTS',
@@ -97,6 +99,10 @@ export const enums = keyMirror({
         SOFTWARE_PRODUCT_DEPLOYMENT:
             breadcrumbsEnum.SOFTWARE_PRODUCT_DEPLOYMENT,
         SOFTWARE_PRODUCT_NETWORKS: breadcrumbsEnum.SOFTWARE_PRODUCT_NETWORKS,
+        SOFTWARE_PRODUCT_VALIDATION:
+            breadcrumbsEnum.SOFTWARE_PRODUCT_VALIDATION,
+        SOFTWARE_PRODUCT_VALIDATION_RESULTS:
+            breadcrumbsEnum.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
         SOFTWARE_PRODUCT_DEPENDENCIES:
             breadcrumbsEnum.SOFTWARE_PRODUCT_DEPENDENCIES,
         SOFTWARE_PRODUCT_ACTIVITY_LOG:
index a735014..d50fccc 100644 (file)
@@ -26,7 +26,7 @@ import Application from 'sdc-app/Application.jsx';
 import store from 'sdc-app/AppStore.js';
 import Configuration from 'sdc-app/config/Configuration.js';
 import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js';
-
+import ConfigHelper from 'sdc-app/common/helpers/ConfigHelper.js';
 import {
     onboardingMethod as onboardingMethodTypes,
     onboardingOriginTypes
@@ -38,9 +38,32 @@ import { AppContainer } from 'react-hot-loader';
 import HeatSetupActionHelper from './softwareProduct/attachments/setup/HeatSetupActionHelper.js';
 
 import { actionTypes, enums, screenTypes } from './OnboardingConstants.js';
+import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
 import OnboardingActionHelper from './OnboardingActionHelper.js';
 import Onboarding from './Onboarding.js';
 
+ConfigHelper.fetchVspConfig()
+    .then(response => {
+        let dispatch = action => store.dispatch(action);
+        OnboardingActionHelper.saveIsValidationDisabled(dispatch, {
+            isValidationDisabled:
+                response.enabled === undefined || response.enabled === ''
+                    ? true
+                    : !response.enabled
+        });
+    })
+    .catch(error => {
+        let dispatch = action => store.dispatch(action);
+        dispatch({
+            type: modalActionTypes.GLOBAL_MODAL_ERROR,
+            data: {
+                title: i18n('ERROR'),
+                msg: error.message || error.responseJSON.message,
+                cancelButtonText: i18n('OK')
+            }
+        });
+    });
+
 export default class OnboardingPunchOut {
     render({ options: { data, apiRoot, apiHeaders }, onEvent }, element) {
         if (!this.unsubscribeFromStore) {
@@ -360,7 +383,8 @@ export default class OnboardingPunchOut {
                 softwareProductEditor: {
                     data: currentSoftwareProduct = { onboardingMethod: '' }
                 },
-                softwareProductComponents: { componentsList }
+                softwareProductComponents: { componentsList },
+                softwareProductValidation: { isValidationDisabled }
             },
             licenseModel: {
                 licenseModelEditor: { data: currentLicenseModel = {} }
@@ -373,7 +397,8 @@ export default class OnboardingPunchOut {
             currentScreen,
             currentSoftwareProduct,
             currentLicenseModel,
-            componentsList
+            componentsList,
+            isValidationDisabled
         };
 
         if (
@@ -402,7 +427,8 @@ export default class OnboardingPunchOut {
         itemId,
         currentSoftwareProduct,
         currentLicenseModel,
-        componentsList
+        componentsList,
+        isValidationDisabled
     }) {
         let {
             onboardingMethod,
@@ -553,6 +579,8 @@ export default class OnboardingPunchOut {
             case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
             case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT:
             case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+            case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION:
+            case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS:
             case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
             case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
             case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
@@ -578,6 +606,10 @@ export default class OnboardingPunchOut {
                         enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPLOYMENT,
                     [enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS]:
                         enums.BREADCRUMS.SOFTWARE_PRODUCT_NETWORKS,
+                    [enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION]:
+                        enums.BREADCRUMS.SOFTWARE_PRODUCT_VALIDATION,
+                    [enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS]:
+                        enums.BREADCRUMS.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
                     [enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES]:
                         enums.BREADCRUMS.SOFTWARE_PRODUCT_DEPENDENCIES,
                     [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]:
@@ -673,6 +705,18 @@ export default class OnboardingPunchOut {
                                             .SOFTWARE_PRODUCT_NETWORKS,
                                     displayText: i18n('Networks')
                                 },
+                                {
+                                    key:
+                                        enums.BREADCRUMS
+                                            .SOFTWARE_PRODUCT_VALIDATION,
+                                    displayText: i18n('Validation')
+                                },
+                                {
+                                    key:
+                                        enums.BREADCRUMS
+                                            .SOFTWARE_PRODUCT_VALIDATION_RESULTS,
+                                    displayText: i18n('Validation Results')
+                                },
                                 {
                                     key:
                                         enums.BREADCRUMS
@@ -719,6 +763,11 @@ export default class OnboardingPunchOut {
                                     case enums.BREADCRUMS
                                         .SOFTWARE_PRODUCT_DEPENDENCIES:
                                         return componentsList.length > 1;
+                                    case enums.BREADCRUMS
+                                        .SOFTWARE_PRODUCT_VALIDATION:
+                                    case enums.BREADCRUMS
+                                        .SOFTWARE_PRODUCT_VALIDATION_RESULTS:
+                                        return !isValidationDisabled;
                                     default:
                                         return true;
                                 }
index 7156e2e..d435890 100644 (file)
@@ -31,6 +31,8 @@ import SoftwareProductAttachments from './softwareProduct/attachments/SoftwarePr
 import SoftwareProductProcesses from './softwareProduct/processes/SoftwareProductProcesses.js';
 import SoftwareProductDeployment from './softwareProduct/deployment/SoftwareProductDeployment.js';
 import SoftwareProductNetworks from './softwareProduct/networks/SoftwareProductNetworks.js';
+import SoftwareProductValidation from './softwareProduct/validation/SoftwareProductValidation.js';
+import SoftwareProductValidationResults from './softwareProduct/validationResults/SoftwareProductValidationResults.js';
 import SoftwareProductDependencies from './softwareProduct/dependencies/SoftwareProductDependencies.js';
 
 import SoftwareProductComponentsList from './softwareProduct/components/SoftwareProductComponents.js';
@@ -145,6 +147,8 @@ export default class OnboardingView extends React.Component {
                         case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
                         case enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT:
                         case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+                        case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION:
+                        case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS:
                         case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
                         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES:
@@ -204,6 +208,21 @@ export default class OnboardingView extends React.Component {
                                                         {...props}
                                                     />
                                                 );
+                                            case enums.SCREEN
+                                                .SOFTWARE_PRODUCT_VALIDATION:
+                                                return (
+                                                    <SoftwareProductValidation
+                                                        className="no-padding-content-area"
+                                                        {...props}
+                                                    />
+                                                );
+                                            case enums.SCREEN
+                                                .SOFTWARE_PRODUCT_VALIDATION_RESULTS:
+                                                return (
+                                                    <SoftwareProductValidationResults
+                                                        {...props}
+                                                    />
+                                                );
                                             case enums.SCREEN
                                                 .SOFTWARE_PRODUCT_DEPENDENCIES:
                                                 return (
index d3d7b96..1362165 100644 (file)
@@ -140,6 +140,7 @@ const buildNavigationBarProps = ({
         candidateOnboardingOrigin,
         onboardingOrigin
     } = currentSoftwareProduct;
+    let { isValidationDisabled } = softwareProduct.softwareProductValidation;
     const groups = [
         {
             id: id,
@@ -176,6 +177,20 @@ const buildNavigationBarProps = ({
                     disabled: false,
                     meta
                 },
+                {
+                    id: enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION,
+                    name: i18n('Validation'),
+                    disabled: false,
+                    hidden: isValidationDisabled,
+                    meta
+                },
+                {
+                    id: enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
+                    name: i18n('Validation Results'),
+                    disabled: false,
+                    hidden: isValidationDisabled,
+                    meta
+                },
                 {
                     id: enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS,
                     name: i18n('Attachments'),
@@ -586,6 +601,8 @@ const mapActionsToProps = (
         case enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS:
         case enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES:
         case enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS:
+        case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION:
+        case enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS:
         case enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES:
         case enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG:
         case enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS:
index fd4f02c..7b8c426 100644 (file)
@@ -25,6 +25,7 @@ import { actionTypes as heatSetupActionTypes } from './attachments/setup/HeatSet
 import SoftwareProductCreationReducer from './creation/SoftwareProductCreationReducer.js';
 import SoftwareProductDetailsReducer from './details/SoftwareProductDetailsReducer.js';
 import SoftwareProductProcessesListReducer from './processes/SoftwareProductProcessesListReducer.js';
+import SoftwareProductValidationReducer from './validation/SoftwareProductValidationReducer.js';
 import SoftwareProductProcessesEditorReducer from './processes/SoftwareProductProcessesEditorReducer.js';
 import SoftwareProductDeploymentListReducer from './deployment/SoftwareProductDeploymentListReducer.js';
 import SoftwareProductDeploymentEditorReducer from './deployment/editor/SoftwareProductDeploymentEditorReducer.js';
@@ -74,6 +75,9 @@ export default combineReducers({
     softwareProductEditor: createPlainDataReducer(
         SoftwareProductDetailsReducer
     ),
+    softwareProductValidation: createPlainDataReducer(
+        SoftwareProductValidationReducer
+    ),
     softwareProductProcesses: combineReducers({
         processesList: SoftwareProductProcessesListReducer,
         processesEditor: createPlainDataReducer(
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js
new file mode 100644 (file)
index 0000000..a6237e8
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { connect } from 'react-redux';
+import SoftwareProductValidationView from './SoftwareProductValidationView.jsx';
+import SoftwareProductValidationActionHelper from './SoftwareProductValidationActionHelper.js';
+
+export const mapStateToProps = ({ softwareProduct }) => {
+    let { softwareProductValidation } = softwareProduct;
+    return {
+        softwareProductValidation
+    };
+};
+
+export const mapActionsToProps = dispatch => {
+    return {
+        onErrorThrown: msg => {
+            SoftwareProductValidationActionHelper.onErrorThrown(dispatch, msg);
+        },
+
+        onTestSubmit: (softwareProductId, version, status, tests) => {
+            SoftwareProductValidationActionHelper.navigateToSoftwareProductValidationResults(
+                dispatch,
+                {
+                    softwareProductId,
+                    version,
+                    status,
+                    tests
+                }
+            );
+        },
+
+        setVspTestsMap: map => {
+            SoftwareProductValidationActionHelper.setVspTestsMap(dispatch, map);
+        },
+
+        setActiveTab: activeTab => {
+            SoftwareProductValidationActionHelper.setActiveTab(
+                dispatch,
+                activeTab
+            );
+        },
+
+        setComplianceChecked: ({ checked }) => {
+            SoftwareProductValidationActionHelper.setComplianceChecked(
+                dispatch,
+                checked
+            );
+        },
+
+        setCertificationChecked: ({ checked }) => {
+            SoftwareProductValidationActionHelper.setCertificationChecked(
+                dispatch,
+                checked
+            );
+        },
+
+        setTestsRequest: (request, info) => {
+            SoftwareProductValidationActionHelper.setTestsRequest(
+                dispatch,
+                request,
+                info
+            );
+        },
+
+        setGeneralInfo: info => {
+            SoftwareProductValidationActionHelper.setGeneralInfo(
+                dispatch,
+                info
+            );
+        }
+    };
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {
+    withRef: true
+})(SoftwareProductValidationView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js
new file mode 100644 (file)
index 0000000..d19416a
--- /dev/null
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 RestAPIUtil from 'nfvo-utils/RestAPIUtil.js';
+import Configuration from 'sdc-app/config/Configuration.js';
+import getValue from 'nfvo-utils/getValue.js';
+import { actionTypes } from './SoftwareProductValidationConstants.js';
+import ScreensHelper from 'sdc-app/common/helpers/ScreensHelper.js';
+import { enums, screenTypes } from 'sdc-app/onboarding/OnboardingConstants.js';
+import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+
+function postVSPCertificationChecks(tests) {
+    const restPrefix = Configuration.get('restPrefix');
+    return RestAPIUtil.post(
+        `${restPrefix}/v1.0/externaltesting/executions`,
+        getValue(tests)
+    );
+}
+
+function fetchVspChecks() {
+    const restPrefix = Configuration.get('restPrefix');
+    return RestAPIUtil.get(`${restPrefix}/v1.0/externaltesting/testcasetree`);
+}
+
+const SoftwareProductValidationActionHelper = {
+    navigateToSoftwareProductValidationResults(
+        dispatch,
+        { softwareProductId, version, status, tests }
+    ) {
+        postVSPCertificationChecks(tests)
+            .then(response => {
+                dispatch({
+                    type: actionTypes.POST_VSP_TESTS,
+                    vspTestResults: response
+                });
+                ScreensHelper.loadScreen(dispatch, {
+                    screen: enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
+                    screenType: screenTypes.SOFTWARE_PRODUCT,
+                    props: {
+                        softwareProductId,
+                        version,
+                        status
+                    }
+                });
+            })
+            .catch(error => {
+                let errMessage = error.message || error.responseJSON.message;
+                let title = error.responseJSON
+                    ? error.responseJSON.status
+                    : i18n('Error');
+                dispatch({
+                    type: modalActionTypes.GLOBAL_MODAL_ERROR,
+                    data: {
+                        title: title,
+                        msg: errMessage,
+                        cancelButtonText: i18n('OK')
+                    }
+                });
+            });
+    },
+
+    fetchVspChecks(dispatch) {
+        return new Promise((resolve, reject) => {
+            fetchVspChecks()
+                .then(response => {
+                    dispatch({
+                        type: actionTypes.FETCH_VSP_CHECKS,
+                        vspChecks: response
+                    });
+                    resolve(response);
+                })
+                .catch(error => {
+                    reject(error);
+                });
+        });
+    },
+
+    setActiveTab(dispatch, { activeTab }) {
+        dispatch({
+            type: actionTypes.SET_ACTIVE_TAB,
+            activeTab
+        });
+    },
+
+    onErrorThrown(dispatch, msg) {
+        dispatch({
+            type: modalActionTypes.GLOBAL_MODAL_ERROR,
+            data: {
+                title: i18n('Error'),
+                modalComponentName: i18n('Error'),
+                modalComponentProps: {
+                    onClose: () =>
+                        dispatch({
+                            type: modalActionTypes.GLOBAL_MODAL_CLOSE
+                        })
+                },
+                msg: msg,
+                cancelButtonText: i18n('OK')
+            }
+        });
+    },
+
+    setVspTestsMap(dispatch, map) {
+        dispatch({
+            type: actionTypes.SET_VSP_TESTS_MAP,
+            vspTestsMap: map
+        });
+    },
+
+    setComplianceChecked(dispatch, checked) {
+        dispatch({
+            type: actionTypes.SET_COMPLIANCE_CHECKED,
+            complianceChecked: checked
+        });
+    },
+
+    setCertificationChecked(dispatch, checked) {
+        dispatch({
+            type: actionTypes.SET_CERTIFICATION_CHECKED,
+            certificationChecked: checked
+        });
+    },
+
+    setTestsRequest(dispatch, request, info) {
+        dispatch({
+            type: actionTypes.SET_TESTS_REQUEST,
+            testsRequest: request,
+            generalInfo: info
+        });
+    },
+
+    setGeneralInfo(dispatch, info) {
+        dispatch({
+            type: actionTypes.SET_GENERAL_INFO,
+            generalInfo: info
+        });
+    },
+
+    setIsVspValidationDisabled(dispatch, { isValidationDisabled }) {
+        dispatch({
+            type: actionTypes.SET_VSP_VALIDATION_DISABLED,
+            isValidationDisabled: isValidationDisabled
+        });
+    }
+};
+
+export default SoftwareProductValidationActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationConstants.js
new file mode 100644 (file)
index 0000000..2dc5a1c
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 keyMirror from 'nfvo-utils/KeyMirror.js';
+
+export const tabsMapping = {
+    SETUP: 1,
+    INPUTS: 2
+};
+
+export const actionTypes = keyMirror(
+    {
+        POST_VSP_TESTS: null,
+        FETCH_VSP_CHECKS: null,
+        SET_ACTIVE_TAB: null,
+        SET_VSP_TESTS_MAP: null,
+        SET_COMPLIANCE_CHECKED: null,
+        SET_CERTIFICATION_CHECKED: null,
+        SET_TESTS_REQUEST: null,
+        SET_GENERAL_INFO: null,
+        SET_VSP_VALIDATION_DISABLED: null
+    },
+    'SoftwareProductValidation'
+);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationReducer.js
new file mode 100644 (file)
index 0000000..4513e23
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { actionTypes } from './SoftwareProductValidationConstants.js';
+
+export default (state = {}, action) => {
+    switch (action.type) {
+        case actionTypes.POST_VSP_TESTS:
+            return {
+                ...state,
+                vspTestResults: action.vspTestResults
+            };
+        case actionTypes.FETCH_VSP_CHECKS:
+            return {
+                ...state,
+                vspChecks: action.vspChecks
+            };
+        case actionTypes.SET_ACTIVE_TAB:
+            return { ...state, activeTab: action.activeTab };
+        case actionTypes.SET_VSP_TESTS_MAP:
+            return {
+                ...state,
+                vspTestsMap: action.vspTestsMap
+            };
+        case actionTypes.SET_COMPLIANCE_CHECKED:
+            return {
+                ...state,
+                complianceChecked: action.complianceChecked
+            };
+        case actionTypes.SET_CERTIFICATION_CHECKED:
+            return {
+                ...state,
+                certificationChecked: action.certificationChecked
+            };
+        case actionTypes.SET_TESTS_REQUEST:
+            return {
+                ...state,
+                testsRequest: action.testsRequest,
+                generalInfo: action.generalInfo
+            };
+        case actionTypes.SET_GENERAL_INFO:
+            return {
+                ...state,
+                generalInfo: action.generalInfo
+            };
+        case actionTypes.SET_VSP_VALIDATION_DISABLED:
+            return {
+                ...state,
+                isValidationDisabled: action.isValidationDisabled
+            };
+        default:
+            return state;
+    }
+};
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx
new file mode 100644 (file)
index 0000000..8611c41
--- /dev/null
@@ -0,0 +1,387 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Button from 'sdc-ui/lib/react/Button.js';
+import { Tab, Tabs } from 'sdc-ui/lib/react';
+import { tabsMapping } from './SoftwareProductValidationConstants.js';
+import VspValidationInputs from './inputs/VspValidationInputs.js';
+import VspValidationSetup from './setup/VspValidationSetup.js';
+
+class SoftwareProductValidation extends Component {
+    static propTypes = {
+        onErrorThrown: PropTypes.func,
+        softwareProductValidation: PropTypes.object,
+        onTestSubmit: PropTypes.func,
+        setVspTestsMap: PropTypes.func,
+        setActiveTab: PropTypes.func,
+        setComplianceChecked: PropTypes.func,
+        setCertificationChecked: PropTypes.func
+    };
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            complianceCheckList: null,
+            certificationCheckList: null,
+            flatTestsMap: {},
+            generalInfo: {},
+            activeTab: tabsMapping.SETUP,
+            goToValidationInput: false
+        };
+    }
+
+    setMapAndGeneralData(element, testScenario) {
+        let flatTestMap = this.state.flatTestsMap;
+        let generalInputData = this.state.generalInfo;
+        flatTestMap[element.testCaseName] = {
+            title: element.description,
+            parameters: element.inputs,
+            endpoint: element.endpoint,
+            testCaseName: element.testCaseName,
+            testSuiteName: element.testSuiteName,
+            scenario: testScenario
+        };
+        generalInputData[element.testCaseName] = {};
+        element.inputs.forEach(key => {
+            generalInputData[element.testCaseName][key.name] = {
+                isValid: true,
+                errorText: ''
+            };
+        });
+
+        this.setState({
+            flatTestsMap: flatTestMap,
+            generalInfo: generalInputData
+        });
+    }
+
+    buildChildElements(setItem, testScenario) {
+        let parentElement = {};
+        parentElement.value = setItem.name;
+        parentElement.label = setItem.description;
+        parentElement.children = [];
+        if (setItem.children !== undefined) {
+            setItem.children.forEach(element => {
+                let childElement = this.buildChildElements(
+                    element,
+                    testScenario
+                );
+                if (childElement.children.length !== 0) {
+                    parentElement.children.push(childElement);
+                }
+            });
+        }
+        if (setItem.tests !== undefined) {
+            setItem.tests.forEach(element => {
+                parentElement.children.push({
+                    value: element.testCaseName,
+                    label: element.description
+                });
+                this.setMapAndGeneralData(element, testScenario);
+            });
+        }
+        return parentElement;
+    }
+
+    buildCheckboxParentNode(parentNode, data) {
+        parentNode.value = data.description;
+        parentNode.label = 'All';
+        parentNode.children = [];
+        let scenario = data.name;
+        data.children.forEach(element => {
+            let childElement = this.buildChildElements(element, scenario);
+            if (childElement.children.length !== 0) {
+                parentNode.children.push(childElement);
+            }
+        });
+        if (data.tests !== undefined) {
+            data.tests.forEach(element => {
+                parentNode.children.push({
+                    value: element.testCaseName,
+                    label: element.description
+                });
+                this.setMapAndGeneralData(element, scenario);
+            });
+        }
+        return parentNode;
+    }
+
+    prepareDataForCheckboxes(res) {
+        let complianceData = {};
+        let certificationData = {};
+        let complianceList = [];
+        let certificationList = [];
+        let { setVspTestsMap } = this.props;
+        if (Object.keys(res).length !== 0 && res.children) {
+            res.children.forEach(element => {
+                if (element.name === 'certification') {
+                    certificationData = element;
+                } else if (element.name === 'compliance') {
+                    complianceData = element;
+                }
+            });
+
+            let complianceParentNode = {};
+            if (
+                Object.keys(complianceData).length !== 0 &&
+                complianceData.children !== undefined
+            ) {
+                complianceParentNode = this.buildCheckboxParentNode(
+                    complianceParentNode,
+                    complianceData
+                );
+                if (complianceParentNode.children.length !== 0) {
+                    complianceList.push(complianceParentNode);
+                }
+            }
+
+            let certificationParentNode = {};
+            if (
+                Object.keys(certificationData).length !== 0 &&
+                certificationData.children !== undefined
+            ) {
+                certificationParentNode = this.buildCheckboxParentNode(
+                    certificationParentNode,
+                    certificationData
+                );
+                if (certificationParentNode.children.length !== 0) {
+                    certificationList.push(certificationParentNode);
+                }
+            }
+        }
+        this.setState({
+            certificationCheckList: certificationList,
+            complianceCheckList: complianceList
+        });
+        setVspTestsMap(this.state.flatTestsMap);
+    }
+
+    resetState() {
+        this.setState({
+            complianceCheckList: [],
+            certificationCheckList: [],
+            flatTestsMap: {},
+            activeTab: tabsMapping.SETUP,
+            goToValidationInput: false
+        });
+    }
+
+    componentWillMount() {}
+
+    shouldComponentUpdate() {
+        return true;
+    }
+
+    componentDidMount() {
+        let { softwareProductValidation } = this.props;
+        if (softwareProductValidation.vspChecks !== undefined) {
+            this.prepareDataForCheckboxes(softwareProductValidation.vspChecks);
+        }
+    }
+
+    componentWillUnmount() {
+        this.resetState();
+    }
+
+    componentWillReceiveProps(nextProps) {
+        if (
+            nextProps.softwareProductValidation.vspChecks !==
+            this.props.softwareProductValidation.vspChecks
+        ) {
+            let { softwareProductValidation, setActiveTab } = nextProps;
+            if (softwareProductValidation.vspChecks !== undefined) {
+                this.prepareDataForCheckboxes(
+                    softwareProductValidation.vspChecks
+                );
+            }
+            this.setState({ activeTab: tabsMapping.SETUP });
+            setActiveTab({ activeTab: tabsMapping.SETUP });
+        }
+    }
+
+    prepareDataForValidationInputsSection() {
+        let {
+            softwareProductId,
+            version,
+            onTestSubmit,
+            onErrorThrown,
+            setTestsRequest,
+            setGeneralInfo
+        } = this.props;
+        return {
+            softwareProductId,
+            version,
+            onTestSubmit,
+            onErrorThrown,
+            setTestsRequest,
+            setGeneralInfo
+        };
+    }
+
+    prepareDataForCheckboxTreeSection() {
+        let {
+            softwareProductValidation,
+            setComplianceChecked,
+            setCertificationChecked
+        } = this.props;
+        let complianceCheckList = this.state.complianceCheckList;
+        let certificationCheckList = this.state.certificationCheckList;
+        return {
+            softwareProductValidation,
+            setComplianceChecked,
+            setCertificationChecked,
+            complianceCheckList,
+            certificationCheckList
+        };
+    }
+
+    handleTabPress(key) {
+        let { setActiveTab } = this.props;
+        switch (key) {
+            case tabsMapping.SETUP:
+                this.setState({ activeTab: tabsMapping.SETUP });
+                setActiveTab({ activeTab: tabsMapping.SETUP });
+                return;
+            case tabsMapping.INPUTS:
+            default:
+                setActiveTab({ activeTab: tabsMapping.INPUTS });
+                this.setState({
+                    goToValidationInput: true,
+                    activeTab: tabsMapping.INPUTS
+                });
+                return;
+        }
+    }
+
+    formTestsRequest(item, testsRequest) {
+        let { vspTestsMap } = this.props.softwareProductValidation;
+        testsRequest[item] = {
+            parameters: {},
+            scenario: vspTestsMap[item]['scenario'],
+            testCaseName: vspTestsMap[item]['testCaseName'],
+            testSuiteName: vspTestsMap[item]['testSuiteName'],
+            endpoint: vspTestsMap[item]['endpoint']
+        };
+        vspTestsMap[item].parameters.forEach(parameter => {
+            testsRequest[item].parameters[parameter.name] =
+                parameter.defaultValue || '';
+        });
+        return testsRequest;
+    }
+
+    onGoToInputs() {
+        let {
+            setActiveTab,
+            softwareProductValidation,
+            setTestsRequest
+        } = this.props;
+        setActiveTab({ activeTab: tabsMapping.INPUTS });
+        let testsRequest = {};
+        if (softwareProductValidation.complianceChecked) {
+            softwareProductValidation.complianceChecked.forEach(item => {
+                testsRequest = this.formTestsRequest(item, testsRequest);
+            });
+        }
+        if (softwareProductValidation.certificationChecked) {
+            softwareProductValidation.certificationChecked.forEach(item => {
+                testsRequest = this.formTestsRequest(item, testsRequest);
+            });
+        }
+        setTestsRequest(testsRequest, this.state.generalInfo);
+        this.setState({
+            goToValidationInput: true,
+            activeTab: tabsMapping.INPUTS
+        });
+    }
+
+    onGoToSetup() {
+        let { setActiveTab } = this.props;
+        setActiveTab({ activeTab: tabsMapping.SETUP });
+        this.setState({
+            goToValidationInput: false,
+            activeTab: tabsMapping.SETUP
+        });
+    }
+
+    render() {
+        let { softwareProductValidation } = this.props;
+        let isNextDisabled =
+            (softwareProductValidation.certificationChecked === undefined ||
+                softwareProductValidation.certificationChecked.length === 0) &&
+            (softwareProductValidation.complianceChecked === undefined ||
+                softwareProductValidation.complianceChecked.length === 0);
+
+        return (
+            <div className="vsp-validation-view">
+                <div className="validation-view-controllers">
+                    {this.state.activeTab === tabsMapping.SETUP && (
+                        <Button
+                            btnType="secondary"
+                            data-test-id="go-to-vsp-validation-inputs"
+                            disabled={isNextDisabled}
+                            className="change-tabs-btn"
+                            onClick={() => this.onGoToInputs()}>
+                            {i18n('NEXT')}
+                        </Button>
+                    )}
+                    {this.state.activeTab === tabsMapping.INPUTS && (
+                        <Button
+                            btnType="secondary"
+                            data-test-id="go-to-vsp-validation-setup"
+                            className="change-tabs-btn"
+                            onClick={() => this.onGoToSetup()}>
+                            {i18n('BACK')}
+                        </Button>
+                    )}
+                </div>
+                <Tabs
+                    className="validation-tabs"
+                    type="header"
+                    activeTab={this.state.activeTab}
+                    onTabClick={key => this.handleTabPress(key)}>
+                    <Tab
+                        tabId={tabsMapping.SETUP}
+                        title={i18n('Setup')}
+                        disabled={this.state.goToValidationInput}>
+                        <div className="validation-view-tab">
+                            {this.state.complianceCheckList &&
+                                this.state.certificationCheckList && (
+                                    <VspValidationSetup
+                                        {...this.prepareDataForCheckboxTreeSection()}
+                                    />
+                                )}
+                        </div>
+                    </Tab>
+                    <Tab
+                        tabId={tabsMapping.INPUTS}
+                        title={i18n('Inputs')}
+                        disabled={!this.state.goToValidationInput}>
+                        <div className="validation-view-tab">
+                            <VspValidationInputs
+                                {...this.prepareDataForValidationInputsSection()}
+                            />
+                        </div>
+                    </Tab>
+                </Tabs>
+            </div>
+        );
+    }
+}
+
+export default SoftwareProductValidation;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputs.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputs.js
new file mode 100644 (file)
index 0000000..375cd45
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { connect } from 'react-redux';
+import VspValidationInputs from './VspValidationInputsView.jsx';
+
+export const mapStateToProps = ({ softwareProduct }) => {
+    let { softwareProductValidation } = softwareProduct;
+    return {
+        softwareProductValidation
+    };
+};
+
+export default connect(mapStateToProps, null, null, {
+    withRef: true
+})(VspValidationInputs);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputsView.jsx
new file mode 100644 (file)
index 0000000..c2990a2
--- /dev/null
@@ -0,0 +1,297 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import Button from 'sdc-ui/lib/react/Button.js';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+import Input from 'nfvo-components/input/validation/Input.jsx';
+import Form from 'nfvo-components/input/validation/Form.jsx';
+
+class VspInputs extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {};
+    }
+
+    shouldComponentUpdate() {
+        return true;
+    }
+
+    changeInputs(e, check, parameterName) {
+        let { testsRequest, generalInfo, setTestsRequest } = this.props;
+        testsRequest[check].parameters[parameterName] = e;
+        generalInfo[check][parameterName] = { isValid: true, errorText: '' };
+        setTestsRequest(testsRequest, generalInfo);
+    }
+
+    renderInputs(check) {
+        let { vspTestsMap, testsRequest, generalInfo } = this.props;
+        return (
+            <div className="div-clear-both">
+                <GridSection
+                    title={i18n('{title} Inputs :', {
+                        title: vspTestsMap[check].title
+                    })}>
+                    {vspTestsMap[check].parameters.map((parameter, index) => {
+                        if (
+                            parameter.type === 'text' &&
+                            !parameter.metadata.hidden
+                        ) {
+                            return (
+                                <GridItem key={index}>
+                                    <Input
+                                        data-test-id={
+                                            check +
+                                            '_' +
+                                            parameter.name +
+                                            '_input'
+                                        }
+                                        isRequired={!parameter.isOptional}
+                                        label={parameter.description}
+                                        isValid={
+                                            generalInfo[check][parameter.name]
+                                                .isValid
+                                        }
+                                        errorText={
+                                            generalInfo[check][parameter.name]
+                                                .errorText
+                                        }
+                                        type={
+                                            parameter.metadata.choices
+                                                ? 'select'
+                                                : 'text'
+                                        }
+                                        value={
+                                            testsRequest[check].parameters[
+                                                parameter.name
+                                            ] || ''
+                                        }
+                                        onChange={e => {
+                                            this.changeInputs(
+                                                e.target ? e.target.value : e,
+                                                check,
+                                                parameter.name
+                                            );
+                                        }}
+                                        disabled={
+                                            parameter.metadata.disabled || false
+                                        }>
+                                        {parameter.metadata.choices && (
+                                            <option key="placeholder" value="">
+                                                {i18n('Select...')}
+                                            </option>
+                                        )}
+                                        {parameter.metadata.choices &&
+                                            parameter.metadata.choices.map(
+                                                selectOption => (
+                                                    <option
+                                                        key={selectOption.key}
+                                                        value={
+                                                            selectOption.key
+                                                        }>
+                                                        {selectOption.label}
+                                                    </option>
+                                                )
+                                            )}
+                                    </Input>
+                                </GridItem>
+                            );
+                        }
+                    })}
+                </GridSection>
+            </div>
+        );
+    }
+
+    render() {
+        let {
+            complianceChecked,
+            vspTestsMap,
+            certificationChecked
+        } = this.props;
+        return (
+            <div>
+                {complianceChecked.map(complianceCheck => {
+                    if (vspTestsMap[complianceCheck].parameters.length === 0) {
+                        return <div />;
+                    } else {
+                        return this.renderInputs(complianceCheck);
+                    }
+                })}
+                {certificationChecked.map(certificateCheck => {
+                    if (vspTestsMap[certificateCheck].parameters.length === 0) {
+                        return <div />;
+                    } else {
+                        return this.renderInputs(certificateCheck);
+                    }
+                })}
+            </div>
+        );
+    }
+}
+
+class VspValidationInputs extends Component {
+    static propTypes = {
+        softwareProductValidation: PropTypes.object
+    };
+
+    constructor(props) {
+        super(props);
+        this.state = {};
+    }
+
+    shouldComponentUpdate() {
+        return true;
+    }
+
+    validateInputs() {
+        let areInputsValid = true;
+        let { softwareProductValidation, setGeneralInfo } = this.props;
+        let generalInfo = softwareProductValidation.generalInfo;
+        Object.keys(softwareProductValidation.testsRequest).forEach(
+            testCaseName => {
+                let requestParameters =
+                    softwareProductValidation.testsRequest[testCaseName]
+                        .parameters;
+                let validationParameters =
+                    softwareProductValidation.vspTestsMap[testCaseName]
+                        .parameters;
+                Object.keys(requestParameters).forEach(parameterName => {
+                    let parameter = validationParameters.find(
+                        o => o.name === parameterName
+                    );
+                    let isParameterValid = true;
+                    let errorText = '';
+                    if (
+                        parameter.type === 'text' &&
+                        parameter.metadata.choices
+                    ) {
+                        if (
+                            !parameter.isOptional &&
+                            !requestParameters[parameterName]
+                        ) {
+                            isParameterValid = false;
+                            errorText = i18n('Field is required');
+                        }
+                    } else if (parameter.type === 'text') {
+                        if (
+                            !parameter.isOptional &&
+                            !requestParameters[parameterName]
+                        ) {
+                            isParameterValid = false;
+                            errorText = i18n('Field is required');
+                        } else if (
+                            (!parameter.isOptional &&
+                                !requestParameters[parameterName]) ||
+                            (parameter.metadata.maxLength &&
+                                requestParameters[parameterName].length >
+                                    parseInt(parameter.metadata.maxLength)) ||
+                            (parameter.metadata.minLength &&
+                                requestParameters[parameterName].length <
+                                    parseInt(parameter.metadata.minLength) &&
+                                requestParameters[parameterName].length > 0)
+                        ) {
+                            isParameterValid = false;
+                            errorText = i18n(
+                                'Value Should Be Minimum of {minLength} characters and a Maximum of {maxLength} characters',
+                                {
+                                    minLength: parameter.metadata.minLength,
+                                    maxLength: parameter.metadata.maxLength
+                                }
+                            );
+                        }
+                    }
+                    generalInfo[testCaseName][
+                        parameterName
+                    ].isValid = isParameterValid;
+                    generalInfo[testCaseName][
+                        parameterName
+                    ].errorText = errorText;
+                    areInputsValid = areInputsValid && isParameterValid;
+                });
+            }
+        );
+        if (!areInputsValid) {
+            setGeneralInfo(generalInfo);
+        }
+        return areInputsValid;
+    }
+
+    performVSPTests() {
+        let tests = [];
+        let {
+            version,
+            onTestSubmit,
+            status,
+            softwareProductId,
+            softwareProductValidation
+        } = this.props;
+
+        Object.keys(softwareProductValidation.testsRequest).forEach(key => {
+            tests.push(softwareProductValidation.testsRequest[key]);
+        });
+        if (this.validateInputs()) {
+            onTestSubmit(softwareProductId, version, status, tests);
+        }
+    }
+
+    prepareDataForVspInputs() {
+        let { setTestsRequest } = this.props;
+        let {
+            complianceChecked,
+            certificationChecked,
+            vspTestsMap,
+            testsRequest,
+            generalInfo
+        } = this.props.softwareProductValidation;
+        return {
+            setTestsRequest,
+            complianceChecked,
+            certificationChecked,
+            vspTestsMap,
+            testsRequest,
+            generalInfo
+        };
+    }
+
+    render() {
+        return (
+            <div className="vsp-validation-view">
+                <Form
+                    hasButtons={false}
+                    formReady={null}
+                    isValid={true}
+                    onSubmit={() => this.performVSPTests()}
+                    isReadOnlyMode={false}>
+                    <VspInputs {...this.prepareDataForVspInputs()} />
+                    <Button
+                        size="default"
+                        data-test-id="proceed-to-validation-results-btn"
+                        disabled={false}
+                        className="proceed-to-validation-monitor-btn"
+                        onClick={() => this.performVSPTests()}>
+                        {i18n('Submit')}
+                    </Button>
+                </Form>
+            </div>
+        );
+    }
+}
+
+export default VspValidationInputs;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetup.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetup.js
new file mode 100644 (file)
index 0000000..875639e
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { connect } from 'react-redux';
+import VspValidationSetupView from './VspValidationSetupView.jsx';
+
+export const mapStateToProps = ({ softwareProduct }) => {
+    let { softwareProductValidation } = softwareProduct;
+    return {
+        softwareProductValidation
+    };
+};
+
+export const mapActionsToProps = () => {
+    return {};
+};
+
+export default connect(mapStateToProps, mapActionsToProps, null, {
+    withRef: true
+})(VspValidationSetupView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetupView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetupView.jsx
new file mode 100644 (file)
index 0000000..012d50a
--- /dev/null
@@ -0,0 +1,320 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+import CheckboxTree from 'react-checkbox-tree';
+
+const icons = {
+    check: <span className="glyphicon glyphicon-check" />,
+    uncheck: <span className="glyphicon glyphicon-unchecked" />,
+    halfCheck: <span className="glyphicon glyphicon-stop" />,
+    expandClose: <span className="glyphicon glyphicon-plus" />,
+    expandOpen: <span className="glyphicon glyphicon-minus" />,
+    expandAll: <span className="glyphicon glyphicon-collapse-down" />,
+    collapseAll: <span className="glyphicon glyphicon-collapse-up" />,
+    parentClose: <span className="glyphicon glyphicon-folder-close" />,
+    parentOpen: <span className="glyphicon glyphicon-folder-open" />,
+    leaf: <span className="glyphicon glyphicon-bookmark" />
+};
+
+class CertificationQuery extends React.Component {
+    constructor(props) {
+        super(props);
+        let { certificationChecked, certificationNodes } = this.props;
+        this.state = {
+            checked:
+                certificationChecked === undefined ? [] : certificationChecked,
+            expanded: certificationNodes[0] ? [certificationNodes[0].value] : []
+        };
+    }
+
+    expandFirstNode() {
+        let { certificationNodes } = this.props;
+        this.setState({
+            expanded: certificationNodes[0] ? [certificationNodes[0].value] : []
+        });
+    }
+
+    componentDidMount() {
+        this.expandFirstNode();
+    }
+
+    shouldComponentUpdate() {
+        return true;
+    }
+
+    componentWillReceiveProps(nextProps) {
+        if (
+            nextProps.certificationChecked !== this.props.certificationChecked
+        ) {
+            let expand = this.state.expanded;
+            this.setState({
+                checked: nextProps.certificationChecked || [],
+                expanded: expand
+            });
+        }
+    }
+
+    populateOptions(checkedCertificationQuery) {
+        let { flatTestsMap } = this.props;
+        return (
+            <option>
+                {flatTestsMap[checkedCertificationQuery].title +
+                    ' (' +
+                    checkedCertificationQuery +
+                    ')'}
+            </option>
+        );
+    }
+
+    render() {
+        let { certificationNodes, setCertificationChecked } = this.props;
+        return (
+            <div className="validation-setup-checkbox-tree-section">
+                <GridSection title={i18n('Certifications Query')}>
+                    <GridItem colSpan={2}>
+                        <div className="validation-view-title">
+                            {certificationNodes[0]
+                                ? certificationNodes[0].value
+                                : ''}
+                        </div>
+                        <div
+                            className="validation-setup-available-tests-section"
+                            data-test-id={
+                                'vsp-validation-certifications-query-checkbox-tree'
+                            }>
+                            {certificationNodes.length > 0 && (
+                                <CheckboxTree
+                                    nodes={certificationNodes}
+                                    checked={this.state.checked}
+                                    expanded={this.state.expanded}
+                                    onCheck={checked => {
+                                        this.setState(
+                                            { checked },
+                                            setCertificationChecked({
+                                                checked
+                                            })
+                                        );
+                                    }}
+                                    onExpand={expanded =>
+                                        this.setState({ expanded })
+                                    }
+                                    icons={icons}
+                                    className="field-section"
+                                />
+                            )}
+                            {certificationNodes.length === 0 && (
+                                <div>
+                                    {i18n(
+                                        'No Certifications Query are Available'
+                                    )}
+                                </div>
+                            )}
+                        </div>
+                    </GridItem>
+                    <GridItem colSpan={2}>
+                        {certificationNodes.length > 0 && (
+                            <div>
+                                <div className="validation-view-title">
+                                    {i18n('Selected Certifications Query')}
+                                </div>
+                                <div>
+                                    <select
+                                        className="validation-setup-selected-tests"
+                                        multiple>
+                                        {this.state.checked.map(row =>
+                                            this.populateOptions(row)
+                                        )}
+                                    </select>
+                                </div>
+                            </div>
+                        )}
+                    </GridItem>
+                </GridSection>
+            </div>
+        );
+    }
+}
+
+class ComplianceTests extends React.Component {
+    constructor(props) {
+        super(props);
+        let { complianceChecked, complianceNodes } = this.props;
+        this.state = {
+            checked: complianceChecked === undefined ? [] : complianceChecked,
+            expanded: complianceNodes[0] ? [complianceNodes[0].value] : []
+        };
+    }
+
+    shouldComponentUpdate() {
+        return true;
+    }
+
+    expandFirstNode() {
+        let { complianceNodes } = this.props;
+        this.setState({
+            expanded: complianceNodes[0] ? [complianceNodes[0].value] : []
+        });
+    }
+
+    componentDidMount() {
+        this.expandFirstNode();
+    }
+
+    componentWillUnmount() {}
+
+    componentWillReceiveProps(nextProps) {
+        let expand = this.state.expanded;
+
+        if (nextProps.complianceChecked !== this.props.complianceChecked) {
+            this.setState({
+                checked: nextProps.complianceChecked || [],
+                expanded: expand
+            });
+        }
+    }
+
+    populateOptions(checkedComplianceTests) {
+        let { flatTestsMap } = this.props;
+        return (
+            <option>
+                {flatTestsMap[checkedComplianceTests].title +
+                    ' (' +
+                    checkedComplianceTests +
+                    ')'}
+            </option>
+        );
+    }
+    render() {
+        let { complianceNodes, setComplianceChecked } = this.props;
+        return (
+            <div className="validation-setup-checkbox-tree-section">
+                <GridSection title={i18n('Compliance Checks')}>
+                    <GridItem colSpan={2}>
+                        <div className="validation-view-title">
+                            {complianceNodes[0] ? complianceNodes[0].value : ''}
+                        </div>
+                        <div
+                            className="validation-setup-available-tests-section"
+                            data-test-id={
+                                'vsp-validation-compliance-checks-checkbox-tree'
+                            }>
+                            {complianceNodes.length > 0 && (
+                                <CheckboxTree
+                                    nodes={complianceNodes}
+                                    checked={this.state.checked}
+                                    expanded={this.state.expanded}
+                                    onCheck={checked => {
+                                        this.setState(
+                                            { checked },
+                                            setComplianceChecked({
+                                                checked
+                                            })
+                                        );
+                                    }}
+                                    onExpand={expanded =>
+                                        this.setState({ expanded })
+                                    }
+                                    icons={icons}
+                                    className="field-section"
+                                />
+                            )}
+                            {complianceNodes.length === 0 && (
+                                <div>
+                                    {i18n('No Compliance Checks are Available')}
+                                </div>
+                            )}
+                        </div>
+                    </GridItem>
+                    <GridItem colSpan={2}>
+                        {complianceNodes.length > 0 && (
+                            <div>
+                                <div className="validation-view-title">
+                                    {i18n('Selected Compliance Tests')}
+                                </div>
+                                <div>
+                                    <select
+                                        className="validation-setup-selected-tests"
+                                        multiple>
+                                        {this.state.checked.map(row =>
+                                            this.populateOptions(row)
+                                        )}
+                                    </select>
+                                </div>
+                            </div>
+                        )}
+                    </GridItem>
+                </GridSection>
+            </div>
+        );
+    }
+}
+
+class VspValidationSetup extends Component {
+    static propTypes = {
+        softwareProductValidation: PropTypes.object,
+        setComplianceChecked: PropTypes.func,
+        setCertificationChecked: PropTypes.func
+    };
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            complianceCheckList: [],
+            certificationCheckList: []
+        };
+    }
+
+    shouldComponentUpdate() {
+        return true;
+    }
+
+    render() {
+        let {
+            softwareProductValidation,
+            setComplianceChecked,
+            setCertificationChecked,
+            complianceCheckList,
+            certificationCheckList
+        } = this.props;
+        return (
+            <div className="vsp-validation-view">
+                <CertificationQuery
+                    certificationNodes={certificationCheckList}
+                    flatTestsMap={softwareProductValidation.vspTestsMap}
+                    setCertificationChecked={setCertificationChecked}
+                    certificationChecked={
+                        softwareProductValidation.certificationChecked
+                    }
+                />
+                <ComplianceTests
+                    complianceNodes={complianceCheckList}
+                    flatTestsMap={softwareProductValidation.vspTestsMap}
+                    setComplianceChecked={setComplianceChecked}
+                    complianceChecked={
+                        softwareProductValidation.complianceChecked
+                    }
+                />
+            </div>
+        );
+    }
+}
+
+export default VspValidationSetup;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js
new file mode 100644 (file)
index 0000000..dffade7
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { connect } from 'react-redux';
+import SoftwareProductValidationResultsView from './SoftwareProductValidationResultsView.jsx';
+
+export const mapStateToProps = ({ softwareProduct }) => {
+    let { softwareProductValidation } = softwareProduct;
+    return {
+        softwareProductValidation
+    };
+};
+
+export default connect(mapStateToProps, null, null, {
+    withRef: true
+})(SoftwareProductValidationResultsView);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsView.jsx
new file mode 100644 (file)
index 0000000..b6cc1d5
--- /dev/null
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 PropTypes from 'prop-types';
+import Accordion from 'sdc-ui/lib/react/Accordion.js';
+import SVGIcon from 'sdc-ui/lib/react/SVGIcon.js';
+import GridSection from 'nfvo-components/grid/GridSection.jsx';
+import GridItem from 'nfvo-components/grid/GridItem.jsx';
+import i18n from 'nfvo-utils/i18n/i18n.js';
+import unCamelCasedString from 'nfvo-utils/unCamelCaseString.js';
+
+const TestResultComponent = ({ tests }) => {
+    return (
+        <div>
+            {tests.map((test, index) => {
+                let name = 'errorCircle';
+                let color = 'warning';
+                if (
+                    test.testResult &&
+                    test.testResult.toLowerCase() === 'pass'
+                ) {
+                    color = 'positive';
+                    name = 'checkCircle';
+                } else if (
+                    test.testResult &&
+                    test.testResult.toLowerCase() === 'fail'
+                ) {
+                    name = 'exclamationTriangleFull';
+                }
+                return (
+                    <li type="none" key={index}>
+                        <SVGIcon
+                            color={color}
+                            name={name}
+                            labelPosition="right"
+                        />
+                        <span className="validation-results-test-result-label">
+                            {test.testName +
+                                ' | ' +
+                                test.testResult +
+                                ' | ' +
+                                test.notes}
+                        </span>
+                    </li>
+                );
+            })}
+        </div>
+    );
+};
+
+class SoftwareProductValidationResultsView extends React.Component {
+    static propTypes = {
+        softwareProductValidation: PropTypes.object
+    };
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            vspId: this.props.softwareProductId,
+            versionNumber: this.props.version.name
+        };
+    }
+
+    buildSubAccordions(result) {
+        if (result.status && result.status.toLowerCase() === 'completed') {
+            if (!result.results.testResults) {
+                return (
+                    <div
+                        title={i18n('Scenario: {scenario} | Status: {status}', {
+                            scenario: result.scenario,
+                            status: result.status
+                        })}>
+                        <SVGIcon
+                            color="negative"
+                            name="errorCircle"
+                            labelPosition="right"
+                        />
+                        <span className="validation-results-test-result-label">
+                            {i18n('{title} results are not available', {
+                                title: result.scenario
+                            })}
+                        </span>
+                    </div>
+                );
+            }
+            return (
+                <Accordion
+                    dataTestId="vsp-validation-test-result-success"
+                    title={i18n('Scenario: {scenario} | Status: {status}', {
+                        scenario: result.scenario,
+                        status: result.status
+                    })}>
+                    {Object.keys(result.results.testResults).map(
+                        (key, index) => {
+                            let title = unCamelCasedString(key);
+                            if (result.results.testResults[key].length > 0) {
+                                return (
+                                    <Accordion
+                                        dataTestId={title}
+                                        title={title}
+                                        key={index}>
+                                        <TestResultComponent
+                                            tests={
+                                                result.results.testResults[key]
+                                            }
+                                        />
+                                    </Accordion>
+                                );
+                            } else {
+                                return (
+                                    <div>
+                                        {i18n(
+                                            '{title} results are not available',
+                                            {
+                                                title: title
+                                            }
+                                        )}
+                                    </div>
+                                );
+                            }
+                        }
+                    )}
+                </Accordion>
+            );
+        } else if (
+            result.status &&
+            result.status.toLowerCase() === 'failed' &&
+            result.results.errors
+        ) {
+            return (
+                <Accordion
+                    dataTestId="vsp-validation-test-result-success"
+                    title={i18n('Scenario: {scenario} | Status: {status}', {
+                        scenario: result.scenario,
+                        status: result.status
+                    })}>
+                    {result.results.errors.map((element, index) => {
+                        return (
+                            <li type="none" key={index}>
+                                <SVGIcon
+                                    color="negative"
+                                    name="errorCircle"
+                                    labelPosition="right"
+                                />
+                                <span className="validation-results-test-result-label">
+                                    {element.reason + ' | ' + element.advice}
+                                </span>
+                            </li>
+                        );
+                    })}
+                </Accordion>
+            );
+        } else if (result.message || result.httpStatus) {
+            return (
+                <div>
+                    <SVGIcon
+                        color="negative"
+                        name="errorCircle"
+                        labelPosition="right"
+                    />
+                    <span className="validation-results-test-result-label">
+                        {result.message + ' | ' + result.httpStatus}
+                    </span>
+                </div>
+            );
+        }
+    }
+
+    render() {
+        let results = this.props.softwareProductValidation.vspTestResults || [];
+        if (results.length > 0) {
+            return (
+                <GridSection title={i18n('Validation Results')}>
+                    <GridItem colSpan={10}>
+                        <Accordion
+                            defaultExpanded
+                            dataTestId="vsp-validation-test-result"
+                            title={i18n('Test Results')}>
+                            {results.map(row => this.buildSubAccordions(row))}
+                        </Accordion>
+                    </GridItem>
+                </GridSection>
+            );
+        } else {
+            return (
+                <GridSection title={i18n('Validation Results')}>
+                    <h4>{i18n('No Validation Checks Performed')}</h4>
+                </GridSection>
+            );
+        }
+    }
+}
+
+export default SoftwareProductValidationResultsView;
index 125050b..2f1cf2c 100644 (file)
@@ -14,6 +14,7 @@
  * permissions and limitations under the License.
  */
 import 'sdc-ui/css/style.css';
+import 'react-checkbox-tree/lib/react-checkbox-tree.css';
 import '../../resources/scss/onboarding.scss';
 import 'dox-sequence-diagram-ui/src/main/webapp/res/sdc-sequencer.scss';
 
index 86a8276..f3ca07c 100644 (file)
  * or implied. See the License for the specific language governing
  * permissions and limitations under the License.
  */
-import {Factory} from 'rosie';
+import { Factory } from 'rosie';
 
-export const SoftwareProductFactory = new Factory()
-       .attrs({
-               softwareProductAttachments: {},
-               softwareProductCreation: {},
-               softwareProductEditor: {},
-               softwareProductProcesses: {
-                       processesList: [],
-                       processesEditor: {},
-                       processToDelete: false
-               },
-               softwareProductNetworks: {
-                       networksList: []
-               },
-               softwareProductComponents: {
-                       componentsList: [],
-                       componentEditor: {},
-                       componentProcesses: {
-                               processesList: [],
-                               processesEditor: {},
-                               processToDelete: false
-                       },
-                       network: {
-                               nicList: [],
-                               nicEditor: {}
-                       }
-               },
-               monitoring: {},
-               softwareProductCategories: [],
-               softwareProductQuestionnaire: {}
-       });
+export const SoftwareProductFactory = new Factory().attrs({
+    softwareProductAttachments: {},
+    softwareProductCreation: {},
+    softwareProductEditor: {},
+    softwareProductValidation: {},
+    softwareProductProcesses: {
+        processesList: [],
+        processesEditor: {},
+        processToDelete: false
+    },
+    softwareProductNetworks: {
+        networksList: []
+    },
+    softwareProductComponents: {
+        componentsList: [],
+        componentEditor: {},
+        componentProcesses: {
+            processesList: [],
+            processesEditor: {},
+            processToDelete: false
+        },
+        network: {
+            nicList: [],
+            nicEditor: {}
+        }
+    },
+    monitoring: {},
+    softwareProductCategories: [],
+    softwareProductQuestionnaire: {}
+});
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js
new file mode 100644 (file)
index 0000000..2ae9249
--- /dev/null
@@ -0,0 +1,498 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { Factory } from 'rosie';
+
+export const VSPComplianceCheckedFactory = new Factory().attrs({
+    complianceChecked: [
+        'compliance.compliancetests.sriov',
+        'compliance.compliancetests.computeflavors'
+    ]
+});
+
+export const VSPCertificationCheckedFactory = new Factory().attrs({
+    certificationChecked: ['certification.certificationtests.certquery']
+});
+
+export const VSPGeneralInfoFactory = new Factory().attrs({
+    generalInfo: {
+        'certification.certificationtests.certquery': {
+            vspId: {
+                isValid: false,
+                errorText: 'Please Enter a Value in the Mandatory Field'
+            },
+            vspVersion: {
+                isValid: false,
+                errorText: 'Please Enter a Value in the Mandatory Field'
+            }
+        },
+        'compliance.compliancetests.sriov': {
+            vspId: {
+                isValid: false,
+                errorText: 'Please Enter a Value in the Mandatory Field'
+            },
+            vspVersion: {
+                isValid: false,
+                errorText: 'Please Enter a Value in the Mandatory Field'
+            },
+            allowSriov: {
+                isValid: true,
+                errorText: ''
+            }
+        },
+        'compliance.compliancetests.computeflavors': {
+            vspId: {
+                isValid: false,
+                errorText: 'Please Enter a Value in the Mandatory Field'
+            },
+            vspVersion: {
+                isValid: false,
+                errorText: 'Please Enter a Value in the Mandatory Field'
+            },
+            csp: {
+                isValid: true,
+                errorText: ''
+            },
+            profilespec: {
+                isValid: true,
+                errorText: ''
+            },
+            vnftype: {
+                isValid: true,
+                errorText: ''
+            }
+        }
+    }
+});
+
+export const VSPTestsRequestFactory = new Factory().attrs({
+    testsRequest: {
+        'compliance.compliancetests.sriov': {
+            parameters: {
+                vspId: '',
+                vspVersion: '',
+                allowSriov: 'false'
+            },
+            scenario: 'compliance',
+            testCaseName: 'compliance.compliancetests.sriov',
+            testSuiteName: 'compliancetests',
+            endpoint: 'vtp'
+        },
+        'compliance.compliancetests.computeflavors': {
+            parameters: {
+                vspId: '',
+                vspVersion: '',
+                csp: 'ZZFT',
+                profilespec: 'gsmafnw14',
+                vnftype: 'B'
+            },
+            scenario: 'compliance',
+            testCaseName: 'compliance.compliancetests.computeflavors',
+            testSuiteName: 'compliancetests',
+            endpoint: 'ovp'
+        },
+        'certification.certificationtests.certquery': {
+            parameters: {
+                vspId: '',
+                vspVersion: ''
+            },
+            scenario: 'certification',
+            testCaseName: 'certification.certificationtests.certquery',
+            testSuiteName: 'certificationtests',
+            endpoint: 'repository'
+        }
+    }
+});
+
+export const VSPTestsMapFactory = new Factory().attrs({
+    vspTestsMap: {
+        'compliance.compliancetests.sriov': {
+            title: ' SR-IOV Test',
+            parameters: [
+                {
+                    name: 'vspId',
+                    description: 'VSP ID',
+                    type: 'text',
+                    isOptional: false,
+                    metadata: {
+                        disabled: false,
+                        maxLength: '36',
+                        minLength: '1'
+                    }
+                },
+                {
+                    name: 'vspVersion',
+                    description: 'VSP Version',
+                    type: 'text',
+                    isOptional: false,
+                    metadata: {
+                        disabled: false,
+                        maxLength: '36',
+                        minLength: '1'
+                    }
+                },
+                {
+                    name: 'allowSriov',
+                    description: 'Allow  SR-IOV?',
+                    type: 'select',
+                    defaultValue: 'false',
+                    isOptional: false,
+                    metadata: {
+                        disabled: true,
+                        choices: [
+                            {
+                                key: 'true',
+                                label: 'Yes'
+                            },
+                            {
+                                key: 'false',
+                                label: 'No'
+                            }
+                        ]
+                    }
+                }
+            ],
+            endpoint: 'vtp',
+            testCaseName: 'compliance.compliancetests.sriov',
+            testSuiteName: 'compliancetests',
+            scenario: 'compliance'
+        },
+        'compliance.compliancetests.computeflavors': {
+            title: 'Compute Flavours Test',
+            parameters: [
+                {
+                    name: 'vspId',
+                    description: 'VSP ID',
+                    type: 'text',
+                    isOptional: false,
+                    metadata: {
+                        disabled: false,
+                        maxLength: '36',
+                        minLength: '1'
+                    }
+                },
+                {
+                    name: 'vspVersion',
+                    description: 'VSP Version',
+                    type: 'text',
+                    isOptional: false,
+                    metadata: {
+                        disabled: false,
+                        maxLength: '36',
+                        minLength: '1'
+                    }
+                },
+                {
+                    name: 'csp',
+                    description: 'CSP',
+                    type: 'select',
+                    defaultValue: 'ZZFT',
+                    isOptional: false,
+                    metadata: {
+                        disabled: false,
+                        choices: [
+                            {
+                                key: 'ZZTF',
+                                label: 'Vodafone Group'
+                            }
+                        ]
+                    }
+                },
+                {
+                    name: 'profilespec',
+                    description: 'Profile Specification',
+                    type: 'select',
+                    defaultValue: 'gsmafnw14',
+                    isOptional: false,
+                    metadata: {
+                        disabled: false,
+                        choices: [
+                            {
+                                key: 'gsmafnw14',
+                                label: 'GSMA NFVI Profiles'
+                            }
+                        ]
+                    }
+                },
+                {
+                    name: 'vnftype',
+                    description: 'VNF Type',
+                    type: 'select',
+                    defaultValue: 'B',
+                    isOptional: false,
+                    metadata: {
+                        disabled: false,
+                        choices: [
+                            {
+                                key: 'B',
+                                label: 'Basic'
+                            },
+                            {
+                                key: 'N',
+                                label: 'Network Intensive'
+                            },
+                            {
+                                key: 'C',
+                                label: 'Compute Intensive'
+                            }
+                        ]
+                    }
+                }
+            ],
+            endpoint: 'ovp',
+            testCaseName: 'compliance.compliancetests.computeflavors',
+            testSuiteName: 'compliancetests',
+            scenario: 'compliance'
+        },
+        'certification.certificationtests.certquery': {
+            title: 'Other Certifications',
+            parameters: [
+                {
+                    name: 'vspId',
+                    description: 'VSP ID',
+                    type: 'text',
+                    defaultValue: '',
+                    isOptional: true,
+                    metadata: {
+                        maxLength: 36,
+                        minLength: 1,
+                        disabled: true
+                    }
+                },
+                {
+                    name: 'vspVersion',
+                    description: 'Previous VSP Version',
+                    type: 'text',
+                    defaultValue: '',
+                    isOptional: true,
+                    metadata: {
+                        maxLength: 36,
+                        minLength: 1,
+                        disabled: true
+                    }
+                }
+            ],
+            endpoint: 'repository',
+            testCaseName: 'certification.certificationtests.certquery',
+            testSuiteName: 'certificationtests',
+            scenario: 'certification'
+        }
+    }
+});
+
+export const VSPChecksFactory = new Factory().attrs({
+    name: 'root',
+    description: 'root',
+    children: [
+        {
+            name: 'certification',
+            description: 'Available Certifications Query',
+            children: [
+                {
+                    name: 'certificationtests',
+                    description: 'Additional Certification',
+                    tests: [
+                        {
+                            testCaseName:
+                                'certification.certificationtests.certquery',
+                            testSuiteName: 'certificationtests',
+                            description: 'Other Certifications',
+                            author: 'jg@example.com',
+                            inputs: [
+                                {
+                                    name: 'vspId',
+                                    description: 'VSP ID',
+                                    type: 'text',
+                                    defaultValue: '',
+                                    isOptional: true,
+                                    metadata: {
+                                        maxLength: 36,
+                                        minLength: 1,
+                                        disabled: true
+                                    }
+                                },
+                                {
+                                    name: 'vspVersion',
+                                    description: 'Previous VSP Version',
+                                    type: 'text',
+                                    defaultValue: '',
+                                    isOptional: true,
+                                    metadata: {
+                                        maxLength: 36,
+                                        minLength: 1,
+                                        disabled: true
+                                    }
+                                }
+                            ],
+                            endpoint: 'repository'
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            name: 'compliance',
+            description: 'Available ComplianceChecks',
+            tests: [],
+            children: [
+                {
+                    name: 'compliancetests',
+                    description: 'Compliance Tests',
+                    tests: [
+                        {
+                            testCaseName: 'compliance.compliancetests.sriov',
+                            testSuiteName: 'compliancetests',
+                            description: ' SR-IOV Test',
+                            author: 'Jim',
+                            inputs: [
+                                {
+                                    name: 'vspId',
+                                    description: 'VSP ID',
+                                    type: 'text',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: false,
+                                        maxLength: '36',
+                                        minLength: '1'
+                                    }
+                                },
+                                {
+                                    name: 'vspVersion',
+                                    description: 'VSP Version',
+                                    type: 'text',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: false,
+                                        maxLength: '36',
+                                        minLength: '1'
+                                    }
+                                },
+                                {
+                                    name: 'allowSriov',
+                                    description: 'Allow  SR-IOV?',
+                                    type: 'select',
+                                    defaultValue: 'false',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: true,
+                                        choices: [
+                                            {
+                                                key: 'true',
+                                                label: 'Yes'
+                                            },
+                                            {
+                                                key: 'false',
+                                                label: 'No'
+                                            }
+                                        ]
+                                    }
+                                }
+                            ],
+                            endpoint: 'vtp'
+                        },
+                        {
+                            testCaseName:
+                                'compliance.compliancetests.computeflavors',
+                            testSuiteName: 'compliancetests',
+                            description: 'Compute Flavours Test',
+                            author: 'Jim',
+                            inputs: [
+                                {
+                                    name: 'vspId',
+                                    description: 'VSP ID',
+                                    type: 'text',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: false,
+                                        maxLength: '36',
+                                        minLength: '1'
+                                    }
+                                },
+                                {
+                                    name: 'vspVersion',
+                                    description: 'VSP Version',
+                                    type: 'text',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: false,
+                                        maxLength: '36',
+                                        minLength: '1'
+                                    }
+                                },
+                                {
+                                    name: 'csp',
+                                    description: 'CSP',
+                                    type: 'select',
+                                    defaultValue: 'ZZFT',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: false,
+                                        choices: [
+                                            {
+                                                key: 'ZZTF',
+                                                label: 'Vodafone Group'
+                                            }
+                                        ]
+                                    }
+                                },
+                                {
+                                    name: 'profilespec',
+                                    description: 'Profile Specification',
+                                    type: 'select',
+                                    defaultValue: 'gsmafnw14',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: false,
+                                        choices: [
+                                            {
+                                                key: 'gsmafnw14',
+                                                label: 'GSMA NFVI Profiles'
+                                            }
+                                        ]
+                                    }
+                                },
+                                {
+                                    name: 'vnftype',
+                                    description: 'VNF Type',
+                                    type: 'select',
+                                    defaultValue: 'B',
+                                    isOptional: false,
+                                    metadata: {
+                                        disabled: false,
+                                        choices: [
+                                            {
+                                                key: 'B',
+                                                label: 'Basic'
+                                            },
+                                            {
+                                                key: 'N',
+                                                label: 'Network Intensive'
+                                            },
+                                            {
+                                                key: 'C',
+                                                label: 'Compute Intensive'
+                                            }
+                                        ]
+                                    }
+                                }
+                            ],
+                            endpoint: 'ovp'
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+});
diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js
new file mode 100644 (file)
index 0000000..6728e04
--- /dev/null
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { Factory } from 'rosie';
+
+export const VSPTestResultsFailureFactory = new Factory().attrs({
+    vspTestResults: [
+        {
+            code: '500',
+            message: 'VTP Test(s) could not be completed',
+            httpStatus: 500
+        }
+    ]
+});
+
+export const VSPTestResultsSuccessFactory = new Factory().attrs({
+    vspTestResults: [
+        {
+            scenario: 'certification',
+            description: 'Other Certifications',
+            testCaseName: 'certification.certificationtests.certquery',
+            testSuiteName: 'certificationtests',
+            executionId: 'ebaa5f21-ed68-4098-97a9-775ac8800f09-1550575025614',
+            parameters: {
+                vspId: 'uuidval',
+                vspVersion: 'ver',
+                other: 'values'
+            },
+            results: {
+                testResults: {
+                    complianceTests: [
+                        {
+                            testName: 'Compute Flavors',
+                            testResult: 'Pass',
+                            notes:
+                                'Diagnostic: test performed against GSMA NFVI Abstraction and Profiling Version 0.1 profiles.'
+                        },
+                        {
+                            testName: 'SR-IOV',
+                            testResult: 'Fail',
+                            notes:
+                                'Diagnostic: SR-IOV found in VNF Template. User advice: VNF binary and VNF Template must be modified to not require SR-IOV.'
+                        },
+                        {
+                            testName: 'Heat',
+                            testResult: 'Pass',
+                            notes: ''
+                        },
+                        {
+                            testName: 'TOSCA',
+                            testResult: 'Pass',
+                            notes:
+                                'Diagnostic: test performed for ETSI GS NFV-SOL001v0.10.0.'
+                        }
+                    ],
+                    validationTests: [
+                        {
+                            testName: 'OpenStack',
+                            testResult: 'Pass',
+                            notes:
+                                'Diagnostic: test performed for OpenStack Rocky.'
+                        },
+                        {
+                            testName: 'VMware',
+                            testResult: 'Fail',
+                            notes:
+                                'Diagnostic: VMware compatible template not found. User advice: add a VMware compatible template to the VSP.'
+                        },
+                        {
+                            testName: 'Kubernetes',
+                            testResult: 'Fail',
+                            notes:
+                                'Diagnostic: Kubernetes compatible template not found. User advice: add a Kubernetes compatible template, such as Helm Chart, to the VSP.'
+                        }
+                    ],
+                    performanceTests: [
+                        {
+                            testName: 'Max Throughput',
+                            testResult: 'Pass',
+                            notes: ''
+                        },
+                        {
+                            testName: 'Latency',
+                            testResult: 'Fail',
+                            notes:
+                                'Diagnostic: maximum latency threshold of 20ms signalling response time exceededUser advice: consider increasing VDU compute resource.'
+                        }
+                    ]
+                }
+            },
+
+            status: 'COMPLETED',
+            startTime: '2019-02-19T11:17:05.670',
+            endTime: '2019-02-19T11:17:05.683'
+        },
+        {
+            scenario: 'compliance',
+            testCaseName: 'compliance.compliancetests.sriov',
+            description: 'Allow_SR-IOV',
+            testSuiteName: 'compliancetests',
+            executionId: 'ebaa5f21-ed68-4098-97a9-775ac8800f09-1550575025614',
+            parameters: {
+                vspId: 'uuidval',
+                vspVersion: 'ver',
+                other: 'values'
+            },
+            results: {
+                errors: [
+                    {
+                        attribute: '',
+                        reason: 'Record Not Found',
+                        advice:
+                            'User must query with (vspId, vspVersion) values for a certifications record that is present in the Repository',
+                        code: 40
+                    },
+                    {
+                        attribute: '',
+                        reason: 'Record Not Found',
+                        advice:
+                            'User must query with (vspId, vspVersion) values for a certifications record that is present in the Repository',
+                        code: 40
+                    }
+                ]
+            },
+            status: 'FAILED',
+            startTime: '2019-02-19T11:17:05.670',
+            endTime: '2019-02-19T11:17:05.683'
+        },
+        {
+            scenario: 'compliance',
+            testCaseName: ' compliance.compliancetests.computeflavours',
+            description: 'Allow  SR-IOV ',
+            testSuiteName: 'compliancetests',
+            executionId: 'ebaa5f21-ed68-4098-97a9-775ac8800f09-1550575025614',
+            parameters: {
+                vspId: 'uuidval',
+                vspVersion: 'ver',
+                other: 'values'
+            },
+            results: {},
+            status: 'COMPLETED',
+            startTime: '2019-02-19T11:17:05.670',
+            endTime: '2019-02-19T11:17:05.683'
+        },
+        {
+            code: '500',
+            message: 'VTP Test(s) could not be completed',
+            httpStatus: 500
+        }
+    ]
+});
diff --git a/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationActionHelper.test.js b/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationActionHelper.test.js
new file mode 100644 (file)
index 0000000..ee6ba90
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 deepFreeze from 'deep-freeze';
+import mockRest from 'test-utils/MockRest.js';
+import { cloneAndSet } from 'test-utils/Util.js';
+import { storeCreator } from 'sdc-app/AppStore.js';
+import SoftwareProductValidationActionHelper from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js';
+import { tabsMapping } from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationConstants.js';
+
+import Configuration from 'sdc-app/config/Configuration.js';
+
+import { VSPComplianceCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPCertificationCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPChecksFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPTestsMapFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+
+describe('Software Product Validation Action Helper Tests', function() {
+    it('Software Products Validation Action Helper : Dsspatch', () => {
+        const store = storeCreator();
+        deepFreeze(store.getState());
+
+        const vspChecksList = VSPChecksFactory.build();
+        const vspTestsMap = VSPTestsMapFactory.build();
+        const certificationChecked = VSPCertificationCheckedFactory.build();
+        const complianceChecked = VSPComplianceCheckedFactory.build();
+        const activeTab = { activeTab: tabsMapping.INPUTS };
+        const errorMessage = { msg: 'Test Error Message' };
+
+        deepFreeze(vspChecksList);
+        deepFreeze(vspTestsMap);
+        deepFreeze(certificationChecked);
+        deepFreeze(complianceChecked);
+        deepFreeze(activeTab);
+
+        let expectedStore = cloneAndSet(
+            store.getState(),
+            'softwareProduct.softwareProductValidation.vspChecks',
+            vspChecksList
+        );
+        expectedStore = cloneAndSet(
+            store.getState(),
+            'softwareProduct.softwareProductValidation.vspTestsMap',
+            vspTestsMap
+        );
+        expectedStore = cloneAndSet(
+            store.getState(),
+            'softwareProduct.softwareProductValidation.certificationChecked',
+            certificationChecked
+        );
+        expectedStore = cloneAndSet(
+            store.getState(),
+            'softwareProduct.softwareProductValidation.complianceChecked',
+            complianceChecked
+        );
+        expectedStore = cloneAndSet(
+            store.getState(),
+            'softwareProduct.softwareProductValidation.activeTab',
+            activeTab
+        );
+        let restPrefix = Configuration.get('restPrefix');
+
+        mockRest.addHandler('fetch', ({ options, data, baseUrl }) => {
+            expect(baseUrl).toEqual(`${restPrefix}/v1.0/externaltesting`);
+            expect(data).toEqual(undefined);
+            expect(options).toEqual(undefined);
+            return { vspChecks: vspChecksList };
+        });
+
+        SoftwareProductValidationActionHelper.setVspTestsMap(store.dispatch, {
+            vspTestsMap
+        });
+        SoftwareProductValidationActionHelper.setComplianceChecked(
+            store.dispatch,
+            { complianceChecked }
+        );
+        SoftwareProductValidationActionHelper.setCertificationChecked(
+            store.dispatch,
+            { certificationChecked }
+        );
+
+        SoftwareProductValidationActionHelper.setActiveTab(store.dispatch, {
+            activeTab
+        });
+
+        SoftwareProductValidationActionHelper.onErrorThrown(store.dispatch, {
+            errorMessage
+        });
+
+        SoftwareProductValidationActionHelper.fetchVspChecks(store.dispatch)
+            .then(() => {
+                expect(store.getState()).toEqual(expectedStore);
+            })
+            .catch(() => {});
+    });
+});
diff --git a/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationInputView.test.js b/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationInputView.test.js
new file mode 100644 (file)
index 0000000..aa00a5d
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { mapStateToProps } from 'sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputs.js';
+
+import VspValidationInputsView from 'sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputsView.jsx';
+import TestUtils from 'react-dom/test-utils';
+
+import { VSPComplianceCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPCertificationCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPChecksFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPTestsMapFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPTestsRequestFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPGeneralInfoFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+
+describe('SoftwareProductValidation Mapper and View Classes', () => {
+    it('mapStateToProps mapper exists', () => {
+        expect(mapStateToProps).toBeTruthy();
+    });
+
+    it('mapStateToProps data test', () => {
+        const vspChecksList = VSPChecksFactory.build();
+        const vspTestsMap = VSPTestsMapFactory.build();
+        const certificationChecked = VSPCertificationCheckedFactory.build();
+        const complianceChecked = VSPComplianceCheckedFactory.build();
+        const generalInfo = VSPGeneralInfoFactory.build();
+        var obj = {
+            softwareProduct: {
+                softwareProductValidation: {
+                    vspChecks: vspChecksList,
+                    vspTestsMap: vspTestsMap.vspTestsMap,
+                    certificationChecked:
+                        certificationChecked.certificationChecked,
+                    complianceChecked: complianceChecked.complianceChecked,
+                    generalInfo: generalInfo.generalInfo
+                }
+            }
+        };
+        var results = mapStateToProps(obj);
+        expect(results.softwareProductValidation.vspChecks).toBeTruthy();
+        expect(results.softwareProductValidation.vspTestsMap).toBeTruthy();
+        expect(
+            results.softwareProductValidation.certificationChecked
+        ).toBeTruthy();
+        expect(
+            results.softwareProductValidation.complianceChecked
+        ).toBeTruthy();
+    });
+
+    it('SoftwareProductValidationInputView render test', () => {
+        const complianceChecked = VSPComplianceCheckedFactory.build();
+        const certificationChecked = VSPCertificationCheckedFactory.build();
+        const vspTestsMap = VSPTestsMapFactory.build();
+        const vspChecksList = VSPChecksFactory.build();
+        const testsRequest = VSPTestsRequestFactory.build();
+        const generalInfo = VSPGeneralInfoFactory.build();
+
+        const version = {
+            name: 1
+        };
+        const softwareProductId = '1234';
+        const status = 'draft';
+
+        var obj = {
+            version: version,
+            softwareProductId: softwareProductId,
+            status: status,
+            softwareProductValidation: {
+                complianceChecked: complianceChecked.complianceChecked,
+                certificationChecked: certificationChecked.certificationChecked,
+                vspTestsMap: vspTestsMap.vspTestsMap,
+                vspChecks: vspChecksList,
+                testsRequest: testsRequest.testsRequest,
+                generalInfo: generalInfo.generalInfo
+            }
+        };
+
+        let vspValidationInputView = TestUtils.renderIntoDocument(
+            <VspValidationInputsView {...obj} />
+        );
+        expect(vspValidationInputView).toBeTruthy();
+    });
+});
diff --git a/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationView.test.js b/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationView.test.js
new file mode 100644 (file)
index 0000000..640f9f6
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright © 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { Provider } from 'react-redux';
+import { storeCreator } from 'sdc-app/AppStore.js';
+
+import { mapStateToProps } from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js';
+import { mapActionsToProps } from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js';
+import SoftwareProductValidationView from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx';
+import { VSPComplianceCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPCertificationCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPChecksFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { VSPTestsMapFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js';
+import { tabsMapping } from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationConstants.js';
+import TestUtils from 'react-dom/test-utils';
+//import { scryRenderedDOMComponentsWithTestId } from 'test-utils/Util.js';
+
+describe('SoftwareProductValidation Mapper and View Classes', () => {
+    it('mapStateToProps mapper exists', () => {
+        expect(mapStateToProps).toBeTruthy();
+    });
+
+    it('mapActionsToProps mapper exists', () => {
+        expect(mapActionsToProps).toBeTruthy();
+    });
+
+    it('mapStateToProps data test', () => {
+        const vspChecksList = VSPChecksFactory.build();
+        const vspTestsMap = VSPTestsMapFactory.build();
+        const certificationChecked = VSPCertificationCheckedFactory.build();
+        const complianceChecked = VSPComplianceCheckedFactory.build();
+
+        var obj = {
+            softwareProduct: {
+                softwareProductValidation: {
+                    vspChecks: vspChecksList,
+                    vspTestsMap: vspTestsMap.vspTestsMap,
+                    certificationChecked: certificationChecked.certificationChecked,
+                    complianceChecked: complianceChecked.complianceChecked,
+                    activeTab: tabsMapping.SETUP
+                }
+            }
+        };
+        var results = mapStateToProps(obj);
+        expect(results.softwareProductValidation.vspChecks).toBeTruthy();
+        expect(results.softwareProductValidation.vspTestsMap).toBeTruthy();
+        expect(
+            results.softwareProductValidation.certificationChecked
+        ).toBeTruthy();
+        expect(
+            results.softwareProductValidation.complianceChecked
+        ).toBeTruthy();
+        expect(results.softwareProductValidation.activeTab).toBeTruthy();
+    });
+
+    it('SoftwareProductValidationView render test', () => {
+        const vspChecksList = VSPChecksFactory.build();
+        const vspTestsMap = VSPTestsMapFactory.build();
+        const certificationChecked = VSPCertificationCheckedFactory.build();
+        const complianceChecked = VSPComplianceCheckedFactory.build();
+        let dummyFunc = () => {};
+        const version = {
+            name: 1
+        };
+        const softwareProductId = '1234';
+        const status = 'draft';
+        var obj = {
+            version: version,
+            softwareProductId: softwareProductId,
+            status: status,
+            softwareProductValidation: {
+                vspChecks: vspChecksList,
+                vspTestsMap: vspTestsMap,
+                certificationChecked: certificationChecked.certificationChecked,
+                complianceChecked: complianceChecked.complianceChecked,
+                activeTab: tabsMapping.SETUP
+            }
+        };
+        const store = storeCreator();
+        let softwareProductValidationView = TestUtils.renderIntoDocument(
+            <Provider store={store}>
+                <SoftwareProductValidationView
+                    {...obj}
+                    onErrorThrown={dummyFunc}
+                    onTestSubmit={dummyFunc}
+                    setVspTestsMap={dummyFunc}
+                    setActiveTab={dummyFunc}
+                    setComplianceChecked={dummyFunc}
+                    setCertificationChecked={dummyFunc}
+                />
+            </Provider>
+        );
+
+        expect(softwareProductValidationView).toBeTruthy();
+
+        // let goToInput = scryRenderedDOMComponentsWithTestId(
+        //     softwareProductValidationView,
+        //     'go-to-inputs'
+        // );
+        // expect(goToInput).toBeTruthy();
+        // TestUtils.Simulate.click(goToInput[0]);
+        // let goToInput = TestUtils.findRenderedDOMComponentWithClass(
+        //     softwareProductValidationView,
+        //     'go-to-inputs-btn'
+        // );
+        // TestUtils.Simulate.click(goToInput);
+    });
+});
diff --git a/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsView.test.js b/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsView.test.js
new file mode 100644 (file)
index 0000000..b2cc2c0
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright © 2019 Vodafone Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 { mapStateToProps } from 'sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js';
+import SoftwareProductValidationResultsView from 'sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsView.jsx';
+import { VSPTestResultsSuccessFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js';
+import { VSPTestResultsFailureFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js';
+import TestUtils from 'react-dom/test-utils';
+
+describe('SoftwareProductValidationResults Mapper and View Classes', () => {
+    it('mapStateToProps mapper exists', () => {
+        expect(mapStateToProps).toBeTruthy();
+    });
+
+    it('mapStateToProps fail data test', () => {
+        const vspTestResults = VSPTestResultsFailureFactory.build();
+
+        var obj = {
+            softwareProduct: {
+                softwareProductValidation: {
+                    vspTestResults: vspTestResults.vspTestResults
+                }
+            }
+        };
+        var results = mapStateToProps(obj);
+        expect(results.softwareProductValidation.vspTestResults).toBeTruthy();
+    });
+
+    it('mapStateToProps success data test', () => {
+        const vspTestResults = VSPTestResultsSuccessFactory.build();
+
+        var obj = {
+            softwareProduct: {
+                softwareProductValidation: {
+                    vspTestResults: vspTestResults.vspTestResults
+                }
+            }
+        };
+        var results = mapStateToProps(obj);
+        expect(results.softwareProductValidation.vspTestResults).toBeTruthy();
+    });
+
+    it('SoftwareProductValidationResultsView test fail render test', () => {
+        const vspTestResults = VSPTestResultsFailureFactory.build();
+
+        const version = {
+            name: 1
+        };
+        const softwareProductId = '1234';
+        var obj = {
+            softwareProductId: softwareProductId,
+            version: version,
+            softwareProductValidation: {
+                vspTestResults: vspTestResults.vspTestResults
+            }
+        };
+        let vspValidationResultsView = TestUtils.renderIntoDocument(
+            <SoftwareProductValidationResultsView {...obj} />
+        );
+        expect(vspValidationResultsView).toBeTruthy();
+    });
+
+    it('SoftwareProductValidationResultsView test success render test', () => {
+        const vspTestResults = VSPTestResultsSuccessFactory.build();
+
+        let version = {
+            name: 1
+        };
+        const softwareProductId = '1234';
+        var obj = {
+            softwareProductId: softwareProductId,
+            version: version,
+            softwareProductValidation: {
+                vspTestResults: vspTestResults.vspTestResults
+            }
+        };
+        let vspValidationResultsView = TestUtils.renderIntoDocument(
+            <SoftwareProductValidationResultsView {...obj} />
+        );
+        expect(vspValidationResultsView).toBeTruthy();
+    });
+});
index db952e4..2e8731e 100644 (file)
@@ -92,7 +92,8 @@ module.exports = (env, argv) => {
                         ),
                         path.join(__dirname, 'node_modules/react-datepicker/'),
                         path.join(__dirname, 'node_modules/react-select/'),
-                        path.join(__dirname, 'node_modules/sdc-ui/')
+                        path.join(__dirname, 'node_modules/sdc-ui/'),
+                        path.join(__dirname, 'node_modules/react-checkbox-tree/')
                     ]
                 },
                 {