@thoughtspot/visual-embed-sdk 1.13.0-alpha.2 → 1.13.0

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 (103) hide show
  1. package/CHANGELOG.md +31 -6
  2. package/README.md +1 -1
  3. package/dist/src/auth.d.ts +4 -1
  4. package/dist/src/auth.spec.d.ts +1 -0
  5. package/dist/src/embed/app.d.ts +5 -0
  6. package/dist/src/embed/liveboard.d.ts +12 -1
  7. package/dist/src/embed/search.d.ts +5 -0
  8. package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts +1 -0
  9. package/dist/src/embed/ts-embed.d.ts +12 -3
  10. package/dist/src/errors.d.ts +2 -0
  11. package/dist/src/test/test-utils.d.ts +6 -0
  12. package/dist/src/types.d.ts +211 -4
  13. package/dist/src/utils/processTrigger.d.ts +1 -1
  14. package/dist/src/utils.d.ts +3 -1
  15. package/dist/tsembed.es.js +292 -24
  16. package/dist/tsembed.js +292 -24
  17. package/lib/package.json +4 -2
  18. package/lib/src/auth.d.ts +4 -1
  19. package/lib/src/auth.js +11 -2
  20. package/lib/src/auth.js.map +1 -1
  21. package/lib/src/auth.spec.d.ts +1 -0
  22. package/lib/src/auth.spec.js +13 -1
  23. package/lib/src/auth.spec.js.map +1 -1
  24. package/lib/src/config.spec.js +7 -0
  25. package/lib/src/config.spec.js.map +1 -1
  26. package/lib/src/embed/app.d.ts +5 -0
  27. package/lib/src/embed/app.js +1 -1
  28. package/lib/src/embed/app.js.map +1 -1
  29. package/lib/src/embed/app.spec.js +18 -6
  30. package/lib/src/embed/app.spec.js.map +1 -1
  31. package/lib/src/embed/embed.spec.js +2 -0
  32. package/lib/src/embed/embed.spec.js.map +1 -1
  33. package/lib/src/embed/events.spec.js +3 -1
  34. package/lib/src/embed/events.spec.js.map +1 -1
  35. package/lib/src/embed/liveboard.d.ts +12 -1
  36. package/lib/src/embed/liveboard.js +22 -4
  37. package/lib/src/embed/liveboard.js.map +1 -1
  38. package/lib/src/embed/liveboard.spec.js +33 -6
  39. package/lib/src/embed/liveboard.spec.js.map +1 -1
  40. package/lib/src/embed/pinboard.spec.js +7 -5
  41. package/lib/src/embed/pinboard.spec.js.map +1 -1
  42. package/lib/src/embed/search.d.ts +5 -0
  43. package/lib/src/embed/search.js +10 -2
  44. package/lib/src/embed/search.js.map +1 -1
  45. package/lib/src/embed/search.spec.js +9 -1
  46. package/lib/src/embed/search.spec.js.map +1 -1
  47. package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts +1 -0
  48. package/lib/src/embed/searchEmbed-basic-auth.spec.js +96 -0
  49. package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
  50. package/lib/src/embed/ts-embed.d.ts +12 -3
  51. package/lib/src/embed/ts-embed.js +29 -10
  52. package/lib/src/embed/ts-embed.js.map +1 -1
  53. package/lib/src/embed/ts-embed.spec.js +38 -5
  54. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  55. package/lib/src/errors.d.ts +2 -0
  56. package/lib/src/errors.js +2 -0
  57. package/lib/src/errors.js.map +1 -1
  58. package/lib/src/react/index.js +3 -2
  59. package/lib/src/react/index.js.map +1 -1
  60. package/lib/src/react/index.spec.js +6 -4
  61. package/lib/src/react/index.spec.js.map +1 -1
  62. package/lib/src/test/test-utils.d.ts +6 -0
  63. package/lib/src/test/test-utils.js +15 -0
  64. package/lib/src/test/test-utils.js.map +1 -1
  65. package/lib/src/types.d.ts +211 -4
  66. package/lib/src/types.js +176 -0
  67. package/lib/src/types.js.map +1 -1
  68. package/lib/src/utils/processTrigger.d.ts +1 -1
  69. package/lib/src/utils/processTrigger.js +28 -8
  70. package/lib/src/utils/processTrigger.js.map +1 -1
  71. package/lib/src/utils/processTrigger.spec.js +11 -1
  72. package/lib/src/utils/processTrigger.spec.js.map +1 -1
  73. package/lib/src/utils.d.ts +3 -1
  74. package/lib/src/utils.js +20 -0
  75. package/lib/src/utils.js.map +1 -1
  76. package/lib/src/utils.spec.js +22 -1
  77. package/lib/src/utils.spec.js.map +1 -1
  78. package/lib/src/visual-embed-sdk.d.ts +240 -9
  79. package/package.json +4 -2
  80. package/src/auth.spec.ts +20 -1
  81. package/src/auth.ts +12 -2
  82. package/src/config.spec.ts +11 -0
  83. package/src/embed/app.spec.ts +22 -3
  84. package/src/embed/app.ts +6 -0
  85. package/src/embed/embed.spec.ts +2 -0
  86. package/src/embed/events.spec.ts +3 -0
  87. package/src/embed/liveboard.spec.ts +46 -6
  88. package/src/embed/liveboard.ts +34 -2
  89. package/src/embed/pinboard.spec.ts +8 -6
  90. package/src/embed/search.spec.ts +11 -1
  91. package/src/embed/search.ts +20 -1
  92. package/src/embed/searchEmbed-basic-auth.spec.ts +115 -0
  93. package/src/embed/ts-embed.spec.ts +51 -5
  94. package/src/embed/ts-embed.ts +40 -12
  95. package/src/errors.ts +3 -0
  96. package/src/react/index.spec.tsx +7 -2
  97. package/src/react/index.tsx +3 -2
  98. package/src/test/test-utils.ts +16 -0
  99. package/src/types.ts +209 -0
  100. package/src/utils/processTrigger.spec.ts +11 -1
  101. package/src/utils/processTrigger.ts +36 -12
  102. package/src/utils.spec.ts +29 -0
  103. package/src/utils.ts +34 -1
