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;
+ }
+};