@thoughtspot/visual-embed-sdk 1.42.3 → 1.43.1

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 (178) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/api-intercept.d.ts +51 -0
  3. package/cjs/src/api-intercept.d.ts.map +1 -0
  4. package/cjs/src/api-intercept.js +180 -0
  5. package/cjs/src/api-intercept.js.map +1 -0
  6. package/cjs/src/api-intercept.spec.d.ts +2 -0
  7. package/cjs/src/api-intercept.spec.d.ts.map +1 -0
  8. package/cjs/src/api-intercept.spec.js +672 -0
  9. package/cjs/src/api-intercept.spec.js.map +1 -0
  10. package/cjs/src/css-variables.d.ts +4 -0
  11. package/cjs/src/css-variables.d.ts.map +1 -1
  12. package/cjs/src/embed/app.d.ts +0 -5
  13. package/cjs/src/embed/app.d.ts.map +1 -1
  14. package/cjs/src/embed/app.js +4 -5
  15. package/cjs/src/embed/app.js.map +1 -1
  16. package/cjs/src/embed/app.spec.js +10 -0
  17. package/cjs/src/embed/app.spec.js.map +1 -1
  18. package/cjs/src/embed/conversation.d.ts +2 -2
  19. package/cjs/src/embed/conversation.js +1 -1
  20. package/cjs/src/embed/conversation.js.map +1 -1
  21. package/cjs/src/embed/conversation.spec.js +17 -0
  22. package/cjs/src/embed/conversation.spec.js.map +1 -1
  23. package/cjs/src/embed/hostEventClient/contracts.d.ts +11 -1
  24. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  25. package/cjs/src/embed/hostEventClient/contracts.js +1 -0
  26. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  27. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  28. package/cjs/src/embed/liveboard.js +4 -2
  29. package/cjs/src/embed/liveboard.js.map +1 -1
  30. package/cjs/src/embed/liveboard.spec.js +11 -0
  31. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  32. package/cjs/src/embed/search.d.ts +0 -7
  33. package/cjs/src/embed/search.d.ts.map +1 -1
  34. package/cjs/src/embed/search.js +1 -4
  35. package/cjs/src/embed/search.js.map +1 -1
  36. package/cjs/src/embed/ts-embed.d.ts +10 -0
  37. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  38. package/cjs/src/embed/ts-embed.js +56 -15
  39. package/cjs/src/embed/ts-embed.js.map +1 -1
  40. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  41. package/cjs/src/embed/ts-embed.spec.js +412 -238
  42. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  43. package/cjs/src/index.d.ts +2 -2
  44. package/cjs/src/index.d.ts.map +1 -1
  45. package/cjs/src/index.js +2 -1
  46. package/cjs/src/index.js.map +1 -1
  47. package/cjs/src/react/all-types-export.d.ts +1 -1
  48. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  49. package/cjs/src/react/all-types-export.js +2 -1
  50. package/cjs/src/react/all-types-export.js.map +1 -1
  51. package/cjs/src/types.d.ts +328 -103
  52. package/cjs/src/types.d.ts.map +1 -1
  53. package/cjs/src/types.js +265 -85
  54. package/cjs/src/types.js.map +1 -1
  55. package/cjs/src/utils/logger.d.ts.map +1 -1
  56. package/cjs/src/utils/logger.js +1 -2
  57. package/cjs/src/utils/logger.js.map +1 -1
  58. package/cjs/src/utils/processData.d.ts +1 -1
  59. package/cjs/src/utils/processData.d.ts.map +1 -1
  60. package/cjs/src/utils/processData.js +8 -8
  61. package/cjs/src/utils/processData.js.map +1 -1
  62. package/cjs/src/utils/processData.spec.js.map +1 -1
  63. package/dist/{index-SVcLgSqi.js → index-CpkMygsc.js} +1 -1
  64. package/dist/src/api-intercept.d.ts +51 -0
  65. package/dist/src/api-intercept.d.ts.map +1 -0
  66. package/dist/src/api-intercept.spec.d.ts +2 -0
  67. package/dist/src/api-intercept.spec.d.ts.map +1 -0
  68. package/dist/src/css-variables.d.ts +4 -0
  69. package/dist/src/css-variables.d.ts.map +1 -1
  70. package/dist/src/embed/app.d.ts +0 -5
  71. package/dist/src/embed/app.d.ts.map +1 -1
  72. package/dist/src/embed/conversation.d.ts +2 -2
  73. package/dist/src/embed/hostEventClient/contracts.d.ts +11 -1
  74. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  75. package/dist/src/embed/liveboard.d.ts.map +1 -1
  76. package/dist/src/embed/search.d.ts +0 -7
  77. package/dist/src/embed/search.d.ts.map +1 -1
  78. package/dist/src/embed/ts-embed.d.ts +10 -0
  79. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  80. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  81. package/dist/src/index.d.ts +2 -2
  82. package/dist/src/index.d.ts.map +1 -1
  83. package/dist/src/react/all-types-export.d.ts +1 -1
  84. package/dist/src/react/all-types-export.d.ts.map +1 -1
  85. package/dist/src/types.d.ts +328 -103
  86. package/dist/src/types.d.ts.map +1 -1
  87. package/dist/src/utils/logger.d.ts.map +1 -1
  88. package/dist/src/utils/processData.d.ts +1 -1
  89. package/dist/src/utils/processData.d.ts.map +1 -1
  90. package/dist/tsembed-react.es.js +519 -133
  91. package/dist/tsembed-react.js +518 -132
  92. package/dist/tsembed.es.js +2642 -2256
  93. package/dist/tsembed.js +2640 -2254
  94. package/dist/visual-embed-sdk-react-full.d.ts +355 -118
  95. package/dist/visual-embed-sdk-react.d.ts +352 -118
  96. package/dist/visual-embed-sdk.d.ts +355 -118
  97. package/lib/package.json +1 -1
  98. package/lib/src/api-intercept.d.ts +51 -0
  99. package/lib/src/api-intercept.d.ts.map +1 -0
  100. package/lib/src/api-intercept.js +173 -0
  101. package/lib/src/api-intercept.js.map +1 -0
  102. package/lib/src/api-intercept.spec.d.ts +2 -0
  103. package/lib/src/api-intercept.spec.d.ts.map +1 -0
  104. package/lib/src/api-intercept.spec.js +669 -0
  105. package/lib/src/api-intercept.spec.js.map +1 -0
  106. package/lib/src/css-variables.d.ts +4 -0
  107. package/lib/src/css-variables.d.ts.map +1 -1
  108. package/lib/src/embed/app.d.ts +0 -5
  109. package/lib/src/embed/app.d.ts.map +1 -1
  110. package/lib/src/embed/app.js +4 -5
  111. package/lib/src/embed/app.js.map +1 -1
  112. package/lib/src/embed/app.spec.js +10 -0
  113. package/lib/src/embed/app.spec.js.map +1 -1
  114. package/lib/src/embed/conversation.d.ts +2 -2
  115. package/lib/src/embed/conversation.js +1 -1
  116. package/lib/src/embed/conversation.js.map +1 -1
  117. package/lib/src/embed/conversation.spec.js +17 -0
  118. package/lib/src/embed/conversation.spec.js.map +1 -1
  119. package/lib/src/embed/hostEventClient/contracts.d.ts +11 -1
  120. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  121. package/lib/src/embed/hostEventClient/contracts.js +1 -0
  122. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  123. package/lib/src/embed/liveboard.d.ts.map +1 -1
  124. package/lib/src/embed/liveboard.js +4 -2
  125. package/lib/src/embed/liveboard.js.map +1 -1
  126. package/lib/src/embed/liveboard.spec.js +11 -0
  127. package/lib/src/embed/liveboard.spec.js.map +1 -1
  128. package/lib/src/embed/search.d.ts +0 -7
  129. package/lib/src/embed/search.d.ts.map +1 -1
  130. package/lib/src/embed/search.js +1 -4
  131. package/lib/src/embed/search.js.map +1 -1
  132. package/lib/src/embed/ts-embed.d.ts +10 -0
  133. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  134. package/lib/src/embed/ts-embed.js +56 -15
  135. package/lib/src/embed/ts-embed.js.map +1 -1
  136. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  137. package/lib/src/embed/ts-embed.spec.js +412 -238
  138. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  139. package/lib/src/index.d.ts +2 -2
  140. package/lib/src/index.d.ts.map +1 -1
  141. package/lib/src/index.js +2 -2
  142. package/lib/src/index.js.map +1 -1
  143. package/lib/src/react/all-types-export.d.ts +1 -1
  144. package/lib/src/react/all-types-export.d.ts.map +1 -1
  145. package/lib/src/react/all-types-export.js +1 -1
  146. package/lib/src/react/all-types-export.js.map +1 -1
  147. package/lib/src/types.d.ts +328 -103
  148. package/lib/src/types.d.ts.map +1 -1
  149. package/lib/src/types.js +264 -84
  150. package/lib/src/types.js.map +1 -1
  151. package/lib/src/utils/logger.d.ts.map +1 -1
  152. package/lib/src/utils/logger.js +1 -2
  153. package/lib/src/utils/logger.js.map +1 -1
  154. package/lib/src/utils/processData.d.ts +1 -1
  155. package/lib/src/utils/processData.d.ts.map +1 -1
  156. package/lib/src/utils/processData.js +8 -8
  157. package/lib/src/utils/processData.js.map +1 -1
  158. package/lib/src/utils/processData.spec.js.map +1 -1
  159. package/package.json +1 -1
  160. package/src/api-intercept.spec.ts +856 -0
  161. package/src/api-intercept.ts +204 -0
  162. package/src/css-variables.ts +5 -0
  163. package/src/embed/app.spec.ts +11 -0
  164. package/src/embed/app.ts +5 -16
  165. package/src/embed/conversation.spec.ts +22 -0
  166. package/src/embed/conversation.ts +3 -3
  167. package/src/embed/hostEventClient/contracts.ts +10 -0
  168. package/src/embed/liveboard.spec.ts +12 -0
  169. package/src/embed/liveboard.ts +6 -2
  170. package/src/embed/search.ts +1 -14
  171. package/src/embed/ts-embed.spec.ts +498 -250
  172. package/src/embed/ts-embed.ts +80 -32
  173. package/src/index.ts +2 -0
  174. package/src/react/all-types-export.ts +1 -0
  175. package/src/types.ts +410 -179
  176. package/src/utils/logger.ts +1 -2
  177. package/src/utils/processData.spec.ts +0 -1
  178. package/src/utils/processData.ts +10 -11
