@thoughtspot/ts-chart-sdk 0.0.1-alpha.0 → 0.0.1-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +782 -0
  2. package/cjs/index.d.ts +9 -0
  3. package/cjs/index.d.ts.map +1 -0
  4. package/cjs/index.js +25 -0
  5. package/cjs/index.js.map +1 -0
  6. package/cjs/main/custom-chart-context.d.ts +47 -0
  7. package/cjs/main/custom-chart-context.d.ts.map +1 -0
  8. package/cjs/main/custom-chart-context.js +326 -0
  9. package/cjs/main/custom-chart-context.js.map +1 -0
  10. package/cjs/main/custom-chart-context.spec.d.ts +2 -0
  11. package/cjs/main/custom-chart-context.spec.d.ts.map +1 -0
  12. package/cjs/main/custom-chart-context.spec.js +699 -0
  13. package/cjs/main/custom-chart-context.spec.js.map +1 -0
  14. package/cjs/main/post-message-event-bridge.d.ts +6 -0
  15. package/cjs/main/post-message-event-bridge.d.ts.map +1 -0
  16. package/cjs/main/post-message-event-bridge.js +46 -0
  17. package/cjs/main/post-message-event-bridge.js.map +1 -0
  18. package/cjs/main/post-message-event-bridge.spec.d.ts +2 -0
  19. package/cjs/main/post-message-event-bridge.spec.d.ts.map +1 -0
  20. package/cjs/main/post-message-event-bridge.spec.js +124 -0
  21. package/cjs/main/post-message-event-bridge.spec.js.map +1 -0
  22. package/cjs/react/mocks/custom-chart-context-mock.d.ts +3 -0
  23. package/cjs/react/mocks/custom-chart-context-mock.d.ts.map +1 -0
  24. package/cjs/react/mocks/custom-chart-context-mock.js +100 -0
  25. package/cjs/react/mocks/custom-chart-context-mock.js.map +1 -0
  26. package/cjs/react/use-custom-chart-context.d.ts +4 -0
  27. package/cjs/react/use-custom-chart-context.d.ts.map +1 -0
  28. package/cjs/react/use-custom-chart-context.js +95 -0
  29. package/cjs/react/use-custom-chart-context.js.map +1 -0
  30. package/cjs/react/use-custom-chart-context.spec.d.ts +2 -0
  31. package/cjs/react/use-custom-chart-context.spec.d.ts.map +1 -0
  32. package/cjs/react/use-custom-chart-context.spec.js +391 -0
  33. package/cjs/react/use-custom-chart-context.spec.js.map +1 -0
  34. package/cjs/react/use-custom-chart-context.util.d.ts +6 -0
  35. package/cjs/react/use-custom-chart-context.util.d.ts.map +1 -0
  36. package/cjs/react/use-custom-chart-context.util.js +60 -0
  37. package/cjs/react/use-custom-chart-context.util.js.map +1 -0
  38. package/cjs/react/use-custom-chart-types.d.ts +23 -0
  39. package/cjs/react/use-custom-chart-types.d.ts.map +1 -0
  40. package/cjs/react/use-custom-chart-types.js +3 -0
  41. package/cjs/react/use-custom-chart-types.js.map +1 -0
  42. package/cjs/test/test-utils.d.ts +7 -0
  43. package/cjs/test/test-utils.d.ts.map +1 -0
  44. package/cjs/test/test-utils.js +14 -0
  45. package/cjs/test/test-utils.js.map +1 -0
  46. package/cjs/types/answer-column.types.d.ts +69 -0
  47. package/cjs/types/answer-column.types.d.ts.map +1 -0
  48. package/cjs/types/answer-column.types.js +59 -0
  49. package/cjs/types/answer-column.types.js.map +1 -0
  50. package/cjs/types/chart-to-ts-event.types.d.ts +98 -0
  51. package/cjs/types/chart-to-ts-event.types.d.ts.map +1 -0
  52. package/cjs/types/chart-to-ts-event.types.js +32 -0
  53. package/cjs/types/chart-to-ts-event.types.js.map +1 -0
  54. package/cjs/types/common.types.d.ts +52 -0
  55. package/cjs/types/common.types.d.ts.map +1 -0
  56. package/cjs/types/common.types.js +3 -0
  57. package/cjs/types/common.types.js.map +1 -0
  58. package/cjs/types/configurator.types.d.ts +15 -0
  59. package/cjs/types/configurator.types.d.ts.map +1 -0
  60. package/cjs/types/configurator.types.js +3 -0
  61. package/cjs/types/configurator.types.js.map +1 -0
  62. package/cjs/types/ts-to-chart-event.types.d.ts +91 -0
  63. package/cjs/types/ts-to-chart-event.types.d.ts.map +1 -0
  64. package/cjs/types/ts-to-chart-event.types.js +18 -0
  65. package/cjs/types/ts-to-chart-event.types.js.map +1 -0
  66. package/cjs/types/visual-prop.types.d.ts +73 -0
  67. package/cjs/types/visual-prop.types.d.ts.map +1 -0
  68. package/cjs/types/visual-prop.types.js +3 -0
  69. package/cjs/types/visual-prop.types.js.map +1 -0
  70. package/dist/ts-chart-sdk.d.ts +151 -23
  71. package/lib/index.d.ts +1 -0
  72. package/lib/index.d.ts.map +1 -1
  73. package/lib/index.js +1 -0
  74. package/lib/index.js.map +1 -1
  75. package/lib/main/custom-chart-context.d.ts +12 -3
  76. package/lib/main/custom-chart-context.d.ts.map +1 -1
  77. package/lib/main/custom-chart-context.js +128 -9
  78. package/lib/main/custom-chart-context.js.map +1 -1
  79. package/lib/main/custom-chart-context.spec.js +381 -25
  80. package/lib/main/custom-chart-context.spec.js.map +1 -1
  81. package/lib/main/post-message-event-bridge.js +1 -1
  82. package/lib/main/post-message-event-bridge.js.map +1 -1
  83. package/lib/main/post-message-event-bridge.spec.js +5 -3
  84. package/lib/main/post-message-event-bridge.spec.js.map +1 -1
  85. package/lib/react/mocks/custom-chart-context-mock.d.ts +3 -0
  86. package/lib/react/mocks/custom-chart-context-mock.d.ts.map +1 -0
  87. package/lib/react/mocks/custom-chart-context-mock.js +94 -0
  88. package/lib/react/mocks/custom-chart-context-mock.js.map +1 -0
  89. package/lib/react/use-custom-chart-context.d.ts +4 -0
  90. package/lib/react/use-custom-chart-context.d.ts.map +1 -0
  91. package/lib/react/use-custom-chart-context.js +68 -0
  92. package/lib/react/use-custom-chart-context.js.map +1 -0
  93. package/lib/react/use-custom-chart-context.spec.d.ts +2 -0
  94. package/lib/react/use-custom-chart-context.spec.d.ts.map +1 -0
  95. package/lib/react/use-custom-chart-context.spec.js +363 -0
  96. package/lib/react/use-custom-chart-context.spec.js.map +1 -0
  97. package/lib/react/use-custom-chart-context.util.d.ts +6 -0
  98. package/lib/react/use-custom-chart-context.util.d.ts.map +1 -0
  99. package/lib/react/use-custom-chart-context.util.js +51 -0
  100. package/lib/react/use-custom-chart-context.util.js.map +1 -0
  101. package/lib/react/use-custom-chart-types.d.ts +23 -0
  102. package/lib/react/use-custom-chart-types.d.ts.map +1 -0
  103. package/lib/react/use-custom-chart-types.js +2 -0
  104. package/lib/react/use-custom-chart-types.js.map +1 -0
  105. package/lib/types/chart-to-ts-event.types.d.ts +63 -13
  106. package/lib/types/chart-to-ts-event.types.d.ts.map +1 -1
  107. package/lib/types/chart-to-ts-event.types.js +13 -0
  108. package/lib/types/chart-to-ts-event.types.js.map +1 -1
  109. package/lib/types/common.types.d.ts +9 -8
  110. package/lib/types/common.types.d.ts.map +1 -1
  111. package/lib/types/ts-to-chart-event.types.d.ts +25 -1
  112. package/lib/types/ts-to-chart-event.types.d.ts.map +1 -1
  113. package/lib/types/ts-to-chart-event.types.js +3 -0
  114. package/lib/types/ts-to-chart-event.types.js.map +1 -1
  115. package/lib/types/visual-prop.types.d.ts +27 -1
  116. package/lib/types/visual-prop.types.d.ts.map +1 -1
  117. package/package.json +9 -3
  118. package/src/index.ts +1 -0
  119. package/src/main/custom-chart-context.spec.ts +513 -26
  120. package/src/main/custom-chart-context.ts +269 -18
  121. package/src/main/post-message-event-bridge.spec.ts +5 -3
  122. package/src/main/post-message-event-bridge.ts +3 -3
  123. package/src/react/mocks/custom-chart-context-mock.ts +114 -0
  124. package/src/react/use-custom-chart-context.spec.tsx +464 -0
  125. package/src/react/use-custom-chart-context.tsx +180 -0
  126. package/src/react/use-custom-chart-context.util.ts +101 -0
  127. package/src/react/use-custom-chart-types.ts +70 -0
  128. package/src/types/answer-column.types.ts +5 -5
  129. package/src/types/chart-to-ts-event.types.ts +233 -31
  130. package/src/types/common.types.ts +37 -26
  131. package/src/types/configurator.types.ts +8 -8
  132. package/src/types/ts-to-chart-event.types.ts +80 -4
  133. package/src/types/visual-prop.types.ts +148 -11
  134. package/lib/dist/ts-chart-sdk.d.ts +0 -312
