fix(#7670): Ensure objects unsubscribe from staleness when destroyed (#7736)

* clear any staleness subscriptions before viewing a new object

* add checkbox to options for createDomainObjectWithDefaults, update swg staleness provider to use new time api, add test

* revert

* modified for simplification and to remove the need to update helper methods

* consistent naming convention

* Update e2e/tests/functional/staleness.e2e.spec.js

Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>

* adding back vars that were removed

---------

Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>
This commit is contained in:
Jamie V 2024-05-31 13:46:59 -07:00 committed by GitHub
parent 017380bb6a
commit eba6f0f505
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 74 additions and 13 deletions

View File

@ -0,0 +1,64 @@
/*****************************************************************************
* 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 { createDomainObjectWithDefaults, navigateToObjectWithRealTime } from '../../appActions.js';
import { expect, test } from '../../pluginFixtures.js';
test.describe('Staleness', () => {
test.beforeEach(async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });
});
test('Does not show staleness after navigating from a stale object', async ({ page }) => {
const objectViewSelector = '.c-object-view';
const isStaleClass = 'is-stale';
const staleSWG = await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator',
name: 'SWG'
});
// edit properties and enable staleness updates
await page.getByLabel('More actions').click();
await page.getByLabel('Edit properties...').click();
await page.getByLabel('Provide Staleness Updates', { exact: true }).click();
await page.getByLabel('Save').click();
const folder = await createDomainObjectWithDefaults(page, {
type: 'Folder',
name: 'Folder 1'
});
// Navigate to the stale object
await navigateToObjectWithRealTime(page, staleSWG.url);
// Assert that staleness is shown
await expect(page.locator(`${objectViewSelector} .${isStaleClass}`)).toBeAttached({
timeout: 30 * 1000 // Give 30 seconds for the staleness to be updated
});
// Immediately navigate to the folder
await page.goto(folder.url);
// Verify that staleness is not shown
await expect(page.locator(`${objectViewSelector} .${isStaleClass}`)).not.toBeAttached();
});
});

View File

@ -26,7 +26,6 @@ export default class SinewaveLimitProvider extends EventEmitter {
#openmct;
#observingStaleness;
#watchingTheClock;
#isRealTime;
constructor(openmct) {
super();
@ -34,7 +33,6 @@ export default class SinewaveLimitProvider extends EventEmitter {
this.#openmct = openmct;
this.#observingStaleness = {};
this.#watchingTheClock = false;
this.#isRealTime = undefined;
}
supportsStaleness(domainObject) {
@ -61,10 +59,7 @@ export default class SinewaveLimitProvider extends EventEmitter {
subscribeToStaleness(domainObject, callback) {
const id = this.#getObjectKeyString(domainObject);
if (this.#isRealTime === undefined) {
this.#updateRealTime(this.#openmct.time.getMode());
}
this.#realTimeCheck();
this.#handleClockUpdate();
if (this.#observerExists(id)) {
@ -92,17 +87,15 @@ export default class SinewaveLimitProvider extends EventEmitter {
if (observers && !this.#watchingTheClock) {
this.#watchingTheClock = true;
this.#openmct.time.on('modeChanged', this.#updateRealTime, this);
this.#openmct.time.on('modeChanged', this.#realTimeCheck, this);
} else if (!observers && this.#watchingTheClock) {
this.#watchingTheClock = false;
this.#openmct.time.off('modeChanged', this.#updateRealTime, this);
this.#openmct.time.off('modeChanged', this.#realTimeCheck, this);
}
}
#updateRealTime(mode) {
this.#isRealTime = mode !== 'fixed';
if (!this.#isRealTime) {
#realTimeCheck() {
if (!this.#openmct.time.isRealTime()) {
Object.keys(this.#observingStaleness).forEach((id) => {
this.#updateStaleness(id, false);
});
@ -140,7 +133,7 @@ export default class SinewaveLimitProvider extends EventEmitter {
}
#providingStaleness(domainObject) {
return domainObject.telemetry?.staleness === true && this.#isRealTime;
return domainObject.telemetry?.staleness === true && this.#openmct.time.isRealTime();
}
#getObjectKeyString(object) {

View File

@ -352,6 +352,10 @@ export default {
show(object, viewKey, immediatelySelect, currentObjectPath) {
this.updateStyle();
if (this.domainObject) {
this.triggerUnsubscribeFromStaleness(this.domainObject);
}
if (this.removeSelectable) {
this.removeSelectable();
delete this.removeSelectable;