@@ -19,8 +19,10 @@ import { processTrigger } from '../utils/processTrigger';
19
19
  import { UIPassthroughEvent } from './hostEventClient/contracts';
20
20
  import * as sessionInfoService from '../utils/sessionInfoService';
21
21
  import * as authToken from '../authToken';
22
+ import * as apiIntercept from '../api-intercept';
22
23
  jest.mock('../utils/processTrigger');
23
24
  const mockProcessTrigger = processTrigger;
25
+ const mockHandleInterceptEvent = jest.spyOn(apiIntercept, 'handleInterceptEvent');
24
26
  const defaultViewConfig = {
25
27
  frameParams: {
26
28
  width: 1280,
@@ -60,6 +62,30 @@ const customVariablesForThirdPartyTools = {
60
62
  key1: '!@#',
61
63
  key2: '*%^',
62
64
  };
65
+ const getMockAppInitPayload = (data) => {
66
+ const defaultData = {
67
+ customisations,
68
+ authToken: '',
69
+ hostConfig: undefined,
70
+ runtimeFilterParams: null,
71
+ runtimeParameterParams: null,
72
+ hiddenHomeLeftNavItems: [],
73
+ hiddenHomepageModules: [],
74
+ hiddenListColumns: [],
75
+ customActions: [],
76
+ reorderedHomepageModules: [],
77
+ customVariablesForThirdPartyTools,
78
+ interceptTimeout: undefined,
79
+ interceptUrls: [],
80
+ };
81
+ return {
82
+ type: EmbedEvent.APP_INIT,
83
+ data: {
84
+ ...defaultData,
85
+ ...data,
86
+ },
87
+ };
88
+ };
63
89
  describe('Unit test case for ts embed', () => {
64
90
  const mockMixPanelEvent = jest.spyOn(mixpanelInstance, 'uploadMixpanelEvent');
65
91
  beforeEach(() => {
@@ -243,22 +269,7 @@ describe('Unit test case for ts embed', () => {
243
269
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
244
270
  });
245
271
  await executeAfterWait(() => {
246
- expect(mockPort.postMessage).toHaveBeenCalledWith({
247
- type: EmbedEvent.APP_INIT,
248
- data: {
249
- customisations,
250
- authToken: '',
251
- runtimeFilterParams: null,
252
- runtimeParameterParams: null,
253
- hiddenHomeLeftNavItems: [],
254
- hiddenHomepageModules: [],
255
- hiddenListColumns: [],
256
- customActions: [],
257
- hostConfig: undefined,
258
- reorderedHomepageModules: [],
259
- customVariablesForThirdPartyTools,
260
- },
261
- });
272
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({}));
262
273
  });
263
274
  });
264
275
  test('verify Customisations from viewConfig', async () => {
@@ -279,22 +290,9 @@ describe('Unit test case for ts embed', () => {
279
290
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
280
291
  });
281
292
  await executeAfterWait(() => {
282
- expect(mockPort.postMessage).toHaveBeenCalledWith({
283
- type: EmbedEvent.APP_INIT,
284
- data: {
285
- customisations: customisationsView,
286
- authToken: '',
287
- runtimeFilterParams: null,
288
- runtimeParameterParams: null,
289
- hiddenHomeLeftNavItems: [],
290
- hiddenHomepageModules: [],
291
- hiddenListColumns: [],
292
- customActions: [],
293
- hostConfig: undefined,
294
- reorderedHomepageModules: [],
295
- customVariablesForThirdPartyTools,
296
- },
297
- });
293
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
294
+ customisations: customisationsView,
295
+ }));
298
296
  });
299
297
  });
