Browse Source

Panels: Added more tests for change panel plugin

Torkel Ödegaard 6 years ago
parent
commit
20fec4d261

+ 1 - 1
packages/grafana-ui/src/types/panel.ts

@@ -32,7 +32,7 @@ export type PanelMigrationHandler<TOptions = any> = (exiting: any, oldVersion?:
 export type PanelTypeChangedHandler<TOptions = any> = (
 export type PanelTypeChangedHandler<TOptions = any> = (
   options: Partial<TOptions>,
   options: Partial<TOptions>,
   prevPluginId: string,
   prevPluginId: string,
-  prevOptions?: any
+  prevOptions: any
 ) => Partial<TOptions>;
 ) => Partial<TOptions>;
 
 
 export class ReactPanelPlugin<TOptions = any> {
 export class ReactPanelPlugin<TOptions = any> {

+ 5 - 1
public/app/core/utils/emitter.ts

@@ -1,7 +1,7 @@
 import { EventEmitter } from 'eventemitter3';
 import { EventEmitter } from 'eventemitter3';
 
 
 export class Emitter {
 export class Emitter {
-  emitter: any;
+  private emitter: EventEmitter;
 
 
   constructor() {
   constructor() {
     this.emitter = new EventEmitter();
     this.emitter = new EventEmitter();
@@ -29,4 +29,8 @@ export class Emitter {
   off(name, handler) {
   off(name, handler) {
     this.emitter.off(name, handler);
     this.emitter.off(name, handler);
   }
   }
+
+  getEventCount(): number {
+    return (this.emitter as any)._eventsCount;
+  }
 }
 }

+ 39 - 0
public/app/features/dashboard/state/PanelModel.test.ts

@@ -1,5 +1,6 @@
 import { PanelModel } from './PanelModel';
 import { PanelModel } from './PanelModel';
 import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks';
 import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks';
+import { ReactPanelPlugin } from '@grafana/ui/src/types/panel';
 
 
 describe('PanelModel', () => {
 describe('PanelModel', () => {
   describe('when creating new panel model', () => {
   describe('when creating new panel model', () => {
@@ -96,6 +97,44 @@ describe('PanelModel', () => {
       });
       });
     });
     });
 
 
+    describe('when changing from angular panel', () => {
+      let tearDownPublished = false;
+
+      beforeEach(() => {
+        model.events.on('panel-teardown', () => {
+          tearDownPublished = true;
+        });
+        model.changePlugin(getPanelPlugin({ id: 'graph', exports: {} }));
+      });
+
+      it('should teardown / destroy panel so angular panels event subscriptions are removed', () => {
+        expect(tearDownPublished).toBe(true);
+        expect(model.events.getEventCount()).toBe(0);
+      });
+    });
+
+    describe('when changing to react panel', () => {
+      const onPanelTypeChanged = jest.fn();
+      const reactPanel = new ReactPanelPlugin({} as any).setPanelChangeHandler(onPanelTypeChanged as any);
+
+      beforeEach(() => {
+        model.changePlugin(
+          getPanelPlugin({
+            id: 'react',
+            exports: {
+              reactPanel,
+            },
+          })
+        );
+      });
+
+      it('should call react onPanelTypeChanged', () => {
+        expect(onPanelTypeChanged.mock.calls.length).toBe(1);
+        expect(onPanelTypeChanged.mock.calls[0][1]).toBe('table');
+        expect(onPanelTypeChanged.mock.calls[0][2].thresholds).toBeDefined();
+      });
+    });
+
     describe('get panel options', () => {
     describe('get panel options', () => {
       it('should apply defaults', () => {
       it('should apply defaults', () => {
         model.options = { existingProp: 10 };
         model.options = { existingProp: 10 };

+ 2 - 2
public/app/features/dashboard/state/PanelModel.ts

@@ -282,11 +282,11 @@ export class PanelModel {
     this.type = pluginId;
     this.type = pluginId;
     this.plugin = newPlugin;
     this.plugin = newPlugin;
 
 
-    // Callback that can validate and migrate any existing settings
+    // Let panel plugins inspect options from previous panel and keep any that it can use
     const onPanelTypeChanged = reactPanel ? reactPanel.onPanelTypeChanged : null;
     const onPanelTypeChanged = reactPanel ? reactPanel.onPanelTypeChanged : null;
     if (onPanelTypeChanged) {
     if (onPanelTypeChanged) {
       this.options = this.options || {};
       this.options = this.options || {};
-      const old = oldOptions ? oldOptions.options : null;
+      const old = oldOptions ? oldOptions.options : {};
       Object.assign(this.options, onPanelTypeChanged(this.options, oldPluginId, old));
       Object.assign(this.options, onPanelTypeChanged(this.options, oldPluginId, old));
     }
     }
   }
   }