@@ -1,6 +1,12 @@
1
1
  import { LiveboardEmbed, LiveboardViewConfig } from './liveboard';
2
2
  import { init } from '../index';
3
- import { Action, AuthType, EmbedEvent, RuntimeFilterOp } from '../types';
3
+ import {
4
+ Action,
5
+ AuthType,
6
+ EmbedEvent,
7
+ HostEvent,
8
+ RuntimeFilterOp,
9
+ } from '../types';
4
10
  import {
5
11
  executeAfterWait,
6
12
  getDocumentBody,
@@ -8,6 +14,7 @@ import {
8
14
  getRootEl,
9
15
  } from '../test/test-utils';
10
16
  import { version } from '../../package.json';
17
+ import * as processTriggerInstance from '../utils/processTrigger';
11
18
 
12
19
  const defaultViewConfig = {
13
20
  frameParams: {
@@ -16,10 +23,14 @@ const defaultViewConfig = {
16
23
  },
17
24
  };
18
25
  const liveboardId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
26
+ const activeTabId = '502693ba-9818-4e71-8ecd-d1a194e46861';
19
27
  const vizId = '6e73f724-660e-11eb-ae93-0242ac130002';
20
28
  const thoughtSpotHost = 'tshost';
21
- const defaultParams = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
29
+ const defaultParamsSansHideAction = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
30
+ const defaultParams = `${defaultParamsSansHideAction}&hideAction=[%22${Action.ReportError}%22]`;
22
31
  const prefixParams = '&isLiveboardEmbed=true&isPinboardV2Enabled=false';
32
+ const prefixParamsVizEmbed =
33
+ '&isLiveboardEmbed=true&isVizEmbed=true&isPinboardV2Enabled=false';
23
34
 
24
35
  beforeAll(() => {
25
36
  init({
@@ -60,7 +71,7 @@ describe('Liveboard/viz embed tests', () => {
60
71
  liveboardEmbed.render();
61
72
  await executeAfterWait(() => {
62
73
  expect(getIFrameSrc()).toBe(
63
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&disableAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]&disableHint=Action%20denied${prefixParams}#/embed/viz/${liveboardId}`,
74
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParamsSansHideAction}&disableAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]&disableHint=Action%20denied&hideAction=[%22${Action.ReportError}%22]${prefixParams}#/embed/viz/${liveboardId}`,
64
75
  );
65
76
  });
66
77
  });
@@ -78,7 +89,7 @@ describe('Liveboard/viz embed tests', () => {
78
89
  liveboardEmbed.render();
79
90
  await executeAfterWait(() => {
80
91
  expect(getIFrameSrc()).toBe(
81
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&hideAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${liveboardId}`,
92
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParamsSansHideAction}&hideAction=[%22${Action.ReportError}%22,%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${liveboardId}`,
82
93
  );
83
94
  });
84
95
  });
@@ -152,7 +163,7 @@ describe('Liveboard/viz embed tests', () => {
152
163
  liveboardEmbed.render();
153
164
  await executeAfterWait(() => {
154
165
  expect(getIFrameSrc()).toBe(
155
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}#/embed/viz/${liveboardId}/${vizId}`,
166
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`,
156
167
  );
157
168
  });
158
169
  });
@@ -173,7 +184,7 @@ describe('Liveboard/viz embed tests', () => {
173
184
  liveboardEmbed.render();
174
185
  await executeAfterWait(() => {
175
186
  expect(getIFrameSrc()).toBe(
176
- `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParams}#/embed/viz/${liveboardId}/${vizId}`,
187
+ `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${liveboardId}/${vizId}`,
177
188
  );
178
189
  });
179
190
  });
@@ -209,4 +220,33 @@ describe('Liveboard/viz embed tests', () => {
209
220
  );
210
221
  });