300
298
  test('hide home page modules from view Config should be part of app_init payload', async () => {
@@ -319,22 +317,9 @@ describe('Unit test case for ts embed', () => {
319
317
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
320
318
  });
321
319
  await executeAfterWait(() => {
322
- expect(mockPort.postMessage).toHaveBeenCalledWith({
323
- type: EmbedEvent.APP_INIT,
324
- data: {
325
- customisations,
326
- authToken: '',
327
- hostConfig: undefined,
328
- runtimeFilterParams: null,
329
- runtimeParameterParams: null,
330
- hiddenHomeLeftNavItems: [],
331
- hiddenHomepageModules: [HomepageModule.MyLibrary, HomepageModule.Learning],
332
- hiddenListColumns: [],
333
- customActions: [],
334
- reorderedHomepageModules: [],
335
- customVariablesForThirdPartyTools,
336
- },
337
- });
320
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
321
+ hiddenHomepageModules: [HomepageModule.MyLibrary, HomepageModule.Learning],
322
+ }));
338
323
  });
339
324
  });
340
325
  test('customVariablesForThirdPartyTools should be part of the app_init payload', async () => {
@@ -354,22 +339,7 @@ describe('Unit test case for ts embed', () => {
354
339
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
355
340
  });
356
341
  await executeAfterWait(() => {
357
- expect(mockPort.postMessage).toHaveBeenCalledWith({
358
- type: EmbedEvent.APP_INIT,
359
- data: {
360
- customisations,
361
- authToken: '',
362
- hostConfig: undefined,
363
- runtimeFilterParams: null,
364
- runtimeParameterParams: null,
365
- hiddenHomeLeftNavItems: [],
366
- hiddenHomepageModules: [],
367
- hiddenListColumns: [],
368
- customActions: [],
369
- reorderedHomepageModules: [],
370
- customVariablesForThirdPartyTools,
371
- },
372
- });
342
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({}));
373
343
  });
374
344
  });
