diff options
Diffstat (limited to 'gui-clamp')
17 files changed, 419 insertions, 504 deletions
diff --git a/gui-clamp/ui-react-lib/libIndex.js b/gui-clamp/ui-react-lib/libIndex.js index b0981b0..2af68db 100644 --- a/gui-clamp/ui-react-lib/libIndex.js +++ b/gui-clamp/ui-react-lib/libIndex.js @@ -59,7 +59,7 @@ export { default as MonitorInstantiation } from '../ui-react/src/components/dial export { default as InstantiationItem } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationItem'; export { default as InstantiationElements } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationElements'; export { default as InstantiationElementItem } from '../ui-react/src/components/dialogs/ControlLoop/InstantiationElementItem'; -export { default as UploadToscaInstantiation } from '../ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation'; +export { default as InstanceModal } from '../ui-react/src/components/dialogs/ControlLoop/InstanceModal'; export { default as ControlLoopService } from '../ui-react/src/api/ControlLoopService'; export { default as GetLocalToscaFileForUpload } from '../ui-react/src/components/dialogs/ControlLoop/GetLocalToscaFileForUpload'; export { default as ReadAndConvertYaml } from '../ui-react/src/components/dialogs/ControlLoop/ReadAndConvertYaml'; diff --git a/gui-clamp/ui-react/src/LoopUI.js b/gui-clamp/ui-react/src/LoopUI.js index 83ba570..bfdd7dd 100644 --- a/gui-clamp/ui-react/src/LoopUI.js +++ b/gui-clamp/ui-react/src/LoopUI.js @@ -55,7 +55,7 @@ import ReadAndConvertYaml from "./components/dialogs/ControlLoop/ReadAndConvertY import MonitorInstantiation from "./components/dialogs/ControlLoop/MonitorInstantiation"; import GetLocalToscaFileForUpload from "./components/dialogs/ControlLoop/GetLocalToscaFileForUpload"; import CommissioningModal from "./components/dialogs/ControlLoop/CommissioningModal"; -import UploadToscaInstantiation from "./components/dialogs/ControlLoop/UploadToscaInstantiation"; +import InstanceModal from "./components/dialogs/ControlLoop/InstanceModal"; const StyledMainDiv = styled.div` background-color: ${ props => props.theme.backgroundColor }; @@ -386,7 +386,7 @@ export default class LoopUI extends React.Component { showFailAlert={ this.showFailAlert }/>) } /> <Route path="/monitorInstantiation" render={ (routeProps) => (<MonitorInstantiation { ...routeProps } />) }/> - <Route path="/uploadToscaInstantiation" render={ (routeProps) => (<UploadToscaInstantiation { ...routeProps } />) }/> + <Route path="/editControlLoopInstanceProperties" render={ (routeProps) => (<InstanceModal { ...routeProps } />) }/> </React.Fragment> ); } diff --git a/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap b/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap index 4529589..2123f37 100644 --- a/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap +++ b/gui-clamp/ui-react/src/__snapshots__/LoopUI.test.js.snap @@ -90,7 +90,7 @@ exports[`Verify LoopUI Test the render method 1`] = ` render={[Function]} /> <Route - path="/uploadToscaInstantiation" + path="/editControlLoopInstanceProperties" render={[Function]} /> <div /> diff --git a/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap b/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap index a5f4c33..d9cf3d3 100644 --- a/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap +++ b/gui-clamp/ui-react/src/__snapshots__/OnapClamp.test.js.snap @@ -119,7 +119,7 @@ exports[`Verify OnapClamp Test the render method 1`] = ` render={[Function]} /> <Route - path="/uploadToscaInstantiation" + path="/editControlLoopInstanceProperties" render={[Function]} /> <div /> diff --git a/gui-clamp/ui-react/src/api/ControlLoopService.js b/gui-clamp/ui-react/src/api/ControlLoopService.js index 5938bd2..513fe68 100644 --- a/gui-clamp/ui-react/src/api/ControlLoopService.js +++ b/gui-clamp/ui-react/src/api/ControlLoopService.js @@ -19,7 +19,7 @@ export default class ControlLoopService { - static async fetchControlLoopInstantiation(windowLocationPathname) { + static async getControlLoopInstantiation(windowLocationPathname) { return await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/getToscaInstantiation', { method: 'GET', @@ -45,18 +45,33 @@ export default class ControlLoopService { }); } - static async uploadToscaInstantiation(toscaObject, windowLocationPathname) { + static async getInstanceProperties(name, version, windowLocationPathname) { + const params = { + name: name, + version: version, + common: "false" + } + + const response = await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/getCommonOrInstanceProperties' + '?' + (new URLSearchParams(params))); + + this.checkResponseForError(response); + + return response; + } + + static async createInstanceProperties(instancePropertiesTemplate, windowLocationPathname) { - const response = await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/postToscaInstantiation', { + const response = await fetch(windowLocationPathname + + '/restservices/clds/v2/toscaControlLoop/postToscaInstanceProperties', { method: 'POST', headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json" }, credentials: 'same-origin', - body: JSON.stringify(toscaObject) + body: JSON.stringify(instancePropertiesTemplate), }); - return response; + return response } static async getToscaTemplate(name, version, windowLocationPathname) { @@ -68,37 +83,11 @@ export default class ControlLoopService { const response = await fetch(windowLocationPathname + '/restservices/clds/v2/toscaControlLoop/getToscaTemplate' + '?' + (new URLSearchParams(params))); - const data = await response; - - return data; - } - - static async deleteToscaTemplate(name, version, windowLocationPathname) { - const params = { - name: name, - version: version + if (!response.ok) { + const message = `An error has occurred: ${ response.status }`; + throw new Error(message); } - const response = await fetch(windowLocationPathname + - '/restservices/clds/v2/toscaControlLoop/decommissionToscaTemplate' + '?' + (new URLSearchParams(params)), - { - method: 'DELETE' - }); - - this.checkResponseForError(response); - - const data = await response; - - return data; - } - - static async getToscaControlLoopDefinitions(windowLocationPathname) { - - const response = await fetch(windowLocationPathname + - '/restservices/clds/v2/toscaControlLoop/getElementDefinitions'); - - this.checkResponseForError(response); - const data = await response; return data; @@ -149,10 +138,11 @@ export default class ControlLoopService { return response; } - static checkResponseForError (response) { + static checkResponseForError(response) { if (!response.ok) { - const message = `An error has occurred: ${response.status}`; + const message = `An error has occurred: ${ response.status }`; throw new Error(message); } } + } diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js new file mode 100644 index 0000000..7a66812 --- /dev/null +++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.js @@ -0,0 +1,261 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import React, { useEffect, useState } from "react"; +import Modal from "react-bootstrap/Modal"; +import styled from "styled-components"; +import Button from "react-bootstrap/Button"; +import ControlLoopService from "../../../api/ControlLoopService"; +import { JSONEditor } from "@json-editor/json-editor"; +import Alert from "react-bootstrap/Alert"; + +const ModalStyled = styled(Modal)` + @media (min-width: 800px) { + .modal-xl { + max-width: 96%; + } + } + background-color: transparent; +` + +const DivWhiteSpaceStyled = styled.div` + overflow: auto; + min-width: 100%; + max-height: 300px; + padding: 5px 5px 0px 5px; + text-align: center; +` + +const templateName = "ToscaServiceTemplateSimple"; +const templateVersion = "1.0.0"; +let tempJsonEditor = null; + +const InstanceModal = (props) => { + const [show, setShow] = useState(true); + const [windowLocationPathname, setWindowLocationPathname] = useState(''); + const [toscaFullTemplate, setToscaFullTemplate] = useState({}); + const [toscaFilteredInitialValues, setToscaFilteredInitialValues] = useState({}); + const [toscaJsonSchema, setToscaJsonSchema] = useState({}); + const [jsonEditor, setJsonEditor] = useState(null); + const [alertMessage, setAlertMessage] = useState(null); + + useEffect(async () => { + const toscaInstanceProperties = await ControlLoopService.getInstanceProperties(templateName, templateVersion, windowLocationPathname).catch(error => error.message); + + const toscaSchemaResponse = await ControlLoopService.getToscaTemplate(templateName, templateVersion, windowLocationPathname).catch(error => error.message); + + await parseJsonSchema(toscaSchemaResponse, toscaInstanceProperties); + + }, []); + + const parseJsonSchema = async (fullTemplate, initialProperties) => { + + const fullJsonSchemaTemplate = await fullTemplate.json(); + setToscaFullTemplate(fullJsonSchemaTemplate); + + const filteredInitialStartValues = {}; + + const instanceProperties = await initialProperties.json().then(properties => { + const filteredTemplateObj = {}; + const propertiesTemplateArray = Object.entries(properties); + + propertiesTemplateArray.forEach(([key, value]) => { + const propertiesObj = { + properties: value.properties + } + + const propValues = {}; + filteredTemplateObj[key] = propertiesObj; + + const jsonNodeSchemaKey = fullJsonSchemaTemplate.topology_template.node_templates[key] + + Object.entries(propertiesObj.properties).forEach(([pKey, pValue]) => { + propValues[pKey] = jsonNodeSchemaKey.properties[pKey]; + }); + + filteredInitialStartValues[key] = propValues; + }); + + setToscaFilteredInitialValues(filteredInitialStartValues); + + return filteredTemplateObj; + }); + + const propertySchema = makeSchemaForInstanceProperties(instanceProperties); + setToscaJsonSchema(propertySchema); + + tempJsonEditor = createJsonEditor(propertySchema, filteredInitialStartValues); + setJsonEditor(tempJsonEditor); + } + + const makeSchemaForInstanceProperties = (instanceProps) => { + const instancePropsArray = Object.entries(instanceProps); + + const newSchemaObject = {}; + + newSchemaObject.title = "InstanceProperties"; + newSchemaObject.type = "object"; + newSchemaObject.properties = {}; + + const newSchemaObjectArray = []; + instancePropsArray.forEach(([key, value]) => { + const templateObj = {}; + const propertiesObject = {}; + + Object.entries(value.properties).forEach(([pKey, pValue]) => { + propertiesObject[pKey] = { + type: getType(pValue.type) + } + }); + + newSchemaObject.properties[key] = { + properties: propertiesObject + } + }); + + return newSchemaObject; + } + + const getType = (pType) => { + switch (pType) { + case "string": + return "string"; + case "integer": + return "integer"; + case "list": + return "array"; + case "object": + return "object"; + default: + return "string"; + + } + } + + const createJsonEditor = (fullSchema, instanceProperties) => { + JSONEditor.defaults.options.collapse = true; + + return new JSONEditor(document.getElementById("editor"), + { + schema: fullSchema, + startval: instanceProperties, + theme: 'bootstrap4', + iconlib: 'fontawesome5', + object_layout: 'normal', + disable_properties: false, + disable_edit_json: false, + disable_array_reorder: true, + disable_array_delete_last_row: true, + disable_array_delete_all_rows: false, + array_controls_top: true, + keep_oneof_values: false, + collapsed: true, + show_errors: 'always', + display_required_only: false, + show_opt_in: false, + prompt_before_delete: true, + required_by_default: false, + }); + } + + const handleClose = () => { + console.log('handleClose called'); + setShow(false); + props.history.push('/'); + } + + const updateTemplate = (jsonEditorValues) => { + const nodeTemplates = toscaFullTemplate.topology_template.node_templates; + const instanceDataProperties = Object.entries(jsonEditorValues); + + instanceDataProperties.forEach(([key, value]) => { + const nodeTemplatesKey = nodeTemplates[key] + Object.entries(value).forEach((pKey, pValue) => { + nodeTemplatesKey.properties[pKey] = pValue; + }); + }); + + toscaFullTemplate.topology_template.node_templates = nodeTemplates; + + setToscaFullTemplate(toscaFullTemplate); + + } + + const handleSave = async () => { + console.log("handleSave called") + + setWindowLocationPathname(window.location.pathname); + + updateTemplate(jsonEditor.getValue()); + + const response = await ControlLoopService.createInstanceProperties(toscaFullTemplate, windowLocationPathname).catch(error => error.message); + + if (response.ok) { + successAlert(); + } else { + await errorAlert(response); + } + } + + const successAlert = () => { + console.log("successAlert called"); + setAlertMessage(<Alert variant="success"> + <Alert.Heading>Instantiation Properties Success</Alert.Heading> + <p>Instance Properties was successfully saved</p> + <hr/> + </Alert>); + } + + const errorAlert = async (response) => { + console.log("errorAlert called"); + setAlertMessage(<Alert variant="danger"> + <Alert.Heading>Instantiation Properties Failure</Alert.Heading> + <p>An error occurred while trying to save</p> + <p>Status code: { await response.status } : { response.statusText }</p> + <p>Status Text: { await response.text() }</p> + <hr/> + </Alert>); + } + + return ( + <ModalStyled size="xl" + show={ show } + onHide={ handleClose } + backdrop="static" + keyboard={ false }> + <Modal.Header closeButton> + <Modal.Title>Change Tosca Instance Properties</Modal.Title> + </Modal.Header> + <div style={ { padding: '5px 5px 0 5px' } }> + <Modal.Body> + <div id="editor"/> + </Modal.Body> + <DivWhiteSpaceStyled> + { alertMessage } + </DivWhiteSpaceStyled> + </div> + <Modal.Footer> + <Button variant="primary" onClick={ handleSave }>Save</Button> + <Button variant="secondary" onClick={ handleClose }>Close</Button> + </Modal.Footer> + </ModalStyled> + ); +} + +export default InstanceModal; diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js new file mode 100644 index 0000000..36a77d7 --- /dev/null +++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/InstanceModal.test.js @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import { mount, shallow } from "enzyme"; +import React from "react"; +import InstanceModal from "./InstanceModal"; +import toJson from "enzyme-to-json"; +import { createMemoryHistory } from "history"; +import MonitorInstantiation from "./MonitorInstantiation"; +import { act } from "react-dom/test-utils"; + +describe('Verify MonitoringInstantiation', () => { + + it("renders without crashing", () => { + shallow(<InstanceModal />); + }); + + it("renders correctly", () => { + const tree = shallow(<InstanceModal />); + expect(toJson(tree)).toMatchSnapshot(); + }); + + it('should have submit button element', () => { + const container = shallow(<InstanceModal/>) + expect(container.find('[variant="primary"]').length).toEqual(1); + }); + + it('should have close button element', () => { + const container = shallow(<InstanceModal/>) + expect(container.find('[variant="secondary"]').length).toEqual(1); + }); + + it('handleCreateUpdateToscaInstanceProperties called when submit button clicked', () => { + const history = createMemoryHistory(); + const component = mount(<InstanceModal />) + const logSpy = jest.spyOn(console, 'log'); + + act(() => { + component.find('[variant="primary"]').simulate('click'); + expect(logSpy).toHaveBeenCalledWith('handleSave called'); + }); + }); + + it('handleClose called when close button clicked', () => { + const history = createMemoryHistory(); + const component = mount(<InstanceModal history={ history }/>) + const logSpy = jest.spyOn(console, 'log'); + + act(() => { + component.find('[variant="secondary"]').simulate('click'); + expect(logSpy).toHaveBeenCalledWith('handleClose called'); + }); + }); +}); diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js index 428defa..47de20c 100644 --- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js +++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/MonitorInstantiation.js @@ -37,7 +37,7 @@ const MonitorInstantiation = (props) => { useEffect(() => { setWindowLocationPathname(window.location.pathname); - ControlLoopService.fetchControlLoopInstantiation(windowLocationPathname).then(controlLoopList => { + ControlLoopService.getControlLoopInstantiation(windowLocationPathname).then(controlLoopList => { setControlLoopList(controlLoopList['controlLoopList']); }); }, []) diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.js deleted file mode 100644 index d9bbe8b..0000000 --- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.js +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -import React, { useState } from "react"; -import Modal from "react-bootstrap/Modal"; -import Button from "react-bootstrap/Button"; -import styled from "styled-components"; -import Row from "react-bootstrap/Row"; -import Form from "react-bootstrap/Form"; -import UploadToscaInstantiationFile from "./UploadToscaInstantiationFile"; -import jsYaml from "js-yaml"; -import Alert from "react-bootstrap/Alert"; - -const ModalStyled = styled(Modal)` - background-color: transparent; -` -const StyledMessagesDiv = styled.div` - overflow: auto; - min-width: 100%; - max-height: 300px; - padding: 5px 5px 0px 5px; - text-align: center; -` - -const UploadToscaInstantiation = (props) => { - const [show, setShow] = useState(true); - const [fileIsSelected, setFileIsSelected] = useState(false); - const [selectedFile, setSelectedFile] = useState(); - const [jsonObject, setJsonObject] = useState([]); - const [alertMessages, setAlertMessages] = useState(); - - const fileUploadHandler = (event) => { - event.preventDefault(); - console.log('fileUploadHandler called'); - - const file = event.currentTarget.files[0]; - - if (file !== undefined) { - console.log('fileDefined called'); - setSelectedFile(file); - setFileIsSelected(true); - - const fileReader = new FileReader(); - fileReader.onload = () => { - const jsonFile = jsYaml.load(fileReader.result, 'utf8') - setJsonObject(jsonFile) - } - - fileReader.readAsText(file); - } else { - console.log('fileUndefined called'); - } - } - - const onResponseReceivedHandler = async (response) => { - console.log('onResponseReceivedHandler called'); - - if (await response.ok) { - setAlertMessages(<Alert variant="success"> - <Alert.Heading>Upload Success</Alert.Heading> - <p>Tosca Instantiation from { selectedFile.name } was Successfully Uploaded</p> - <hr/> - <p>Type: { selectedFile.type }</p><p>Size: { +selectedFile.size / 1000 }Kb</p> - </Alert>); - } else { - setAlertMessages(<Alert variant="danger"> - <Alert.Heading>Upload Failure</Alert.Heading> - <p>Tosca Instantiation from { selectedFile.name } failed to upload</p> - <p>Status code: { await response.status }: { response.statusText }</p> - <p>Response Text: { await response.text() }</p> - <hr/> - <p>Type: { selectedFile.type }</p><p>Size: { +selectedFile.size / 1000 }Kb</p> - </Alert>); - } - } - - const handleClose = () => { - console.log('handleClose called'); - setShow(false); - props.history.push('/'); - } - - return ( - <ModalStyled size="lg" show={ show } onHide={ handleClose } backdrop="static" keyboard={ false }> - <Modal.Header closeButton> - <Modal.Title>Tosca Control Loop - Create Instantiation</Modal.Title> - </Modal.Header> - <div style={ { padding: '5px 5px 0px 5px' } }> - <Modal.Body> - <Form style={ { paddingTop: '20px' } }> - <Form.Group as={ Row }> - <Form.File - type="file" - className="custom-file-label" - id="inputGroupFile01" - onChange={ fileUploadHandler } - custom - accept=".yaml,.yml,.json" - label={ fileIsSelected ? selectedFile.name : 'Please select a file' }></Form.File> - <UploadToscaInstantiationFile - jsonObject={jsonObject} - onResponseReceived={onResponseReceivedHandler}/> - <Form.Text>Only .yaml, .yml and .json files are supported</Form.Text> - </Form.Group> - <Form.Group as={ Row }> - <StyledMessagesDiv> - { alertMessages } - </StyledMessagesDiv> - </Form.Group> - </Form> - </Modal.Body> - </div> - <Modal.Footer> - <Button variant="secondary" type="null" onClick={ handleClose }>Close</Button> - </Modal.Footer> - </ModalStyled> - ) -} - -export default UploadToscaInstantiation; diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.test.js deleted file mode 100644 index 79daafb..0000000 --- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiation.test.js +++ /dev/null @@ -1,102 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -import { mount, shallow } from "enzyme"; -import React from "react"; -import toJson from "enzyme-to-json"; -import UploadToscaInstantiation from "./UploadToscaInstantiation"; -import { createMemoryHistory } from "history"; -import { act } from "react-dom/test-utils"; - -describe("Verify UploadToscaInstantiation", () => { - const fs = require("fs"); - const jsonFile = fs.readFileSync("src/components/dialogs/Policy/toscaInstantiationData.test.json"); - const file = new Blob([jsonFile], { type: 'file' }); - - it("renders without crashing", () => { - shallow(<UploadToscaInstantiation/>); - }); - - it("renders correctly", () => { - const tree = shallow(<UploadToscaInstantiation/>); - expect(toJson(tree)).toMatchSnapshot(); - }); - - it('should have a Button element', () => { - const container = shallow(<UploadToscaInstantiation/>) - expect(container.find('Button').length).toEqual(1); - }); - - it('handleClose called when bottom button clicked', () => { - const history = createMemoryHistory(); - const component = mount(<UploadToscaInstantiation history={ history }/>) - const logSpy = jest.spyOn(console, 'log'); - - - act(() => { - component.find('[variant="secondary"]').simulate('click'); - expect(logSpy).toHaveBeenCalledWith('handleClose called'); - }); - }); - - it('handleClose called when top-right button clicked', () => { - const history = createMemoryHistory(); - const component = mount(<UploadToscaInstantiation history={ history }/>) - const logSpy = jest.spyOn(console, 'log'); - - - act(() => { - component.find('[size="lg"]').get(0).props.onHide(); - expect(logSpy).toHaveBeenCalledWith('handleClose called'); - }); - }); - - it('fileUploadHandler called when uploading a defined file', () => { - const component = mount(<UploadToscaInstantiation/>) - const logSpy = jest.spyOn(console, 'log'); - - const event = { - preventDefault() { - }, - currentTarget: { files: [file] } - }; - - act(() => { - component.find('[type="file"]').get(0).props.onChange(event); - expect(logSpy).toHaveBeenCalledWith('fileUploadHandler called'); - expect(logSpy).toHaveBeenCalledWith('fileDefined called'); - }); - }); - - it('fileUploadHandler called when uploading a undefined file', () => { - const component = mount(<UploadToscaInstantiation/>) - const logSpy = jest.spyOn(console, 'log'); - - const event = { - preventDefault() { - }, - currentTarget: { files: [] } - }; - - act(() => { - component.find('[type="file"]').get(0).props.onChange(event); - expect(logSpy).toHaveBeenCalledWith('fileUndefined called'); - }); - }); -}); diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.js deleted file mode 100644 index 5329bc0..0000000 --- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -import React, { useEffect, useState } from "react"; -import Button from "react-bootstrap/Button"; -import ControlLoopService from "../../../api/ControlLoopService"; - -const UploadToscaInstantiationFile = (props) => { - const [windowLocationPathName, setWindowLocationPathname] = useState(''); - - const postToscaInstantiationHandler = async (event) => { - event.preventDefault(); - console.log('postToscaInstantiationHandler called'); - - setWindowLocationPathname(window.location.pathname); - - const response = await ControlLoopService.uploadToscaInstantiation(props.jsonObject, windowLocationPathName) - .catch(error => error.message); - - props.onResponseReceived(response); - } - - return ( - <React.Fragment> - <Button variant="primary" - block={ true } - type="submit" - onClick={ postToscaInstantiationHandler }> - Upload Tosca Instantiation - </Button> - </React.Fragment> - ); -} - -export default UploadToscaInstantiationFile; - diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.test.js b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.test.js deleted file mode 100644 index 83ab8d5..0000000 --- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/UploadToscaInstantiationFile.test.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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. - * - * SPDX-License-Identifier: Apache-2.0 - * ============LICENSE_END========================================================= - */ - -import { mount, shallow } from "enzyme"; -import React from "react"; -import UploadToscaInstantiationFile from "./UploadToscaInstantiationFile"; -import toJson from "enzyme-to-json"; -import { act } from "react-dom/test-utils"; - -describe('Verify UploadToscaInstantiationFile', () => { - - it("renders without crashing", () => { - shallow(<UploadToscaInstantiationFile />); - }); - - it("renders correctly", () => { - const tree = shallow(<UploadToscaInstantiationFile />); - expect(toJson(tree)).toMatchSnapshot(); - }); - - it('should have a Button element', () => { - const container = shallow(<UploadToscaInstantiationFile />) - expect(container.find('Button').length).toEqual(1); - }); - - it('Button should have a specific text', () => { - const container = shallow(<UploadToscaInstantiationFile />) - expect(container.find('Button').text()).toBe('Upload Tosca Instantiation'); - }); - - it('button should call postToscaInstantiationHandler when clicked', async () => { - const mockFunction = jest.fn(() => 'default'); - const component = mount(<UploadToscaInstantiationFile onResponseReceived={mockFunction}/>) - const logSpy = jest.spyOn(console, 'log'); - const event = { - preventDefault() { - } - }; - - await act(async () => { - component.find('[variant="primary"]').get(0).props.onClick(event); - expect(logSpy).toHaveBeenCalledWith('postToscaInstantiationHandler called'); - }); - }); -}); diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap new file mode 100644 index 0000000..07ae8f8 --- /dev/null +++ b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/InstanceModal.test.js.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Verify MonitoringInstantiation renders correctly 1`] = ` +<Styled(Modal) + backdrop="static" + keyboard={false} + onHide={[Function]} + show={true} + size="xl" +> + <ModalHeader + closeButton={true} + closeLabel="Close" + > + <ModalTitle> + Change Tosca Instance Properties + </ModalTitle> + </ModalHeader> + <div + style={ + Object { + "padding": "5px 5px 0 5px", + } + } + > + <ModalBody> + <div + id="editor" + /> + </ModalBody> + <styled.div /> + </div> + <ModalFooter> + <Button + active={false} + disabled={false} + onClick={[Function]} + variant="primary" + > + Save + </Button> + <Button + active={false} + disabled={false} + onClick={[Function]} + variant="secondary" + > + Close + </Button> + </ModalFooter> +</Styled(Modal)> +`; diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiation.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiation.test.js.snap deleted file mode 100644 index 77e4b99..0000000 --- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiation.test.js.snap +++ /dev/null @@ -1,91 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Verify UploadToscaInstantiation renders correctly 1`] = ` -<Styled(Modal) - backdrop="static" - keyboard={false} - onHide={[Function]} - show={true} - size="lg" -> - <ModalHeader - closeButton={true} - closeLabel="Close" - > - <ModalTitle> - Tosca Control Loop - Create Instantiation - </ModalTitle> - </ModalHeader> - <div - style={ - Object { - "padding": "5px 5px 0px 5px", - } - } - > - <ModalBody> - <Form - inline={false} - style={ - Object { - "paddingTop": "20px", - } - } - > - <FormGroup - as={ - Object { - "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "noGutters": false, - }, - "render": [Function], - } - } - > - <FormFile - accept=".yaml,.yml,.json" - className="custom-file-label" - custom={true} - id="inputGroupFile01" - label="Please select a file" - onChange={[Function]} - type="file" - /> - <UploadToscaInstantiationFile - jsonObject={Array []} - onResponseReceived={[Function]} - /> - <FormText> - Only .yaml, .yml and .json files are supported - </FormText> - </FormGroup> - <FormGroup - as={ - Object { - "$$typeof": Symbol(react.forward_ref), - "defaultProps": Object { - "noGutters": false, - }, - "render": [Function], - } - } - > - <styled.div /> - </FormGroup> - </Form> - </ModalBody> - </div> - <ModalFooter> - <Button - active={false} - disabled={false} - onClick={[Function]} - type="null" - variant="secondary" - > - Close - </Button> - </ModalFooter> -</Styled(Modal)> -`; diff --git a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiationFile.test.js.snap b/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiationFile.test.js.snap deleted file mode 100644 index 3ac5087..0000000 --- a/gui-clamp/ui-react/src/components/dialogs/ControlLoop/__snapshots__/UploadToscaInstantiationFile.test.js.snap +++ /dev/null @@ -1,16 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Verify UploadToscaInstantiationFile renders correctly 1`] = ` -<Fragment> - <Button - active={false} - block={true} - disabled={false} - onClick={[Function]} - type="submit" - variant="primary" - > - Upload Tosca Instantiation - </Button> -</Fragment> -`; diff --git a/gui-clamp/ui-react/src/components/menu/MenuBar.js b/gui-clamp/ui-react/src/components/menu/MenuBar.js index abe73c1..7ee7ffd 100644 --- a/gui-clamp/ui-react/src/components/menu/MenuBar.js +++ b/gui-clamp/ui-react/src/components/menu/MenuBar.js @@ -116,7 +116,7 @@ export default class MenuBar extends React.Component { <StyledNavDropdown title="TOSCA Control Loop"> <NavDropdown.Header>Instantiation</NavDropdown.Header> <NavDropdown.Item as={ StyledLink } to="/monitorInstantiation">Monitor Instantiation</NavDropdown.Item> - <NavDropdown.Item as={ StyledLink } to="/uploadToscaInstantiation">Upload Tosca Instantiation</NavDropdown.Item> + <NavDropdown.Item as={ StyledLink } to="/editControlLoopInstanceProperties">Edit Control Loop Instance Properties</NavDropdown.Item> <NavDropdown.Divider /> <NavDropdown.Header>Commissioning</NavDropdown.Header> <NavDropdown.Item as={ StyledLink } to="/readToscaTemplate">Manage Commissioned Tosca Template</NavDropdown.Item> diff --git a/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap b/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap index 800e1dd..edc0624 100644 --- a/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap +++ b/gui-clamp/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap @@ -1136,9 +1136,9 @@ exports[`Verify MenuBar Test the render method 1`] = ` } } disabled={false} - to="/uploadToscaInstantiation" + to="/editControlLoopInstanceProperties" > - Upload Tosca Instantiation + Edit Control Loop Instance Properties </DropdownItem> <DropdownDivider role="separator" |