211
222
  });
223
+ test('should process the trigger, for vizEmbed', async () => {
224
+ const mockProcessTrigger = spyOn(
225
+ processTriggerInstance,
226
+ 'processTrigger',
227
+ );
228
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
229
+ enableVizTransformations: true,
230
+ ...defaultViewConfig,
231
+ vizId: '1234',
232
+ liveboardId,
233
+ } as LiveboardViewConfig);
234
+ liveboardEmbed.render();
235
+ const result = await liveboardEmbed.trigger(HostEvent.Pin);
236
+ expect(mockProcessTrigger).toBeCalled();
237
+ });
238
+
239
+ test('should render active tab when activeTab present', async () => {
240
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
241
+ liveboardId,
242
+ activeTabId,
243
+ liveboardV2: true,
244
+ } as LiveboardViewConfig);
245
+ liveboardEmbed.render();
246
+ await executeAfterWait(() => {
247
+ expect(getIFrameSrc()).toBe(
248
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardEmbed=true&isPinboardV2Enabled=true#/embed/viz/${liveboardId}/tab/${activeTabId}`,
249
+ );
250
+ });
251
+ });
212
252
  });
@@ -82,6 +82,11 @@ export interface LiveboardViewConfig extends ViewConfig {
82
82
  * @hidden
83
83
  */
84
84
  liveboardV2?: boolean;
85
+ /**
86
+ * Tab Id of the Liveboard that is supposed to be active
87
+ * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
88
+ */
89
+ activeTabId?: string;
85
90
  }
86
91
 