375
345
  test('Reordering the home page modules from view Config should be part of app_init payload', async () => {
@@ -394,22 +364,9 @@ describe('Unit test case for ts embed', () => {
394
364
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
395
365
  });
396
366
  await executeAfterWait(() => {
397
- expect(mockPort.postMessage).toHaveBeenCalledWith({
398
- type: EmbedEvent.APP_INIT,
399
- data: {
400
- customisations,
401
- authToken: '',
402
- hostConfig: undefined,
403
- runtimeFilterParams: null,
404
- runtimeParameterParams: null,
405
- hiddenHomeLeftNavItems: [],
406
- hiddenHomepageModules: [],
407
- hiddenListColumns: [],
408
- customActions: [],
409
- reorderedHomepageModules: [HomepageModule.MyLibrary, HomepageModule.Watchlist],
410
- customVariablesForThirdPartyTools,
411
- },
412
- });
367
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
368
+ reorderedHomepageModules: [HomepageModule.MyLibrary, HomepageModule.Watchlist],
369
+ }));
413
370
  });
414
371
  });
415
372
  test('Runtime parameters from view Config should be part of app_init payload when excludeRuntimeParametsfromURL is true', async () => {
@@ -437,22 +394,9 @@ describe('Unit test case for ts embed', () => {
437
394
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
438
395
  });
439
396
  await executeAfterWait(() => {
440
- expect(mockPort.postMessage).toHaveBeenCalledWith({
441
- type: EmbedEvent.APP_INIT,
442
- data: {
443
- customisations,
444
- authToken: '',
445
- runtimeFilterParams: null,
446
- runtimeParameterParams: 'param1=color&paramVal1=blue',
447
- hiddenHomeLeftNavItems: [],
448
- hiddenHomepageModules: [],
449
- hiddenListColumns: [],
450
- customActions: [],
451
- hostConfig: undefined,
452
- reorderedHomepageModules: [],
453
- customVariablesForThirdPartyTools,
454
- },
455
- });
397
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
398
+ runtimeParameterParams: 'param1=color&paramVal1=blue',
399
+ }));
456
400
  });
457
401
  });
458
402
  test('Runtime filters from view Config should be part of app_init payload when excludeRuntimeFiltersfromURL is true', async () => {
@@ -481,22 +425,9 @@ describe('Unit test case for ts embed', () => {
481
425
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
482
426
  });
483
427
  await executeAfterWait(() => {
484
- expect(mockPort.postMessage).toHaveBeenCalledWith({
485
- type: EmbedEvent.APP_INIT,
486
- data: {
487
- customisations,
488
- authToken: '',
489
- runtimeFilterParams: 'col1=color&op1=EQ&val1=blue',
490
- runtimeParameterParams: null,
491
- hiddenHomeLeftNavItems: [],
492
- hiddenHomepageModules: [],
493
- hiddenListColumns: [],
494
- customActions: [],
495
- hostConfig: undefined,
496
- reorderedHomepageModules: [],
497
- customVariablesForThirdPartyTools,
498
- },
499
- });
428
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
429
+ runtimeFilterParams: 'col1=color&op1=EQ&val1=blue',
430
+ }));
500
431
  });
501
432
  });
502
433
  test('Runtime filters from view Config should be not part of app_init payload when excludeRuntimeFiltersfromURL is undefined', async () => {
@@ -524,22 +455,7 @@ describe('Unit test case for ts embed', () => {
524
455
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
525
456
  });
526
457
  await executeAfterWait(() => {
527
- expect(mockPort.postMessage).toHaveBeenCalledWith({
528
- type: EmbedEvent.APP_INIT,
529
- data: {
530
- customisations,
531
- authToken: '',
532
- runtimeFilterParams: null,
533
- runtimeParameterParams: null,
534
- hiddenHomeLeftNavItems: [],
535
- hiddenHomepageModules: [],
536
- hiddenListColumns: [],
537
- customActions: [],
538
- hostConfig: undefined,
539
- reorderedHomepageModules: [],
540
- customVariablesForThirdPartyTools,
541
- },
542
- });
458
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({}));
543
459
  });
544
460
  });
545
461
  test('Runtime filters from view Config should not be part of app_init payload when excludeRuntimeFiltersfromURL is false', async () => {
@@ -568,22 +484,7 @@ describe('Unit test case for ts embed', () => {
568
484
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
569
485
  });
570
486
  await executeAfterWait(() => {
571
- expect(mockPort.postMessage).toHaveBeenCalledWith({
572
- type: EmbedEvent.APP_INIT,
573
- data: {
574
- customisations,
575
- authToken: '',
576
- runtimeFilterParams: null,
577
- runtimeParameterParams: null,
578
- hiddenHomeLeftNavItems: [],
579
- hiddenHomepageModules: [],
580
- hiddenListColumns: [],
581
- customActions: [],
582
- hostConfig: undefined,
583
- reorderedHomepageModules: [],
584
- customVariablesForThirdPartyTools,
585
- },
586
- });
487
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({}));
587
488
  });
588
489
  });
