@thoughtspot/visual-embed-sdk 1.51.2 → 1.52.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.
- package/cjs/package.json +9 -1
- package/cjs/src/api-intercept.d.ts.map +1 -1
- package/cjs/src/api-intercept.js +1 -0
- package/cjs/src/api-intercept.js.map +1 -1
- package/cjs/src/contracts/contracts.spec.d.ts +2 -0
- package/cjs/src/contracts/contracts.spec.d.ts.map +1 -0
- package/cjs/src/contracts/contracts.spec.js +345 -0
- package/cjs/src/contracts/contracts.spec.js.map +1 -0
- package/cjs/src/contracts/embed-event-payloads.d.ts +73 -0
- package/cjs/src/contracts/embed-event-payloads.d.ts.map +1 -0
- package/cjs/src/contracts/embed-event-payloads.js +3 -0
- package/cjs/src/contracts/embed-event-payloads.js.map +1 -0
- package/cjs/src/contracts/host-event-contracts.d.ts +378 -0
- package/cjs/src/contracts/host-event-contracts.d.ts.map +1 -0
- package/cjs/src/contracts/host-event-contracts.js +3 -0
- package/cjs/src/contracts/host-event-contracts.js.map +1 -0
- package/cjs/src/contracts/index.d.ts +22 -0
- package/cjs/src/contracts/index.d.ts.map +1 -0
- package/cjs/src/contracts/index.js +33 -0
- package/cjs/src/contracts/index.js.map +1 -0
- package/cjs/src/contracts/ui-passthrough-contracts.d.ts +277 -0
- package/cjs/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
- package/cjs/src/{embed/hostEventClient/contracts.js → contracts/ui-passthrough-contracts.js} +6 -2
- package/cjs/src/contracts/ui-passthrough-contracts.js.map +1 -0
- package/cjs/src/css-variables.d.ts +1 -1
- package/cjs/src/embed/app.d.ts +17 -140
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +20 -120
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +70 -26
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +5 -5
- package/cjs/src/embed/events.spec.js +12 -2
- package/cjs/src/embed/events.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts +3 -2
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.js +23 -18
- package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js +36 -36
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.d.ts +1 -1
- package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/utils.js +3 -3
- package/cjs/src/embed/hostEventClient/utils.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +9 -161
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +68 -135
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +215 -32
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/search.d.ts +14 -0
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +4 -1
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/search.spec.js +65 -0
- package/cjs/src/embed/search.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +21 -25
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +105 -72
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +380 -33
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/full-height.d.ts +137 -0
- package/cjs/src/full-height.d.ts.map +1 -0
- package/cjs/src/full-height.js +272 -0
- package/cjs/src/full-height.js.map +1 -0
- package/cjs/src/full-height.spec.d.ts +2 -0
- package/cjs/src/full-height.spec.d.ts.map +1 -0
- package/cjs/src/full-height.spec.js +835 -0
- package/cjs/src/full-height.spec.js.map +1 -0
- package/cjs/src/index.d.ts +4 -3
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +5 -4
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/all-types-export.parity.spec.js +55 -3
- package/cjs/src/react/all-types-export.parity.spec.js.map +1 -1
- package/cjs/src/react/index.d.ts +8 -8
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +1 -1
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +7 -7
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +664 -39
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +406 -13
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processTrigger.d.ts +3 -1
- package/cjs/src/utils/processTrigger.d.ts.map +1 -1
- package/cjs/src/utils/processTrigger.js +19 -51
- package/cjs/src/utils/processTrigger.js.map +1 -1
- package/cjs/src/utils/transport/iframe-transport.d.ts +55 -0
- package/cjs/src/utils/transport/iframe-transport.d.ts.map +1 -0
- package/cjs/src/utils/transport/iframe-transport.js +108 -0
- package/cjs/src/utils/transport/iframe-transport.js.map +1 -0
- package/cjs/src/utils/transport/iframe-transport.spec.d.ts +2 -0
- package/cjs/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
- package/cjs/src/utils/transport/iframe-transport.spec.js +140 -0
- package/cjs/src/utils/transport/iframe-transport.spec.js.map +1 -0
- package/cjs/src/utils.d.ts +18 -0
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +39 -1
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.js +62 -0
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-D8_Zs-Nr.js → index-C1pmYb5H.js} +1 -1
- package/dist/src/api-intercept.d.ts.map +1 -1
- package/dist/src/contracts/contracts.spec.d.ts +2 -0
- package/dist/src/contracts/contracts.spec.d.ts.map +1 -0
- package/dist/src/contracts/embed-event-payloads.d.ts +73 -0
- package/dist/src/contracts/embed-event-payloads.d.ts.map +1 -0
- package/dist/src/contracts/host-event-contracts.d.ts +378 -0
- package/dist/src/contracts/host-event-contracts.d.ts.map +1 -0
- package/dist/src/contracts/index.d.ts +22 -0
- package/dist/src/contracts/index.d.ts.map +1 -0
- package/dist/src/contracts/ui-passthrough-contracts.d.ts +277 -0
- package/dist/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
- package/dist/src/css-variables.d.ts +1 -1
- package/dist/src/embed/app.d.ts +17 -140
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +5 -5
- package/dist/src/embed/hostEventClient/host-event-client.d.ts +3 -2
- package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/utils.d.ts +1 -1
- package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +9 -161
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +14 -0
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +21 -25
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/dist/src/full-height.d.ts +137 -0
- package/dist/src/full-height.d.ts.map +1 -0
- package/dist/src/full-height.spec.d.ts +2 -0
- package/dist/src/full-height.spec.d.ts.map +1 -0
- package/dist/src/index.d.ts +4 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/react/index.d.ts +8 -8
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +664 -39
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/processTrigger.d.ts +3 -1
- package/dist/src/utils/processTrigger.d.ts.map +1 -1
- package/dist/src/utils/transport/iframe-transport.d.ts +55 -0
- package/dist/src/utils/transport/iframe-transport.d.ts.map +1 -0
- package/dist/src/utils/transport/iframe-transport.spec.d.ts +2 -0
- package/dist/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
- package/dist/src/utils.d.ts +18 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +1031 -392
- package/dist/tsembed-react.js +1030 -391
- package/dist/tsembed.es.js +1031 -392
- package/dist/tsembed.js +1029 -390
- package/dist/visual-embed-sdk-react-full.d.ts +1483 -693
- package/dist/visual-embed-sdk-react.d.ts +1364 -647
- package/dist/visual-embed-sdk.d.ts +1426 -659
- package/lib/package.json +9 -1
- package/lib/src/api-intercept.d.ts.map +1 -1
- package/lib/src/api-intercept.js +2 -1
- package/lib/src/api-intercept.js.map +1 -1
- package/lib/src/contracts/contracts.spec.d.ts +2 -0
- package/lib/src/contracts/contracts.spec.d.ts.map +1 -0
- package/lib/src/contracts/contracts.spec.js +342 -0
- package/lib/src/contracts/contracts.spec.js.map +1 -0
- package/lib/src/contracts/embed-event-payloads.d.ts +73 -0
- package/lib/src/contracts/embed-event-payloads.d.ts.map +1 -0
- package/lib/src/contracts/embed-event-payloads.js +2 -0
- package/lib/src/contracts/embed-event-payloads.js.map +1 -0
- package/lib/src/contracts/host-event-contracts.d.ts +378 -0
- package/lib/src/contracts/host-event-contracts.d.ts.map +1 -0
- package/lib/src/contracts/host-event-contracts.js +2 -0
- package/lib/src/contracts/host-event-contracts.js.map +1 -0
- package/lib/src/contracts/index.d.ts +22 -0
- package/lib/src/contracts/index.d.ts.map +1 -0
- package/lib/src/contracts/index.js +22 -0
- package/lib/src/contracts/index.js.map +1 -0
- package/lib/src/contracts/ui-passthrough-contracts.d.ts +277 -0
- package/lib/src/contracts/ui-passthrough-contracts.d.ts.map +1 -0
- package/lib/src/{embed/hostEventClient/contracts.js → contracts/ui-passthrough-contracts.js} +6 -2
- package/lib/src/contracts/ui-passthrough-contracts.js.map +1 -0
- package/lib/src/css-variables.d.ts +1 -1
- package/lib/src/embed/app.d.ts +17 -140
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +22 -122
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +70 -26
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +5 -5
- package/lib/src/embed/events.spec.js +12 -2
- package/lib/src/embed/events.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.d.ts +3 -2
- package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.js +6 -1
- package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.spec.js +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/utils.d.ts +1 -1
- package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/utils.js +1 -1
- package/lib/src/embed/hostEventClient/utils.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +9 -161
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +70 -137
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +215 -32
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/search.d.ts +14 -0
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +4 -1
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/search.spec.js +65 -0
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +21 -25
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +106 -73
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +378 -31
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/full-height.d.ts +137 -0
- package/lib/src/full-height.d.ts.map +1 -0
- package/lib/src/full-height.js +268 -0
- package/lib/src/full-height.js.map +1 -0
- package/lib/src/full-height.spec.d.ts +2 -0
- package/lib/src/full-height.spec.d.ts.map +1 -0
- package/lib/src/full-height.spec.js +833 -0
- package/lib/src/full-height.spec.js.map +1 -0
- package/lib/src/index.d.ts +4 -3
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +3 -3
- package/lib/src/index.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/react/all-types-export.parity.spec.js +55 -3
- package/lib/src/react/all-types-export.parity.spec.js.map +1 -1
- package/lib/src/react/index.d.ts +8 -8
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +1 -1
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +7 -7
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +664 -39
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +405 -12
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processTrigger.d.ts +3 -1
- package/lib/src/utils/processTrigger.d.ts.map +1 -1
- package/lib/src/utils/processTrigger.js +19 -51
- package/lib/src/utils/processTrigger.js.map +1 -1
- package/lib/src/utils/transport/iframe-transport.d.ts +55 -0
- package/lib/src/utils/transport/iframe-transport.d.ts.map +1 -0
- package/lib/src/utils/transport/iframe-transport.js +101 -0
- package/lib/src/utils/transport/iframe-transport.js.map +1 -0
- package/lib/src/utils/transport/iframe-transport.spec.d.ts +2 -0
- package/lib/src/utils/transport/iframe-transport.spec.d.ts.map +1 -0
- package/lib/src/utils/transport/iframe-transport.spec.js +138 -0
- package/lib/src/utils/transport/iframe-transport.spec.js.map +1 -0
- package/lib/src/utils.d.ts +18 -0
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +37 -0
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +63 -1
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +1426 -659
- package/package.json +9 -1
- package/src/api-intercept.ts +2 -1
- package/src/contracts/contracts.spec.ts +392 -0
- package/src/contracts/embed-event-payloads.ts +83 -0
- package/src/contracts/host-event-contracts.ts +456 -0
- package/src/contracts/index.ts +53 -0
- package/src/contracts/ui-passthrough-contracts.ts +301 -0
- package/src/css-variables.ts +1 -1
- package/src/embed/app.spec.ts +86 -34
- package/src/embed/app.ts +37 -264
- package/src/embed/conversation.ts +5 -5
- package/src/embed/events.spec.ts +14 -2
- package/src/embed/hostEventClient/host-event-client.spec.ts +2 -2
- package/src/embed/hostEventClient/host-event-client.ts +18 -5
- package/src/embed/hostEventClient/utils.ts +2 -1
- package/src/embed/liveboard.spec.ts +261 -42
- package/src/embed/liveboard.ts +78 -297
- package/src/embed/search.spec.ts +80 -0
- package/src/embed/search.ts +20 -0
- package/src/embed/ts-embed.spec.ts +518 -31
- package/src/embed/ts-embed.ts +133 -82
- package/src/full-height.spec.ts +1008 -0
- package/src/full-height.ts +361 -0
- package/src/index.ts +95 -5
- package/src/react/all-types-export.parity.spec.ts +63 -3
- package/src/react/all-types-export.ts +46 -0
- package/src/react/index.spec.tsx +7 -7
- package/src/react/index.tsx +9 -9
- package/src/types.ts +665 -37
- package/src/utils/processTrigger.ts +28 -58
- package/src/utils/transport/iframe-transport.spec.ts +177 -0
- package/src/utils/transport/iframe-transport.ts +122 -0
- package/src/utils.spec.ts +71 -0
- package/src/utils.ts +38 -0
- package/cjs/src/embed/hostEventClient/contracts.d.ts +0 -231
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +0 -1
- package/cjs/src/embed/hostEventClient/contracts.js.map +0 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts +0 -231
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +0 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts +0 -231
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +0 -1
- package/lib/src/embed/hostEventClient/contracts.js.map +0 -1
- package/src/embed/hostEventClient/contracts.ts +0 -262
|
@@ -2,7 +2,7 @@ import { resetValueFromWindow } from '../utils';
|
|
|
2
2
|
import { ERROR_MESSAGE } from '../errors';
|
|
3
3
|
import { resetCachedAuthToken } from '../authToken';
|
|
4
4
|
import { AuthType, init, EmbedEvent, SearchEmbed, PinboardEmbed, AppEmbed, LiveboardEmbed, AnswerService, SpotterEmbed, } from '../index';
|
|
5
|
-
import { Action, HomeLeftNavItem, RuntimeFilterOp, HomepageModule, HostEvent, ContextMenuTriggerOptions, CustomActionTarget, CustomActionsPosition, ErrorDetailsTypes, EmbedErrorCodes, } from '../types';
|
|
5
|
+
import { Action, HomeLeftNavItem, RuntimeFilterOp, HomepageModule, HostEvent, ContextMenuTriggerOptions, CustomActionTarget, CustomActionsPosition, ErrorDetailsTypes, EmbedErrorCodes, EmbedErrorSeverity, } from '../types';
|
|
6
6
|
import { executeAfterWait, getDocumentBody, getIFrameEl, getIFrameSrc, getRootEl, postMessageToParent, defaultParamsForPinboardEmbed, waitFor, expectUrlMatchesWithParams, expectUrlToHaveParamsWithValues, mockMessageChannel, createRootEleForEmbed, fixedEncodeURI, } from '../test/test-utils';
|
|
7
7
|
import * as config from '../config';
|
|
8
8
|
import * as embedConfig from './embedConfig';
|
|
@@ -16,7 +16,7 @@ import { logger } from '../utils/logger';
|
|
|
16
16
|
import { version } from '../../package.json';
|
|
17
17
|
import { HiddenActionItemByDefaultForSearchEmbed } from './search';
|
|
18
18
|
import { processTrigger } from '../utils/processTrigger';
|
|
19
|
-
import { UIPassthroughEvent } from '
|
|
19
|
+
import { UIPassthroughEvent } from '../contracts/ui-passthrough-contracts';
|
|
20
20
|
import * as sessionInfoService from '../utils/sessionInfoService';
|
|
21
21
|
import * as authToken from '../authToken';
|
|
22
22
|
import * as apiIntercept from '../api-intercept';
|
|
@@ -164,6 +164,9 @@ describe('Unit test case for ts embed', () => {
|
|
|
164
164
|
liveboardEmbed.render();
|
|
165
165
|
mockProcessTrigger.mockResolvedValue({ session: 'test' });
|
|
166
166
|
await executeAfterWait(async () => {
|
|
167
|
+
// `false` is a deliberately off-contract payload here — this
|
|
168
|
+
// asserts raw passthrough to processTrigger, not a real Save
|
|
169
|
+
// payload — so it is cast past the typed `data` parameter.
|
|
167
170
|
await liveboardEmbed.trigger(HostEvent.Save, false);
|
|
168
171
|
expect(mockProcessTrigger).toHaveBeenCalledWith(getIFrameEl(), HostEvent.Save, 'http://tshost', false, undefined);
|
|
169
172
|
});
|
|
@@ -1557,9 +1560,48 @@ describe('Unit test case for ts embed', () => {
|
|
|
1557
1560
|
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1558
1561
|
message: ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
1559
1562
|
code: EmbedErrorCodes.INIT_ERROR,
|
|
1563
|
+
severity: EmbedErrorSeverity.SEV1,
|
|
1560
1564
|
error: ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
1561
1565
|
});
|
|
1562
1566
|
});
|
|
1567
|
+
test('a missing init is reported to the host as SEV1', async () => {
|
|
1568
|
+
const errorHandler = jest.fn();
|
|
1569
|
+
const tsEmbed = new SearchEmbed(getRootEl(), {});
|
|
1570
|
+
tsEmbed.on(EmbedEvent.Error, errorHandler);
|
|
1571
|
+
await tsEmbed.render();
|
|
1572
|
+
expect(errorHandler.mock.calls[0][0]).toEqual(expect.objectContaining({
|
|
1573
|
+
code: EmbedErrorCodes.INIT_ERROR,
|
|
1574
|
+
severity: EmbedErrorSeverity.SEV1,
|
|
1575
|
+
}));
|
|
1576
|
+
});
|
|
1577
|
+
});
|
|
1578
|
+
describe('error severity', () => {
|
|
1579
|
+
beforeEach(() => {
|
|
1580
|
+
jest.spyOn(config, 'getThoughtSpotHost').mockImplementation(() => 'http://tshost');
|
|
1581
|
+
});
|
|
1582
|
+
test('defaults to SEV3 when the raising site does not set one', () => {
|
|
1583
|
+
const errorHandler = jest.fn();
|
|
1584
|
+
const tsEmbed = new SearchEmbed(getRootEl(), {});
|
|
1585
|
+
tsEmbed.on(EmbedEvent.Error, errorHandler);
|
|
1586
|
+
tsEmbed.handleError({
|
|
1587
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1588
|
+
message: 'no severity set',
|
|
1589
|
+
code: EmbedErrorCodes.HOST_EVENT_VALIDATION,
|
|
1590
|
+
});
|
|
1591
|
+
expect(errorHandler.mock.calls[0][0]).toEqual(expect.objectContaining({ severity: EmbedErrorSeverity.SEV3 }));
|
|
1592
|
+
});
|
|
1593
|
+
test('does not override a severity the raising site set', () => {
|
|
1594
|
+
const errorHandler = jest.fn();
|
|
1595
|
+
const tsEmbed = new SearchEmbed(getRootEl(), {});
|
|
1596
|
+
tsEmbed.on(EmbedEvent.Error, errorHandler);
|
|
1597
|
+
tsEmbed.handleError({
|
|
1598
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1599
|
+
message: 'explicitly fatal',
|
|
1600
|
+
code: EmbedErrorCodes.HOST_EVENT_VALIDATION,
|
|
1601
|
+
severity: EmbedErrorSeverity.SEV1,
|
|
1602
|
+
});
|
|
1603
|
+
expect(errorHandler.mock.calls[0][0]).toEqual(expect.objectContaining({ severity: EmbedErrorSeverity.SEV1 }));
|
|
1604
|
+
});
|
|
1563
1605
|
});
|
|
1564
1606
|
describe('V1Embed ', () => {
|
|
1565
1607
|
beforeEach(() => {
|
|
@@ -2897,12 +2939,12 @@ describe('Unit test case for ts embed', () => {
|
|
|
2897
2939
|
expect(preRenderWrapper.style.zIndex).toBe('-5');
|
|
2898
2940
|
libEmbed.destroy();
|
|
2899
2941
|
});
|
|
2900
|
-
it('should use preRenderConfig.
|
|
2942
|
+
it('should use preRenderConfig.id to identify the pre-render instance', async () => {
|
|
2901
2943
|
createRootEleForEmbed();
|
|
2902
2944
|
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2903
2945
|
liveboardId: 'myLiveboardId',
|
|
2904
2946
|
preRenderConfig: {
|
|
2905
|
-
|
|
2947
|
+
id: 'config-level-id',
|
|
2906
2948
|
},
|
|
2907
2949
|
});
|
|
2908
2950
|
await libEmbed.preRender();
|
|
@@ -2912,13 +2954,13 @@ describe('Unit test case for ts embed', () => {
|
|
|
2912
2954
|
expect(document.getElementById(preRenderIds.wrapper)).not.toBeNull();
|
|
2913
2955
|
libEmbed.destroy();
|
|
2914
2956
|
});
|
|
2915
|
-
it('should prefer preRenderConfig.
|
|
2957
|
+
it('should prefer preRenderConfig.id over top-level preRenderId', async () => {
|
|
2916
2958
|
createRootEleForEmbed();
|
|
2917
2959
|
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2918
2960
|
liveboardId: 'myLiveboardId',
|
|
2919
2961
|
preRenderId: 'top-level-id',
|
|
2920
2962
|
preRenderConfig: {
|
|
2921
|
-
|
|
2963
|
+
id: 'config-level-id',
|
|
2922
2964
|
},
|
|
2923
2965
|
});
|
|
2924
2966
|
await libEmbed.preRender();
|
|
@@ -2928,7 +2970,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
2928
2970
|
expect(preRenderIds.wrapper).not.toContain('top-level-id');
|
|
2929
2971
|
libEmbed.destroy();
|
|
2930
2972
|
});
|
|
2931
|
-
it('should mount the wrapper into preRenderConfig.
|
|
2973
|
+
it('should mount the wrapper into preRenderConfig.containerSelector', async () => {
|
|
2932
2974
|
createRootEleForEmbed();
|
|
2933
2975
|
const customContainer = document.createElement('div');
|
|
2934
2976
|
customContainer.id = 'config-level-container';
|
|
@@ -2936,8 +2978,8 @@ describe('Unit test case for ts embed', () => {
|
|
|
2936
2978
|
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2937
2979
|
liveboardId: 'myLiveboardId',
|
|
2938
2980
|
preRenderConfig: {
|
|
2939
|
-
|
|
2940
|
-
|
|
2981
|
+
id: 'container-via-config',
|
|
2982
|
+
containerSelector: '#config-level-container',
|
|
2941
2983
|
},
|
|
2942
2984
|
});
|
|
2943
2985
|
await libEmbed.preRender();
|
|
@@ -2948,7 +2990,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
2948
2990
|
libEmbed.destroy();
|
|
2949
2991
|
customContainer.remove();
|
|
2950
2992
|
});
|
|
2951
|
-
it('should prefer preRenderConfig.
|
|
2993
|
+
it('should prefer preRenderConfig.containerSelector over top-level preRenderContainer', async () => {
|
|
2952
2994
|
createRootEleForEmbed();
|
|
2953
2995
|
const topContainer = document.createElement('div');
|
|
2954
2996
|
topContainer.id = 'top-level-container';
|
|
@@ -2960,8 +3002,8 @@ describe('Unit test case for ts embed', () => {
|
|
|
2960
3002
|
liveboardId: 'myLiveboardId',
|
|
2961
3003
|
preRenderContainer: '#top-level-container',
|
|
2962
3004
|
preRenderConfig: {
|
|
2963
|
-
|
|
2964
|
-
|
|
3005
|
+
id: 'container-precedence',
|
|
3006
|
+
containerSelector: '#config-level-container-2',
|
|
2965
3007
|
},
|
|
2966
3008
|
});
|
|
2967
3009
|
await libEmbed.preRender();
|
|
@@ -2974,7 +3016,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
2974
3016
|
topContainer.remove();
|
|
2975
3017
|
configContainer.remove();
|
|
2976
3018
|
});
|
|
2977
|
-
it('should not attach ResizeObserver when preRenderConfig.
|
|
3019
|
+
it('should not attach ResizeObserver when preRenderConfig.doNotTrackSize is true', async () => {
|
|
2978
3020
|
createRootEleForEmbed();
|
|
2979
3021
|
const observeMock = jest.fn();
|
|
2980
3022
|
window.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
@@ -2985,8 +3027,8 @@ describe('Unit test case for ts embed', () => {
|
|
|
2985
3027
|
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
2986
3028
|
liveboardId: 'myLiveboardId',
|
|
2987
3029
|
preRenderConfig: {
|
|
2988
|
-
|
|
2989
|
-
|
|
3030
|
+
id: 'no-track-via-config',
|
|
3031
|
+
doNotTrackSize: true,
|
|
2990
3032
|
},
|
|
2991
3033
|
});
|
|
2992
3034
|
await libEmbed.preRender();
|
|
@@ -2995,7 +3037,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
2995
3037
|
expect(observeMock).not.toHaveBeenCalled();
|
|
2996
3038
|
libEmbed.destroy();
|
|
2997
3039
|
});
|
|
2998
|
-
it('should prefer preRenderConfig.
|
|
3040
|
+
it('should prefer preRenderConfig.doNotTrackSize over top-level doNotTrackPreRenderSize', async () => {
|
|
2999
3041
|
createRootEleForEmbed();
|
|
3000
3042
|
const observeMock = jest.fn();
|
|
3001
3043
|
window.ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
@@ -3007,8 +3049,8 @@ describe('Unit test case for ts embed', () => {
|
|
|
3007
3049
|
liveboardId: 'myLiveboardId',
|
|
3008
3050
|
doNotTrackPreRenderSize: false,
|
|
3009
3051
|
preRenderConfig: {
|
|
3010
|
-
|
|
3011
|
-
|
|
3052
|
+
id: 'no-track-precedence',
|
|
3053
|
+
doNotTrackSize: true,
|
|
3012
3054
|
},
|
|
3013
3055
|
});
|
|
3014
3056
|
await libEmbed.preRender();
|
|
@@ -3526,7 +3568,9 @@ describe('Unit test case for ts embed', () => {
|
|
|
3526
3568
|
});
|
|
3527
3569
|
test('should return getPreRenderObj and log if same object', () => {
|
|
3528
3570
|
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3529
|
-
|
|
3571
|
+
// debug, not info: the wrapper points at the embed being shown, so
|
|
3572
|
+
// this is now the common case rather than a rare diagnostic.
|
|
3573
|
+
const loggerSpy = jest.spyOn(logger, 'debug');
|
|
3530
3574
|
// getPreRenderObj reads the embed reference from preRenderWrapper
|
|
3531
3575
|
searchEmbed.preRenderWrapper = {
|
|
3532
3576
|
[searchEmbed['embedNodeKey']]: searchEmbed,
|
|
@@ -4228,16 +4272,6 @@ describe('Additional Coverage Tests', () => {
|
|
|
4228
4272
|
expect(getIFrameEl().style.height).toBe('500px');
|
|
4229
4273
|
});
|
|
4230
4274
|
});
|
|
4231
|
-
test('should test getIframeCenter calculation', async () => {
|
|
4232
|
-
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
4233
|
-
await searchEmbed.render();
|
|
4234
|
-
await executeAfterWait(() => {
|
|
4235
|
-
const center = searchEmbed['getIframeCenter']();
|
|
4236
|
-
expect(center).toHaveProperty('iframeCenter');
|
|
4237
|
-
expect(center).toHaveProperty('iframeHeight');
|
|
4238
|
-
expect(center).toHaveProperty('viewPortHeight');
|
|
4239
|
-
});
|
|
4240
|
-
});
|
|
4241
4275
|
test('should handle preRender with replaceExistingPreRender=true', async () => {
|
|
4242
4276
|
createRootEleForEmbed();
|
|
4243
4277
|
const embed1 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
@@ -4537,7 +4571,8 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
|
|
|
4537
4571
|
});
|
|
4538
4572
|
embed2.showPreRender();
|
|
4539
4573
|
await executeAfterWait(() => {
|
|
4540
|
-
|
|
4574
|
+
// Not LastCalledWith: LiveboardEmbed fires Navigate after this.
|
|
4575
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({
|
|
4541
4576
|
liveboardId: 'original-lb',
|
|
4542
4577
|
visibleVizs: ['viz-1'],
|
|
4543
4578
|
runtimeFilters: [
|
|
@@ -4580,7 +4615,8 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
|
|
|
4580
4615
|
});
|
|
4581
4616
|
embed2.showPreRender();
|
|
4582
4617
|
await executeAfterWait(() => {
|
|
4583
|
-
|
|
4618
|
+
// Not LastCalledWith: LiveboardEmbed fires Navigate after this.
|
|
4619
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({
|
|
4584
4620
|
liveboardId: 'original-lb',
|
|
4585
4621
|
visibleVizs: ['viz-1', 'viz-2'],
|
|
4586
4622
|
runtimeFilters: [
|
|
@@ -4593,6 +4629,317 @@ describe('ShowPreRender with UpdateEmbedParams', () => {
|
|
|
4593
4629
|
}), undefined);
|
|
4594
4630
|
});
|
|
4595
4631
|
});
|
|
4632
|
+
test('should carry the new config filters in UpdateEmbedParams', async () => {
|
|
4633
|
+
await setupPreRenderTest('params-new-filters', { liveboardId: 'original-lb' });
|
|
4634
|
+
const runtimeFilters = [
|
|
4635
|
+
{
|
|
4636
|
+
columnName: 'Color',
|
|
4637
|
+
operator: RuntimeFilterOp.IN,
|
|
4638
|
+
values: ['red', 'blue'],
|
|
4639
|
+
},
|
|
4640
|
+
];
|
|
4641
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4642
|
+
preRenderId: 'params-new-filters',
|
|
4643
|
+
liveboardId: 'original-lb',
|
|
4644
|
+
runtimeFilters,
|
|
4645
|
+
});
|
|
4646
|
+
embed2.showPreRender();
|
|
4647
|
+
await executeAfterWait(() => {
|
|
4648
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({
|
|
4649
|
+
runtimeFilters,
|
|
4650
|
+
// The serialized form is the one the container reads.
|
|
4651
|
+
runtimeFilterParams: 'col1=Color&op1=IN&val1=red&val1=blue',
|
|
4652
|
+
}), undefined);
|
|
4653
|
+
// Everything rides in the params payload; nothing follows it.
|
|
4654
|
+
const runtimeFilterCalls = mockProcessTrigger.mock.calls.filter((call) => call[1] === HostEvent.UpdateRuntimeFilters);
|
|
4655
|
+
expect(runtimeFilterCalls).toHaveLength(0);
|
|
4656
|
+
});
|
|
4657
|
+
});
|
|
4658
|
+
test('should serialize the filters when they are not excluded from the URL', async () => {
|
|
4659
|
+
await setupPreRenderTest('params-url-filters', { liveboardId: 'original-lb' });
|
|
4660
|
+
// With the flag off, getDefaultAppInitData leaves runtimeFilterParams
|
|
4661
|
+
// null and a URL render carries the filters in the iframe's query
|
|
4662
|
+
// string. A show cycle has no URL, so the payload has to carry them.
|
|
4663
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4664
|
+
preRenderId: 'params-url-filters',
|
|
4665
|
+
liveboardId: 'original-lb',
|
|
4666
|
+
excludeRuntimeFiltersfromURL: false,
|
|
4667
|
+
runtimeFilters: [
|
|
4668
|
+
{
|
|
4669
|
+
columnName: 'Color',
|
|
4670
|
+
operator: RuntimeFilterOp.IN,
|
|
4671
|
+
values: ['red'],
|
|
4672
|
+
},
|
|
4673
|
+
],
|
|
4674
|
+
});
|
|
4675
|
+
embed2.showPreRender();
|
|
4676
|
+
await executeAfterWait(() => {
|
|
4677
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({
|
|
4678
|
+
runtimeFilterParams: 'col1=Color&op1=IN&val1=red',
|
|
4679
|
+
}), undefined);
|
|
4680
|
+
});
|
|
4681
|
+
});
|
|
4682
|
+
test('should trigger Navigate only after UpdateEmbedParams has settled', async () => {
|
|
4683
|
+
await setupPreRenderTest('navigate-after-params', {
|
|
4684
|
+
liveboardId: 'original-lb',
|
|
4685
|
+
runtimeFilters: [
|
|
4686
|
+
{
|
|
4687
|
+
columnName: 'Color',
|
|
4688
|
+
operator: RuntimeFilterOp.IN,
|
|
4689
|
+
values: ['red'],
|
|
4690
|
+
},
|
|
4691
|
+
],
|
|
4692
|
+
});
|
|
4693
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4694
|
+
preRenderId: 'navigate-after-params',
|
|
4695
|
+
liveboardId: 'updated-lb',
|
|
4696
|
+
});
|
|
4697
|
+
embed2.showPreRender();
|
|
4698
|
+
// Inside the settle window the params are already out
|
|
4699
|
+
// and Navigate is not.
|
|
4700
|
+
await executeAfterWait(() => {
|
|
4701
|
+
const eventTypes = mockProcessTrigger.mock.calls.map((call) => call[1]);
|
|
4702
|
+
expect(eventTypes).toContain(HostEvent.UpdateEmbedParams);
|
|
4703
|
+
expect(eventTypes).not.toContain(HostEvent.Navigate);
|
|
4704
|
+
}, 50);
|
|
4705
|
+
await executeAfterWait(() => {
|
|
4706
|
+
const eventTypes = mockProcessTrigger.mock.calls.map((call) => call[1]);
|
|
4707
|
+
// A Navigate that beat the params would make the container load
|
|
4708
|
+
// `updated-lb` while still holding `original-lb`'s runtime filters,
|
|
4709
|
+
// and drop the params that then arrive mid-load (SCAL-336321).
|
|
4710
|
+
expect(eventTypes).toContain(HostEvent.Navigate);
|
|
4711
|
+
expect(eventTypes.indexOf(HostEvent.UpdateEmbedParams)).toBeLessThan(eventTypes.indexOf(HostEvent.Navigate));
|
|
4712
|
+
}, 300);
|
|
4713
|
+
});
|
|
4714
|
+
test('should mark the params empty when the config declares no filters', async () => {
|
|
4715
|
+
await setupPreRenderTest('params-clear-filters', {
|
|
4716
|
+
liveboardId: 'original-lb',
|
|
4717
|
+
runtimeFilters: [
|
|
4718
|
+
{
|
|
4719
|
+
columnName: 'Color',
|
|
4720
|
+
operator: RuntimeFilterOp.IN,
|
|
4721
|
+
values: ['red', 'blue'],
|
|
4722
|
+
},
|
|
4723
|
+
],
|
|
4724
|
+
});
|
|
4725
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4726
|
+
preRenderId: 'params-clear-filters',
|
|
4727
|
+
liveboardId: 'original-lb',
|
|
4728
|
+
});
|
|
4729
|
+
embed2.showPreRender();
|
|
4730
|
+
await executeAfterWait(() => {
|
|
4731
|
+
// Not null and not '': the container only reads this field when it
|
|
4732
|
+
// is truthy, so either would leave the previous embed's filters in
|
|
4733
|
+
// place. A lone separator passes that gate and parses to {}.
|
|
4734
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({ runtimeFilterParams: '&' }), undefined);
|
|
4735
|
+
const runtimeFilterCalls = mockProcessTrigger.mock.calls.filter((call) => call[1] === HostEvent.UpdateRuntimeFilters);
|
|
4736
|
+
expect(runtimeFilterCalls).toHaveLength(0);
|
|
4737
|
+
});
|
|
4738
|
+
});
|
|
4739
|
+
test('should mark the params empty for an explicitly empty filter array', async () => {
|
|
4740
|
+
await setupPreRenderTest('params-empty-array', {
|
|
4741
|
+
liveboardId: 'original-lb',
|
|
4742
|
+
runtimeFilters: [
|
|
4743
|
+
{
|
|
4744
|
+
columnName: 'Color',
|
|
4745
|
+
operator: RuntimeFilterOp.IN,
|
|
4746
|
+
values: ['red'],
|
|
4747
|
+
},
|
|
4748
|
+
],
|
|
4749
|
+
});
|
|
4750
|
+
// `runtimeFilters: []` is the shape the customer reported as not
|
|
4751
|
+
// resetting anything.
|
|
4752
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4753
|
+
preRenderId: 'params-empty-array',
|
|
4754
|
+
liveboardId: 'original-lb',
|
|
4755
|
+
runtimeFilters: [],
|
|
4756
|
+
});
|
|
4757
|
+
embed2.showPreRender();
|
|
4758
|
+
await executeAfterWait(() => {
|
|
4759
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({ runtimeFilterParams: '&' }), undefined);
|
|
4760
|
+
});
|
|
4761
|
+
});
|
|
4762
|
+
test('should mark the params empty when no config in the chain has filters', async () => {
|
|
4763
|
+
await setupPreRenderTest('params-no-filters', { liveboardId: 'original-lb' });
|
|
4764
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4765
|
+
preRenderId: 'params-no-filters',
|
|
4766
|
+
liveboardId: 'updated-lb',
|
|
4767
|
+
});
|
|
4768
|
+
embed2.showPreRender();
|
|
4769
|
+
await executeAfterWait(() => {
|
|
4770
|
+
const paramsCall = mockProcessTrigger.mock.calls.find((call) => call[1] === HostEvent.UpdateEmbedParams);
|
|
4771
|
+
expect(paramsCall === null || paramsCall === void 0 ? void 0 : paramsCall[3]).not.toHaveProperty('runtimeFilters');
|
|
4772
|
+
expect(paramsCall === null || paramsCall === void 0 ? void 0 : paramsCall[3].runtimeFilterParams).toBe('&');
|
|
4773
|
+
});
|
|
4774
|
+
});
|
|
4775
|
+
test('should state each embed filters as the pre-render is handed along', async () => {
|
|
4776
|
+
await setupPreRenderTest('params-chain', {
|
|
4777
|
+
liveboardId: 'original-lb',
|
|
4778
|
+
runtimeFilters: [
|
|
4779
|
+
{
|
|
4780
|
+
columnName: 'Color',
|
|
4781
|
+
operator: RuntimeFilterOp.IN,
|
|
4782
|
+
values: ['red', 'blue'],
|
|
4783
|
+
},
|
|
4784
|
+
],
|
|
4785
|
+
});
|
|
4786
|
+
// Second in the chain declares none, so it empties the field rather
|
|
4787
|
+
// than letting the creator's filters stand.
|
|
4788
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4789
|
+
preRenderId: 'params-chain',
|
|
4790
|
+
liveboardId: 'second-lb',
|
|
4791
|
+
});
|
|
4792
|
+
await embed2.showPreRender();
|
|
4793
|
+
await executeAfterWait(() => {
|
|
4794
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({ runtimeFilterParams: '&' }), undefined);
|
|
4795
|
+
});
|
|
4796
|
+
mockProcessTrigger.mockClear();
|
|
4797
|
+
// Third declares its own, and states them without reference to either
|
|
4798
|
+
// embed before it.
|
|
4799
|
+
const embed3 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4800
|
+
preRenderId: 'params-chain',
|
|
4801
|
+
liveboardId: 'third-lb',
|
|
4802
|
+
runtimeFilters: [
|
|
4803
|
+
{
|
|
4804
|
+
columnName: 'Region',
|
|
4805
|
+
operator: RuntimeFilterOp.EQ,
|
|
4806
|
+
values: ['North'],
|
|
4807
|
+
},
|
|
4808
|
+
],
|
|
4809
|
+
});
|
|
4810
|
+
await embed3.showPreRender();
|
|
4811
|
+
await executeAfterWait(() => {
|
|
4812
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({
|
|
4813
|
+
runtimeFilterParams: 'col1=Region&op1=EQ&val1=North',
|
|
4814
|
+
}), undefined);
|
|
4815
|
+
});
|
|
4816
|
+
});
|
|
4817
|
+
test('should carry the new config runtime parameters in UpdateEmbedParams', async () => {
|
|
4818
|
+
await setupPreRenderTest('params-parameters', {
|
|
4819
|
+
liveboardId: 'original-lb',
|
|
4820
|
+
runtimeParameters: [{ name: 'Region Param', value: 'East' }],
|
|
4821
|
+
});
|
|
4822
|
+
const runtimeParameters = [{ name: 'Region Param', value: 'West' }];
|
|
4823
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4824
|
+
preRenderId: 'params-parameters',
|
|
4825
|
+
liveboardId: 'original-lb',
|
|
4826
|
+
runtimeParameters,
|
|
4827
|
+
});
|
|
4828
|
+
embed2.showPreRender();
|
|
4829
|
+
await executeAfterWait(() => {
|
|
4830
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({
|
|
4831
|
+
runtimeParameters,
|
|
4832
|
+
runtimeParameterParams: 'param1=Region%20Param¶mVal1=West',
|
|
4833
|
+
}), undefined);
|
|
4834
|
+
// A parameter always carries a value, so the payload says everything
|
|
4835
|
+
// there is to say — no follow-up event.
|
|
4836
|
+
const parameterCalls = mockProcessTrigger.mock.calls.filter((call) => call[1] === HostEvent.UpdateParameters);
|
|
4837
|
+
expect(parameterCalls).toHaveLength(0);
|
|
4838
|
+
});
|
|
4839
|
+
});
|
|
4840
|
+
test('should mark the params empty when the config declares no parameters', async () => {
|
|
4841
|
+
await setupPreRenderTest('params-clear-parameters', {
|
|
4842
|
+
liveboardId: 'original-lb',
|
|
4843
|
+
runtimeParameters: [{ name: 'Region Param', value: 'East' }],
|
|
4844
|
+
});
|
|
4845
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4846
|
+
preRenderId: 'params-clear-parameters',
|
|
4847
|
+
liveboardId: 'original-lb',
|
|
4848
|
+
});
|
|
4849
|
+
embed2.showPreRender();
|
|
4850
|
+
await executeAfterWait(() => {
|
|
4851
|
+
// Same gate as the filters: the container only reads this field
|
|
4852
|
+
// when it is truthy, so null would leave 'East' standing.
|
|
4853
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({ runtimeParameterParams: '&' }), undefined);
|
|
4854
|
+
});
|
|
4855
|
+
});
|
|
4856
|
+
test('should keep an empty string parameter value distinct from having none', async () => {
|
|
4857
|
+
await setupPreRenderTest('params-empty-value', { liveboardId: 'original-lb' });
|
|
4858
|
+
// `paramVal1=` is that parameter's value, not an absence — so it must
|
|
4859
|
+
// not collapse to the empty marker.
|
|
4860
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4861
|
+
preRenderId: 'params-empty-value',
|
|
4862
|
+
liveboardId: 'original-lb',
|
|
4863
|
+
runtimeParameters: [{ name: 'Region Param', value: '' }],
|
|
4864
|
+
});
|
|
4865
|
+
embed2.showPreRender();
|
|
4866
|
+
await executeAfterWait(() => {
|
|
4867
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(expect.any(Object), HostEvent.UpdateEmbedParams, expect.any(String), expect.objectContaining({
|
|
4868
|
+
runtimeParameterParams: 'param1=Region%20Param¶mVal1=',
|
|
4869
|
+
}), undefined);
|
|
4870
|
+
});
|
|
4871
|
+
});
|
|
4872
|
+
test('should hand the pre-render over to the embed being shown', async () => {
|
|
4873
|
+
const embed1 = await setupPreRenderTest('take-over-state', { liveboardId: 'original-lb' });
|
|
4874
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4875
|
+
preRenderId: 'take-over-state',
|
|
4876
|
+
liveboardId: 'second-lb',
|
|
4877
|
+
});
|
|
4878
|
+
await embed2.showPreRender();
|
|
4879
|
+
// It connected to embed1's pre-render and is now what the wrapper
|
|
4880
|
+
// points at, so getPreRenderObj() means "what is showing".
|
|
4881
|
+
expect(embed2.getPreRenderObj()).toBe(embed2);
|
|
4882
|
+
expect(embed1.getPreRenderObj()).toBe(embed2);
|
|
4883
|
+
});
|
|
4884
|
+
test('should not strand callbacks when the container loads after the shown embed was hidden', async () => {
|
|
4885
|
+
// The creator is subscribed but the container has NOT announced itself
|
|
4886
|
+
// yet, which is the state a real pre-render starts in.
|
|
4887
|
+
const embed1 = await setupPreRenderTest('loaded-after-hide', { liveboardId: 'original-lb' });
|
|
4888
|
+
embed1.isEmbedContainerLoaded = false;
|
|
4889
|
+
// Second embed shows, takes the pre-render over, then is hidden — which
|
|
4890
|
+
// unsubscribes it, so it will never hear EmbedListenerReady itself.
|
|
4891
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4892
|
+
preRenderId: 'loaded-after-hide',
|
|
4893
|
+
liveboardId: 'second-lb',
|
|
4894
|
+
});
|
|
4895
|
+
await embed2.showPreRender();
|
|
4896
|
+
embed2.hidePreRender();
|
|
4897
|
+
expect(embed2.isEmbedContainerLoaded).toBe(false);
|
|
4898
|
+
// Container comes up and the creator hears it.
|
|
4899
|
+
embed1.createEmbedContainerHandler(EmbedEvent.EmbedListenerReady)();
|
|
4900
|
+
mockProcessTrigger.mockClear();
|
|
4901
|
+
mockProcessTrigger.mockResolvedValue({});
|
|
4902
|
+
// A third embed reads the state off embed2, which owns the wrapper and
|
|
4903
|
+
// never learned the container was up. Reading a per-instance snapshot
|
|
4904
|
+
// here leaves UpdateEmbedParams queued forever and the pre-render stuck
|
|
4905
|
+
// on the previous liveboard.
|
|
4906
|
+
const embed3 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4907
|
+
preRenderId: 'loaded-after-hide',
|
|
4908
|
+
liveboardId: 'third-lb',
|
|
4909
|
+
});
|
|
4910
|
+
await embed3.showPreRender();
|
|
4911
|
+
expect(embed3.isEmbedContainerLoaded).toBe(true);
|
|
4912
|
+
await executeAfterWait(() => {
|
|
4913
|
+
const eventTypes = mockProcessTrigger.mock.calls.map((call) => call[1]);
|
|
4914
|
+
expect(eventTypes).toContain(HostEvent.UpdateEmbedParams);
|
|
4915
|
+
}, 300);
|
|
4916
|
+
});
|
|
4917
|
+
test('should not reconcile runtime filters unless the view config opts in', async () => {
|
|
4918
|
+
await setupPreRenderTest('reconcile-flag-off', {
|
|
4919
|
+
liveboardId: 'original-lb',
|
|
4920
|
+
runtimeFilters: [
|
|
4921
|
+
{
|
|
4922
|
+
columnName: 'Color',
|
|
4923
|
+
operator: RuntimeFilterOp.IN,
|
|
4924
|
+
values: ['red', 'blue'],
|
|
4925
|
+
},
|
|
4926
|
+
],
|
|
4927
|
+
});
|
|
4928
|
+
// Same shape as the clear-filters case above, minus the flag: the
|
|
4929
|
+
// previous config left filters on the shared pre-render and this one
|
|
4930
|
+
// declares none. Without preRenderConfig.reconcileRuntimeParams the SDK
|
|
4931
|
+
// leaves that to the container, so no UpdateRuntimeFilters goes out.
|
|
4932
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
4933
|
+
preRenderId: 'reconcile-flag-off',
|
|
4934
|
+
liveboardId: 'original-lb',
|
|
4935
|
+
});
|
|
4936
|
+
embed2.showPreRender();
|
|
4937
|
+
await executeAfterWait(() => {
|
|
4938
|
+
const eventTypes = mockProcessTrigger.mock.calls.map((call) => call[1]);
|
|
4939
|
+
expect(eventTypes).toContain(HostEvent.UpdateEmbedParams);
|
|
4940
|
+
expect(eventTypes).not.toContain(HostEvent.UpdateRuntimeFilters);
|
|
4941
|
+
});
|
|
4942
|
+
});
|
|
4596
4943
|
test('should handle error when getUpdateEmbedParamsObject fails during showPreRender', async () => {
|
|
4597
4944
|
await setupPreRenderTest('error-test', { liveboardId: 'original-lb' });
|
|
4598
4945
|
const handleErrorSpy = jest.spyOn(LiveboardEmbed.prototype, 'handleError');
|