From 3360016759778e945973889152b9f56f345a94f7 Mon Sep 17 00:00:00 2001 From: Jamie V Date: Fri, 12 Jul 2024 14:04:15 -0700 Subject: [PATCH] Update unit tests invalidated by legacy removal changes (#183) --- src/exportDataAction/ExportDataActionSpec.js | 314 +++++++++---------- src/exportDataAction/ExportDataTask.js | 2 +- src/exportDataAction/ExportDataTaskSpec.js | 132 ++++---- src/types/TypeCompositionPolicySpec.js | 49 ++- 4 files changed, 220 insertions(+), 277 deletions(-) diff --git a/src/exportDataAction/ExportDataActionSpec.js b/src/exportDataAction/ExportDataActionSpec.js index aad9103..3b5c443 100644 --- a/src/exportDataAction/ExportDataActionSpec.js +++ b/src/exportDataAction/ExportDataActionSpec.js @@ -1,220 +1,198 @@ /*global define,describe,beforeEach,jasmine,spyOn,Promise,it,expect,waitsFor,runs,afterEach*/ define([ - '../src/ExportDataAction' -], function (ExportDataAction) { - 'use strict'; - - xdescribe("The Export Data action", function () { - var mockExportService, - openmct, - mockTelemetryObject, - mockRealtimeOnlyTelemetryObject, - mockDelegatingObject, - mockDelegateObjects, - mockNotification, - mockCallback, - telemetryPromises, - telemetryRequested; - - function makeMockDomainObject(id, capabilities, realtimeOnly) { - var mockDomainObject = jasmine.createSpyObj('object-' + id, [ - 'getId', - 'getModel', - 'hasCapability', - 'useCapability', - 'getCapability' - ]); - mockDomainObject.getId.and.returnValue(id); - mockDomainObject.getModel.and.returnValue({telemetry: {realtimeOnly: realtimeOnly}}); - mockDomainObject.hasCapability.and.callFake(function (c) { - return !!(capabilities[c]); - }); - mockDomainObject.getCapability.and.callFake(function (c) { - return capabilities[c]; - }); - mockDomainObject.useCapability.and.callFake(function (c) { - return capabilities[c].invoke(); - }); + './ExportDataAction' +], (ExportDataActionModule) => { + const ExportDataAction = ExportDataActionModule.default; + + describe('The Export Data action', () => { + let mockOpenmct; + let mockCompositionCollection; + let mockComposition; + let mockTelemetryObject; + let mockRealtimeOnlyTelemetryObject; + let mockTelemetryObjectWithComposition; + let mockNotification; + let telemetryPromises; + let exportDataAction; + let telemetryRequested; + let telemetryRequestCount; + + function makeMockDomainObject(id, telemetry, realtimeOnly) { + let mockDomainObject = { + identifier: { + namespace: 'object', + key: id + }, + type: 'validType', + } + + if (telemetry) { + mockDomainObject.telemetry = {}; + } + + if (realtimeOnly) { + mockDomainObject.realtimeOnly = true; + } + return mockDomainObject; } function telemetryPromise() { - return new Promise(function (resolve, reject) { - telemetryPromises.push({ resolve: resolve, reject: reject }); + return new Promise((resolve, reject) => { + telemetryPromises.push({ resolve, reject }); setTimeout(telemetryRequested); }); } - function makeMockTelemetryObject(id) { - var mockTelemetry = jasmine.createSpyObj('telemetry-' + id, [ - 'requestData', - 'subscribe' - ]); - mockTelemetry.requestData.and.callFake(telemetryPromise); - return makeMockDomainObject(id, { telemetry: mockTelemetry }); - } - - function makeMockRealtimeOnlyTelemetryObject(id) { - var mockTelemetry = jasmine.createSpyObj('telemetry-' + id, [ - 'requestData', - 'subscribe' - ]); - mockTelemetry.requestData.and.callFake(telemetryPromise); - return makeMockDomainObject(id, { telemetry: mockTelemetry }, true); - } - - beforeEach(function () { - var mockCapabilities = { - composition: jasmine.createSpyObj('composition', ['invoke']), - delegation: jasmine.createSpyObj( - 'delegation', - ['doesDelegateCapability'] - ) - }; - + beforeEach(() => { telemetryPromises = []; - telemetryRequested = jasmine.createSpy('telemetryRequested'); + telemetryRequested = jasmine.createSpy('telemetryRequested').and.callFake(() => { + telemetryRequestCount--; + if (telemetryRequestCount === 0) { + telemetryRequested.done(); + } + }); - openmct = jasmine.createSpyObj('openmct', + mockOpenmct = jasmine.createSpyObj('mockOpenmct', [ - 'overlays', - 'notifications' + 'notifications', + 'composition', + 'telemetry' ] ); - openmct.notifications = jasmine.createSpyObj('notificationService', - ['error'] - ); - openmct.overlays = jasmine.createSpyObj('overlays', - ['progressDialog'] - ); - mockExportService = jasmine.createSpyObj( - 'exportService', - ['exportCSV'] + mockTelemetry = []; + mockCompositionCollection = jasmine.createSpyObj('compositionCollection', ['load']); + mockCompositionCollection.load.and.returnValue(Promise.resolve(mockComposition)); + mockOpenmct.composition = jasmine.createSpyObj('composition', ['get']); + mockOpenmct.composition.get.and.returnValue(mockCompositionCollection); + mockOpenmct.telemetry = jasmine.createSpyObj('telemetry', ['isTelemetryObject', 'request']); + mockOpenmct.telemetry.request.and.callFake(telemetryPromise); + mockOpenmct.telemetry.isTelemetryObject.and.callFake((object) => { + return object.telemetry; + }); + mockOpenmct.notifications = jasmine.createSpyObj('notificationService', + [ + 'error', + 'progress', + 'info' + ] ); mockNotification = jasmine.createSpyObj('notification', ['dismiss']); - mockTelemetryObject = makeMockTelemetryObject('singular'); - mockRealtimeOnlyTelemetryObject = makeMockRealtimeOnlyTelemetryObject('singular'); - mockDelegateObjects = - ['a', 'b', 'c'].map(makeMockTelemetryObject); - mockDelegatingObject = - makeMockDomainObject('delegator', mockCapabilities); - - openmct.overlays.progressDialog.and.returnValue(mockNotification); - - mockCapabilities.delegation.doesDelegateCapability - .and.callFake(function (c) { - return c === 'telemetry'; - }); - mockCapabilities.composition.invoke - .and.returnValue(Promise.resolve(mockDelegateObjects)); - - mockCallback = jasmine.createSpy('callback'); - }); - + mockTelemetryObject = makeMockDomainObject('singular', true); + mockRealtimeOnlyTelemetryObject = makeMockDomainObject('singular', true, true); + mockTelemetryObjectWithComposition = makeMockDomainObject('composition'); - it("applies to objects with a telemetry capability", function () { - expect(ExportDataAction.appliesTo({ - domainObject: mockTelemetryObject - })).toBe(true); - }); + mockOpenmct.notifications.progress.and.returnValue(mockNotification); - it("applies to objects which delegate the telemetry capability", function () { - expect(ExportDataAction.appliesTo({ - domainObject: mockDelegatingObject - })).toBe(true); + exportDataAction = new ExportDataAction( + mockOpenmct, + ['validType'] + ); }); - it("does not apply to objects with no such capabilities", function () { - expect(ExportDataAction.appliesTo({ - domainObject: makeMockDomainObject('foo', {}) - })).toBe(false); + it('applies to objects with a valid type', () => { + expect(exportDataAction.appliesTo([mockTelemetryObject])).toBe(true); }); - it("does not apply to realtime only telemetry objects", function () { - expect(ExportDataAction.appliesTo({ - domainObject: mockRealtimeOnlyTelemetryObject - })).toBe(false); + it('does not apply to realtime only telemetry objects', (done) => { + telemetryRequested.and.callFake(done); + exportDataAction.invoke([mockRealtimeOnlyTelemetryObject]).then(() => { + expect(mockOpenmct.notifications.info).toHaveBeenCalledWith('No historical data to export'); + }); }); - - [ false, true ].forEach(function (singular) { - var targetDescription = singular ? - "a single object" : "multiple objects"; - - describe("when performed on " + targetDescription, function () { - var mockTarget; - - beforeEach(function (done) { - mockTarget = singular ? - mockTelemetryObject : mockDelegatingObject; - telemetryRequested.and.callFake(done); - - new ExportDataAction( - mockExportService, - openmct, - { domainObject: mockTarget } - ).perform().then(mockCallback); + [ false, true ].forEach((singular) => { + let targetDescription; + + if (singular) { + targetDescription = 'a single object'; + } else { + targetDescription = 'multiple objects'; + mockComposition = [ + makeMockDomainObject('composition-1', true), + makeMockDomainObject('composition-2', true) + ]; + } + + describe('when performed on ' + targetDescription, () => { + let mockTarget; + + beforeEach((done) => { + let doneCalled = false; + const callDoneOnce = () => { + if (!doneCalled) { + doneCalled = true; + done(); + } + }; + + spyOn(exportDataAction, 'runExportTask').and.callThrough(); + spyOn(exportDataAction, 'exportCompositionData').and.callThrough(); + mockTarget = singular ? mockTelemetryObject : mockTelemetryObjectWithComposition; + telemetryRequestCount = singular ? 1 : mockComposition.length; + telemetryRequested.done = callDoneOnce; + exportDataAction.invoke([mockTarget]).finally(callDoneOnce); }); - it("shows a progress notification", function () { - expect(openmct.overlays.progressDialog) - .toHaveBeenCalled(); + it('shows a progress notification', () => { + expect(mockOpenmct.notifications.progress).toHaveBeenCalled(); }); if (singular) { - it("initiates a telemetry request", function () { + it('initiates a telemetry request', () => { expect(telemetryPromises.length).toEqual(1); }); } else { - it("initiates telemetry requests", function () { - expect(telemetryPromises.length) - .toEqual(mockDelegateObjects.length); + it('initiates telemetry requests', () => { + expect(telemetryPromises.length).toEqual(mockComposition.length); }); } - describe("and data is provided", function () { - beforeEach(function (done) { - mockCallback.and.callFake(done); - - telemetryPromises.forEach(function (p, i) { - var mockSeries = jasmine.createSpyObj( - 'series-' + i, - [ 'getData' ] - ); - mockSeries.getData.and.returnValue([]); - p.resolve(mockSeries); + describe('and data is provided', () => { + beforeEach((done) => { + telemetryPromises.forEach((promise) => { + promise.resolve([]); }); + setTimeout(done, 0); // Ensure all promises are resolved }); - it("dismisses its progress notification", function () { - expect(mockNotification.dismiss) - .toHaveBeenCalled(); + it('does not show an error notification', () => { + expect(mockOpenmct.notifications.error).not.toHaveBeenCalled(); }); - it("triggers a CSV export", function () { - expect(mockExportService.exportCSV) - .toHaveBeenCalledWith( - jasmine.any(Array), - { headers: jasmine.any(Array) } - ); + it('dismisses its progress notification', (done) => { + setTimeout(() => { + expect(mockNotification.dismiss).toHaveBeenCalled(); + done(); + }, 0); }); + + if (singular) { + it('triggers a CSV export for one object', () => { + expect(exportDataAction.runExportTask).toHaveBeenCalled(); + }); + } else { + it('triggers a CSV export for each object', () => { + expect(exportDataAction.exportCompositionData).toHaveBeenCalled(); + }); + } }); - describe("and a request failure occurs", function () { - beforeEach(function (done) { - mockCallback.and.callFake(done); - telemetryPromises[0].reject(); + describe('and a request failure occurs', () => { + beforeEach((done) => { + telemetryPromises.forEach((promise) => { + promise.reject(); + }); + done(); }); - it("dismisses its progress notification", function () { - expect(mockNotification.dismiss) - .toHaveBeenCalled(); + it('dismisses its progress notification', () => { + expect(mockNotification.dismiss).toHaveBeenCalled(); }); - it("displays an error notification", function () { - expect(openmct.notifications.error) - .toHaveBeenCalled(); + it('displays an error notification', () => { + expect(mockOpenmct.notifications.error).toHaveBeenCalled(); }); }); diff --git a/src/exportDataAction/ExportDataTask.js b/src/exportDataAction/ExportDataTask.js index 5943a52..ddc175f 100644 --- a/src/exportDataAction/ExportDataTask.js +++ b/src/exportDataAction/ExportDataTask.js @@ -29,7 +29,7 @@ export default class ExportDataTask { } async fetchAllTelemetryData() { - return Promise.all(this.domainObjects.map(async (domainObject) => { + return Promise.all(this.domainObjects.map((domainObject) => { return this.openmct.telemetry.request(domainObject, { strategy: 'comprehensive' }); })); } diff --git a/src/exportDataAction/ExportDataTaskSpec.js b/src/exportDataAction/ExportDataTaskSpec.js index 55b42b3..cbb46e8 100644 --- a/src/exportDataAction/ExportDataTaskSpec.js +++ b/src/exportDataAction/ExportDataTaskSpec.js @@ -1,51 +1,30 @@ /*global define,describe,beforeEach,jasmine,spyOn,Promise,it,expect,waitsFor,runs,afterEach*/ define([ - '../src/ExportDataTask' -], function (ExportDataTask) { - 'use strict'; - - xdescribe("ExportDataTask", function () { - var testIds, - testTelemetryData, - mockExportService, - mockTelemetryObjects, - mockTelemetryCapabilities, - pendingPromises, - task; + './ExportDataTask' +], function (ExportDataTaskModule) { + const ExportDataTask = ExportDataTaskModule.default; + + describe('ExportDataTask', () => { + let testIds; + let testTelemetryData; + let mockTelemetryObjects; + let mockOpenMct; + let pendingPromises; + let task; function makeMockTelemetryObject(id) { - var mockTelemetryObject = jasmine.createSpyObj( - 'object-' + id, - [ 'getId', 'getModel', 'getCapability' ] - ), - mockTelemetryCapability = jasmine.createSpyObj( - 'telemetry-' + id, - [ 'requestData' ] - ), - mockTelemetrySeries = jasmine.createSpyObj( - 'series-' + id, - [ 'getData' ] - ), - seriesPromise = Promise.resolve(mockTelemetrySeries); - - mockTelemetryObject.getId.and.returnValue(id); - mockTelemetryObject.getModel.and.returnValue({}); - mockTelemetryObject.getCapability.and.callFake(function (c) { - return c === 'telemetry' && mockTelemetryCapability; - }); - - mockTelemetryCapability.requestData.and.returnValue(seriesPromise); - mockTelemetrySeries.getData.and.returnValue(testTelemetryData[id]); - - mockTelemetryCapabilities[id] = mockTelemetryCapability; - - pendingPromises.push(seriesPromise); + const mockTelemetryObject = { + identifier: { + namespace: 'object', + key: id + } + }; return mockTelemetryObject; } - beforeEach(function () { + beforeEach(() => { testIds = [ 'a', 'b', 'c' ]; testTelemetryData = { @@ -60,81 +39,76 @@ define([ { y : 1, z: 8, id: 'b' } ], c: [ - { x: "foo", id: 'c' } + { x: 'foo', id: 'c' } ] }; + mockOpenMct = {}; + mockOpenMct.telemetry = jasmine.createSpyObj('telemetryApi', [ + 'request' + ]); + mockOpenMct.telemetry.request.and.callFake(function (telemetryObject) { + return Promise.resolve(testTelemetryData[telemetryObject.identifier.key]); + }); + pendingPromises = []; - mockTelemetryCapabilities = {}; + spyOn(ExportDataTask.prototype, 'exportCSV').and.callThrough(); - mockExportService = jasmine.createSpyObj( - 'exportService', - [ 'exportCSV' ] - ); - mockTelemetryObjects = - ['a', 'b', 'c'].map(makeMockTelemetryObject); + mockTelemetryObjects = ['a', 'b', 'c'].map(makeMockTelemetryObject); - task = new ExportDataTask(mockExportService, mockTelemetryObjects); + task = new ExportDataTask(mockOpenMct, 'TestObject', mockTelemetryObjects); }); - describe("when performed", function () { - let taskPromise; + describe('when invoked', () => { - beforeEach(function () { - taskPromise = task.perform(); + beforeEach(async (done) => { + await task.invoke(); + done(); }); - it("requests comprehensive telemetry for all objects", function () { + it('requests comprehensive telemetry for all objects', () => { testIds.forEach(function (id) { - expect(mockTelemetryCapabilities[id].requestData) - .toHaveBeenCalledWith({ strategy: 'comprehensive' }); + const telemetryObject = mockTelemetryObjects.find(obj => obj.identifier.key === id); + expect(mockOpenMct.telemetry.request) + .toHaveBeenCalledWith(telemetryObject, { strategy: 'comprehensive' }); }); }); - describe("and data is received", function () { - beforeEach(function () { - return taskPromise; - }); + describe('and data is received', () => { - it("initiates a CSV export", function () { - expect(mockExportService.exportCSV) - .toHaveBeenCalled(); + it('initiates a CSV export', () => { + expect(ExportDataTask.prototype.exportCSV).toHaveBeenCalled(); }); - it("includes rows for telemetry for all objects", function () { - var rows = - mockExportService.exportCSV.calls.mostRecent().args[0]; + it('includes rows for telemetry for all objects', () => { + const rows = ExportDataTask.prototype.exportCSV.calls.mostRecent().args[0]; expect(rows.length).toEqual(testIds.map(function (id) { return testTelemetryData[id].length; }).reduce(function (a, b) { return a + b; })); }); - it("includes headers for all data properties", function () { - var options = - mockExportService.exportCSV.calls.mostRecent().args[1], - headers = options.headers; + it('includes headers for all data properties', () => { + const options = ExportDataTask.prototype.exportCSV.calls.mostRecent().args[1]; + const headers = options.headers; expect(headers.sort()).toEqual(['id', 'x', 'y', 'z']); }); - it("contains all telemetry data for all objects", function () { - var rows = - mockExportService.exportCSV.calls.mostRecent().args[0], - options = - mockExportService.exportCSV.calls.mostRecent().args[1], - headers = options.headers; + it('contains all telemetry data for all objects', () => { + const rows = ExportDataTask.prototype.exportCSV.calls.mostRecent().args[0]; + const options = ExportDataTask.prototype.exportCSV.calls.mostRecent().args[1]; + const headers = options.headers; function hasValue(id, key, value) { - return rows.filter(function (row) { + return rows.some(function (row) { return row.id === id && row[key] === value; - }).length > 0; + }); } testIds.forEach(function (id) { testTelemetryData[id].forEach(function (datum) { Object.keys(datum).forEach(function (key) { - expect(hasValue(id, key, datum[key])) - .toBeTruthy(); + expect(hasValue(id, key, datum[key])).toBeTruthy(); }); }); }); diff --git a/src/types/TypeCompositionPolicySpec.js b/src/types/TypeCompositionPolicySpec.js index ee9aa39..cfa039b 100644 --- a/src/types/TypeCompositionPolicySpec.js +++ b/src/types/TypeCompositionPolicySpec.js @@ -1,48 +1,38 @@ define([ './TypeCompositionPolicy' ], function ( - TypeCompositionPolicy + TypeCompositionPolicyModule // Importing the module, not the constructor directly ) { + const TypeCompositionPolicy = TypeCompositionPolicyModule.default; // Accessing the default export - xdescribe('TypeCompositionPolicy', function () { - var policy; - var parentModel; - var parent; - var childModel; - var child; + describe('TypeCompositionPolicy', () => { + let policy; + let parent; + let child; - beforeEach(function () { - parentModel = {}; - parent = jasmine.createSpyObj('parentObject', [ - 'getModel' - ]); - parent.getModel.and.returnValue(parentModel); - - childModel = {}; - child = jasmine.createSpyObj('childObject', [ - 'getModel' - ]); - child.getModel.and.returnValue(childModel); + beforeEach(() => { + parent = {}; + child = {}; policy = new TypeCompositionPolicy(); }); - it('Allows by default', function () { + it('Allows by default', () => { expect(policy.allow(parent, child)).toBe(true); }); - it('does not allow packet summary events in table', function () { - parentModel.type = 'table'; - childModel.type = 'vista.packetSummaryEvents'; + it('does not allow packet summary events in table', () => { + parent.type = 'table'; + child.type = 'vista.packetSummaryEvents'; expect(policy.allow(parent, child)).toBe(false); }); - it('allows other types in table', function () { - parentModel.type = 'table'; + it('allows other types in table', () => { + parent.type = 'table'; expect(policy.allow(parent, child)).toBe(true); }); - it('does not allow anything in dataset nodes', function () { - [ + it('does not allow anything in dataset nodes', () => { + const types = [ 'vista.channelAlarms', 'vista.channelGroup', 'vista.channelSource', @@ -57,8 +47,9 @@ define([ 'vista.evr', 'vista.packets', 'vista.packetSummaryEvents' - ].forEach(function (t) { - parentModel.type = t; + ]; + types.forEach(function (t) { + parent.type = t; expect(policy.allow(parent, child)).toBe(false); }); });