589
490
  test('homeLeftNav from view Config should be part of app_init payload', async () => {
@@ -608,22 +509,9 @@ describe('Unit test case for ts embed', () => {
608
509
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
609
510
  });
610
511
  await executeAfterWait(() => {
611
- expect(mockPort.postMessage).toHaveBeenCalledWith({
612
- type: EmbedEvent.APP_INIT,
613
- data: {
614
- customisations,
615
- authToken: '',
616
- hostConfig: undefined,
617
- runtimeFilterParams: null,
618
- runtimeParameterParams: null,
619
- hiddenHomeLeftNavItems: [HomeLeftNavItem.Home, HomeLeftNavItem.MonitorSubscription],
620
- hiddenHomepageModules: [],
621
- hiddenListColumns: [],
622
- customActions: [],
623
- reorderedHomepageModules: [],
624
- customVariablesForThirdPartyTools,
625
- },
626
- });
512
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
513
+ hiddenHomeLeftNavItems: [HomeLeftNavItem.Home, HomeLeftNavItem.MonitorSubscription],
514
+ }));
627
515
  });
628
516
  });
629
517
  test('when Embed event status have start status', (done) => {
@@ -755,22 +643,10 @@ describe('Unit test case for ts embed', () => {
755
643
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
756
644
  });
757
645
  await executeAfterWait(() => {
758
- expect(mockPort.postMessage).toHaveBeenCalledWith({
759
- type: EmbedEvent.APP_INIT,
760
- data: {
761
- customisations,
762
- authToken: 'test_auth_token1',
763
- runtimeFilterParams: null,
764
- runtimeParameterParams: null,
765
- hiddenHomeLeftNavItems: [],
766
- hiddenHomepageModules: [],
767
- hiddenListColumns: [],
768
- customActions: [],
769
- hostConfig: undefined,
770
- reorderedHomepageModules: [],
771
- customVariablesForThirdPartyTools: {},
772
- },
773
- });
646
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
647
+ authToken: 'test_auth_token1',
648
+ customVariablesForThirdPartyTools: {},
649
+ }));
774
650
  });
775
651
  jest.spyOn(authService, 'verifyTokenService').mockClear();
776
652
  });
@@ -820,36 +696,25 @@ describe('Unit test case for ts embed', () => {
820
696
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
821
697
  });
