 e9968e3649
			
		
	
	e9968e3649
	
	
	
		
			
			* Added new test to telemetry tables to check that telemetry data is correctly rendered in rows * Added test tools for mocking builtins * Changed order that promises are resolved to address race condition * Remove duplicate installation of UTC Time System * Added additional test telemetry * Start Open MCT headless * Added headless mode start option. Fixes #3064 * Added new non-angular URL handler * Removed legacy Angular TimeSettingsURLHandler * Added function to testTools to reset application state * Use resetApplicationState function from telemetry table spec * Added new TimeSettingsURLHandler to plugins * Added missing semicolons * #2826 Refactored code into separate class * Handling of hash-relative URLs * Refactoring URL sync code * Refactored to external class * Moved utils to new 'utils' directory. Refactored location util functions from class to exported functions * Added test specs for openmctLocation * Added new function to destroy instances of Open MCT between test runs * Ensure test specs are cleaning up after themselves * Added test spec for new URLTimeSettingsSynchronizer * Removed use of shell script as it doesn't work in windows * Pushed test coverage to 100% * Added missing copyright statement * Removed debugging output * Fixed linting error * Upgrade node version * Clear cache * Re-enabled tests Co-authored-by: Melanie Lean <melanielean@Melanies-MacBook-Pro.local> Co-authored-by: Shefali Joshi <simplyrender@gmail.com> Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
		
			
				
	
	
		
			360 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			360 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*****************************************************************************
 | |
|  * Open MCT, Copyright (c) 2014-2020, United States Government
 | |
|  * as represented by the Administrator of the National Aeronautics and Space
 | |
|  * Administration. All rights reserved.
 | |
|  *
 | |
|  * Open MCT is 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.
 | |
|  *
 | |
|  * Open MCT includes source code licensed under additional open source
 | |
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | |
|  * this source code distribution or the Licensing information page available
 | |
|  * at runtime from the About dialog for additional information.
 | |
|  *****************************************************************************/
 | |
| 
 | |
| import { createOpenMct, resetApplicationState } from "utils/testing";
 | |
| import ConditionPlugin from "./plugin";
 | |
| import StylesView from "./components/inspector/StylesView.vue";
 | |
| import Vue from 'vue';
 | |
| import {getApplicableStylesForItem} from "./utils/styleUtils";
 | |
| 
 | |