87
92
  /**
@@ -110,6 +115,8 @@ export class LiveboardEmbed extends V1Embed {
110
115
  defaultHeight,
111
116
  visibleVizs,
112
117
  liveboardV2 = false,
118
+ vizId,
119
+ activeTabId,
113
120
  } = this.viewConfig;
114
121
 
115
122
  const preventLiveboardFilterRemoval =
@@ -134,6 +141,9 @@ export class LiveboardEmbed extends V1Embed {
134
141
  params[Param.visibleVizs] = visibleVizs;
135
142
  }
136
143
  params[Param.livedBoardEmbed] = true;
144
+ if (vizId) {
145
+ params[Param.vizEmbed] = true;
146
+ }
137
147
  params[Param.LiveboardV2Enabled] = liveboardV2;
138
148
  const queryParams = getQueryParamString(params, true);
139
149
 
@@ -152,6 +162,7 @@ export class LiveboardEmbed extends V1Embed {
152
162
  liveboardId: string,
153
163
  vizId?: string,
154
164
  runtimeFilters?: RuntimeFilter[],
165
+ activeTabId?: string,
155
166
  ) {
156
167
  const filterQuery = getFilterQuery(runtimeFilters || []);
157
168
  const queryParams = this.getEmbedParams();
@@ -164,6 +175,9 @@ export class LiveboardEmbed extends V1Embed {
164
175
  false,
165
176
  false,
166
177
  )}/viz/${liveboardId}`;
178
+ if (activeTabId) {
179
+ url = `${url}/tab/${activeTabId}`;
180
+ }
167
181
  if (vizId) {
168
182
  url = `${url}/${vizId}`;
169
183
  }
@@ -194,13 +208,26 @@ export class LiveboardEmbed extends V1Embed {
194
208
  }
195
209
  };
196
210
 
211
+ /**
212
+ * Triggers an event to the embedded app
213
+ * @param messageType The event type
214
+ * @param data The payload to send with the message
215
+ */
216
+ public trigger(messageType: HostEvent, data: any = {}): Promise<any> {
217
+ const dataWithVizId = data;
218
+ if (this.viewConfig.vizId) {
219
+ dataWithVizId.vizId = this.viewConfig.vizId;
220
+ }
221
+ return super.trigger(messageType, dataWithVizId);
222
+ }
223
+
197
224
  /**
198
225
  * Render an embedded ThoughtSpot Liveboard or visualization
199
226
  * @param renderOptions An object specifying the Liveboard ID,
200
227
  * visualization ID and the runtime filters.
201
228
  */