822
698
  await executeAfterWait(() => {
823
- expect(mockPort.postMessage).toHaveBeenCalledWith({
824
- type: EmbedEvent.APP_INIT,
825
- data: {
826
- customisations: {
827
- content: {
828
- strings: {
829
- Liveboard: 'Dashboard',
830
- },
831
- stringIDsUrl: 'https://sample-string-ids-url.com',
832
- stringIDs: {
833
- 'liveboard.header.title': 'Dashboard name',
834
- },
699
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
700
+ customisations: {
701
+ content: {
702
+ strings: {
703
+ Liveboard: 'Dashboard',
835
704
  },
836
- style: {
837
- customCSS: {},
838
- customCSSUrl: undefined,
705
+ stringIDsUrl: 'https://sample-string-ids-url.com',
706
+ stringIDs: {
707
+ 'liveboard.header.title': 'Dashboard name',
839
708
  },
840
709
  },
841
- authToken: 'test_auth_token1',
842
- runtimeFilterParams: null,
843
- runtimeParameterParams: null,
844
- hiddenHomeLeftNavItems: [],
845
- hiddenHomepageModules: [],
846
- hiddenListColumns: [],
847
- customActions: [],
848
- hostConfig: undefined,
849
- reorderedHomepageModules: [],
850
- customVariablesForThirdPartyTools: {},
710
+ style: {
711
+ customCSS: {},
712
+ customCSSUrl: undefined,
713
+ },
851
714
  },
852
- });
715
+ authToken: 'test_auth_token1',
716
+ customVariablesForThirdPartyTools: {},
717
+ }));
853
718
  const customisationContent = mockPort.postMessage.mock.calls[0][0].data.customisations.content;
854
719
  expect(customisationContent.stringIDsUrl)
855
720
  .toBe('https://sample-string-ids-url.com');
@@ -925,43 +790,33 @@ describe('Unit test case for ts embed', () => {
925
790
  postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
926
791
  });
927
792
  await executeAfterWait(() => {
928
- expect(mockPort.postMessage).toHaveBeenCalledWith({
929
- type: EmbedEvent.APP_INIT,
930
- data: {
931
- customisations: {
932
- content: {},
933
- style: {
934
- customCSS: {},
935
- customCSSUrl: undefined,
936
- },
793
+ expect(mockPort.postMessage).toHaveBeenCalledWith(getMockAppInitPayload({
794
+ customisations: {
795
+ content: {},
796
+ style: {
797
+ customCSS: {},
798
+ customCSSUrl: undefined,
937
799
  },
938
- authToken: 'test_auth_token1',
939
- runtimeFilterParams: null,
940
- runtimeParameterParams: null,
941
- hiddenHomeLeftNavItems: [],
942
- hiddenHomepageModules: [],
943
- hiddenListColumns: [],
944
- customActions: [
945
- {
946
- id: 'action2',
947
- name: 'Another Valid Action',
948
- target: CustomActionTarget.VIZ,
949
- position: CustomActionsPosition.MENU,
950
- metadataIds: { vizIds: ['viz456'] }
951
- },
952
- {
953
- id: 'action1',
954
- name: 'Valid Action',
955
- target: CustomActionTarget.LIVEBOARD,
956
- position: CustomActionsPosition.PRIMARY,
957
- metadataIds: { liveboardIds: ['lb123'] }
958
- }
959
- ],
960
- hostConfig: undefined,
961
- reorderedHomepageModules: [],
962
- customVariablesForThirdPartyTools: {},
963
800
  },
964
- });
801
+ authToken: 'test_auth_token1',
802
+ customActions: [
803
+ {
804
+ id: 'action2',
805
+ name: 'Another Valid Action',
806
+ target: CustomActionTarget.VIZ,
807
+ position: CustomActionsPosition.MENU,
808
+ metadataIds: { vizIds: ['viz456'] }
809
+ },
810
+ {
811
+ id: 'action1',
812
+ name: 'Valid Action',
813
+ target: CustomActionTarget.LIVEBOARD,
814
+ position: CustomActionsPosition.PRIMARY,
815
+ metadataIds: { liveboardIds: ['lb123'] }
816
+ }
817
+ ],
818
+ customVariablesForThirdPartyTools: {},
819
+ }));
965
820
  // Verify that CustomActionsValidationResult structure is
966
821
  // correct
967
822
  const appInitData = mockPort.postMessage.mock.calls[0][0].data;
@@ -2905,7 +2760,7 @@ describe('Unit test case for ts embed', () => {
2905
2760
  const triggerSpy = jest.spyOn(appEmbed, 'trigger').mockResolvedValue(null);
2906
2761
  const removeChildSpy = jest.spyOn(Node.prototype, 'removeChild').mockImplementation(() => getRootEl());
2907
2762
  appEmbed.destroy();
2908
- // Should be called immediately when waitForCleanupOnDestroy is true
2763
+ // Should be called immediately when config is enabled
2909
2764
  expect(triggerSpy).toHaveBeenCalledWith(HostEvent.DestroyEmbed);
2910
2765
  // Wait for the timeout to complete
2911
2766
  await new Promise(resolve => setTimeout(resolve, 1100));
@@ -2957,5 +2812,324 @@ describe('Unit test case for ts embed', () => {
2957
2812
  });
2958
2813
  });
2959
2814
  });
2815
+ describe('handleApiInterceptEvent', () => {
2816
+ beforeEach(() => {
2817
+ document.body.innerHTML = getDocumentBody();
2818
+ init({
2819
+ thoughtSpotHost: 'tshost',
2820
+ authType: AuthType.None,
2821
+ });
2822
+ jest.clearAllMocks();
2823
+ mockHandleInterceptEvent.mockClear();
2824
+ });
2825
+ test('should call handleInterceptEvent with correct parameters', async () => {
2826
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
2827
+ await searchEmbed.render();
2828
+ const mockEventData = {
2829
+ type: EmbedEvent.ApiIntercept,
2830
+ data: JSON.stringify({
2831
+ input: '/prism/?op=GetChartWithData',
2832
+ init: {
2833
+ method: 'POST',
2834
+ body: JSON.stringify({
2835
+ variables: {
2836
+ session: { sessionId: 'session-123' },
2837
+ contextBookId: 'viz-456'
2838
+ }
2839
+ })
2840
+ }
2841
+ })
2842
+ };
2843
+ const mockPort = {
2844
+ postMessage: jest.fn(),
2845
+ };
2846
+ await executeAfterWait(() => {
2847
+ const iframe = getIFrameEl();
2848
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
2849
+ });
2850
+ await executeAfterWait(() => {
2851
+ expect(mockHandleInterceptEvent).toHaveBeenCalledTimes(1);
2852
+ const call = mockHandleInterceptEvent.mock.calls[0][0];
2853
+ expect(call.eventData).toEqual(mockEventData);
2854
+ expect(call.executeEvent).toBeInstanceOf(Function);
2855
+ expect(call.getUnsavedAnswerTml).toBeInstanceOf(Function);
2856
+ expect(call.viewConfig).toMatchObject(defaultViewConfig);
2857
+ });
2858
+ });
2859
+ test('should execute callbacks through executeEvent function', async () => {
2860
+ let capturedExecuteEvent;
2861
+ mockHandleInterceptEvent.mockImplementation((params) => {
2862
+ capturedExecuteEvent = params.executeEvent;
2863
+ });
2864
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
2865
+ const mockCallback = jest.fn();
2866
+ searchEmbed.on(EmbedEvent.CustomAction, mockCallback);
2867
+ await searchEmbed.render();
2868
+ const mockEventData = {
2869
+ type: EmbedEvent.ApiIntercept,
2870
+ data: JSON.stringify({
2871
+ input: '/prism/?op=GetChartWithData',
2872
+ init: {}
2873
+ })
2874
+ };
2875
+ const mockPort = {
2876
+ postMessage: jest.fn(),
2877
+ };
2878
+ await executeAfterWait(() => {
2879
+ const iframe = getIFrameEl();
2880
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
2881
+ });
2882
+ await executeAfterWait(() => {
2883
+ expect(capturedExecuteEvent).toBeDefined();
2884
+ // Simulate executeEvent being called by handleInterceptEvent
2885
+ const testData = { test: 'data' };
2886
+ capturedExecuteEvent(EmbedEvent.CustomAction, testData);
2887
+ // executeEvent passes data as first param to callback
2888
+ expect(mockCallback).toHaveBeenCalled();
2889
+ expect(mockCallback.mock.calls[0][0]).toEqual(testData);
2890
+ });
2891
+ });
2892
+ test('should call triggerUIPassThrough through getUnsavedAnswerTml function', async () => {
2893
+ let capturedGetUnsavedAnswerTml;
2894
+ mockHandleInterceptEvent.mockImplementation((params) => {
2895
+ capturedGetUnsavedAnswerTml = params.getUnsavedAnswerTml;
2896
+ });
2897
+ const mockTmlResponse = { tml: 'test-tml-content' };
2898
+ mockProcessTrigger.mockResolvedValue([{ value: mockTmlResponse }]);
2899
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
2900
+ await searchEmbed.render();
2901
+ const mockEventData = {
2902
+ type: EmbedEvent.ApiIntercept,
2903
+ data: JSON.stringify({
2904
+ input: '/prism/?op=GetChartWithData',
2905
+ init: {}
2906
+ })
2907
+ };
2908
+ const mockPort = {
2909
+ postMessage: jest.fn(),
2910
+ };
2911
+ await executeAfterWait(() => {
2912
+ const iframe = getIFrameEl();
2913
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
2914
+ });
2915
+ await executeAfterWait(async () => {
2916
+ expect(capturedGetUnsavedAnswerTml).toBeDefined();
2917
+ // Clear previous calls
2918
+ mockProcessTrigger.mockClear();
2919
+ // Simulate getUnsavedAnswerTml being called by
2920
+ // handleInterceptEvent
2921
+ const result = await capturedGetUnsavedAnswerTml({
2922
+ sessionId: 'session-123',
2923
+ vizId: 'viz-456'
2924
+ });
2925
+ expect(mockProcessTrigger).toHaveBeenCalled();
2926
+ const callArgs = mockProcessTrigger.mock.calls[0];
2927
+ // Verify UIPassthrough event is triggered with the right params
2928
+ expect(callArgs[1]).toBe('UiPassthrough');
2929
+ expect(callArgs[3]).toMatchObject({
2930
+ type: 'getUnsavedAnswerTML',
2931
+ parameters: {
2932
+ sessionId: 'session-123',
2933
+ vizId: 'viz-456'
2934
+ }
2935
+ });
2936
+ expect(result).toEqual(mockTmlResponse);
2937
+ });
2938
+ });
2939
+ test('should pass viewConfig to handleInterceptEvent', async () => {
2940
+ const customViewConfig = {
2941
+ ...defaultViewConfig,
2942
+ interceptUrls: ['/api/test'],
2943
+ interceptTimeout: 5000,
2944
+ };
2945
+ const searchEmbed = new SearchEmbed(getRootEl(), customViewConfig);
2946
+ await searchEmbed.render();
2947
+ const mockEventData = {
2948
+ type: EmbedEvent.ApiIntercept,
2949
+ data: JSON.stringify({
2950
+ input: '/api/test',
2951
+ init: {}
2952
+ })
2953
+ };
2954
+ const mockPort = {
2955
+ postMessage: jest.fn(),
2956
+ };
2957
+ await executeAfterWait(() => {
2958
+ const iframe = getIFrameEl();
2959
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
2960
+ });
2961
+ await executeAfterWait(() => {
2962
+ const call = mockHandleInterceptEvent.mock.calls[0][0];
2963
+ expect(call.viewConfig).toMatchObject({
2964
+ interceptUrls: ['/api/test'],
2965
+ interceptTimeout: 5000,
2966
+ });
2967
+ });
2968
+ });
2969
+ test('should handle ApiIntercept event with eventPort', async () => {
2970
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
2971
+ await searchEmbed.render();
2972
+ const mockEventData = {
2973
+ type: EmbedEvent.ApiIntercept,
2974
+ data: JSON.stringify({
2975
+ input: '/prism/?op=GetChartWithData',
2976
+ init: {}
2977
+ })
2978
+ };
2979
+ const mockPort = {
2980
+ postMessage: jest.fn(),
2981
+ };
2982
+ await executeAfterWait(() => {
2983
+ const iframe = getIFrameEl();
2984
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
2985
+ });
2986
+ await executeAfterWait(() => {
2987
+ expect(mockHandleInterceptEvent).toHaveBeenCalled();
2988
+ // Verify the executeEvent function uses the port
2989
+ const executeEventFn = mockHandleInterceptEvent.mock.calls[0][0].executeEvent;
2990
+ expect(executeEventFn).toBeDefined();
2991
+ });
2992
+ });
2993
+ test('should not process non-ApiIntercept events through handleApiInterceptEvent', async () => {
2994
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
2995
+ await searchEmbed.render();
2996
+ const mockEventData = {
2997
+ type: EmbedEvent.Save,
2998
+ data: { answerId: '123' },
2999
+ };
3000
+ const mockPort = {
3001
+ postMessage: jest.fn(),
3002
+ };
3003
+ await executeAfterWait(() => {
3004
+ const iframe = getIFrameEl();
3005
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
3006
+ });
3007
+ await executeAfterWait(() => {
3008
+ expect(mockHandleInterceptEvent).not.toHaveBeenCalled();
3009
+ });
3010
+ });
3011
+ test('should handle multiple ApiIntercept events', async () => {
3012
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3013
+ await searchEmbed.render();
3014
+ const mockEventData1 = {
3015
+ type: EmbedEvent.ApiIntercept,
3016
+ data: JSON.stringify({
3017
+ input: '/prism/?op=GetChartWithData',
3018
+ init: {}
3019
+ })
3020
+ };
3021
+ const mockEventData2 = {
3022
+ type: EmbedEvent.ApiIntercept,
3023
+ data: JSON.stringify({
3024
+ input: '/prism/?op=LoadContextBook',
3025
+ init: {}
3026
+ })
3027
+ };
3028
+ const mockPort = {
3029
+ postMessage: jest.fn(),
3030
+ };
3031
+ await executeAfterWait(() => {
3032
+ const iframe = getIFrameEl();
3033
+ postMessageToParent(iframe.contentWindow, mockEventData1, mockPort);
3034
+ });
3035
+ await executeAfterWait(() => {
3036
+ postMessageToParent(getIFrameEl().contentWindow, mockEventData2, mockPort);
3037
+ });
3038
+ await executeAfterWait(() => {
3039
+ expect(mockHandleInterceptEvent).toHaveBeenCalledTimes(2);
3040
+ });
3041
+ });
3042
+ test('should pass eventPort to executeCallbacks', async () => {
3043
+ let capturedExecuteEvent;
3044
+ mockHandleInterceptEvent.mockImplementation((params) => {
3045
+ capturedExecuteEvent = params.executeEvent;
3046
+ });
3047
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3048
+ const mockCallback = jest.fn();
3049
+ searchEmbed.on(EmbedEvent.ApiIntercept, mockCallback);
3050
+ await searchEmbed.render();
3051
+ const mockEventData = {
3052
+ type: EmbedEvent.ApiIntercept,
3053
+ data: JSON.stringify({
3054
+ input: '/prism/?op=GetChartWithData',
3055
+ init: {}
3056
+ })
3057
+ };
3058
+ const mockPort = {
3059
+ postMessage: jest.fn(),
3060
+ };
3061
+ await executeAfterWait(() => {
3062
+ const iframe = getIFrameEl();
3063
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
3064
+ });
3065
+ await executeAfterWait(() => {
3066
+ expect(capturedExecuteEvent).toBeDefined();
3067
+ // Call executeEvent with a response
3068
+ const responseData = { execute: true };
3069
+ capturedExecuteEvent(EmbedEvent.ApiIntercept, responseData);
3070
+ // Verify the callback was invoked with the data
3071
+ expect(mockCallback).toHaveBeenCalled();
3072
+ expect(mockCallback.mock.calls[0][0]).toEqual(responseData);
3073
+ });
3074
+ });
3075
+ test('should handle getUnsavedAnswerTml with empty response', async () => {
3076
+ let capturedGetUnsavedAnswerTml;
3077
+ mockHandleInterceptEvent.mockImplementation((params) => {
3078
+ capturedGetUnsavedAnswerTml = params.getUnsavedAnswerTml;
3079
+ });
3080
+ mockProcessTrigger.mockResolvedValue([]);
3081
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3082
+ await searchEmbed.render();
3083
+ const mockEventData = {
3084
+ type: EmbedEvent.ApiIntercept,
3085
+ data: JSON.stringify({
3086
+ input: '/prism/?op=GetChartWithData',
3087
+ init: {}
3088
+ })
3089
+ };
3090
+ const mockPort = {
3091
+ postMessage: jest.fn(),
3092
+ };
3093
+ await executeAfterWait(() => {
3094
+ const iframe = getIFrameEl();
3095
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
3096
+ });
3097
+ await executeAfterWait(async () => {
3098
+ expect(capturedGetUnsavedAnswerTml).toBeDefined();
3099
+ const result = await capturedGetUnsavedAnswerTml({
3100
+ sessionId: 'session-123',
3101
+ vizId: 'viz-456'
3102
+ });
3103
+ expect(result).toBeUndefined();
3104
+ });
3105
+ });
3106
+ test('should work with LiveboardEmbed', async () => {
3107
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
3108
+ ...defaultViewConfig,
3109
+ liveboardId: 'test-liveboard-id',
3110
+ });
3111
+ await liveboardEmbed.render();
3112
+ const mockEventData = {
3113
+ type: EmbedEvent.ApiIntercept,
3114
+ data: JSON.stringify({
3115
+ input: '/prism/?op=LoadContextBook',
3116
+ init: {}
3117
+ })
3118
+ };
3119
+ const mockPort = {
3120
+ postMessage: jest.fn(),
3121
+ };
3122
+ await executeAfterWait(() => {
3123
+ const iframe = getIFrameEl();
3124
+ postMessageToParent(iframe.contentWindow, mockEventData, mockPort);
3125
+ });
3126
+ await executeAfterWait(() => {
3127
+ expect(mockHandleInterceptEvent).toHaveBeenCalledTimes(1);
3128
+ expect(mockHandleInterceptEvent).toHaveBeenCalledWith(expect.objectContaining({
3129
+ eventData: mockEventData,
3130
+ }));
3131
+ });
3132
+ });
3133
+ });
2960
3134
  });
2961
3135
  //# sourceMappingURL=ts-embed.spec.js.map