| describe('the plugin', function () {
 | |
|     let conditionSetDefinition;
 | |
|     let mockConditionSetDomainObject;
 | |
|     let element;
 | |
|     let child;
 | |
|     let openmct;
 | |
| 
 | |
|     beforeAll(() => {
 | |
|         resetApplicationState(openmct);
 | |
|     });
 | |
| 
 | |
|     beforeEach((done) => {
 | |
|         openmct = createOpenMct();
 | |
|         openmct.install(new ConditionPlugin());
 | |
| 
 | |
|         conditionSetDefinition = openmct.types.get('conditionSet').definition;
 | |
| 
 | |
|         element = document.createElement('div');
 | |
|         child = document.createElement('div');
 | |
|         element.appendChild(child);
 | |
| 
 | |
|         mockConditionSetDomainObject = {
 | |
|             identifier: {
 | |
|                 key: 'testConditionSetKey',
 | |
|                 namespace: ''
 | |
|             },
 | |
|             type: 'conditionSet'
 | |
|         };
 | |
| 
 | |
|         conditionSetDefinition.initialize(mockConditionSetDomainObject);
 | |
| 
 | |
|         openmct.on('start', done);
 | |
|         openmct.startHeadless();
 | |
|     });
 | |
| 
 | |
|     afterEach(() => {
 | |
|         resetApplicationState(openmct);
 | |
|     });
 | |
| 
 | |
|     let mockConditionSetObject = {
 | |
|         name: 'Condition Set',
 | |
|         key: 'conditionSet',
 | |
|         creatable: true
 | |
|     };
 | |
| 
 | |
|     it('defines a conditionSet object type with the correct key', () => {
 | |
|         expect(conditionSetDefinition.key).toEqual(mockConditionSetObject.key);
 | |
|     });
 | |
| 
 | |
|     describe('the conditionSet object', () => {
 | |
| 
 | |
|         it('is creatable', () => {
 | |
|             expect(conditionSetDefinition.creatable).toEqual(mockConditionSetObject.creatable);
 | |
|         });
 | |
| 
 | |
|         it('initializes with an empty composition list', () => {
 | |
|             expect(mockConditionSetDomainObject.composition instanceof Array).toBeTrue();
 | |
|             expect(mockConditionSetDomainObject.composition.length).toEqual(0);
 | |
|         });
 | |
| 
 | |
|         it('provides a view', () => {
 | |
|             const testViewObject = {
 | |
|                 id:"test-object",
 | |
|                 type: "conditionSet",
 | |
|                 configuration: {
 | |
|                     conditionCollection: []
 | |
|                 }
 | |
|             };
 | |
| 
 | |
|             const applicableViews = openmct.objectViews.get(testViewObject);
 | |
|             let conditionSetView = applicableViews.find((viewProvider) => viewProvider.key === 'conditionSet.view');
 | |
|             expect(conditionSetView).toBeDefined();
 | |
|         });
 | |
| 
 | |
|     });
 | |
| 
 | |
|     describe('the condition set usage for multiple display layout items', () => {
 | |
|         let displayLayoutItem;
 | |
|         let lineLayoutItem;
 | |
|         let boxLayoutItem;
 | |
|         let selection;
 | |
|         let component;
 | |
|         let styleViewComponentObject;
 | |
|         const conditionSetDomainObject = {
 | |
|             "configuration":{
 | |
|                 "conditionTestData":[
 | |
|                     {
 | |
|                         "telemetry":"",
 | |
|                         "metadata":"",
 | |
|                         "input":""
 | |
|                     }
 | |
|                 ],
 | |
|                 "conditionCollection":[
 | |
|                     {
 | |
|                         "id":"39584410-cbf9-499e-96dc-76f27e69885d",
 | |
|                         "configuration":{
 | |
|                             "name":"Unnamed Condition",
 | |
|                             "output":"Sine > 0",
 | |
|                             "trigger":"all",
 | |
|                             "criteria":[
 | |
|                                 {
 | |
|                                     "id":"85fbb2f7-7595-42bd-9767-a932266c5225",
 | |
|                                     "telemetry":{
 | |
|                                         "namespace":"",
 | |
|                                         "key":"be0ba97f-b510-4f40-a18d-4ff121d5ea1a"
 | |
|                                     },
 | |
|                                     "operation":"greaterThan",
 | |
|                                     "input":[
 | |
|                                         "0"
 | |
|                                     ],
 | |
|                                     "metadata":"sin"
 | |
|                                 },
 | |
|                                 {
 | |
|                                     "id":"35400132-63b0-425c-ac30-8197df7d5862",
 | |
|                                     "telemetry":"any",
 | |
|                                     "operation":"enumValueIs",
 | |
|                                     "input":[
 | |
|                                         "0"
 | |
|                                     ],
 | |
|                                     "metadata":"state"
 | |
|                                 }
 | |
|                             ]
 | |
|                         },
 | |
|                         "summary":"Match if all criteria are met: Sine Wave Generator Sine > 0 and any telemetry State is OFF "
 | |
|                     },
 | |
|                     {
 | |
|                         "isDefault":true,
 | |
|                         "id":"2532d90a-e0d6-4935-b546-3123522da2de",
 | |
|                         "configuration":{
 | |
|                             "name":"Default",
 | |
|                             "output":"Default",
 | |
|                             "trigger":"all",
 | |
|                             "criteria":[
 | |
|                             ]
 | |
|                         },
 | |
|                         "summary":""
 | |
|                     }
 | |
|                 ]
 | |
|             },
 | |
|             "composition":[
 | |
|                 {
 | |
|                     "namespace":"",
 | |
|                     "key":"be0ba97f-b510-4f40-a18d-4ff121d5ea1a"
 | |
|                 },
 | |
|                 {
 | |
|                     "namespace":"",
 | |
|                     "key":"077ffa67-e78f-4e99-80e0-522ac33a3888"
 | |
|                 }
 | |
|             ],
 | |
|             "telemetry":{
 | |
|             },
 | |
|             "name":"Condition Set",
 | |
|             "type":"conditionSet",
 | |
|             "identifier":{
 | |
|                 "namespace":"",
 | |
|                 "key":"863012c1-f6ca-4ab0-aed7-fd43d5e4cd12"
 | |
|             }
 | |
| 
 | |
|         };
 | |
|         const staticStyle = {
 | |
|             "style":{
 | |
|                 "backgroundColor":"#717171",
 | |
|                 "border":"1px solid #00ffff"
 | |
|             }
 | |
|         };
 | |
|         const conditionalStyle = {
 | |
|             "conditionId":"39584410-cbf9-499e-96dc-76f27e69885d",
 | |
|             "style":{
 | |
|                 "isStyleInvisible":"",
 | |
|                 "backgroundColor":"#717171",
 | |
|                 "border":"1px solid #ffff00"
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         beforeEach(() => {
 | |
|             displayLayoutItem = {
 | |
|                 "composition":[
 | |
|                 ],
 | |
|                 "configuration":{
 | |
|                     "items":[
 | |
|                         {
 | |
|                             "fill":"#717171",
 | |
|                             "stroke":"",
 | |
|                             "x":1,
 | |
|                             "y":1,
 | |
|                             "width":10,
 | |
|                             "height":5,
 | |
|                             "type":"box-view",
 | |
|                             "id":"89b88746-d325-487b-aec4-11b79afff9e8"
 | |
|                         },
 | |
|                         {
 | |
|                             "x":18,
 | |
|                             "y":9,
 | |
|                             "x2":23,
 | |
|                             "y2":4,
 | |
|                             "stroke":"#717171",
 | |
|                             "type":"line-view",
 | |
|                             "id":"57d49a28-7863-43bd-9593-6570758916f0"
 | |
|                         }
 | |
|                     ],
 | |
|                     "layoutGrid":[
 | |
|                         10,
 | |
|                         10
 | |
|                     ]
 | |
|                 },
 | |
|                 "name":"Display Layout",
 | |
|                 "type":"layout",
 | |
|                 "identifier":{
 | |
|                     "namespace":"",
 | |
|                     "key":"c5e636c1-6771-4c9c-b933-8665cab189b3"
 | |
|                 }
 | |
|             };
 | |
|             lineLayoutItem = {
 | |
|                 "x":18,
 | |
|                 "y":9,
 | |
|                 "x2":23,
 | |
|                 "y2":4,
 | |
|                 "stroke":"#717171",
 | |
|                 "type":"line-view",
 | |
|                 "id":"57d49a28-7863-43bd-9593-6570758916f0"
 | |
|             };
 | |
|             boxLayoutItem = {
 | |
|                 "fill": "#717171",
 | |
|                 "stroke": "",
 | |
|                 "x": 1,
 | |
|                 "y": 1,
 | |
|                 "width": 10,
 | |
|                 "height": 5,
 | |
|                 "type": "box-view",
 | |
|                 "id": "89b88746-d325-487b-aec4-11b79afff9e8"
 | |
|             };
 | |
|             selection = [
 | |
|                 [{
 | |
|                     context: {
 | |
|                         "layoutItem": lineLayoutItem,
 | |
|                         "index":1
 | |
|                     }
 | |
|                 },
 | |
|                 {
 | |
|                     context: {
 | |
|                         "item": displayLayoutItem,
 | |
|                         "supportsMultiSelect":true
 | |
|                     }
 | |
|                 }],
 | |
|                 [{
 | |
|                     context: {
 | |
|                         "layoutItem": boxLayoutItem,
 | |
|                         "index": 0
 | |
|                     }
 | |
|                 },
 | |
|                 {
 | |
|                     context: {
 | |
|                         item: displayLayoutItem,
 | |
|                         "supportsMultiSelect":true
 | |
|                     }
 | |
|                 }]
 | |
|             ];
 | |
|             let viewContainer = document.createElement('div');
 | |
|             child.append(viewContainer);
 | |
|             component = new Vue({
 | |
|                 provide: {
 | |
|                     openmct: openmct,
 | |
|                     selection: selection
 | |
|                 },
 | |
|                 el: viewContainer,
 | |
|                 components: {
 | |
|                     StylesView
 | |
|                 },
 | |
|                 template: '<styles-view/>'
 | |
|             });
 | |
|             return Vue.nextTick().then(() => {
 | |
|                 styleViewComponentObject = component.$root.$children[0];
 | |
|                 styleViewComponentObject.setEditState(true);
 | |
|             });
 | |
|         });
 | |
| 
 | |
|         it('initializes the items in the view', () => {
 | |
|             expect(styleViewComponentObject.items.length).toBe(2);
 | |
|         });
 | |
| 
 | |
|         it('initializes conditional styles', () => {
 | |
|             styleViewComponentObject.conditionSetDomainObject = conditionSetDomainObject;
 | |
|             styleViewComponentObject.conditionalStyles = [];
 | |
|             styleViewComponentObject.initializeConditionalStyles();
 | |
|             expect(styleViewComponentObject.conditionalStyles.length).toBe(2);
 | |
|         });
 | |
| 
 | |
|         it('updates applicable conditional styles', () => {
 | |
|             styleViewComponentObject.conditionSetDomainObject = conditionSetDomainObject;
 | |
|             styleViewComponentObject.conditionalStyles = [];
 | |
|             styleViewComponentObject.initializeConditionalStyles();
 | |
|             expect(styleViewComponentObject.conditionalStyles.length).toBe(2);
 | |
|             styleViewComponentObject.updateConditionalStyle(conditionalStyle, 'border');
 | |
|             return Vue.nextTick().then(() => {
 | |
|                 expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
 | |
|                 [boxLayoutItem, lineLayoutItem].forEach((item) => {
 | |
|                     const itemStyles = styleViewComponentObject.domainObject.configuration.objectStyles[item.id].styles;
 | |
|                     expect(itemStyles.length).toBe(2);
 | |
|                     const foundStyle = itemStyles.find((style) => {
 | |
|                         return style.conditionId === conditionalStyle.conditionId;
 | |
|                     });
 | |
|                     expect(foundStyle).toBeDefined();
 | |
|                     const applicableStyles = getApplicableStylesForItem(styleViewComponentObject.domainObject, item);
 | |
|                     const applicableStylesKeys = Object.keys(applicableStyles).concat(['isStyleInvisible']);
 | |
|                     Object.keys(foundStyle.style).forEach((key) => {
 | |
|                         expect(applicableStylesKeys.indexOf(key)).toBeGreaterThan(-1);
 | |
|                         expect(foundStyle.style[key]).toEqual(conditionalStyle.style[key]);
 | |
|                     });
 | |
|                 });
 | |
|             });
 | |
|         });
 | |
| 
 | |
|         it('updates applicable static styles', () => {
 | |
|             styleViewComponentObject.updateStaticStyle(staticStyle, 'border');
 | |
|             return Vue.nextTick().then(() => {
 | |
|                 expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
 | |
|                 [boxLayoutItem, lineLayoutItem].forEach((item) => {
 | |
|                     const itemStyle = styleViewComponentObject.domainObject.configuration.objectStyles[item.id].staticStyle;
 | |
|                     expect(itemStyle).toBeDefined();
 | |
|                     const applicableStyles = getApplicableStylesForItem(styleViewComponentObject.domainObject, item);
 | |
|                     const applicableStylesKeys = Object.keys(applicableStyles).concat(['isStyleInvisible']);
 | |
|                     Object.keys(itemStyle.style).forEach((key) => {
 | |
|                         expect(applicableStylesKeys.indexOf(key)).toBeGreaterThan(-1);
 | |
|                         expect(itemStyle.style[key]).toEqual(staticStyle.style[key]);
 | |
|                     });
 | |
|                 });
 | |
|             });
 | |
|         });
 | |
| 
 | |
|     });
 | |
| });
 |