202
229
  public render(): LiveboardEmbed {
203
- const { vizId, runtimeFilters } = this.viewConfig;
230
+ const { vizId, activeTabId, runtimeFilters } = this.viewConfig;
204
231
  const liveboardId =
205
232
  this.viewConfig.liveboardId ?? this.viewConfig.pinboardId;
206
233
 
@@ -219,7 +246,12 @@ export class LiveboardEmbed extends V1Embed {
219
246
 
220
247
  super.render();
221
248
 
222
- const src = this.getIFrameSrc(liveboardId, vizId, runtimeFilters);
249
+ const src = this.getIFrameSrc(
250
+ liveboardId,
251
+ vizId,
252
+ runtimeFilters,
253
+ activeTabId,
254
+ );
223
255
  this.renderV1Embed(src);
224
256
 
225
257
  return this;
@@ -18,9 +18,11 @@ const defaultViewConfig = {
18
18
  const pinboardId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
19
19
  const vizId = '6e73f724-660e-11eb-ae93-0242ac130002';
20
20
  const thoughtSpotHost = 'tshost';
21
- const defaultParams = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
21
+ const defaultParamsWithoutHideActions = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
22
+ const defaultParams = `${defaultParamsWithoutHideActions}&hideAction=[%22${Action.ReportError}%22]`;
22
23
  const prefixParams = '&isLiveboardEmbed=true&isPinboardV2Enabled=false';
23
-
24
+ const prefixParamsVizEmbed =
25
+ '&isLiveboardEmbed=true&isVizEmbed=true&isPinboardV2Enabled=false';
24
26
  beforeAll(() => {
25
27
  init({
26
28
  thoughtSpotHost,
@@ -60,7 +62,7 @@ describe('Pinboard/viz embed tests', () => {
60
62
  pinboardEmbed.render();
61
63
  await executeAfterWait(() => {
62
64
  expect(getIFrameSrc()).toBe(
63
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&disableAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]&disableHint=Action%20denied${prefixParams}#/embed/viz/${pinboardId}`,
65
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParamsWithoutHideActions}&disableAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]&disableHint=Action%20denied&hideAction=[%22${Action.ReportError}%22]${prefixParams}#/embed/viz/${pinboardId}`,
64
66
  );
65
67
  });
66
68
  });
@@ -78,7 +80,7 @@ describe('Pinboard/viz embed tests', () => {
78
80
  pinboardEmbed.render();
79
81
  await executeAfterWait(() => {
80
82
  expect(getIFrameSrc()).toBe(
81
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&hideAction=[%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${pinboardId}`,
83
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParamsWithoutHideActions}&hideAction=[%22${Action.ReportError}%22,%22${Action.DownloadAsCsv}%22,%22${Action.DownloadAsPdf}%22,%22${Action.DownloadAsXlsx}%22]${prefixParams}#/embed/viz/${pinboardId}`,
82
84
  );
83
85
  });
84
86
  });
@@ -152,7 +154,7 @@ describe('Pinboard/viz embed tests', () => {
152
154
  pinboardEmbed.render();
153
155
  await executeAfterWait(() => {
154
156
  expect(getIFrameSrc()).toBe(
155
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}#/embed/viz/${pinboardId}/${vizId}`,
157
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${pinboardId}/${vizId}`,
156
158
  );
157
159
  });
158
160
  });
@@ -173,7 +175,7 @@ describe('Pinboard/viz embed tests', () => {
173
175
  pinboardEmbed.render();
174
176
  await executeAfterWait(() => {
175
177
  expect(getIFrameSrc()).toBe(
176
- `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParams}#/embed/viz/${pinboardId}/${vizId}`,
178
+ `http://${thoughtSpotHost}/?embedApp=true&col1=sales&op1=EQ&val1=1000${defaultParams}${prefixParamsVizEmbed}#/embed/viz/${pinboardId}/${vizId}`,
177
179
  );
178
180
  });
179
181
  });
@@ -1,4 +1,5 @@
1
1
  import { SearchEmbed, HiddenActionItemByDefaultForSearchEmbed } from './search';
2
+ import * as authInstance from '../auth';
2
3
  import { init } from '../index';
3
4
  import { Action, AuthType } from '../types';
4
5
  import {
@@ -20,7 +21,10 @@ const answerId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
20
21
  const thoughtSpotHost = 'tshost';
21
22
  const defaultParams = `hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
22
23
  const hideBydefault = `&hideAction=${fixedEncodeURI(
23
- JSON.stringify(HiddenActionItemByDefaultForSearchEmbed),
24
+ JSON.stringify([
25
+ Action.ReportError,
26
+ ...HiddenActionItemByDefaultForSearchEmbed,
27
+ ]),
24
28
  )}`;
25
29
  const defaultParamsWithHiddenActions = defaultParams + hideBydefault;
26
30
  const prefixParams = '&isSearchEmbed=true';
@@ -30,11 +34,15 @@ beforeAll(() => {
30
34
  thoughtSpotHost,
31
35
  authType: AuthType.None,
32
36
  });
37
+ spyOn(window, 'alert');
33
38
  });
34
39
 
35
40
  describe('Search embed tests', () => {
36
41
  beforeEach(() => {
37
42
  document.body.innerHTML = getDocumentBody();
43
+ jest.spyOn(authInstance, 'getReleaseVersion').mockReturnValue(
44
+ '7.4.0.sw',
45
+ );
38
46
  });
39
47
 
40
48
  test('should render', async () => {
@@ -197,6 +205,7 @@ describe('Search embed tests', () => {
197
205
  searchEmbed.render();
198
206
  const hideActionUrl = fixedEncodeURI(
199
207
  JSON.stringify([
208
+ Action.ReportError,
200
209
  ...hiddenActionsForSearch,
201
210
  ...HiddenActionItemByDefaultForSearchEmbed,
202
211
  ]),
@@ -220,6 +229,7 @@ describe('Search embed tests', () => {
220
229
  searchEmbed.render();
221
230
  const hideActionUrl = fixedEncodeURI(
222
231
  JSON.stringify([
232
+ Action.ReportError,
223
233
  ...hiddenActionsForSearch,
224
234
  ...HiddenActionItemByDefaultForSearchEmbed,
225
235
  ]),
@@ -8,9 +8,12 @@
8
8
  */
9
9
 
10
10
  import { DataSourceVisualMode, DOMSelector, Param, Action } from '../types';
11
- import { getQueryParamString } from '../utils';
11
+ import { getQueryParamString, checkReleaseVersionInBeta } from '../utils';
12
12
  import { ViewConfig, TsEmbed } from './ts-embed';
13
13
  import { version } from '../../package.json';
14
+ import { ERROR_MESSAGE } from '../errors';
15
+ import { getAuthPromise, getEmbedConfig } from './base';
16
+ import { getReleaseVersion } from '../auth';
14
17
 
15
18
  /**
16
19
  * Configuration for search options
@@ -49,8 +52,13 @@ export interface SearchViewConfig extends ViewConfig {
49
52
  * using raw answer data.
50
53
  */
51
54
  hideResults?: boolean;
55
+ /**
56
+ * If set to true, expands all the data sources panel.
57
+ */
58
+ expandAllDataSource?: boolean;
52
59
  /**
53
60
  * If set to true, the Search Assist feature is enabled.
61
+ * @version SDK: 1.13.0 | ThoughtSpot: 8.5.0.cl
54
62
  */
55
63
  enableSearchAssist?: boolean;
56
64
  /**
@@ -126,6 +134,7 @@ export class SearchEmbed extends TsEmbed {
126
134
  private getIFrameSrc(answerId: string, dataSources?: string[]) {
127
135
  const {
128
136
  hideResults,
137
+ expandAllDataSource,
129
138
  enableSearchAssist,
130
139
  forceTable,
131
140
  searchOptions,
@@ -184,6 +193,16 @@ export class SearchEmbed extends TsEmbed {
184
193
 
185
194
  const src = this.getIFrameSrc(answerId, dataSources);
186
195
  this.renderIFrame(src, this.viewConfig.frameParams);
196
+ getAuthPromise().then(() => {
197
+ if (
198
+ checkReleaseVersionInBeta(
199
+ getReleaseVersion(),
200
+ getEmbedConfig().suppressSearchEmbedBetaWarning,
201
+ )
202
+ ) {
203
+ alert(ERROR_MESSAGE.SEARCHEMBED_BETA_WRANING_MESSAGE);
204
+ }
205
+ });
187
206
  return this;
188
207
  }
189
208
  }
@@ -0,0 +1,115 @@
1
+ import { SearchEmbed } from './search';
2
+ import * as baseInstance from './base';
3
+ import * as authService from '../utils/authService';
4
+ import * as authInstance from '../auth';
5
+ import * as config from '../config';
6
+
7
+ import { init } from '../index';
8
+ import { AuthType } from '../types';
9
+ import { getDocumentBody, getRootEl } from '../test/test-utils';
10
+ import { mockSessionInfo } from '../auth.spec';
11
+ import { ERROR_MESSAGE } from '../errors';
12
+
13
+ const thoughtSpotHost = 'tshost';
14
+ init({
15
+ thoughtSpotHost,
16
+ authType: AuthType.Basic,
17
+ username: 'tsadmin',
18
+ password: 'admin',
19
+ });
20
+
21
+ describe('Search embed tests when authType is Basic', () => {
22
+ function setupVersion(version: string) {
23
+ jest.spyOn(window, 'addEventListener').mockImplementationOnce(
24
+ (event, handler, options) => {
25
+ handler({
26
+ data: {
27
+ type: 'xyz',
28
+ },
29
+ ports: [3000],
30
+ source: null,
31
+ });
32
+ },
33
+ );
34
+ jest.spyOn(authService, 'fetchSessionInfoService').mockImplementation(
35
+ async () => ({
36
+ json: () => ({
37
+ ...mockSessionInfo,
38
+ releaseVersion: version,
39
+ }),
40
+ status: 200,
41
+ }),
42
+ );
43
+ jest.spyOn(authInstance, 'getReleaseVersion').mockReturnValue(version);
44
+ }
45
+ beforeEach(() => {
46
+ document.body.innerHTML = getDocumentBody();
47
+ jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValue(true);
48
+ });
49
+
50
+ afterEach(() => {
51
+ jest.clearAllMocks();
52
+ });
53
+
54
+ test('when releaseVersion is empty', async () => {
55
+ setupVersion('');
56
+ const mockAlert = spyOn(window, 'alert');
57
+ const searchEmbed = new SearchEmbed(getRootEl(), {});
58
+ await searchEmbed.render();
59
+ expect(mockAlert).not.toBeCalled();
60
+ });
61
+
62
+ test("when releaseVersion is '7.0.1.cl' ", async () => {
63
+ setupVersion('7.0.1.cl');
64
+ const mockAlert = jest.spyOn(window, 'alert');
65
+ const searchEmbed = new SearchEmbed(getRootEl(), {});
66
+ await searchEmbed.render();
67
+ expect(mockAlert).not.toBeCalled();
68
+ });
69
+ test('when releaseVersion is above 8.4.0.sw', async () => {
70
+ setupVersion('8.4.0.sw');
71
+ const mockAlert = jest.spyOn(window, 'alert');
72
+ const searchEmbed = new SearchEmbed(getRootEl(), {});
73
+ await searchEmbed.render();
74
+ expect(mockAlert).not.toBeCalled();
75
+ });
76
+
77
+ test('releaseVersion is above 8.4.0.sw', async () => {
78
+ setupVersion('8.8.0.sw');
79
+ jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(
80
+ () => 'http://tshost',
81
+ );
82
+ const mockAlert = jest.spyOn(window, 'alert');
83
+ const searchEmbed = new SearchEmbed(getRootEl(), {});
84
+ await searchEmbed.render();
85
+ expect(mockAlert).not.toBeCalled();
86
+ });
87
+
88
+ test('Alert should not appear when suppressSearchEmbedBetaWarning is true and releaseVersion is ts7.dec.cl', async () => {
89
+ setupVersion('ts7.dec.cl');
90
+ jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(
91
+ () => 'http://tshost',
92
+ );
93
+ jest.spyOn(baseInstance, 'getEmbedConfig').mockReturnValue({
94
+ suppressSearchEmbedBetaWarning: true,
95
+ });
96
+ const mockAlert = jest.spyOn(window, 'alert');
97
+ const searchEmbed = new SearchEmbed(getRootEl(), {});
98
+ await searchEmbed.render();
99
+ expect(mockAlert).not.toBeCalled();
100
+ });
101
+
102
+ test('Alert should not appear when suppressSearchEmbedBetaWarning is true and releaseVersion is 8.4.0.sw', async () => {
103
+ setupVersion('8.4.0.sw');
104
+ jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(
105
+ () => 'http://tshost',
106
+ );
107
+ jest.spyOn(baseInstance, 'getEmbedConfig').mockReturnValue({
108
+ suppressSearchEmbedBetaWarning: true,
109
+ });
110
+ const mockAlert = jest.spyOn(window, 'alert');
111
+ const searchEmbed = new SearchEmbed(getRootEl(), {});
112
+ await searchEmbed.render();
113
+ expect(mockAlert).not.toBeCalled();
114
+ });
115
+ });
@@ -34,9 +34,20 @@ const defaultViewConfig = {
34
34
  const pinboardId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
35
35
  const liveboardId = 'eca215d4-0d2c-4a55-90e3-d81ef6848ae0';
36
36
  const thoughtSpotHost = 'tshost';
37
- const defaultParamsForPinboardEmbed = `hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
37
+ const defaultParamsForPinboardEmbed = `hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&hideAction=[%22${Action.ReportError}%22]`;
38
38
  const defaultParamsPost = '&isPinboardV2Enabled=false';
39
39
 
40
+ beforeAll(() => {
41
+ spyOn(window, 'alert');
42
+ });
43
+
44
+ const customisations = {
45
+ style: {
46
+ customCSSUrl: 'http://localhost:3000',
47
+ },
48
+ content: {},
49
+ };
50
+
40
51
  describe('Unit test case for ts embed', () => {
41
52
  const mockMixPanelEvent = jest.spyOn(
42
53
  mixpanelInstance,
@@ -55,6 +66,31 @@ describe('Unit test case for ts embed', () => {
55
66
  init({
56
67
  thoughtSpotHost: 'tshost',
57
68
  authType: AuthType.None,
69
+ customisations,
70
+ });
71
+ });
72
+
73
+ test('verify Customisations', async () => {
74
+ const mockEmbedEventPayload = {
75
+ type: EmbedEvent.APP_INIT,
76
+ data: {},
77
+ };
78
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
79
+ searchEmbed.render();
80
+ const mockPort: any = {
81
+ postMessage: jest.fn(),
82
+ };
83
+ await executeAfterWait(() => {
84
+ const iframe = getIFrameEl();
85
+ postMessageToParent(
86
+ iframe.contentWindow,
87
+ mockEmbedEventPayload,
88
+ mockPort,
89
+ );
90
+ });
91
+ expect(mockPort.postMessage).toHaveBeenCalledWith({
92
+ type: EmbedEvent.APP_INIT,
93
+ data: { customisations },
58
94
  });
59
95
  });
60
96
 
@@ -261,7 +297,7 @@ describe('Unit test case for ts embed', () => {
261
297
 
262
298
  describe('when visible actions are set', () => {
263
299
  test('should throw error when there are both visible and hidden actions - pinboard', async () => {
264
- spyOn(console, 'log');
300
+ spyOn(console, 'error');
265
301
  const pinboardEmbed = new PinboardEmbed(getRootEl(), {
266
302
  hiddenActions: [Action.DownloadAsCsv],
267
303
  visibleActions: [Action.DownloadAsCsv],
@@ -270,7 +306,7 @@ describe('Unit test case for ts embed', () => {
270
306
  } as LiveboardViewConfig);
271
307
  await pinboardEmbed.render();
272
308
  expect(pinboardEmbed['isError']).toBe(true);
273
- expect(console.log).toHaveBeenCalledWith(
309
+ expect(console.error).toHaveBeenCalledWith(
274
310
  'You cannot have both hidden actions and visible actions',
275
311
  );
276
312
  });
@@ -288,7 +324,7 @@ describe('Unit test case for ts embed', () => {
288
324
  hiddenActions: Array<Action>,
289
325
  visibleActions: Array<Action>,
290
326
  ) {
291
- spyOn(console, 'log');
327
+ spyOn(console, 'error');
292
328
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
293
329
  hiddenActions,
294
330
  visibleActions,
@@ -297,7 +333,7 @@ describe('Unit test case for ts embed', () => {
297
333
  } as LiveboardViewConfig);
298
334
  await liveboardEmbed.render();
299
335
  expect(liveboardEmbed['isError']).toBe(true);
300
- expect(console.log).toHaveBeenCalledWith(
336
+ expect(console.error).toHaveBeenCalledWith(
301
337
  'You cannot have both hidden actions and visible actions',
302
338
  );
303
339
  }
@@ -346,14 +382,19 @@ describe('Unit test case for ts embed', () => {
346
382
  });
347
383
 
348
384
  test('Error should be true', async () => {
385
+ spyOn(console, 'error');
349
386
  const tsEmbed = new SearchEmbed(getRootEl(), {});
350
387
  tsEmbed.render();
351
388
  expect(tsEmbed['isError']).toBe(true);
389
+ expect(console.error).toHaveBeenCalledWith(
390
+ 'You need to init the ThoughtSpot SDK module first',
391
+ );
352
392
  });
353
393
  });
354
394
 
355
395
  describe('V1Embed ', () => {
356
396
  test('when isRendered is true than isError will be true', () => {
397
+ spyOn(console, 'error');
357
398
  const viEmbedIns = new tsEmbedInstance.V1Embed(
358
399
  getRootEl(),
359
400
  defaultViewConfig,
@@ -362,11 +403,15 @@ describe('Unit test case for ts embed', () => {
362
403
  viEmbedIns.render();
363
404
  viEmbedIns.on(EmbedEvent.CustomAction, jest.fn()).render();
364
405
  expect(viEmbedIns['isError']).toBe(true);
406
+ expect(console.error).toHaveBeenCalledWith(
407
+ 'Please register event handlers before calling render',
408
+ );
365
409
  });
366
410
  });
367
411
 
368
412
  describe('Navigate to Page API', () => {
369
413
  const path = 'viz/e0836cad-4fdf-42d4-bd97-567a6b2a6058';
414
+
370
415
  beforeEach(() => {
371
416
  jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(
372
417
  () => 'http://tshost',
@@ -415,6 +460,7 @@ describe('Unit test case for ts embed', () => {
415
460
  });
416
461
  describe('Navigate to Page API - Pinboard', () => {
417
462
  const path = 'pinboard/e0836cad-4fdf-42d4-bd97-567a6b2a6058';
463
+
418
464
  beforeEach(() => {
419
465
  jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(
420
466
  () => 'http://tshost',