mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DetectChanges: Serialize message payload to avoid non-clonable props (#92831)
Detect changes: Serialize message payload to avoid non-clonable properties
This commit is contained in:
parent
35ba8fbad1
commit
ae0e970bef
@ -1,7 +1,23 @@
|
||||
import { SceneObjectStateChangedEvent } from '@grafana/scenes';
|
||||
import { Dashboard } from '@grafana/schema';
|
||||
import { CorsWorker } from 'app/core/utils/CorsWorker';
|
||||
import * as createDetectChangesWorker from 'app/features/dashboard-scene/saving/createDetectChangesWorker';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
|
||||
import { DashboardSceneChangeTracker } from './DashboardSceneChangeTracker';
|
||||
|
||||
jest.mock('../serialization/transformSceneToSaveModel', () => {
|
||||
return {
|
||||
transformSceneToSaveModel: () => {
|
||||
return {
|
||||
title: 'updated dashboard',
|
||||
invalidProp: () => 'function',
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe('DashboardSceneChangeTracker', () => {
|
||||
it('should set _changesWorker to undefined when terminate is called', () => {
|
||||
const terminate = jest.fn();
|
||||
@ -20,4 +36,32 @@ describe('DashboardSceneChangeTracker', () => {
|
||||
changeTracker.terminate();
|
||||
expect(changeTracker['_changesWorker']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should remove non clonable properties before sending to worker', () => {
|
||||
const scene = new DashboardScene({});
|
||||
const postMessage = jest.fn();
|
||||
|
||||
jest.spyOn(createDetectChangesWorker, 'createWorker').mockImplementation(() => {
|
||||
return {
|
||||
postMessage,
|
||||
} as unknown as CorsWorker;
|
||||
});
|
||||
jest.spyOn(DashboardSceneChangeTracker, 'isUpdatingPersistedState').mockImplementation(() => {
|
||||
return true;
|
||||
});
|
||||
jest.spyOn(scene, 'getInitialSaveModel').mockReturnValue({
|
||||
title: 'initial dashboard',
|
||||
invalidProp: () => 'function',
|
||||
} as unknown as Dashboard);
|
||||
|
||||
const changeTracker = new DashboardSceneChangeTracker(scene);
|
||||
changeTracker.startTrackingChanges();
|
||||
|
||||
scene.publishEvent({ type: SceneObjectStateChangedEvent.type, payload: { a: 1 } });
|
||||
|
||||
expect(postMessage).toHaveBeenCalledWith({
|
||||
initial: { title: 'initial dashboard' },
|
||||
changed: { title: 'updated dashboard' },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -139,10 +139,16 @@ export class DashboardSceneChangeTracker {
|
||||
}
|
||||
|
||||
private detectSaveModelChanges() {
|
||||
this._changesWorker?.postMessage({
|
||||
changed: transformSceneToSaveModel(this._dashboard),
|
||||
initial: this._dashboard.getInitialSaveModel(),
|
||||
});
|
||||
const changedDashboard = transformSceneToSaveModel(this._dashboard);
|
||||
const initialDashboard = this._dashboard.getInitialSaveModel();
|
||||
|
||||
// Objects must be stringify to ensure they are clonable, so they don't contain functions
|
||||
const changed =
|
||||
typeof changedDashboard === 'object' ? JSON.parse(JSON.stringify(changedDashboard)) : changedDashboard;
|
||||
const initial =
|
||||
typeof initialDashboard === 'object' ? JSON.parse(JSON.stringify(initialDashboard)) : initialDashboard;
|
||||
|
||||
this._changesWorker?.postMessage({ initial, changed });
|
||||
}
|
||||
|
||||
private hasMetadataChanges() {
|
||||
|
Loading…
Reference in New Issue
Block a user