diff options
28 files changed, 1343 insertions, 542 deletions
diff --git a/openecomp-ui/resources/scss/modules/_softwareProductValidationPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductValidationPage.scss index 3f944057cd..2be9c8a022 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductValidationPage.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductValidationPage.scss @@ -77,4 +77,13 @@ .validation-setup-checkbox-tree-section label { margin-bottom: 0px; } + .validation-form-content .grid-col-1 { + flex-basis: 30%; + } + .form-group input[type=file] { + border: 1px solid $light-gray; + height: 30px; + padding-top: 3px; + width: 100% + } } diff --git a/openecomp-ui/resources/scss/modules/_softwareProductValidationResultsPage.scss b/openecomp-ui/resources/scss/modules/_softwareProductValidationResultsPage.scss index 303f1f041d..d8d55ab7d3 100644 --- a/openecomp-ui/resources/scss/modules/_softwareProductValidationResultsPage.scss +++ b/openecomp-ui/resources/scss/modules/_softwareProductValidationResultsPage.scss @@ -18,3 +18,21 @@ width: 900px; max-width: 900px; } +.vcp-validation-refresh-btn { + float: right; + border: 1px solid $dark-gray; + width: 98px; + height: 32px; + border-radius: 2px; + padding-top: 6px; + padding-left: 10px; + margin-left: 9px; + margin-right: 10px; + .__versionControllerSync { + height: 12px; + } + &:hover:not(.disabled) { + cursor: pointer; + background-color: $tlv-light-gray; +} +} diff --git a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx index 16a0abc5fd..3feb06da0e 100644 --- a/openecomp-ui/src/nfvo-components/input/validation/Input.jsx +++ b/openecomp-ui/src/nfvo-components/input/validation/Input.jsx @@ -105,7 +105,16 @@ class Input extends React.Component { data-test-id={this.props['data-test-id']} /> )} - + {type === 'file' && ( + <FormControl + bsClass={'form-control input-options-other'} + onChange={e => this.onChangeFile(e)} + disabled={isReadOnlyMode || Boolean(disabled)} + type={type} + data-test-id={this.props['data-test-id']} + inputRef={input => (this.input = input)} + /> + )} {type === 'textarea' && ( <FormControl className="form-control input-options-other" @@ -220,6 +229,11 @@ class Input extends React.Component { onChange(value); } + onChangeFile(e) { + let { onChange } = this.props; + onChange(e.target.files[0]); + } + onChangeCheckBox(e) { let { onChange } = this.props; let checked = e.target.checked; diff --git a/openecomp-ui/src/nfvo-utils/i18n/en.json b/openecomp-ui/src/nfvo-utils/i18n/en.json index f57b7fdd3c..5b2d09a6ad 100644 --- a/openecomp-ui/src/nfvo-utils/i18n/en.json +++ b/openecomp-ui/src/nfvo-utils/i18n/en.json @@ -645,15 +645,18 @@ "Certifications Query": "Certifications Query", "No Certifications Query are Available": "No Certifications Query are Available", "Selected Certifications Query": "Selected Certifications Query", - "Compliance Checks": "Compliance Checks", - "No Compliance Checks are Available": "No Compliance Checks are Available", - "Selected Compliance Tests": "Selected Compliance Tests", + "Available Tests": "Available Tests", + "No Tests are Available": "No Tests are Available", + "Selected Tests": "Selected Tests", "Value Should Be Minimum of {minLength} characters and a Maximum of {maxLength} characters": "Value Should Be Minimum of {minLength} characters and a Maximum of {maxLength} characters", "{title} Inputs :": "{title} Inputs :", "Scenario: {scenario} | Title: {title} | Test Case: {testCaseName} | Status: {status}": "Scenario: {scenario} | Title: {title} | Test Case: {testCaseName} | Status: {status}", "{title} results are not available": "{title} results are not available", "Test Results": "Test Results", - "No Validation Checks Performed": "No Validation Checks Performed", - "Unknown": "Unknown" + "No Test Performed": "No Test Performed", + "Unknown": "Unknown", + "No Test Result Available": "No Test Result Available", + "Test is In-progress": "Test is In-progress", + "has passed all checks": "has passed all checks" } diff --git a/openecomp-ui/src/sdc-app/config/config.json b/openecomp-ui/src/sdc-app/config/config.json index 784f19a1fc..c2c794024c 100644 --- a/openecomp-ui/src/sdc-app/config/config.json +++ b/openecomp-ui/src/sdc-app/config/config.json @@ -11,5 +11,6 @@ "defaultDebugWebsocketPort": "9000", "defaultWebsocketPath": "notification-api/ws/notificationHandler", "defaultNotificationsWorkerUpdateMillisecond": 10000, - "showBrowseVNF": true + "showBrowseVNF": true, + "allTestScenario": "onap-dublin" } diff --git a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js index 754c11206d..688806cf9a 100644 --- a/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js +++ b/openecomp-ui/src/sdc-app/onboarding/OnboardingActionHelper.js @@ -49,6 +49,8 @@ import FeaturesActionHelper from 'sdc-app/features/FeaturesActionHelper.js'; import { notificationActions } from 'nfvo-components/notification/NotificationsConstants.js'; import i18n from 'nfvo-utils/i18n/i18n.js'; import SoftwareProductValidationActionHelper from './softwareProduct/validation/SoftwareProductValidationActionHelper.js'; +import 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 @@ const OnboardingActionHelper = { 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 7b8c426964..dcec5c683f 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 SoftwareProductComponentsComputeFlavorListReducer from './components/comp 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 @@ export default combineReducers({ 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 a6237e878a..27d9b5ebf8 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 @@ export const mapActionsToProps = dispatch => { 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 1ebb94b77c..fc6de3e2eb 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 @@ function fetchVspChecks() { 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 - }); - 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') - } + 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); }); - }); + }); }, 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 4513e23205..4a7f257e73 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 @@ export default (state = {}, action) => { 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 fac69616bb..36cc7c7672 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 @@ class SoftwareProductValidation extends Component { 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 @@ class SoftwareProductValidation extends Component { } 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 @@ class SoftwareProductValidation extends Component { parentNode.children.push({ value: element.testCaseName, label: element.description + ? element.description + : element.testCaseName }); this.setMapAndGeneralData(element, scenario); }); @@ -129,10 +135,11 @@ class SoftwareProductValidation extends Component { 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 8888c92f6d..cda3fe2c92 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 @@ class VspInputs extends React.Component { 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 ( + !this.props.filterField(parameter) || + parameter.metadata.hidden + ) { + return; + } if ( - parameter.type === 'text' && - !parameter.metadata.hidden + parameter.type === 'text' || + parameter.type === 'string' || + parameter.type === 'json' ) { return ( <GridItem key={index}> @@ -112,6 +140,31 @@ class VspInputs extends React.Component { </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 @@ class VspInputs extends React.Component { } = 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 @@ class VspValidationInputs extends Component { 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 @@ class VspValidationInputs extends Component { ); let isParameterValid = true; let errorText = ''; - if ( - parameter.type === 'text' && - parameter.metadata.choices - ) { - if ( - !parameter.isOptional && - !requestParameters[parameterName] - ) { - isParameterValid = false; - errorText = i18n('Field is required'); - } - } else if (parameter.type === 'text') { + if (!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'); + 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 @@ class VspValidationInputs extends Component { } = 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 @@ class VspValidationInputs extends Component { 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 012d50ac93..d1952bf7f2 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 @@ class ComplianceTests extends React.Component { 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 @@ class ComplianceTests extends React.Component { /> )} {complianceNodes.length === 0 && ( - <div> - {i18n('No Compliance Checks are Available')} - </div> + <div>{i18n('No Tests are Available')}</div> )} </div> </GridItem> @@ -247,7 +249,7 @@ class ComplianceTests extends React.Component { {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 dffade7c9a..ed88dddc5a 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 2c2cccd711..c5da4f6ca1 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 { SVGIcon } from 'onap-ui-react'; 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 @@ class SoftwareProductValidationResultsView extends React.Component { ); } - 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 @@ class SoftwareProductValidationResultsView extends React.Component { </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 @@ class SoftwareProductValidationResultsView extends React.Component { ); } - 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 0000000000..4da8b9b30d --- /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 0000000000..22fcb12131 --- /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 0000000000..99bf68f723 --- /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; + } +}; diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js index c763e9d3e7..336c435b45 100644 --- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js +++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js @@ -18,7 +18,8 @@ import { Factory } from 'rosie'; export const VSPComplianceCheckedFactory = new Factory().attrs({ complianceChecked: [ 'compliance.compliancetests.sriov', - 'compliance.compliancetests.computeflavors' + 'compliance.compliancetests.computeflavors', + 'vnf-validation' ] }); @@ -73,6 +74,20 @@ export const VSPGeneralInfoFactory = new Factory().attrs({ isValid: true, errorText: '' } + }, + 'vnf-validation': { + 'vspId': { + isValid: true, + errorText: '' + }, + 'host-password': { + isValid: true, + errorText: '' + }, + 'vsp-csar': { + isValid: true, + errorText: '' + } } } }); @@ -112,10 +127,43 @@ export const VSPTestsRequestFactory = new Factory().attrs({ testCaseName: 'certification.certificationtests.certquery', testSuiteName: 'certificationtests', endpoint: 'repository' + }, + 'vnf-validation': { + parameters: { + 'vspId': 'abc', + 'host-password': '123', + 'vsp-csar': 'vsp.csar', + }, + testCaseName: 'vnf-validation', + testSuiteName: 'vnf-validation', + scenario: 'onap-dublin', + endpoint: 'vtp' } } }); +export const VSPTestRequestFactory = new Factory().attrs({ + vspTestRequest: [ + { + 'parameters': { + 'config-json': '/opt/oclip/conf/vnf-tosca-provision.json', + 'vsp': '', + 'vnf-csar': 'file://1574080373688.csar', + 'ns-csar': '', + 'vnfm-driver': 'gvnfmdriver ', + 'onap-objects': '{}', + 'mode': 'provision ', + 'vnf-name': 'ABC', + 'vnf-vendor-name': 'ABC', + 'timeout': '60000' + }, + 'scenario': 'onap-dublin', + 'testCaseName': 'vnf-tosca-provision', + 'testSuiteName': 'vnf-validation', + 'endpoint': 'vtp' + } + ] + }); export const VSPTestsMapFactory = new Factory().attrs({ vspTestsMap: { 'compliance.compliancetests.sriov': { @@ -288,7 +336,42 @@ export const VSPTestsMapFactory = new Factory().attrs({ testCaseName: 'certification.certificationtests.certquery', testSuiteName: 'certificationtests', scenario: 'certification' - } + }, + 'vnf-validation': { + title: 'vnf-validation', + parameters: [ + { + name: 'vspId', + description: 'VSP ID', + type: 'text', + defaultValue: '$vspid', + isOptional: true, + metadata: { + maxLength: 36, + minLength: 1, + disabled: true + } + }, + { + name: 'vsp-csar', + description: 'Vsp Csar', + type: 'binary', + defaultValue: '', + isOptional: true + }, + { + name: 'host-password', + description: 'host-password', + type: 'binary', + defaultValue: '', + isOptional: true + } + ], + endpoint: 'vtp', + testCaseName: 'vnf-validation', + testSuiteName: 'vnf-validation', + scenario: 'onap-dublin' + } } }); @@ -493,6 +576,89 @@ export const VSPChecksFactory = new Factory().attrs({ ] } ] + }, + { + 'name': 'onap-dublin', + 'children': [ + { + 'name': 'vnf-validation', + 'tests': [ + { + 'scenario': 'onap-dublin', + 'testCaseName': 'vnf-tosca-provision', + 'testSuiteName': 'vnf-validation', + 'description': 'ONAP TOSCA VNF validation', + 'author': 'ONAP VTP Team kanagaraj.manickam@huawei.com', + 'inputs': [ + { + 'name': 'config-json', + 'description': 'Configuration file path', + 'type': 'string', + 'defaultValue': '$s{env:OPEN_CLI_HOME}/conf/vnf-tosca-provision.json', + 'isOptional': false + }, + { + 'name': 'vsp', + 'description': 'Path to the ONAP vendor service product (VSP) for the VNF to provision', + 'type': 'binary', + 'isOptional': false + }, + { + 'name': 'vnf-csar', + 'description': 'Path to the TOSCA CSAR for the VNF to provision', + 'type': 'binary', + 'isOptional': false + }, + { + 'name': 'ns-csar', + 'description': 'Path to the TOSCA CSAR for the NS service to provision', + 'type': 'binary', + 'isOptional': true + }, + { + 'name': 'vnfm-driver', + 'description': 'VNFM driver to use. One of gvnfmdriver or hwvnfmdriver', + 'type': 'string', + 'isOptional': false + }, + { + 'name': 'onap-objects', + 'description': 'Existing ONAP object ids to use instead of creating them while running this task', + 'type': 'json', + 'isOptional': true + }, + { + 'name': 'mode', + 'description': 'setup or standup or cleanup or provision or validate', + 'type': 'string', + 'defaultValue': 'checkup', + 'isOptional': true + }, + { + 'name': 'vnf-name', + 'description': 'VNF Name', + 'type': 'string', + 'isOptional': false + }, + { + 'name': 'vnf-vendor-name', + 'description': 'VNF Vendor Name', + 'type': 'string', + 'isOptional': false + }, + { + 'name': 'timeout', + 'description': 'timeout for command to complete the given task in milliseconds', + 'type': 'string', + 'defaultValue': '60000', + 'isOptional': true + } + ], + 'endpoint': 'vtp' + } + ] + } + ] } ] }); diff --git a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js index a4a069e355..d204753b83 100644 --- a/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js +++ b/openecomp-ui/test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js @@ -15,7 +15,14 @@ */ import { Factory } from 'rosie'; +export const VSPTestResultKeysFactory = new Factory().attrs({ + testResultKeys: { + requestId: "1", + endPoints: ["vtp"] + } +}) export const VSPTestResultsFailureFactory = new Factory().attrs({ + vspTestResults: [ { scenario: 'certification', @@ -107,137 +114,150 @@ export const VSPTestResultsFailureFactory = new Factory().attrs({ export const VSPTestResultsSuccessFactory = new Factory().attrs({ vspTestResults: [ - { - scenario: 'certification', - description: 'Other Certifications', - testCaseName: 'certification.certificationtests.certquery', - testSuiteName: 'certificationtests', - executionId: 'ebaa5f21-ed68-4098-97a9-775ac8800f09-1550575025614', - parameters: { - vspId: 'uuidval', - vspVersion: 'ver', - other: 'values' - }, - results: { - testResults: { - complianceTests: [ - { - testName: 'Compute Flavors', - testResult: 'Pass', - notes: - 'Diagnostic: test performed against GSMA NFVI Abstraction and Profiling Version 0.1 profiles.' - }, - { - testName: 'SR-IOV', - testResult: 'Fail', - notes: - 'Diagnostic: SR-IOV found in VNF Template. User advice: VNF binary and VNF Template must be modified to not require SR-IOV.' - }, - { - testName: 'Heat', - testResult: 'Pass', - notes: '' - }, - { - testName: 'TOSCA', - testResult: 'Pass', - notes: - 'Diagnostic: test performed for ETSI GS NFV-SOL001v0.10.0.' - } - ], - validationTests: [ - { - testName: 'OpenStack', - testResult: 'Pass', - notes: - 'Diagnostic: test performed for OpenStack Rocky.' - }, - { - testName: 'VMware', - testResult: 'Fail', - notes: - 'Diagnostic: VMware compatible template not found. User advice: add a VMware compatible template to the VSP.' - }, - { - testName: 'Kubernetes', - testResult: 'Fail', - notes: - 'Diagnostic: Kubernetes compatible template not found. User advice: add a Kubernetes compatible template, such as Helm Chart, to the VSP.' - } - ], - performanceTests: [ - { - testName: 'Max Throughput', - testResult: 'Pass', - notes: '' - }, - { - testName: 'Latency', - testResult: 'Fail', - notes: - 'Diagnostic: maximum latency threshold of 20ms signalling response time exceededUser advice: consider increasing VDU compute resource.' - } - ] - } - }, - - status: 'COMPLETED', - startTime: '2019-02-19T11:17:05.670', - endTime: '2019-02-19T11:17:05.683' + { + "scenario": "onap-dublin", + "testCaseName": "vsp-package", + "testSuiteName": "sdc.onboarding", + "executionId": "onap-dublin", + "parameters": { + "vsp-id": "0cf7923588df4877989d8c01243e1e69", + "host-password": "demo123456!", + "vsp-version": "b19f1f74b5874127bb7778a84eadd99b", + "host-url": "http://192.168.209.129:30280", + "host-username": "cs0008" }, - { - scenario: 'compliance', - testCaseName: 'compliance.compliancetests.sriov', - description: 'Allow_SR-IOV', - testSuiteName: 'compliancetests', - executionId: 'ebaa5f21-ed68-4098-97a9-775ac8800f09-1550575025614', - parameters: { - vspId: 'uuidval', - vspVersion: 'ver', - other: 'values' - }, - results: { - errors: [ - { - attribute: '', - reason: 'Record Not Found', - advice: - 'User must query with (vspId, vspVersion) values for a certifications record that is present in the Repository', - code: 40 - }, - { - attribute: '', - reason: 'Record Not Found', - advice: - 'User must query with (vspId, vspVersion) values for a certifications record that is present in the Repository', - code: 40 - } - ] - }, - status: 'FAILED', - startTime: '2019-02-19T11:17:05.670', - endTime: '2019-02-19T11:17:05.683' + "results": [ + {} + ], + "status": "completed", + "startTime": "2019-09-24T08:35:09.000", + "endTime": "2019-09-24T08:35:10.000" + }, + { + "scenario": "onap-dublin", + "testCaseName": "customer-create", + "testSuiteName": "aai", + "executionId": "onap-dublin", + "parameters": { + "host-password": "AAI", + "subscriber-name": "ovp-uygCLjl9", + "customer-name": "ovp-uygCLjl9", + "host-url": "https://192.168.209.129:30233", + "host-username": "AAI" }, - { - scenario: 'compliance', - testCaseName: ' compliance.compliancetests.computeflavours', - description: 'Allow SR-IOV ', - testSuiteName: 'compliancetests', - executionId: 'ebaa5f21-ed68-4098-97a9-775ac8800f09-1550575025614', - parameters: { - vspId: 'uuidval', - vspVersion: 'ver', - other: 'values' - }, - results: {}, - status: 'COMPLETED', - startTime: '2019-02-19T11:17:05.670', - endTime: '2019-02-19T11:17:05.683' + "results": [ + {} + ], + "status": "in-progress", + "startTime": "2019-09-24T08:34:33.000", + "endTime": "2019-09-24T08:34:33.000" + }, + { + "scenario": "onap-dublin", + "testCaseName": "vnf-tosca-provision", + "testSuiteName": "vnf-validation", + "executionId": "uygCLjl9-1569314036837", + "parameters": { + "mode": "validate", + "vsp": "/tmp/data/vtp-tmp-files/1569313993969.csar", + "vnfm-driver": "gvnfmdriver", + "config-json": "/opt/oclip/conf/vnf-tosca-provision.json", + "vnf-vendor-name": "VM", + "ns-csar": "/tmp/data/vtp-tmp-files/1569314002901.csar", + "onap-objects": "{}", + "timeout": "600000", + "vnf-name": "SWITCH", + "vnf-csar": "/tmp/data/vtp-tmp-files/1569313997224.csar" }, - { - code: '500', - message: 'VTP Test(s) could not be completed', - httpStatus: 500 - } + "results": { + "error": "1::0x6001::Command vnf-tosca-provision failed to execute, " + }, + "status": "failed", + "startTime": "2019-09-24T08:33:56.000", + "endTime": "2019-09-24T08:35:13.000" + }, + { + "scenario": "onap-dublin", + "testCaseName": "vlm-submit", + "testSuiteName": "sdc.onboarding", + "executionId": "onap-dublin", + "parameters": { + "vlm-version": "115d4d29994a41a38c2ed2bf75c93f5d", + "vlm-id": "7fbb14e88d9e45c48021e96f35970419", + "host-password": "demo123456!", + "host-url": "http://192.168.209.129:30280", + "host-username": "cs0008" + }, + "results": [ + {} + ], + "status": "completed", + "startTime": "2019-09-24T08:34:13.000", + "endTime": "2019-09-24T08:34:13.000" + }, + { + "scenario": "onap-dublin", + "testCaseName": "vsp-validate", + "testSuiteName": "sdc.onboarding", + "executionId": "onap-dublin", + "parameters": { + "vsp-id": "0cf7923588df4877989d8c01243e1e69", + "host-password": "demo123456!", + "vsp-version": "b19f1f74b5874127bb7778a84eadd99b", + "host-url": "http://192.168.209.129:30280", + "host-username": "cs0008" + }, + "results": { + "errors": {}, + "status": "Success" + }, + "status": "completed", + "startTime": "2019-09-24T08:34:58.000", + "endTime": "2019-09-24T08:34:59.000" + }, + { + "scenario": "onap-dublin", + "testCaseName": "vlm-feature-group-create", + "testSuiteName": "sdc.onboarding", + "executionId": "onap-dublin", + "parameters": { + "vlm-entitle-pool-id": "fa33494286004b4ebec6703da43f92a5", + "vlm-id": "7fbb14e88d9e45c48021e96f35970419", + "vlm-version": "115d4d29994a41a38c2ed2bf75c93f5d", + "part-number": "1000VM00", + "host-password": "demo123456!", + "vlm-key-group-id": "ea95efa4ccb149d49640166972a4e8f8", + "name": "VM-uygCLjl9 Feature group", + "host-url": "http://192.168.209.129:30280", + "host-username": "cs0008" + }, + "results": { + "id": "4dc4f39e28ea488b946aedb0f74c436a" + }, + "status": "completed", + "startTime": "2019-09-24T08:34:08.000", + "endTime": "2019-09-24T08:34:08.000" + } , + { + "scenario": "onap-dublin", + "testCaseName": "subscription-list", + "testSuiteName": "aai", + "executionId": "onap-dublin", + "parameters": { + "host-password": "AAI", + "customer-name": "ovp-uygCLjl9", + "host-url": "https://192.168.209.129:30233", + "host-username": "AAI" + }, + "results": [ + { + "resource-version": "1569314083390", + "service-type": "tosca_vnf_validation-uygCLjl9" + } + ], + "status": "completed", + "startTime": "2019-09-24T08:34:45.000", + "endTime": "2019-09-24T08:34:46.000" + } ] }); diff --git a/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationActionHelper.test.js b/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationActionHelper.test.js index 0a8f640426..3be1d68bbc 100644 --- a/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationActionHelper.test.js +++ b/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationActionHelper.test.js @@ -24,12 +24,14 @@ import Configuration from 'sdc-app/config/Configuration.js'; import { VSPComplianceCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; import { VSPCertificationCheckedFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; +import { VSPTestResultKeysFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; import { VSPChecksFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; import { VSPTestsMapFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; import { VSPTestsRequestFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; import { VSPGeneralInfoFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; import { VSPTestResultsSuccessFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; import { mapActionsToProps } from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidation.js'; +import { VSPTestRequestFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; describe('Software Product Validation Action Helper Tests', function() { const store = storeCreator(); @@ -45,8 +47,10 @@ describe('Software Product Validation Action Helper Tests', function() { const generalInfo = VSPGeneralInfoFactory.build(); const isValidationDisabled = false; const vspTestResults = VSPTestResultsSuccessFactory.build(); + const testResultKeys = VSPTestResultKeysFactory.build(); let restPrefix = Configuration.get('restPrefix'); let onClose = () => {}; + const vspTestRequest = VSPTestRequestFactory.build(); const modal = { type: 'error', @@ -91,28 +95,50 @@ describe('Software Product Validation Action Helper Tests', function() { }); }); - // it('Software Products Validation Action Helper : post test', () => { - // mockRest.addHandler('post', ({ options, data, baseUrl }) => { - // expect(baseUrl).toEqual( - // `${restPrefix}/v1.0/externaltesting/executions` - // ); - // //expect(data).toEqual(testsRequest); - // expect(options).toEqual(undefined); - // return { vspTestResults: vspTestResults }; - // }); - // const version = { - // id: 12345, - // name: 1 - // }; - // const softwareProductId = '1234'; - // const status = 'draft'; - // mapActionsToProps(store.dispatch).onTestSubmit( - // softwareProductId, - // version, - // status, - // testsRequest - // ); - // }); + it('Software Products Validation Action Helper : post test', () => { + + const str = storeCreator({ + softwareProduct: { + softwareProductValidation: { + testResultKeys: testResultKeys.testResultKeys + } + } + }); + deepFreeze(str.getState()); + let expectedStore = cloneAndSet( + str.getState(), + 'softwareProduct.softwareProductValidation.vspTestResults', + vspTestResults.vspTestResults + ); + const version = { + id: 12345, + name: 1 + }; + const requestId = "1" + const softwareProductId = '1234'; + const status = 'success'; + mockRest.addHandler('post', ({ options, data, baseUrl }) => { + expect(baseUrl).toEqual( + `${restPrefix}/v1.0/externaltesting/executions?vspId=${softwareProductId}&vspVersionId=${version.id}&requestId=${requestId}` + ); + return vspTestResults.vspTestResults ; + }); + SoftwareProductValidationActionHelper.navigateToSoftwareProductValidationResults( + str.dispatch,{ + softwareProductId: softwareProductId, + version: version, + status: status, + tests :vspTestRequest.vspTestRequest, + requestId: requestId + } + ).then(() => { + expect(str.getState()).toEqual(expectedStore); + }) + .catch((e) => { + console.log('Executions test returned Error'); + }); + + }); it('Software Products Validation Action Helper : setCertificationChecked', () => { let expectedStore = cloneAndSet( diff --git a/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationInputView.test.js b/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationInputView.test.js index 68a8cdd957..c66cf91df4 100644 --- a/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationInputView.test.js +++ b/openecomp-ui/test/softwareProduct/validation/SoftwareProductValidationInputView.test.js @@ -112,5 +112,9 @@ describe('SoftwareProductValidation Mapper and View Classes', () => { ); expect(inputForm).toBeTruthy(); TestUtils.Simulate.submit(inputForm); + let result = TestUtils.scryRenderedDOMComponentsWithTag(vspValidationInputView, 'input'); + expect(result).toBeTruthy(); + expect(result.length).toBeTruthy(); + TestUtils.Simulate.change(result[0]); }); }); diff --git a/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsView.test.js b/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsView.test.js index 67e9fcfd89..8bd3779ea2 100644 --- a/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsView.test.js +++ b/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsView.test.js @@ -18,64 +18,93 @@ import React from 'react'; import { mapStateToProps } from 'sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResults.js'; import SoftwareProductValidationResultsView from 'sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsView.jsx'; import { VSPTestResultsSuccessFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; +import { VSPTestResultKeysFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; import { VSPTestResultsFailureFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; import { VSPTestsMapFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; +import { VSPChecksFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; import TestUtils from 'react-dom/test-utils'; describe('SoftwareProductValidationResults Mapper and View Classes', () => { - it('mapStateToProps mapper exists', () => { + it('mapStateToProps mapper exists', () => { expect(mapStateToProps).toBeTruthy(); }); it('mapStateToProps fail data test', () => { const vspTestResults = VSPTestResultsFailureFactory.build(); const vspTestsMap = VSPTestsMapFactory.build(); - + const testResultKeys = VSPTestResultKeysFactory.build(); + const version = { + name: 1 + }; + const softwareProductId = '1234'; + var testResultToDisplay = {}; + var vspIdAndVer = softwareProductId+version.name; + testResultToDisplay[vspIdAndVer] = vspTestResults.vspTestResults; + var testResultKeyByVspId = {}; + testResultKeyByVspId[vspIdAndVer] = testResultKeys.testResultKeys; var obj = { softwareProduct: { softwareProductValidation: { - vspTestResults: vspTestResults.vspTestResults, - vspTestsMap: vspTestsMap.vspTestsMap + testResultKeys: testResultKeys.testResultKeys + }, + softwareProductValidationResult: { + testResultToDisplay: testResultToDisplay, } } }; var results = mapStateToProps(obj); - expect(results.softwareProductValidation.vspTestResults).toBeTruthy(); + expect(results.softwareProductValidationResult.testResultToDisplay[vspIdAndVer]).toBeTruthy(); }); - it('mapStateToProps success data test', () => { + it('mapStateToProps success data test', () => { const vspTestResults = VSPTestResultsSuccessFactory.build(); const vspTestsMap = VSPTestsMapFactory.build(); - + const vspChecksList = VSPChecksFactory.build(); var obj = { softwareProduct: { softwareProductValidation: { + }, + softwareProductValidationResult: { vspTestResults: vspTestResults.vspTestResults, - vspTestsMap: vspTestsMap.vspTestsMap + vspChecks: vspChecksList, + refreshValidationResults: [] } } }; var results = mapStateToProps(obj); - expect(results.softwareProductValidation.vspTestResults).toBeTruthy(); + expect(results.softwareProductValidationResult.vspTestResults).toBeTruthy(); }); it('SoftwareProductValidationResultsView test fail render test', () => { const vspTestResults = VSPTestResultsFailureFactory.build(); const vspTestsMap = VSPTestsMapFactory.build(); + const testResultKeys = VSPTestResultKeysFactory.build(); + const vspChecksList = VSPChecksFactory.build(); const version = { name: 1 }; const softwareProductId = '1234'; - var obj = { - softwareProductId: softwareProductId, - version: version, - softwareProductValidation: { - vspTestResults: vspTestResults.vspTestResults, - vspTestsMap: vspTestsMap.vspTestsMap - } - }; + var testResultToDisplay = {}; + var vspIdAndVer = softwareProductId+version.name; + testResultToDisplay[vspIdAndVer] = vspTestResults.vspTestResults; + var testResultKeyByVspId = {}; + testResultKeyByVspId[vspIdAndVer] = testResultKeys.testResultKeys; + var obj = { + softwareProductId: softwareProductId, + version: version, + softwareProductValidation:{ + testResultKeys: testResultKeys.testResultKeys + }, + softwareProductValidationResult: { + testResultToDisplay: testResultToDisplay, + vspChecks: vspChecksList, + refreshValidationResults: [], + testResultKeys: testResultKeyByVspId + } + }; + let vspValidationResultsView = TestUtils.renderIntoDocument( <SoftwareProductValidationResultsView {...obj} /> ); @@ -84,18 +113,29 @@ describe('SoftwareProductValidationResults Mapper and View Classes', () => { it('SoftwareProductValidationResultsView test success render test', () => { const vspTestResults = VSPTestResultsSuccessFactory.build(); + const testResultKeys = VSPTestResultKeysFactory.build(); const vspTestsMap = VSPTestsMapFactory.build(); - + const vspChecksList = VSPChecksFactory.build(); let version = { name: 1 }; + const softwareProductId = '1234'; + var testResultToDisplay = {}; + var vspIdAndVer = softwareProductId+version.name; + testResultToDisplay[vspIdAndVer] = vspTestResults.vspTestResults; + var testResultKeyByVspId = {}; + testResultKeyByVspId[vspIdAndVer] = testResultKeys.testResultKeys; + var obj = { softwareProductId: softwareProductId, version: version, - softwareProductValidation: { - vspTestResults: vspTestResults.vspTestResults, - vspTestsMap: vspTestsMap.vspTestsMap + softwareProductValidation:{ + testResultKeys: testResultKeys.testResultKeys + }, + softwareProductValidationResult: { + testResultToDisplay: testResultToDisplay, + vspChecks: vspChecksList } }; let vspValidationResultsView = TestUtils.renderIntoDocument( diff --git a/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.test.js b/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.test.js new file mode 100644 index 0000000000..064a32312c --- /dev/null +++ b/openecomp-ui/test/softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.test.js @@ -0,0 +1,107 @@ +/* + * Copyright © 2019 Vodafone Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import deepFreeze from 'deep-freeze'; +import mockRest from 'test-utils/MockRest.js'; +import { cloneAndSet } from 'test-utils/Util.js'; +import { storeCreator } from 'sdc-app/AppStore.js'; +import SoftwareProductValidationResultsViewActionHelper from 'sdc-app/onboarding/softwareProduct/validationResults/SoftwareProductValidationResultsViewActionHelper.js'; +import { tabsMapping } from 'sdc-app/onboarding/softwareProduct/validation/SoftwareProductValidationConstants.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import { VSPTestResultsSuccessFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; +import { VSPTestResultsFailureFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; +import { VSPTestResultKeysFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationResultsFactory.js'; +import { VSPTestsMapFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; +import { VSPChecksFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; +import { VSPTestsRequestFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; +import { VSPGeneralInfoFactory } from 'test-utils/factories/softwareProduct/SoftwareProductValidationFactory.js'; +import VersionFactory from 'test-utils/factories/common/VersionFactory.js'; + + +describe('Software Product Validation Test Result Action Helper Tests', function() { + const store = storeCreator(); + deepFreeze(store.getState()); + const version = VersionFactory.build(); + const vspId = 10000; + const vspChecksList = VSPChecksFactory.build(); + const vspTestsMap = VSPTestsMapFactory.build(); + + const errorMessage = { msg: 'Test Error Message' }; + const testsRequest = VSPTestsRequestFactory.build(); + const generalInfo = VSPGeneralInfoFactory.build(); + const isValidationDisabled = false; + const testResultKeys = VSPTestResultKeysFactory.build(); + const vspTestResults = VSPTestResultsSuccessFactory.build(); + const requestQuery = "requestId="+testResultKeys.testResultKeys.requestId + + "&" + "endPoint=" + testResultKeys.testResultKeys.endPoints[0]; + let restPrefix = Configuration.get('restPrefix'); + let onClose = () => {}; + + const modal = { + type: 'error', + title: 'Error', + modalComponentName: 'Error', + modalComponentProps: { + onClose: onClose + }, + msg: { + msg: 'Test Error Message' + }, + cancelButtonText: 'OK' + }; + + it('Software Products Validation Test Result Action Helper : fetch vsp', () => { + let expectedStore = cloneAndSet( + store.getState(), + 'softwareProduct.softwareProductValidationResult.vspChecks', + vspChecksList + ); + mockRest.addHandler('fetch', ({ baseUrl }) => { + expect(baseUrl).toEqual( + `${restPrefix}/v1.0/externaltesting/testcasetree` + ); + return vspChecksList; + }); + return SoftwareProductValidationResultsViewActionHelper.fetchVspChecks( + store.dispatch + ).then(() => { + var stat = store.getState(); + expect(stat).toEqual(expectedStore); + }) + }); + + it('Software Products Validation Test Result Action Helper : RefreshValidationResults', () => { + let expectedStore = cloneAndSet( + store.getState(), + 'softwareProduct.softwareProductValidationResult.vspTestResults', + vspTestResults.vspTestResults + ); + mockRest.addHandler('fetch', ({ baseUrl }) => { + expect(baseUrl).toEqual( + `${restPrefix}/v1.0/externaltesting/executions?${requestQuery}` + ); + return vspTestResults.vspTestResults; + }); + return SoftwareProductValidationResultsViewActionHelper.refreshValidationResults( + store.dispatch, { + requestId: testResultKeys.testResultKeys.requestId, + endPoints: testResultKeys.testResultKeys.endPoints + } + ).then(() => { + var stt = store.getState(); + expect(stt).toEqual(expectedStore); + }) + }); +}) diff --git a/test-apis-ci/sdc-api-tests/chef-repo/cookbooks/sdc-api-tests/files/default/Files/VNFs/vsp-vgw.csar b/test-apis-ci/sdc-api-tests/chef-repo/cookbooks/sdc-api-tests/files/default/Files/VNFs/vsp-vgw.csar Binary files differnew file mode 100644 index 0000000000..52de39a93e --- /dev/null +++ b/test-apis-ci/sdc-api-tests/chef-repo/cookbooks/sdc-api-tests/files/default/Files/VNFs/vsp-vgw.csar diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/dataProvider/OnbordingDataProviders.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/dataProvider/OnbordingDataProviders.java index 6594049fc5..89d90df24d 100644 --- a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/dataProvider/OnbordingDataProviders.java +++ b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/dataProvider/OnbordingDataProviders.java @@ -20,17 +20,19 @@ package org.openecomp.sdc.ci.tests.dataProvider; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import org.openecomp.sdc.ci.tests.datatypes.enums.XnfTypeEnum; import org.openecomp.sdc.ci.tests.utilities.FileHandling; import org.openecomp.sdc.ci.tests.utils.general.OnboardingUtils; +import org.testng.Assert; import org.testng.annotations.DataProvider; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - public class OnbordingDataProviders { + private static final String VSP_VGW_CSAR = "vsp-vgw.csar"; private static final int NUMBER_OF_RANDOMLY_ONBOARD_VNF = 3; protected static String filepath = FileHandling.getVnfRepositoryPath(); @@ -60,8 +62,10 @@ public class OnbordingDataProviders { Object[][] filteredArObject = null; - objectArr[0] = new Object[]{"1-2016-20-visbc3vf-(VOIP)_v2.1.zip", "2-2016-20-visbc3vf-(VOIP)_v2.1_RenameResourceToShay.zip"}; - objectArr[1] = new Object[]{"1-2017-404_vUSP_vCCF_AIC3.0-(VOIP)_v6.0.zip", "2-2017-404_vUSP_vCCF_AIC3.0-(VOIP)_v6.0_Added2TestParameters.zip"}; + objectArr[0] = new Object[] {"1-2016-20-visbc3vf-(VOIP)_v2.1.zip", + "2-2016-20-visbc3vf-(VOIP)_v2.1_RenameResourceToShay.zip"}; + objectArr[1] = new Object[] {"1-2017-404_vUSP_vCCF_AIC3.0-(VOIP)_v6.0.zip", + "2-2017-404_vUSP_vCCF_AIC3.0-(VOIP)_v6.0_Added2TestParameters.zip"}; filteredArObject = OnboardingUtils.filterObjectArrWithExcludedVnfs(objectArr); @@ -70,12 +74,15 @@ public class OnbordingDataProviders { } - // -----------------------factories----------------------------------------- -// @Factory(dataProvider = "VNF_List") -// public Object[] OnbordingDataProviders(String filepath, String vnfFile){ -// return new Object[] { new ToscaValidationTest(filepath, vnfFile)}; -// } + @DataProvider(name = "Single_Vsp_Test_Csar", parallel = true) + private static Object[][] singleVspTestCsar() throws Exception { + List<String> fileNamesFromFolder = OnboardingUtils.getXnfNamesFileList(XnfTypeEnum.VNF); + if (!fileNamesFromFolder.contains(VSP_VGW_CSAR)) { + Assert.fail("Vsp Test file is not exits in the path"); + } + return provideData(Arrays.asList(VSP_VGW_CSAR), filepath); + } // -----------------------methods----------------------------------------- static Object[][] provideData(List<String> fileNamesFromFolder, String filepath) { @@ -83,7 +90,7 @@ public class OnbordingDataProviders { Object[][] arObject = new Object[fileNamesFromFolder.size()][]; int index = 0; for (Object obj : fileNamesFromFolder) { - arObject[index++] = new Object[]{filepath, obj}; + arObject[index++] = new Object[] {filepath, obj}; } return arObject; } @@ -106,37 +113,4 @@ public class OnbordingDataProviders { } } - -// private static String[][] arrangeFilesVersionPairs(List<String> filesArr) { -// String[][] filesArrangeByPairs = null; -// -// List<String> versionOneFiles= null; -// List<String> versionTowFiles= null; -// -// for ( String fileName : filesArr ) -// { -// if(fileName.startsWith("1-")) -// { -// versionOneFiles.add(fileName); -// } -// else if(fileName.startsWith("2-")) -// { -// versionTowFiles.add(fileName); -// } -// } -// -// Collections.sort(versionOneFiles); -// Collections.sort(versionTowFiles); -// -// for (int i=0 ; i<versionOneFiles.size() ; i++ ) -// { -// for (int j=0 ; j<versionTowFiles.size() ; j++ ) -// { -// -// } -// } -// -// return filesArrangeByPairs; -// } - } diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/OnboardingFlowsUi.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/OnboardingFlowsUi.java index 595c43801c..9a28ee9078 100644 --- a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/OnboardingFlowsUi.java +++ b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/OnboardingFlowsUi.java @@ -80,6 +80,20 @@ import org.testng.annotations.Test; public class OnboardingFlowsUi extends SetupCDTest { private static final Logger LOGGER = LoggerFactory.getLogger(OnboardingFlowsUi.class); + private static final String NO_TESTS_ARE_AVAILABLE = "No Tests are Available"; + private static final String NEXT_BUTTON_IS_ENABLED_IT_SHOULD_HAVE_BEEN_ENABLED = + "Next Button is enabled, it should have been enabled"; + private static final String NEXT_BUTTON_IS_DISABLED_IT_SHOULD_HAVE_BEEN_ENABLED = + "Next Button is disabled, it should have been enabled"; + private static final String RESULTS_ARE_NOT_AVAILABLE = "Results are not available"; + private static final String THE_TESTS_ARE_ALREADY_SELECTED_THE_LIST_SHOULD_INITIALLY_BE_EMPTY = + "The tests are already selected, the list should initially be empty"; + private static final String THE_SELECTED_TESTS_ARE_NOT_POPULATED_IN_THE_LIST = + "The selected tests are not populated in the list"; + private static final String THE_SELECTED_TESTS_ARE_NOT_DELETED_FROM_THE_LIST = + "The selected tests are not deleted from the list"; + private static final String NEXT_BUTTON_IS_ENABLED_IT_SHOULD_HAVE_BEEN_DISABLED = + "Next Button is enabled, it should have been disabled"; protected static String filePath = FileHandling.getVnfRepositoryPath(); private Boolean makeDistributionValue; @@ -142,10 +156,11 @@ public class OnboardingFlowsUi extends SetupCDTest { checkVspValidationLinksVisibility(); VspValidationPage.navigateToVspValidationPageUsingNavbar(); - assertTrue("Next Button is enabled, it should have been disabled", VspValidationPage.checkNextButtonDisabled()); + assertTrue(NEXT_BUTTON_IS_ENABLED_IT_SHOULD_HAVE_BEEN_DISABLED, + VspValidationPage.checkNextButtonDisabled()); VspValidationResultsPage.navigateToVspValidationResultsPageUsingNavbar(); GeneralUIUtils.ultimateWait(); - assertNotNull(GeneralUIUtils.findByText("No Validation Checks Performed")); + assertNotNull(GeneralUIUtils.findByText("No Test Performed")); } else { goToVspScreen(true, vspName); @@ -191,28 +206,28 @@ public class OnboardingFlowsUi extends SetupCDTest { goToVspScreen(true, vspName); } VspValidationPage.navigateToVspValidationPageUsingNavbar(); - assertTrue("Next Button is enabled, it should have been disabled", VspValidationPage.checkNextButtonDisabled()); + assertTrue(NEXT_BUTTON_IS_ENABLED_IT_SHOULD_HAVE_BEEN_DISABLED, VspValidationPage.checkNextButtonDisabled()); if (VspValidationPage.checkCertificationQueryExists()) { VspValidationPage.clickCertificationQueryAll(); GeneralUIUtils.ultimateWait(); - assertTrue("Next Button is disabled, it should have been enabled", !VspValidationPage.checkNextButtonDisabled()); + assertTrue(NEXT_BUTTON_IS_DISABLED_IT_SHOULD_HAVE_BEEN_ENABLED, + !VspValidationPage.checkNextButtonDisabled()); VspValidationPage.clickOnNextButton(); GeneralUIUtils.ultimateWait(); VspValidationPage.clickOnSubmitButton(); GeneralUIUtils.waitForLoader(); - assertTrue("Results are not available", VspValidationResultsPage.checkResultsExist()); + assertTrue(RESULTS_ARE_NOT_AVAILABLE, VspValidationResultsPage.checkResultsExist()); } else { assertNotNull(GeneralUIUtils.findByText("No Certifications Query are Available")); } } - @Test(dataProviderClass = OnboardingDataProviders.class, dataProvider = "Single_VNF") + @Test(dataProviderClass = OnbordingDataProviders.class, dataProvider = "Single_Vsp_Test_Csar") public void onapOnboardVSPComplianceCheckFlow(String filePath, String vnfFile) throws Exception { setLog(vnfFile); String vspName = createNewVSP(filePath, vnfFile); - final String complianceNotAvailableLabel = "No Compliance Checks are Available"; if (!OnboardingUiUtils.getVspValidationCongiguration()) { //change config to true to test the feature changeVspValidationConfig(true, vspName, OnboardingUiUtils.getVspValidationCongiguration()); @@ -221,19 +236,20 @@ public class OnboardingFlowsUi extends SetupCDTest { } VspValidationPage.navigateToVspValidationPageUsingNavbar(); - assertTrue("Next Button is enabled, it should have been enabled", VspValidationPage.checkNextButtonDisabled()); + assertTrue(NEXT_BUTTON_IS_ENABLED_IT_SHOULD_HAVE_BEEN_ENABLED, VspValidationPage.checkNextButtonDisabled()); if (VspValidationPage.checkComplianceCheckExists()) { VspValidationPage.clickComplianceChecksAll(); GeneralUIUtils.ultimateWait(); - assertFalse("Next Button is disabled, it should have been enabled", - VspValidationPage.checkNextButtonDisabled()); + assertFalse(NEXT_BUTTON_IS_DISABLED_IT_SHOULD_HAVE_BEEN_ENABLED, + VspValidationPage.checkNextButtonDisabled()); VspValidationPage.clickOnNextButton(); GeneralUIUtils.ultimateWait(); + VspValidationPage.loadVSPFile(filePath, vnfFile); VspValidationPage.clickOnSubmitButton(); GeneralUIUtils.ultimateWait(); - assertTrue("Results are not available", VspValidationResultsPage.checkResultsExist()); + assertTrue(RESULTS_ARE_NOT_AVAILABLE, VspValidationResultsPage.checkResultsExist()); } else { - assertNotNull(GeneralUIUtils.findByText(complianceNotAvailableLabel)); + assertNotNull(GeneralUIUtils.findByText(NO_TESTS_ARE_AVAILABLE)); } } @@ -250,19 +266,20 @@ public class OnboardingFlowsUi extends SetupCDTest { } VspValidationPage.navigateToVspValidationPageUsingNavbar(); - assertTrue("Next Button is enabled, it should have been enabled", VspValidationPage.checkNextButtonDisabled()); + assertTrue(NEXT_BUTTON_IS_ENABLED_IT_SHOULD_HAVE_BEEN_ENABLED, VspValidationPage.checkNextButtonDisabled()); if (VspValidationPage.checkComplianceCheckExists()) { - assertFalse("The tests are already selected, the list should initially be empty", - VspValidationPage.checkSelectedComplianceCheckExists()); + assertFalse(THE_TESTS_ARE_ALREADY_SELECTED_THE_LIST_SHOULD_INITIALLY_BE_EMPTY, + VspValidationPage.checkSelectedComplianceCheckExists()); VspValidationPage.clickComplianceChecksAll(); GeneralUIUtils.ultimateWait(); - assertTrue("The selected tests are not populated in the list", VspValidationPage.checkSelectedComplianceCheckExists()); + assertTrue(THE_SELECTED_TESTS_ARE_NOT_POPULATED_IN_THE_LIST, + VspValidationPage.checkSelectedComplianceCheckExists()); VspValidationPage.clickComplianceChecksAll(); GeneralUIUtils.ultimateWait(); - assertFalse("The selected tests are not deleted from the list", - VspValidationPage.checkSelectedComplianceCheckExists()); + assertFalse(THE_SELECTED_TESTS_ARE_NOT_DELETED_FROM_THE_LIST, + VspValidationPage.checkSelectedComplianceCheckExists()); } else { - assertNotNull(GeneralUIUtils.findByText("No Compliance Checks are Available")); + assertNotNull(GeneralUIUtils.findByText(NO_TESTS_ARE_AVAILABLE)); } } @@ -279,19 +296,19 @@ public class OnboardingFlowsUi extends SetupCDTest { } VspValidationPage.navigateToVspValidationPageUsingNavbar(); - assertTrue("Next Button is enabled, it should have been enabled", VspValidationPage.checkNextButtonDisabled()); + assertTrue(NEXT_BUTTON_IS_ENABLED_IT_SHOULD_HAVE_BEEN_ENABLED, VspValidationPage.checkNextButtonDisabled()); if (VspValidationPage.checkCertificationQueryExists()) { - assertFalse("The tests are already selected, the list should initially be empty", + assertFalse(THE_TESTS_ARE_ALREADY_SELECTED_THE_LIST_SHOULD_INITIALLY_BE_EMPTY, VspValidationPage.checkSelectedCertificationQueryExists()); VspValidationPage.clickCertificationQueryAll(); GeneralUIUtils.ultimateWait(); - assertTrue("The selected tests are not populated in the list", VspValidationPage.checkSelectedCertificationQueryExists()); + assertTrue(THE_SELECTED_TESTS_ARE_NOT_POPULATED_IN_THE_LIST, VspValidationPage.checkSelectedCertificationQueryExists()); VspValidationPage.clickCertificationQueryAll(); GeneralUIUtils.ultimateWait(); - assertFalse("The selected tests are not deleted from the list", + assertFalse(THE_SELECTED_TESTS_ARE_NOT_DELETED_FROM_THE_LIST, VspValidationPage.checkSelectedCertificationQueryExists()); } else { - assertNotNull(GeneralUIUtils.findByText("No Compliance Checks are Available")); + assertNotNull(GeneralUIUtils.findByText(NO_TESTS_ARE_AVAILABLE)); } } diff --git a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspValidationPage.java b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspValidationPage.java index ae01e9c207..12b5251e81 100644 --- a/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspValidationPage.java +++ b/ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/VspValidationPage.java @@ -17,15 +17,15 @@ package org.openecomp.sdc.ci.tests.pages; import com.aventstack.extentreports.Status; +import java.io.File; +import java.util.List; +import org.apache.commons.collections.CollectionUtils; import org.openecomp.sdc.ci.tests.datatypes.DataTestIdEnum; import org.openecomp.sdc.ci.tests.execute.setup.SetupCDTest; import org.openecomp.sdc.ci.tests.utilities.GeneralUIUtils; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; - -import java.util.List; - -import static org.testng.AssertJUnit.assertTrue; +import org.testng.Assert; public class VspValidationPage extends GeneralPageElements { @@ -53,25 +53,44 @@ public class VspValidationPage extends GeneralPageElements { clickOnElementUsingTestId(DataTestIdEnum.VspValidationPage.VSP_VALIDATION_PAGE_PROCEED_TO_RESULTS_BUTTON); } + public static void loadVSPFile(String path, String filename) { + List<WebElement> checkboxes = + GeneralUIUtils.findElementsByXpath("//div[@class='validation-input-wrapper']//input"); + boolean hasValue = CollectionUtils.isNotEmpty(checkboxes); + if (hasValue) { + WebElement browseWebElement = checkboxes.get(0); + browseWebElement.sendKeys(path + File.separator + filename); + GeneralUIUtils.ultimateWait(); + } else { + Assert.fail("Did not find File input field in the page for loading VSP test file"); + } + + } public static boolean checkNextButtonDisabled() throws Exception { return GeneralUIUtils.isElementDisabled(DataTestIdEnum.VspValidationPage.VSP_VALIDATION_PAGE_PROCEED_TO_INPUTS_BUTTON.getValue()); } public static void clickCertificationQueryAll() throws Exception { List<WebElement> checkboxes = GeneralUIUtils.findElementsByXpath("//div[@data-test-id='vsp-validation-certifications-query-checkbox-tree']//label//span[@class='rct-checkbox']"); - if (checkboxes.size() > 0) { + if (!checkboxes.isEmpty()) { checkboxes.get(0).click(); } else { - assertTrue("Checkbox Not Found", checkboxes.size() > 0); + Assert.fail("Did not find certification test checkbox in the page"); } } public static void clickComplianceChecksAll() throws Exception { - List<WebElement> checkboxes = GeneralUIUtils.findElementsByXpath("//div[@data-test-id='vsp-validation-compliance-checks-checkbox-tree']//label//span[@class='rct-checkbox']"); - if (checkboxes.size() > 0) { + List<WebElement> vnfComplianceCheckboxes = GeneralUIUtils.findElementsByXpath("//div[@data-test-id='vsp-validation-compliance-checks-checkbox-tree']//span[@class='rct-text' and .//label//text()='vnf-compliance']//button"); + if (!vnfComplianceCheckboxes.isEmpty()) { + vnfComplianceCheckboxes.get(vnfComplianceCheckboxes.size() - 1).click(); + } else { + Assert.fail("Did not find vnf-compliance test checkbox in the page"); + } + List<WebElement> checkboxes = GeneralUIUtils.findElementsByXpath("//div[@data-test-id='vsp-validation-compliance-checks-checkbox-tree']//label//span[@class='rct-title' and text()='csar-validate']"); + if (!checkboxes.isEmpty()) { checkboxes.get(checkboxes.size() - 1).click(); } else { - assertTrue("Checkbox Not Found", checkboxes.size() > 0); + Assert.fail("Did not find csar-validate test Checkbox in the page"); } } @@ -79,14 +98,14 @@ public class VspValidationPage extends GeneralPageElements { WebElement parentDiv = GeneralUIUtils.getWebElementByTestID(DataTestIdEnum.VspValidationPage.VSP_VALIDATION_PAGE_CERTIFICATION_CHECKBOX_TREE.getValue()); List<WebElement> checkboxTreeDivs = getChildElements(parentDiv); List<WebElement> orderedList = getChildElements(checkboxTreeDivs.get(0)); - return (orderedList.size() > 0); + return (!orderedList.isEmpty()); } public static boolean checkComplianceCheckExists() throws Exception { WebElement parentDiv = GeneralUIUtils.getWebElementByTestID(DataTestIdEnum.VspValidationPage.VSP_VALIDATION_PAGE_COMPLIANCE_CHECKBOX_TREE.getValue()); List<WebElement> checkboxTreeDivs = getChildElements(parentDiv); List<WebElement> orderedList = getChildElements(checkboxTreeDivs.get(0)); - return (orderedList.size() > 0); + return (!orderedList.isEmpty()); } public static boolean checkSelectedComplianceCheckExists() throws Exception { |