@@ -4,8 +4,9 @@
4
4
  * @author Chetan Agrawal <chetan.agrawal@thoughtspot.com>
5
5
  */
6
6
 
7
+ import _ from 'lodash';
7
8
  import { mockInitializeContextPayload } from '../test/test-utils';
8
- import { ErrorType } from '../types/chart-to-ts-event.types';
9
+ import { ChartToTSEvent, ErrorType } from '../types/chart-to-ts-event.types';
9
10
  import { TSToChartEvent } from '../types/ts-to-chart-event.types';
10
11
  import { CustomChartContext, getChartContext } from './custom-chart-context';
11
12
  import * as PostMessageEventBridge from './post-message-event-bridge';
@@ -17,7 +18,7 @@ jest.spyOn(console, 'log').mockImplementation(() => {
17
18
  });
18
19
 
19
20
  describe('CustomChartContext', () => {
20
- let eventProcesor: any;
21
+ let eventProcessor: any;
21
22
 
22
23
  let getDefaultChartConfig = jest.fn();
23
24
  let getQueriesFromChartConfig = jest.fn();
@@ -37,7 +38,11 @@ describe('CustomChartContext', () => {
37
38
  renderChart = jest.fn();
38
39
 
39
40
  mockInitMessage.mockImplementation((fn: any) => {
40
- eventProcesor = fn;
41
+ eventProcessor = fn;
42
+ });
43
+
44
+ mockPostMessageToHost.mockImplementation(() => {
45
+ return global.Promise.resolve();
41
46
  });
42
47
  });
43
48
 
@@ -53,9 +58,9 @@ describe('CustomChartContext', () => {
53
58
 
54
59
  afterEach(() => {
55
60
  // Destroy the chart context after each test
56
- customChartContext.destroy();
57
61
  jest.resetAllMocks();
58
- eventProcesor = null;
62
+ customChartContext.destroy();
63
+ eventProcessor = null;
59
64
  });
60
65
 
61
66
  test('should wait till the parent calls initialize', async () => {
@@ -81,7 +86,7 @@ describe('CustomChartContext', () => {
81
86
 
82
87
  // Check that the hasInitializedPromise has resolved
83
88
  const mockPostMessage = jest.fn();
84
- eventProcesor({
89
+ eventProcessor({
85
90
  data: {
86
91
  payload: mockInitializeContextPayload,
87
92
  eventType: TSToChartEvent.Initialize,
@@ -90,8 +95,19 @@ describe('CustomChartContext', () => {
90
95
  ports: [{ postMessage: mockPostMessage }],
91
96
  });
92
97
 
98
+ eventProcessor({
99
+ data: {
100
+ payload: {},
101
+ eventType: TSToChartEvent.InitializeComplete,
102
+ source: 'ts-host-app',
103
+ },
104
+ ports: [{ postMessage: mockPostMessage }],
105
+ });
106
+
93
107
  await expect(promise).resolves.toBeUndefined();
94
- expect(mockPostMessage).toHaveBeenCalledWith({
108
+ expect(mockPostMessage).toHaveBeenCalledTimes(2);
109
+
110
+ expect(mockPostMessage.mock.calls[0][0]).toEqual({
95
111
  isConfigValid: false,
96
112
  defaultChartConfig: undefined,
97
113
  chartConfigEditorDefinition: undefined,
@@ -107,7 +123,7 @@ describe('CustomChartContext', () => {
107
123
 
108
124
  // Check that the hasInitializedPromise has resolved
109
125
  const mockPostMessage = jest.fn();
110
- eventProcesor({
126
+ eventProcessor({
111
127
  data: {
112
128
  payload: mockInitializeContextPayload,
113
129
  eventType: TSToChartEvent.Initialize,
@@ -116,6 +132,15 @@ describe('CustomChartContext', () => {
116
132
  ports: [{ postMessage: mockPostMessage }],
117
133
  });
118
134
 
135
+ eventProcessor({
136
+ data: {
137
+ payload: {},
138
+ eventType: TSToChartEvent.InitializeComplete,
139
+ source: 'ts-host-app',
140
+ },
141
+ ports: [{ postMessage: mockPostMessage }],
142
+ });
143
+
119
144
  await expect(promise).resolves.toBeUndefined();
120
145
 
121
146
  let error;
@@ -156,7 +181,7 @@ describe('CustomChartContext', () => {
156
181
  // Destroy the chart context after each test
157
182
  jest.resetAllMocks();
158
183
  customChartContext.destroy();
159
- eventProcesor = null;
184
+ eventProcessor = null;
160
185
  });
161
186
 
162
187
  test('should not trigger post message if host is not accurate', () => {
@@ -164,7 +189,7 @@ describe('CustomChartContext', () => {
164
189
 
165
190
  // mock the event trigger for ChartConfigValidate
166
191
  const mockPostMessage = jest.fn();
167
- eventProcesor({
192
+ eventProcessor({
168
193
  data: {
169
194
  payload: mockInitializeContextPayload,
170
195
  eventType: TSToChartEvent.ChartConfigValidate,
@@ -182,7 +207,7 @@ describe('CustomChartContext', () => {
182
207
 
183
208
  // mock the event trigger for ChartConfigValidate
184
209
  const mockPostMessage = jest.fn();
185
- eventProcesor({
210
+ eventProcessor({
186
211
  data: {
187
212
  payload: mockInitializeContextPayload,
188
213
  eventType: TSToChartEvent.ChartConfigValidate,
@@ -197,7 +222,7 @@ describe('CustomChartContext', () => {
197
222
  mockPostMessage.mockReset();
198
223
 
199
224
  // mock the event trigger for VisualPropsValidate
200
- eventProcesor({
225
+ eventProcessor({
201
226
  data: {
202
227
  payload: mockInitializeContextPayload,
203
228
  eventType: TSToChartEvent.VisualPropsValidate,
@@ -213,7 +238,7 @@ describe('CustomChartContext', () => {
213
238
  mockPostMessage.mockReset();
214
239
 
215
240
  // mock the event trigger for TriggerRenderChart
216
- eventProcesor({
241
+ eventProcessor({
217
242
  data: {
218
243
  payload: mockInitializeContextPayload,
219
244
  eventType: TSToChartEvent.TriggerRenderChart,
@@ -228,7 +253,7 @@ describe('CustomChartContext', () => {
228
253
  mockPostMessage.mockReset();
229
254
 
230
255
  // mock the event trigger for getQueriesFromChartConfig
231
- eventProcesor({
256
+ eventProcessor({
232
257
  data: {
233
258
  payload: mockInitializeContextPayload,
234
259
  eventType: TSToChartEvent.GetDataQuery,
@@ -246,7 +271,7 @@ describe('CustomChartContext', () => {
246
271
 
247
272
  // mock the event trigger for DataUpdate
248
273
  const mockPostMessage = jest.fn();
249
- eventProcesor({
274
+ eventProcessor({
250
275
  data: {
251
276
  payload: {
252
277
  data: 'random data',
@@ -264,7 +289,7 @@ describe('CustomChartContext', () => {
264
289
  mockPostMessage.mockReset();
265
290
 
266
291
  // mock the event trigger for VisualPropsValidate
267
- eventProcesor({
292
+ eventProcessor({
268
293
  data: {
269
294
  payload: {
270
295
  chartModel: {
@@ -288,8 +313,8 @@ describe('CustomChartContext', () => {
288
313
 
289
314
  mockPostMessage.mockReset();
290
315
 
291
- // mock the event trigger for TriggerRenderChart
292
- eventProcesor({
316
+ // mock the event trigger for VisualPropsUpdate
317
+ eventProcessor({
293
318
  data: {
294
319
  payload: {
295
320
  visualProps: 'random data',
@@ -306,6 +331,71 @@ describe('CustomChartContext', () => {
306
331
  expect(customChartContext.getChartModel().visualProps).toBe(
307
332
  'random data',
308
333
  );
334
+ mockPostMessage.mockReset();
335
+
336
+ // mock the event trigger for AxisMenuActionClick
337
+ customChartContext.axisMenuCustomActionPreProcessor([
338
+ {
339
+ customActions: [
340
+ {
341
+ icon: '',
342
+ id: 'custom-action-1',
343
+ label: 'Custom user action 1',
344
+ onClick: () => _.noop(),
345
+ },
346
+ ],
347
+ },
348
+ ] as any);
349
+ eventProcessor({
350
+ data: {
351
+ payload: {
352
+ customAction: {
353
+ id: 'custom-action-1',
354
+ columnIds: ['9f96b5b0-f7e4-4a5e-aa11-4c77fdf42125'],
355
+ },
356
+ },
357
+ eventType: TSToChartEvent.AxisMenuActionClick,
358
+ source: 'ts-host-app',
359
+ },
360
+ ports: [{ postMessage: mockPostMessage }],
361
+ });
362
+ // Check that the response was valid which means action gets
363
+ // executed successfully
364
+ expect(mockPostMessage).toHaveBeenCalledWith({
365
+ isValid: true,
366
+ });
367
+
368
+ // mock the event trigger for ContextMenuActionClick
369
+ customChartContext.contextMenuCustomActionPreProcessor([
370
+ {
371
+ customActions: [
372
+ {
373
+ icon: '',
374
+ id: 'custom-action-1',
375
+ label: 'Custom user action 1',
376
+ onClick: () => _.noop(),
377
+ },
378
+ ],
379
+ },
380
+ ] as any);
381
+ eventProcessor({
382
+ data: {
383
+ payload: {
384
+ customAction: {
385
+ id: 'custom-action-1',
386
+ columnIds: ['9f96b5b0-f7e4-4a5e-aa11-4c77fdf42125'],
387
+ },
388
+ },
389
+ eventType: TSToChartEvent.ContextMenuActionClick,
390
+ source: 'ts-host-app',
391
+ },
392
+ ports: [{ postMessage: mockPostMessage }],
393
+ });
394
+ // Check that the response was valid which means action gets
395
+ // executed successfully
396
+ expect(mockPostMessage).toHaveBeenCalledWith({
397
+ isValid: true,
398
+ });
309
399
  });
310
400
 
311
401
  test('should add an event listener to the specified event type', () => {
@@ -319,7 +409,7 @@ describe('CustomChartContext', () => {
319
409
 
320
410
  // mock the event trigger
321
411
  const mockPostMessage = jest.fn();
322
- eventProcesor({
412
+ eventProcessor({
323
413
  data: {
324
414
  payload: mockInitializeContextPayload,
325
415
  eventType: TEST_EVENT_TYPE,
@@ -339,7 +429,7 @@ describe('CustomChartContext', () => {
339
429
 
340
430
  // mock the event trigger
341
431
  const mockPostMessage = jest.fn();
342
- eventProcesor({
432
+ eventProcessor({
343
433
  data: {
344
434
  payload: mockInitializeContextPayload,
345
435
  eventType: TEST_EVENT_TYPE,
@@ -356,8 +446,9 @@ describe('CustomChartContext', () => {
356
446
  });
357
447
  });
358
448
 
359
- describe('emitEvent', () => {
449
+ describe('off', () => {
360
450
  let customChartContext: CustomChartContext;
451
+
361
452
  beforeEach(() => {
362
453
  customChartContext = new CustomChartContext({
363
454
  getDefaultChartConfig,
@@ -365,11 +456,127 @@ describe('CustomChartContext', () => {
365
456
  renderChart,
366
457
  });
367
458
  });
459
+
368
460
  afterEach(() => {
369
461
  // Destroy the chart context after each test
462
+ customChartContext.destroy();
463
+ eventProcessor = null;
370
464
  jest.resetAllMocks();
465
+ });
466
+
467
+ test('should remove the event listener for the specified event type', () => {
468
+ // Define a test event type and callback function
469
+ const TEST_EVENT_TYPE = 'testEventType' as any;
470
+ const testCallbackFn = jest.fn();
471
+ // Call the on function with the test event type and callback
472
+ // function to add the event listener
473
+ customChartContext.on(TEST_EVENT_TYPE, testCallbackFn);
474
+
475
+ // mock the event trigger for the test event type
476
+ const mockPostMessage = jest.fn();
477
+ eventProcessor({
478
+ data: {
479
+ payload: mockInitializeContextPayload,
480
+ eventType: TEST_EVENT_TYPE,
481
+ source: 'ts-host-app',
482
+ },
483
+ ports: [{ postMessage: mockPostMessage }],
484
+ });
485
+
486
+ // Call the off function to remove the event listener
487
+ customChartContext.off(TEST_EVENT_TYPE);
488
+
489
+ // Check that the event listener was not called
490
+ expect(testCallbackFn).toHaveBeenCalled();
491
+ expect(
492
+ (customChartContext as any).eventListeners[TEST_EVENT_TYPE],
493
+ ).toHaveLength(0);
494
+ });
495
+
496
+ test('should remove a specific event listener without affecting others', () => {
497
+ // Define two test event types and callback functions
498
+ const TEST_EVENT_TYPE_1: any = 'testEventType1';
499
+ const TEST_EVENT_TYPE_2: any = 'testEventType2';
500
+ const testCallbackFn1 = jest.fn();
501
+ const testCallbackFn2 = jest.fn();
502
+
503
+ // Add event listeners with the test event types and callback
504
+ // functions
505
+ customChartContext.on(TEST_EVENT_TYPE_1, testCallbackFn1);
506
+ customChartContext.on(TEST_EVENT_TYPE_2, testCallbackFn2);
507
+
508
+ // Verify that both event listeners are in the eventListeners array
509
+ expect(
510
+ (customChartContext as any).eventListeners[TEST_EVENT_TYPE_1],
511
+ ).toHaveLength(1);
512
+ expect(
513
+ (customChartContext as any).eventListeners[TEST_EVENT_TYPE_2],
514
+ ).toHaveLength(1);
515
+
516
+ // Emit events for both event types
517
+ const mockPostMessage = jest.fn();
518
+ eventProcessor({
519
+ data: {
520
+ payload: {},
521
+ eventType: TEST_EVENT_TYPE_1,
522
+ source: 'ts-host-app',
523
+ },
524
+ ports: [{ postMessage: mockPostMessage }],
525
+ });
526
+ eventProcessor({
527
+ data: {
528
+ payload: {},
529
+ eventType: TEST_EVENT_TYPE_2,
530
+ source: 'ts-host-app',
531
+ },
532
+ ports: [{ postMessage: mockPostMessage }],
533
+ });
534
+
535
+ // Check that both callback functions were called
536
+ expect(testCallbackFn1).toHaveBeenCalled();
537
+ expect(testCallbackFn2).toHaveBeenCalled();
538
+
539
+ // Remove the first event listener (TEST_EVENT_TYPE_1)
540
+ customChartContext.off(TEST_EVENT_TYPE_1);
541
+
542
+ // Verify that the first event listener is removed while the second
543
+ // is still present
544
+ expect(
545
+ (customChartContext as any).eventListeners[TEST_EVENT_TYPE_1],
546
+ ).toHaveLength(0);
547
+ expect(
548
+ (customChartContext as any).eventListeners[TEST_EVENT_TYPE_2],
549
+ ).toHaveLength(1);
550
+ });
551
+
552
+ test('should make sure not to throw error when off is called before', () => {
553
+ // Define two test event types and callback functions
554
+ const TEST_EVENT_TYPE_1: any = 'testEventType1';
555
+ customChartContext.off(TEST_EVENT_TYPE_1);
556
+
557
+ // Verify that the first event listener is removed while the second
558
+ // is still present
559
+ expect(
560
+ (customChartContext as any).eventListeners[TEST_EVENT_TYPE_1],
561
+ ).toHaveLength(0);
562
+ });
563
+ });
564
+
565
+ describe('emitEvent', () => {
566
+ let customChartContext: CustomChartContext;
567
+
568
+ beforeEach(() => {
569
+ customChartContext = new CustomChartContext({
570
+ getDefaultChartConfig,
571
+ getQueriesFromChartConfig,
572
+ renderChart,
573
+ });
574
+ });
575
+ afterEach(() => {
576
+ // Destroy the chart context after each test
371
577
  customChartContext.destroy();
372
- eventProcesor = null;
578
+ eventProcessor = null;
579
+ jest.resetAllMocks();
373
580
  });
374
581
 
375
582
  test('should reject the promise if the chart context is not initialized', async () => {
@@ -384,13 +591,13 @@ describe('CustomChartContext', () => {
384
591
 
385
592
  // Check that the result is defined
386
593
  expect(mockPostMessageToHost).not.toHaveBeenCalled();
387
- await expect(result).rejects.not.toBeDefined();
594
+ await expect(result).rejects.toBeDefined();
388
595
  });
389
596
 
390
597
  test('should resolve the promise if the chart context is initialized', async () => {
391
598
  // Check that the hasInitializedPromise has resolved
392
599
  const mockPostMessage = jest.fn();
393
- eventProcesor({
600
+ eventProcessor({
394
601
  data: {
395
602
  payload: mockInitializeContextPayload,
396
603
  eventType: TSToChartEvent.Initialize,
@@ -399,6 +606,19 @@ describe('CustomChartContext', () => {
399
606
  ports: [{ postMessage: mockPostMessage }],
400
607
  });
401
608
 
609
+ eventProcessor({
610
+ data: {
611
+ payload: {},
612
+ eventType: TSToChartEvent.InitializeComplete,
613
+ source: 'ts-host-app',
614
+ },
615
+ ports: [{ postMessage: mockPostMessage }],
616
+ });
617
+
618
+ const promise = customChartContext.initialize();
619
+ await expect(promise).resolves.toBeUndefined();
620
+ expect(mockPostMessage).toHaveBeenCalledTimes(2);
621
+
402
622
  // define mock response for the postMessage response promise
403
623
  let resolve: any;
404
624
  mockPostMessageToHost.mockImplementation(
@@ -417,8 +637,9 @@ describe('CustomChartContext', () => {
417
637
  TEST_EVENT_TYPE,
418
638
  testPayload,
419
639
  );
420
- global.setTimeout(() => resolve('helloworld'), 3000);
640
+ global.setTimeout(() => resolve('helloworld'), 1000);
421
641
 
642
+ await expect(result).resolves.toEqual('helloworld');
422
643
  // Check that the result is defined
423
644
  expect(mockPostMessageToHost).toHaveBeenCalledWith(
424
645
  mockInitializeContextPayload.componentId,
@@ -426,7 +647,273 @@ describe('CustomChartContext', () => {
426
647
  testPayload,
427
648
  TEST_EVENT_TYPE,
428
649
  );
429
- await expect(result).resolves.toBe('helloworld');
650
+
651
+ // test for null payload
652
+ // Call the emitEvent function and wait for it to resolve
653
+ mockPostMessageToHost.mockReset();
654
+ mockPostMessageToHost.mockImplementation(
655
+ () =>
656
+ new global.Promise<any>((res) => {
657
+ resolve = res;
658
+ }),
659
+ );
660
+ const result2 = customChartContext.emitEvent(
661
+ ChartToTSEvent.RenderStart,
662
+ );
663
+ global.setTimeout(() => resolve('helloworld'), 1000);
664
+
665
+ await expect(result2).resolves.toEqual('helloworld');
666
+ // Check that the result is defined
667
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
668
+ mockInitializeContextPayload.componentId,
669
+ mockInitializeContextPayload.hostUrl,
670
+ null,
671
+ ChartToTSEvent.RenderStart,
672
+ );
673
+ });
674
+ test('should process the event payload for context menu custom actions', async () => {
675
+ const mockPostMessage = jest.fn();
676
+ const mockCustomAction = jest.fn();
677
+ let resolve: any;
678
+ eventProcessor({
679
+ data: {
680
+ payload: mockInitializeContextPayload,
681
+ eventType: TSToChartEvent.Initialize,
682
+ source: 'ts-host-app',
683
+ },
684
+ ports: [{ postMessage: mockPostMessage }],
685
+ });
686
+ eventProcessor({
687
+ data: {
688
+ payload: {},
689
+ eventType: TSToChartEvent.InitializeComplete,
690
+ source: 'ts-host-app',
691
+ },
692
+ ports: [{ postMessage: mockPostMessage }],
693
+ });
694
+ customChartContext.initialize();
695
+ mockPostMessageToHost.mockImplementation(
696
+ () =>
697
+ new global.Promise<any>((res) => {
698
+ resolve = res;
699
+ }),
700
+ );
701
+
702
+ // Define a test event type and payload
703
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenContextMenu as any;
704
+ const testPayload = {
705
+ customActions: [
706
+ {
707
+ id: 'custom-action-1',
708
+ label: 'Custom user action 1',
709
+ icon: '',
710
+ onClick: mockCustomAction,
711
+ },
712
+ ],
713
+ };
714
+
715
+ // Call the emitEvent function and wait for it to resolve
716
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
717
+
718
+ // Check that the result is defined
719
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
720
+ mockInitializeContextPayload.componentId,
721
+ mockInitializeContextPayload.hostUrl,
722
+ {
723
+ customActions: [
724
+ {
725
+ icon: '',
726
+ id: 'custom-action-1',
727
+ label: 'Custom user action 1',
728
+ },
729
+ ],
730
+ },
731
+ TEST_EVENT_TYPE,
732
+ );
733
+ eventProcessor({
734
+ data: {
735
+ payload: {
736
+ customAction: {
737
+ id: 'custom-action-1',
738
+ clickedPoint: {},
739
+ event: {},
740
+ selectedPoints: [{}],
741
+ },
742
+ },
743
+ eventType: TSToChartEvent.ContextMenuActionClick,
744
+ source: 'ts-host-app',
745
+ },
746
+ ports: [{ postMessage: mockPostMessage }],
747
+ });
748
+ expect(mockCustomAction).toHaveBeenCalled();
749
+ expect(mockCustomAction).toHaveBeenCalledWith({
750
+ clickedPoint: {},
751
+ event: {},
752
+ id: 'custom-action-1',
753
+ selectedPoints: [{}],
754
+ });
755
+ });
756
+ test('should process the event payload for axis menu custom actions', async () => {
757
+ const mockPostMessage = jest.fn();
758
+ const mockCustomAction = jest.fn();
759
+ let resolve: any;
760
+ eventProcessor({
761
+ data: {
762
+ payload: mockInitializeContextPayload,
763
+ eventType: TSToChartEvent.Initialize,
764
+ source: 'ts-host-app',
765
+ },
766
+ ports: [{ postMessage: mockPostMessage }],
767
+ });
768
+ eventProcessor({
769
+ data: {
770
+ payload: {},
771
+ eventType: TSToChartEvent.InitializeComplete,
772
+ source: 'ts-host-app',
773
+ },
774
+ ports: [{ postMessage: mockPostMessage }],
775
+ });
776
+ customChartContext.initialize();
777
+ mockPostMessageToHost.mockImplementation(
778
+ () =>
779
+ new global.Promise<any>((res) => {
780
+ resolve = res;
781
+ }),
782
+ );
783
+
784
+ // Define a test event type and payload
785
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenAxisMenu as any;
786
+ const testPayload = {
787
+ customActions: [
788
+ {
789
+ id: 'custom-action-1',
790
+ label: 'Custom user action 1',
791
+ icon: '',
792
+ onClick: mockCustomAction,
793
+ },
794
+ ],
795
+ };
796
+
797
+ // Call the emitEvent function and wait for it to resolve
798
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
799
+ // Check that the result is defined
800
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
801
+ mockInitializeContextPayload.componentId,
802
+ mockInitializeContextPayload.hostUrl,
803
+ {
804
+ customActions: [
805
+ {
806
+ icon: '',
807
+ id: 'custom-action-1',
808
+ label: 'Custom user action 1',
809
+ },
810
+ ],
811
+ },
812
+ TEST_EVENT_TYPE,
813
+ );
814
+
815
+ eventProcessor({
816
+ data: {
817
+ payload: {
818
+ customAction: {
819
+ id: 'custom-action-1',
820
+ columnIds: ['123'],
821
+ event: {},
822
+ },
823
+ },
824
+ eventType: TSToChartEvent.AxisMenuActionClick,
825
+ source: 'ts-host-app',
826
+ },
827
+ ports: [{ postMessage: mockPostMessage }],
828
+ });
829
+ expect(mockCustomAction).toHaveBeenCalled();
830
+ expect(mockCustomAction).toHaveBeenCalledWith({
831
+ id: 'custom-action-1',
832
+ columnIds: ['123'],
833
+ event: {},
834
+ });
835
+ });
836
+
837
+ test('should process the event payload for axis menu when custom actions are not defined', async () => {
838
+ const mockPostMessage = jest.fn();
839
+ let resolve: any;
840
+ eventProcessor({
841
+ data: {
842
+ payload: mockInitializeContextPayload,
843
+ eventType: TSToChartEvent.Initialize,
844
+ source: 'ts-host-app',
845
+ },
846
+ ports: [{ postMessage: mockPostMessage }],
847
+ });
848
+ eventProcessor({
849
+ data: {
850
+ payload: {},
851
+ eventType: TSToChartEvent.InitializeComplete,
852
+ source: 'ts-host-app',
853
+ },
854
+ ports: [{ postMessage: mockPostMessage }],
855
+ });
856
+ customChartContext.initialize();
857
+ mockPostMessageToHost.mockImplementation(
858
+ () =>
859
+ new global.Promise<any>((res) => {
860
+ resolve = res;
861
+ }),
862
+ );
863
+
864
+ // Define a test event type and payload
865
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenAxisMenu as any;
866
+ const testPayload = {};
867
+ // Call the emitEvent function and wait for it to resolve
868
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
869
+ // Check that the result is defined
870
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
871
+ mockInitializeContextPayload.componentId,
872
+ mockInitializeContextPayload.hostUrl,
873
+ {},
874
+ TEST_EVENT_TYPE,
875
+ );
876
+ });
877
+
878
+ test('should process the event payload for context menu when custom actions are not defined', async () => {
879
+ const mockPostMessage = jest.fn();
880
+ let resolve: any;
881
+ eventProcessor({
882
+ data: {
883
+ payload: mockInitializeContextPayload,
884
+ eventType: TSToChartEvent.Initialize,
885
+ source: 'ts-host-app',
886
+ },
887
+ ports: [{ postMessage: mockPostMessage }],
888
+ });
889
+ eventProcessor({
890
+ data: {
891
+ payload: {},
892
+ eventType: TSToChartEvent.InitializeComplete,
893
+ source: 'ts-host-app',
894
+ },
895
+ ports: [{ postMessage: mockPostMessage }],
896
+ });
897
+ customChartContext.initialize();
898
+ mockPostMessageToHost.mockImplementation(
899
+ () =>
900
+ new global.Promise<any>((res) => {
901
+ resolve = res;
902
+ }),
903
+ );
904
+
905
+ // Define a test event type and payload
906
+ const TEST_EVENT_TYPE = ChartToTSEvent.OpenContextMenu as any;
907
+ const testPayload = {};
908
+ // Call the emitEvent function and wait for it to resolve
909
+ customChartContext.emitEvent(TEST_EVENT_TYPE, testPayload);
910
+ // Check that the result is defined
911
+ expect(mockPostMessageToHost).toHaveBeenCalledWith(
912
+ mockInitializeContextPayload.componentId,
913
+ mockInitializeContextPayload.hostUrl,
914
+ {},
915
+ TEST_EVENT_TYPE,
916
+ );
430
917
  });
431
918
  });
432
919
  });