/***************************************************************************** * Open MCT, Copyright (c) 2014-2023, 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 { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing'; import { nextTick } from 'vue'; import { FIXED_MODE_KEY } from '../../api/time/constants.js'; import { getPreciseDuration, millisecondsToDHMS } from '../../utils/duration.js'; import ConductorPlugin from './plugin.js'; const THIRTY_SECONDS = 30 * 1000; const ONE_MINUTE = THIRTY_SECONDS * 2; const FIVE_MINUTES = ONE_MINUTE * 5; const FIFTEEN_MINUTES = FIVE_MINUTES * 3; const THIRTY_MINUTES = FIFTEEN_MINUTES * 2; const date = new Date(Date.UTC(78, 0, 20, 0, 0, 0)).getTime(); describe('time conductor', () => { let element; let child; let appHolder; let openmct; let config = { menuOptions: [ { name: 'FixedTimeRange', timeSystem: 'utc', bounds: { start: date - THIRTY_MINUTES, end: date }, presets: [], records: 2 }, { name: 'LocalClock', timeSystem: 'utc', clock: 'local', clockOffsets: { start: -THIRTY_MINUTES, end: THIRTY_SECONDS }, presets: [] } ] }; beforeEach((done) => { openmct = createOpenMct(); openmct.install(new ConductorPlugin(config)); element = document.createElement('div'); element.style.width = '640px'; element.style.height = '480px'; child = document.createElement('div'); child.style.width = '640px'; child.style.height = '480px'; element.appendChild(child); openmct.on('start', () => { openmct.time.setMode(FIXED_MODE_KEY, { start: config.menuOptions[0].bounds.start, end: config.menuOptions[0].bounds.end }); nextTick(() => { done(); }); }); appHolder = document.createElement('div'); openmct.start(appHolder); }); afterEach(() => { appHolder = undefined; openmct = undefined; return resetApplicationState(openmct); }); describe('in fixed time mode', () => { it('shows delta inputs', () => { const fixedModeEl = appHolder.querySelector('.is-fixed-mode'); const dateTimeInputs = fixedModeEl.querySelectorAll('.c-compact-tc__setting-value__elem'); expect(dateTimeInputs[0].innerHTML.trim()).toEqual('Fixed Timespan'); expect(dateTimeInputs[1].innerHTML.trim()).toEqual('Local Clock'); expect(dateTimeInputs[2].innerHTML.trim()).toEqual('UTC'); const dateTimes = fixedModeEl.querySelectorAll('.c-compact-tc__setting-value'); expect(dateTimes[1].innerHTML.trim()).toEqual('1978-01-19 23:30:00.000Z'); expect(dateTimes[2].innerHTML.trim()).toEqual('1978-01-20 00:00:00.000Z'); }); }); describe('in realtime mode', () => { beforeEach(async () => { openmct.time.setClockOffsets({ start: -THIRTY_MINUTES, end: THIRTY_SECONDS }); const switcher = appHolder.querySelector('.is-fixed-mode'); const clickEvent = createMouseEvent('click'); switcher.dispatchEvent(clickEvent); await nextTick(); const modeButton = switcher.querySelector('.c-tc-input-popup .c-button--menu'); const clickEvent1 = createMouseEvent('click'); modeButton.dispatchEvent(clickEvent1); await nextTick(); const clockItem = document.querySelectorAll( '.c-conductor__mode-menu .c-super-menu__menu li' )[1]; const clickEvent2 = createMouseEvent('click'); clockItem.dispatchEvent(clickEvent2); await nextTick(); await nextTick(); }); it('shows delta inputs', () => { const realtimeModeEl = appHolder.querySelector('.is-realtime-mode'); const dateTimeInputs = realtimeModeEl.querySelectorAll('.c-compact-tc__setting-value__elem'); expect(dateTimeInputs[0].innerHTML.trim()).toEqual('Real-Time'); const dateTimes = realtimeModeEl.querySelectorAll('.c-compact-tc__setting-value'); expect(dateTimes[1].innerHTML.replace(/[^(\d|:)]/g, '')).toEqual('00:30:00'); expect(dateTimes[2].innerHTML.replace(/[^(\d|:)]/g, '')).toEqual('00:00:30'); }); it('shows clock options', () => { const realtimeModeEl = appHolder.querySelector('.is-realtime-mode'); const dateTimeInputs = realtimeModeEl.querySelectorAll('.c-compact-tc__setting-value__elem'); expect(dateTimeInputs[1].innerHTML.trim()).toEqual('Local Clock'); }); it('shows the current time', () => { const realtimeModeEl = appHolder.querySelector('.is-realtime-mode'); const currentTimeEl = realtimeModeEl.querySelector('.c-compact-tc__current-update'); const currentTime = openmct.time.clock().currentValue(); const { start, end } = openmct.time.bounds(); expect(currentTime).toBeGreaterThan(start); expect(currentTime).toBeLessThanOrEqual(end); expect(currentTimeEl.innerHTML.trim().length).toBeGreaterThan(0); }); }); }); describe('duration functions', () => { it('should transform milliseconds to DHMS', () => { const functionResults = [ millisecondsToDHMS(0), millisecondsToDHMS(86400000), millisecondsToDHMS(129600000), millisecondsToDHMS(661824000), millisecondsToDHMS(213927028) ]; const validResults = [' ', '+ 1d', '+ 1d 12h', '+ 7d 15h 50m 24s', '+ 2d 11h 25m 27s 28ms']; expect(validResults).toEqual(functionResults); }); it('should get precise duration', () => { const functionResults = [ getPreciseDuration(0), getPreciseDuration(643680000), getPreciseDuration(1605312000), getPreciseDuration(213927028) ]; const validResults = [ '00:00:00:00:000', '07:10:48:00:000', '18:13:55:12:000', '02:11:25:27:028' ]; expect(validResults).toEqual(functionResults); }); });