Refresh option in validation result page

Issue-ID: SDC-2585
Co-authored-by: nikhil.soni@vodafone.com
Signed-off-by: atulpurohit <atul.purohit1@vodafone.com>
Change-Id: I78f1385d219837c300cb33aff82b7459f137babb
Signed-off-by: atulpurohit <atul.purohit1@vodafone.com>
diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
index 754c112..688806c 100644
--- a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js
@@ -49,6 +49,8 @@
 import { notificationActions } from 'nfvo-components/notification/NotificationsConstants.js';
 import i18n from 'nfvo-utils/i18n/i18n.js';
 import SoftwareProductValidationActionHelper from './softwareProduct/validation/SoftwareProductValidationActionHelper.js';
+import SoftwareProductValidationResultsViewActionHelper from './softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.js';
+
 import { actionTypes as modalActionTypes } from 'nfvo-components/modal/GlobalModalConstants.js';
 
 function setCurrentScreen(dispatch, screen, props = {}) {
@@ -446,11 +448,26 @@
         dispatch,
         { softwareProductId, version, status }
     ) {
-        setCurrentScreen(
-            dispatch,
-            enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
-            { softwareProductId, version, status }
-        );
+        SoftwareProductValidationResultsViewActionHelper.fetchVspChecks(
+            dispatch
+        )
+            .then(() => {
+                setCurrentScreen(
+                    dispatch,
+                    enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
+                    { softwareProductId, version, status }
+                );
+            })
+            .catch(error => {
+                dispatch({
+                    type: modalActionTypes.GLOBAL_MODAL_ERROR,
+                    data: {
+                        title: 'ERROR',
+                        msg: error.responseJSON.message,
+                        cancelButtonText: i18n('OK')
+                    }
+                });
+            });
     },
 
     navigateToSoftwareProductDependencies(
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
index 7b8c426..dcec5c6 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/SoftwareProductReducer.js
@@ -46,6 +46,7 @@
 import SoftwareProductComponentsComputeFlavorReducer from './components/compute/computeComponents/computeFlavor/ComputeFlavorReducer.js';
 import { createPlainDataReducer } from 'sdc-app/common/reducers/PlainDataReducer.js';
 import SoftwareProductDependenciesReducer from './dependencies/SoftwareProductDependenciesReducer.js';
+import SoftwareProductValidationResultsViewReducer from './validationResults/SoftwareProductValidationResultsViewReducer.js';
 import {
     createJSONSchemaReducer,
     createComposedJSONSchemaReducer
@@ -78,6 +79,9 @@
     softwareProductValidation: createPlainDataReducer(
         SoftwareProductValidationReducer
     ),
+    softwareProductValidationResult: createPlainDataReducer(
+        SoftwareProductValidationResultsViewReducer
+    ),
     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
index a6237e8..27d9b5e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js
@@ -30,14 +30,21 @@
             SoftwareProductValidationActionHelper.onErrorThrown(dispatch, msg);
         },
 
-        onTestSubmit: (softwareProductId, version, status, tests) => {
+        onTestSubmit: (
+            softwareProductId,
+            version,
+            status,
+            tests,
+            requestId
+        ) => {
             SoftwareProductValidationActionHelper.navigateToSoftwareProductValidationResults(
                 dispatch,
                 {
                     softwareProductId,
                     version,
                     status,
-                    tests
+                    tests,
+                    requestId
                 }
             );
         },
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js
index 1ebb94b..fc6de3e 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationActionHelper.js
@@ -15,18 +15,40 @@
  */
 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) {
+function createCertificationFormData(tests) {
+    var formData = new FormData();
+    var testData = [];
+    for (var test of tests) {
+        if (test.files) {
+            for (var file of test.files) {
+                formData.append('files', file.file, file.name);
+            }
+        }
+        delete test.files;
+        testData.push(test);
+    }
+    formData.append('testdata', JSON.stringify(testData));
+
+    return formData;
+}
+function postVSPCertificationChecks(
+    tests,
+    version,
+    softwareProductId,
+    requestId
+) {
     const restPrefix = Configuration.get('restPrefix');
+    var id = version.id;
+    var formData = createCertificationFormData(tests);
     return RestAPIUtil.post(
-        `${restPrefix}/v1.0/externaltesting/executions`,
-        getValue(tests)
+        `${restPrefix}/v1.0/externaltesting/executions?vspId=${softwareProductId}&vspVersionId=${id}&requestId=${requestId}`,
+        formData
     );
 }
 
@@ -35,41 +57,59 @@
     return RestAPIUtil.fetch(`${restPrefix}/v1.0/externaltesting/testcasetree`);
 }
 
+function extractEndPoint(tests) {
+    return [...new Set(tests.map(test => test.endpoint))];
+}
 const SoftwareProductValidationActionHelper = {
     navigateToSoftwareProductValidationResults(
         dispatch,
-        { softwareProductId, version, status, tests }
+        { softwareProductId, version, status, tests, requestId }
     ) {
-        postVSPCertificationChecks(tests)
-            .then(response => {
-                dispatch({
-                    type: actionTypes.POST_VSP_TESTS,
-                    vspTestResults: response
+        return new Promise((resolve, reject) => {
+            postVSPCertificationChecks(
+                tests,
+                version,
+                softwareProductId,
+                requestId
+            )
+                .then(response => {
+                    var testResultKeys = {};
+                    testResultKeys.endPoints = extractEndPoint(tests);
+                    testResultKeys.requestId = requestId;
+                    dispatch({
+                        type: actionTypes.POST_VSP_TESTS,
+                        vspTestResults: response,
+                        testResultKeys: testResultKeys
+                    });
+                    ScreensHelper.loadScreen(dispatch, {
+                        screen:
+                            enums.SCREEN.SOFTWARE_PRODUCT_VALIDATION_RESULTS,
+                        screenType: screenTypes.SOFTWARE_PRODUCT,
+                        props: {
+                            softwareProductId,
+                            version,
+                            status
+                        }
+                    });
+                    resolve(response);
+                })
+                .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')
+                        }
+                    });
+                    reject(error);
                 });
-                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) {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationReducer.js
index 4513e23..4a7f257 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationReducer.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationReducer.js
@@ -20,7 +20,8 @@
         case actionTypes.POST_VSP_TESTS:
             return {
                 ...state,
-                vspTestResults: action.vspTestResults
+                vspTestResults: action.vspTestResults,
+                testResultKeys: action.testResultKeys
             };
         case actionTypes.FETCH_VSP_CHECKS:
             return {
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx
index fac6961..36cc7c7 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationView.jsx
@@ -15,7 +15,7 @@
  */
 import React, { Component } from 'react';
 import PropTypes from 'prop-types';
-
+import Configuration from 'sdc-app/config/Configuration.js';
 import i18n from 'nfvo-utils/i18n/i18n.js';
 import { Button } from 'onap-ui-react';
 import { Tab, Tabs } from 'onap-ui-react';
@@ -74,7 +74,9 @@
     buildChildElements(setItem, testScenario) {
         let parentElement = {};
         parentElement.value = setItem.name;
-        parentElement.label = setItem.description;
+        parentElement.label = setItem.description
+            ? setItem.description
+            : setItem.name;
         parentElement.children = [];
         if (setItem.children !== undefined) {
             setItem.children.forEach(element => {
@@ -89,11 +91,13 @@
         }
         if (setItem.tests !== undefined) {
             setItem.tests.forEach(element => {
-                parentElement.children.push({
-                    value: element.testCaseName,
-                    label: element.description
-                });
-                this.setMapAndGeneralData(element, testScenario);
+                if (element.inputs) {
+                    parentElement.children.push({
+                        value: element.testCaseName,
+                        label: element.testCaseName
+                    });
+                    this.setMapAndGeneralData(element, testScenario);
+                }
             });
         }
         return parentElement;
@@ -115,6 +119,8 @@
                 parentNode.children.push({
                     value: element.testCaseName,
                     label: element.description
+                        ? element.description
+                        : element.testCaseName
                 });
                 this.setMapAndGeneralData(element, scenario);
             });
@@ -129,10 +135,11 @@
         let certificationList = [];
         let { setVspTestsMap } = this.props;
         if (Object.keys(res).length !== 0 && res.children) {
+            let allTestScenario = Configuration.get('allTestScenario');
             res.children.forEach(element => {
                 if (element.name === 'certification') {
                     certificationData = element;
-                } else if (element.name === 'compliance') {
+                } else if (element.name === allTestScenario) {
                     complianceData = element;
                 }
             });
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
index 8888c92..cda3fe2 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputsView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/inputs/VspValidationInputsView.jsx
@@ -15,7 +15,7 @@
  */
 import React, { Component } from 'react';
 import PropTypes from 'prop-types';
-
+import UUID from 'uuid-js';
 import i18n from 'nfvo-utils/i18n/i18n.js';
 import { Button } from 'onap-ui-react';
 import GridSection from 'nfvo-components/grid/GridSection.jsx';
@@ -35,23 +35,51 @@
 
     changeInputs(e, check, parameterName) {
         let { testsRequest, generalInfo, setTestsRequest } = this.props;
-        testsRequest[check].parameters[parameterName] = e;
+        if (e instanceof File) {
+            var timestamp = new Date().getTime();
+            var fileExtension = (
+                e.name.match(/[^\\\/]\.([^.\\\/]+)$/) || [null]
+            ).pop();
+            var fileName = fileExtension
+                ? timestamp + '.' + fileExtension
+                : timestamp;
+            testsRequest[check].parameters[parameterName] =
+                'file://' + fileName;
+
+            testsRequest[check].files = testsRequest[check].files
+                ? testsRequest[check].files
+                : [];
+            testsRequest[check].files.push({ file: e, name: fileName });
+        } else {
+            testsRequest[check].parameters[parameterName] = e;
+        }
+
         generalInfo[check][parameterName] = { isValid: true, errorText: '' };
         setTestsRequest(testsRequest, generalInfo);
     }
 
-    renderInputs(check) {
+    renderInputs(check, indexKey) {
         let { vspTestsMap, testsRequest, generalInfo } = this.props;
         return (
-            <div className="div-clear-both">
+            <div key={indexKey} className="div-clear-both">
                 <GridSection
                     title={i18n('{title} Inputs :', {
-                        title: vspTestsMap[check].title
+                        title: vspTestsMap[check].title.split(/\r?\n/)[0]
                     })}>
                     {vspTestsMap[check].parameters.map((parameter, index) => {
+                        parameter.metadata = parameter.metadata
+                            ? parameter.metadata
+                            : {};
                         if (
-                            parameter.type === 'text' &&
-                            !parameter.metadata.hidden
+                            !this.props.filterField(parameter) ||
+                            parameter.metadata.hidden
+                        ) {
+                            return;
+                        }
+                        if (
+                            parameter.type === 'text' ||
+                            parameter.type === 'string' ||
+                            parameter.type === 'json'
                         ) {
                             return (
                                 <GridItem key={index}>
@@ -112,6 +140,31 @@
                                     </Input>
                                 </GridItem>
                             );
+                        } else if (parameter.type === 'binary') {
+                            return (
+                                <GridItem key={index}>
+                                    <Input
+                                        label={parameter.description}
+                                        type="file"
+                                        isRequired={!parameter.isOptional}
+                                        isValid={
+                                            generalInfo[check][parameter.name]
+                                                .isValid
+                                        }
+                                        errorText={
+                                            generalInfo[check][parameter.name]
+                                                .errorText
+                                        }
+                                        onChange={e => {
+                                            this.changeInputs(
+                                                e.target ? e.target.value : e,
+                                                check,
+                                                parameter.name
+                                            );
+                                        }}
+                                    />
+                                </GridItem>
+                            );
                         }
                     })}
                 </GridSection>
@@ -127,18 +180,18 @@
         } = this.props;
         return (
             <div>
-                {complianceChecked.map(complianceCheck => {
+                {complianceChecked.map((complianceCheck, index) => {
                     if (vspTestsMap[complianceCheck].parameters.length === 0) {
                         return <div />;
                     } else {
-                        return this.renderInputs(complianceCheck);
+                        return this.renderInputs(complianceCheck, index);
                     }
                 })}
-                {certificationChecked.map(certificateCheck => {
+                {certificationChecked.map((certificateCheck, index) => {
                     if (vspTestsMap[certificateCheck].parameters.length === 0) {
                         return <div />;
                     } else {
-                        return this.renderInputs(certificateCheck);
+                        return this.renderInputs(certificateCheck, index);
                     }
                 })}
             </div>
@@ -159,7 +212,19 @@
     shouldComponentUpdate() {
         return true;
     }
-
+    filterField(parameter) {
+        if (
+            parameter.name === 'host-username' ||
+            parameter.name === 'vsp' ||
+            parameter.name === 'vsp-zip' ||
+            parameter.name === 'host-password' ||
+            parameter.name === 'host-url'
+        ) {
+            return false;
+        } else {
+            return true;
+        }
+    }
     validateInputs() {
         let areInputsValid = true;
         let { softwareProductValidation, setGeneralInfo } = this.props;
@@ -178,43 +243,57 @@
                     );
                     let isParameterValid = true;
                     let errorText = '';
-                    if (
-                        parameter.type === 'text' &&
-                        parameter.metadata.choices
-                    ) {
+                    if (!this.filterField(parameter)) {
+                        // Not required any action
+                    } else {
                         if (
-                            !parameter.isOptional &&
-                            !requestParameters[parameterName]
+                            (parameter.type === 'text' ||
+                                parameter.type === 'string') &&
+                            parameter.metadata.choices
                         ) {
-                            isParameterValid = false;
-                            errorText = i18n('Field is required');
-                        }
-                    } else if (parameter.type === 'text') {
-                        if (
-                            !parameter.isOptional &&
-                            !requestParameters[parameterName]
-                        ) {
-                            isParameterValid = false;
-                            errorText = i18n('Field is required');
+                            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)
+                            parameter.type === 'text' ||
+                            parameter.type === 'string' ||
+                            parameter.type === 'json' ||
+                            parameter.type === 'binary'
                         ) {
-                            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
-                                }
-                            );
+                            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][
@@ -244,13 +323,22 @@
         } = this.props;
 
         Object.keys(softwareProductValidation.testsRequest).forEach(key => {
-            tests.push(softwareProductValidation.testsRequest[key]);
+            var testReq = softwareProductValidation.testsRequest[key];
+            this.removeParameterFromTest(testReq);
+            tests.push(testReq);
         });
         if (this.validateInputs()) {
-            onTestSubmit(softwareProductId, version, status, tests);
+            var requestId = UUID.create()
+                .toString()
+                .split('-')[0];
+            onTestSubmit(softwareProductId, version, status, tests, requestId);
         }
     }
-
+    removeParameterFromTest(testReq) {
+        delete testReq.parameters['host-username'];
+        delete testReq.parameters['host-password'];
+        delete testReq.parameters['host-url'];
+    }
     prepareDataForVspInputs() {
         let { setTestsRequest } = this.props;
         let {
@@ -279,7 +367,10 @@
                     isValid={true}
                     onSubmit={() => this.performVSPTests()}
                     isReadOnlyMode={false}>
-                    <VspInputs {...this.prepareDataForVspInputs()} />
+                    <VspInputs
+                        {...this.prepareDataForVspInputs()}
+                        filterField={this.filterField}
+                    />
                     <Button
                         size="default"
                         data-test-id="proceed-to-validation-results-btn"
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
index 012d50a..d1952bf 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetupView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validation/setup/VspValidationSetupView.jsx
@@ -206,10 +206,14 @@
         let { complianceNodes, setComplianceChecked } = this.props;
         return (
             <div className="validation-setup-checkbox-tree-section">
-                <GridSection title={i18n('Compliance Checks')}>
+                <GridSection title={i18n('Available Tests')}>
                     <GridItem colSpan={2}>
                         <div className="validation-view-title">
-                            {complianceNodes[0] ? complianceNodes[0].value : ''}
+                            {complianceNodes[0] && complianceNodes[0].value ? (
+                                complianceNodes[0].value
+                            ) : (
+                                <br />
+                            )}
                         </div>
                         <div
                             className="validation-setup-available-tests-section"
@@ -237,9 +241,7 @@
                                 />
                             )}
                             {complianceNodes.length === 0 && (
-                                <div>
-                                    {i18n('No Compliance Checks are Available')}
-                                </div>
+                                <div>{i18n('No Tests are Available')}</div>
                             )}
                         </div>
                     </GridItem>
@@ -247,7 +249,7 @@
                         {complianceNodes.length > 0 && (
                             <div>
                                 <div className="validation-view-title">
-                                    {i18n('Selected Compliance Tests')}
+                                    {i18n('Selected Tests')}
                                 </div>
                                 <div>
                                     <select
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js
index dffade7..ed88ddd 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js
@@ -15,14 +15,32 @@
  */
 import { connect } from 'react-redux';
 import SoftwareProductValidationResultsView from './SoftwareProductValidationResultsView.jsx';
+import SoftwareProductValidationResultsViewActionHelper from './SoftwareProductValidationResultsViewActionHelper.js';
 
 export const mapStateToProps = ({ softwareProduct }) => {
+    let { softwareProductValidationResult } = softwareProduct;
     let { softwareProductValidation } = softwareProduct;
     return {
+        softwareProductValidationResult,
         softwareProductValidation
     };
 };
-
-export default connect(mapStateToProps, null, null, {
+export const mapActionsToProps = dispatch => {
+    return {
+        refreshValidationResults: (requestId, endPoints) => {
+            return SoftwareProductValidationResultsViewActionHelper.refreshValidationResults(
+                dispatch,
+                { requestId, endPoints }
+            );
+        },
+        updateDisplayTestResultData: testResultToDisplay => {
+            return SoftwareProductValidationResultsViewActionHelper.updateDisplayTestResultData(
+                dispatch,
+                { testResultToDisplay }
+            );
+        }
+    };
+};
+export default connect(mapStateToProps, mapActionsToProps, 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
index 2c2cccd..c5da4f6 100644
--- a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsView.jsx
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsView.jsx
@@ -20,64 +20,48 @@
 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
+        softwareProductValidation: PropTypes.object,
+        refreshValidationResults: PropTypes.func
     };
 
     constructor(props) {
         super(props);
         this.state = {
             vspId: this.props.softwareProductId,
-            versionNumber: this.props.version.name
+            versionNumber: this.props.version.name,
+            refreshValidationResults: this.props.refreshValidationResults,
+            vspTestResults: this.props.vspTestResults,
+            flatTestsMap: {},
+            generalInfo: {}
         };
     }
+    componentDidMount() {
+        this.configBasicTestData();
+    }
+    componentDidUpdate() {
+        this.updateTestResultToDisplay();
+    }
+
+    prepareDataForCheckboxes(children, ftm) {
+        for (var val of children) {
+            if (val.children) {
+                this.prepareDataForCheckboxes(val.children, ftm);
+            } else if (val.tests) {
+                for (var test of val.tests) {
+                    ftm[test.testCaseName] = test.description;
+                }
+            }
+        }
+        return ftm;
+    }
 
     getTitle(result) {
-        let { vspTestsMap } = this.props.softwareProductValidation;
+        let { flatTestsMap: vspTestsMap } = this.state;
         let title = vspTestsMap[result.testCaseName]
-            ? vspTestsMap[result.testCaseName].title
+            ? vspTestsMap[result.testCaseName].split(/\r?\n/)[0]
             : i18n('Unknown');
         return i18n(
             'Scenario: {scenario} | Title: {title} | Test Case: {testCaseName} | Status: {status}',
@@ -90,19 +74,36 @@
         );
     }
 
-    renderJSON(result) {
+    renderJSON(result, indexKey) {
+        if (result.status === 'in-progress') {
+            return this.renderInprogress(i18n('Test is In-progress'), indexKey);
+        } else {
+            return (
+                <li key={indexKey} type="none">
+                    <textarea
+                        disabled={true}
+                        className="validation-results-test-result-json"
+                        value={JSON.stringify(result, null, 2)}
+                    />
+                </li>
+            );
+        }
+    }
+    renderInprogress(result, indexKey) {
         return (
-            <li type="none">
-                <textarea
-                    disabled={true}
-                    className="validation-results-test-result-json"
-                    value={JSON.stringify(result, null, 2)}
+            <li key={indexKey} type="none">
+                <SVGIcon
+                    color="warning"
+                    name="exclamationTriangleLine"
+                    labelPosition="right"
                 />
+                <span className="validation-results-test-result-label">
+                    {result}
+                </span>
             </li>
         );
     }
-
-    renderError(result) {
+    renderError(result, indexKey) {
         if (Array.isArray(result)) {
             return result.map((parameter, index) => {
                 return (
@@ -120,95 +121,60 @@
                     </li>
                 );
             });
-        } else {
+        } else if (
+            typeof result === 'string' ||
+            result.hasOwnProperty('code') ||
+            result.hasOwnProperty('advice') ||
+            result.hasOwnProperty('message') ||
+            result.hasOwnProperty('error')
+        ) {
+            result =
+                result instanceof Object && result.error instanceof Object
+                    ? result.error
+                    : result;
             return (
-                <li type="none">
+                <li key={indexKey} type="none">
                     <SVGIcon
                         color="negative"
                         name="errorCircle"
                         labelPosition="right"
                     />
                     <span className="validation-results-test-result-label">
-                        {(result.code || '') +
-                            ' | ' +
-                            (result.advice || result.message)}
+                        {typeof result === 'string'
+                            ? result
+                            : (result.code || '') +
+                              ' | ' +
+                              (result.advice || result.message || result.error)}
                     </span>
                 </li>
             );
-        }
-    }
-
-    renderResults(result) {
-        if (typeof result === 'string' || result instanceof String) {
+        } else {
             return (
-                <div>
-                    <SVGIcon
-                        color="warning"
-                        name="errorCircle"
-                        labelPosition="right"
-                    />
-                    <span className="validation-results-test-result-label">
-                        {result}
-                    </span>
-                </div>
+                <Accordion key={indexKey} defaultExpanded>
+                    {this.renderJSON(result)}
+                </Accordion>
             );
         }
-        return Object.keys(result).map((key, index) => {
-            let title = unCamelCasedString(key);
-            if (
-                typeof result[key] === 'string' ||
-                result[key] instanceof String
-            ) {
-                return (
-                    <Accordion
-                        defaultExpanded
-                        dataTestId={title}
-                        title={title}
-                        key={index}>
-                        {this.renderString(result[key])}
-                    </Accordion>
-                );
-            } else if (Array.isArray(result[key])) {
-                if (result[key].length > 0) {
-                    return (
-                        <Accordion
-                            defaultExpanded
-                            dataTestId={title}
-                            title={title}
-                            key={index}>
-                            <TestResultComponent tests={result[key]} />
-                        </Accordion>
-                    );
-                } else {
-                    return (
-                        <Accordion
-                            defaultExpanded
-                            dataTestId={title}
-                            title={title}
-                            key={index}>
-                            {i18n('{title} results are not available', {
-                                title: title
-                            })}
-                        </Accordion>
-                    );
-                }
-            } else {
-                return (
-                    <Accordion
-                        defaultExpanded
-                        dataTestId={title}
-                        title={title}
-                        key={index}>
-                        {this.renderJSON(result[key])}
-                    </Accordion>
-                );
-            }
-        });
     }
 
-    renderString(result) {
+    renderResults(result, indexKey) {
         return (
-            <li type="none">
+            <li key={indexKey} type="none">
+                <SVGIcon
+                    color="positive"
+                    name="checkCircle"
+                    labelPosition="right"
+                />
+                <span className="validation-results-test-result-label">
+                    {result}
+                </span>
+            </li>
+        );
+    }
+
+    renderString(result, indexKey) {
+        return (
+            <li key={indexKey} type="none">
                 <textarea
                     type="textarea"
                     disabled={true}
@@ -219,92 +185,191 @@
         );
     }
 
-    buildSubAccordions(result) {
+    buildSubAccordions(result, indexKey) {
         let results = result.results;
 
         if (!results) {
             return (
                 <Accordion
+                    key={indexKey}
                     defaultExpanded
                     dataTestId="vsp-test-no-results"
                     title={this.getTitle(result)}>
-                    {this.renderJSON(result)}
+                    {this.renderJSON(result, indexKey)}
                 </Accordion>
             );
         } else if (typeof results === 'string' || results instanceof String) {
             return (
                 <Accordion
+                    key={indexKey}
                     defaultExpanded
                     dataTestId="vsp-test-string-results"
                     title={this.getTitle(result)}>
-                    {this.renderString(results)}
+                    {this.renderString(results, indexKey)}
                 </Accordion>
             );
         } else {
             return (
                 <Accordion
+                    key={indexKey}
                     defaultExpanded
                     dataTestId="vsp-test-object-results"
                     title={this.getTitle(result)}>
                     {Object.keys(results).length === 0
                         ? this.renderString(
-                              i18n('{title} results are not available', {
-                                  title: 'Test'
-                              })
+                              i18n(
+                                  '{title} results are not available',
+                                  {
+                                      title: 'Test'
+                                  },
+                                  indexKey
+                              )
                           )
-                        : Object.keys(results).map(key => {
-                              if (key === 'errors' || key === 'error') {
-                                  return this.renderError(results[key]);
-                              } else if (key === 'testResults') {
-                                  return this.renderResults(results[key]);
-                              } else {
-                                  let title = unCamelCasedString(key);
-                                  if (results[key] instanceof Object) {
-                                      return (
-                                          <Accordion
-                                              defaultExpanded
-                                              dataTestId={title}
-                                              title={title}>
-                                              {this.renderJSON(results[key])}
-                                          </Accordion>
-                                      );
-                                  } else {
-                                      return (
-                                          <Accordion
-                                              defaultExpanded
-                                              dataTestId={title}
-                                              title={title}>
-                                              {this.renderString(results[key])}
-                                          </Accordion>
-                                      );
-                                  }
-                              }
-                          })}
+                        : Array.isArray(results)
+                          ? Object.keys(results).map((key, indexKey) => {
+                                if (Object.keys(results[key]).length === 0) {
+                                    return this.renderResults(
+                                        result.testCaseName +
+                                            ' ' +
+                                            i18n('has passed all checks'),
+                                        indexKey
+                                    );
+                                } else {
+                                    return this.renderError(
+                                        results[key],
+                                        indexKey
+                                    );
+                                }
+                            })
+                          : this.renderError(results, indexKey)}
                 </Accordion>
             );
         }
     }
-
+    refreshValidationResult(thisObj) {
+        let { refreshValidationResults } = thisObj.props;
+        var testResultKey = this.props.softwareProductValidationResult
+            .testResultKeys[this.state.vspId + this.state.versionNumber];
+        refreshValidationResults(
+            testResultKey.requestId,
+            testResultKey.endPoints
+        );
+        delete this.props.softwareProductValidation.vspTestResults;
+    }
+    configBasicTestData() {
+        let {
+            softwareProductValidationResult,
+            softwareProductValidation
+        } = this.props;
+        if (
+            softwareProductValidationResult.vspChecks !== undefined &&
+            softwareProductValidationResult.vspChecks.children !== undefined
+        ) {
+            var ftm = this.prepareDataForCheckboxes(
+                this.props.softwareProductValidationResult.vspChecks.children,
+                {}
+            );
+            this.setState({
+                flatTestsMap: ftm
+            });
+        }
+        if (softwareProductValidation.testResultKeys) {
+            if (!this.props.softwareProductValidationResult.testResultKeys) {
+                this.props.softwareProductValidationResult.testResultKeys = {};
+            }
+            this.props.softwareProductValidationResult.testResultKeys[
+                this.state.vspId + this.state.versionNumber
+            ] =
+                softwareProductValidation.testResultKeys;
+            delete this.props.softwareProductValidation.testResultKeys;
+        }
+    }
+    updateTestResultToDisplay() {
+        if (this.props.softwareProductValidation.vspTestResults) {
+            let { updateDisplayTestResultData } = this.props;
+            var testResultToDisplay = this.props.softwareProductValidationResult
+                .testResultToDisplay;
+            testResultToDisplay = testResultToDisplay
+                ? testResultToDisplay
+                : {};
+            testResultToDisplay[
+                this.state.vspId + this.state.versionNumber
+            ] = this.props.softwareProductValidation.vspTestResults;
+            updateDisplayTestResultData(testResultToDisplay);
+            delete this.props.softwareProductValidation.vspTestResults;
+        } else if (this.props.softwareProductValidationResult.vspTestResults) {
+            let { updateDisplayTestResultData } = this.props;
+            var testResultToDisplay = this.props.softwareProductValidationResult
+                .testResultToDisplay
+                ? this.props.softwareProductValidationResult.testResultToDisplay
+                : {};
+            testResultToDisplay[
+                this.state.vspId + this.state.versionNumber
+            ] = this.props.softwareProductValidationResult.vspTestResults;
+            updateDisplayTestResultData(testResultToDisplay);
+            delete this.props.softwareProductValidationResult.vspTestResults;
+        }
+    }
     render() {
-        let results = this.props.softwareProductValidation.vspTestResults || [];
-        if (results.length > 0) {
+        let testResultToDisplay = this.props.softwareProductValidationResult
+            .testResultToDisplay;
+        let results = testResultToDisplay
+            ? testResultToDisplay[this.state.vspId + this.state.versionNumber]
+            : null;
+        if (!results) {
             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 title={i18n('Test Results')}>
+                    <h4>{i18n('No Test Performed')}</h4>
                 </GridSection>
             );
+        } else if (results.length > 0) {
+            return (
+                <div>
+                    <div
+                        onClick={() => this.refreshValidationResult(this)}
+                        data-test-id="vsp-validation-refresh-btn"
+                        className={'vcp-validation-refresh-btn'}>
+                        <SVGIcon
+                            label="Refresh"
+                            labelPosition="left"
+                            color=""
+                            iconClassName="vcp-validation-refresh-icon"
+                            name="versionControllerSync"
+                        />
+                    </div>
+                    <GridSection title={i18n('Test Results')}>
+                        <GridItem colSpan={10}>
+                            <Accordion
+                                defaultExpanded
+                                dataTestId="vsp-validation-test-result"
+                                title={i18n('Test Results')}>
+                                {results.map((row, index) =>
+                                    this.buildSubAccordions(row, index)
+                                )}
+                            </Accordion>
+                        </GridItem>
+                    </GridSection>
+                </div>
+            );
         } else {
             return (
-                <GridSection title={i18n('Validation Results')}>
-                    <h4>{i18n('No Validation Checks Performed')}</h4>
-                </GridSection>
+                <div>
+                    <div
+                        onClick={() => this.refreshValidationResult(this)}
+                        data-test-id="vsp-validation-refresh-btn"
+                        className={'vcp-validation-refresh-btn'}>
+                        <SVGIcon
+                            label="Refresh"
+                            labelPosition="left"
+                            color=""
+                            iconClassName="vcp-validation-refresh-icon"
+                            name="versionControllerSync"
+                        />
+                    </div>
+                    <GridSection title={i18n('Test Results')}>
+                        <h4>{i18n('No Test Result Available')}</h4>
+                    </GridSection>
+                </div>
             );
         }
     }
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.js
new file mode 100644
index 0000000..4da8b9b
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.js
@@ -0,0 +1,79 @@
+/**
+ * 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 { actionTypes } from './SoftwareProductValidationResultsViewConstants.js';
+
+function encodeResultQueryData(requestId, endPoints) {
+    const query = [];
+    query.push('requestId=' + requestId);
+    endPoints.forEach(endPoint => {
+        query.push('endPoint=' + encodeURIComponent(endPoint));
+    });
+
+    return query.join('&');
+}
+function fetchVspValidationResults(requestId, endPoints) {
+    const restPrefix = Configuration.get('restPrefix');
+    const requestQuery = encodeResultQueryData(requestId, endPoints);
+    return RestAPIUtil.fetch(
+        `${restPrefix}/v1.0/externaltesting/executions?${requestQuery}`
+    );
+}
+function fetchVspChecks() {
+    const restPrefix = Configuration.get('restPrefix');
+    return RestAPIUtil.fetch(`${restPrefix}/v1.0/externaltesting/testcasetree`);
+}
+const SoftwareProductValidationResultsViewActionHelper = {
+    refreshValidationResults(dispatch, { requestId, endPoints }) {
+        return new Promise((resolve, reject) => {
+            fetchVspValidationResults(requestId, endPoints)
+                .then(response => {
+                    dispatch({
+                        type: actionTypes.FETCH_VSP_RESULT,
+                        vspTestResults: response
+                    });
+                    resolve(response);
+                })
+                .catch(error => {
+                    reject(error);
+                });
+        });
+    },
+    fetchVspChecks(dispatch) {
+        return new Promise((resolve, reject) => {
+            fetchVspChecks()
+                .then(response => {
+                    dispatch({
+                        type: actionTypes.FETCH_VSP_CHECKS,
+                        vspChecks: response
+                    });
+                    resolve(response);
+                })
+                .catch(error => {
+                    reject(error);
+                });
+        });
+    },
+    updateDisplayTestResultData(dispatch, { testResultToDisplay }) {
+        dispatch({
+            type: actionTypes.UPDATE_DISPLAY_TEST_RESULT_DATA,
+            testResultToDisplay: testResultToDisplay
+        });
+    }
+};
+
+export default SoftwareProductValidationResultsViewActionHelper;
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewConstants.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewConstants.js
new file mode 100644
index 0000000..22fcb12
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewConstants.js
@@ -0,0 +1,25 @@
+/**
+ * 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 actionTypes = keyMirror(
+    {
+        FETCH_VSP_RESULT: null,
+        FETCH_VSP_CHECKS: null,
+        UPDATE_DISPLAY_TEST_RESULT_DATA: null
+    },
+    'SoftwareProductValidationResults'
+);
diff --git a/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewReducer.js b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewReducer.js
new file mode 100644
index 0000000..99bf68f
--- /dev/null
+++ b/openecomp-ui/src/sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewReducer.js
@@ -0,0 +1,27 @@
+import { actionTypes } from './SoftwareProductValidationResultsViewConstants.js';
+
+export default (state = {}, action) => {
+    switch (action.type) {
+        case actionTypes.FETCH_VSP_RESULT: {
+            return {
+                ...state,
+                vspTestResults: action.vspTestResults
+            };
+        }
+        case actionTypes.FETCH_VSP_CHECKS: {
+            return {
+                ...state,
+                vspChecks: action.vspChecks
+            };
+        }
+        case actionTypes.UPDATE_DISPLAY_TEST_RESULT_DATA: {
+            return {
+                ...state,
+                vspTestResults: null,
+                testResultToDisplay: action.testResultToDisplay
+            };
+        }
+        default:
+            return state;
+    }
+};