@thoughtspot/visual-embed-sdk 1.39.2 → 1.39.3
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 +1 -1
- package/cjs/src/config.spec.js +9 -0
- package/cjs/src/config.spec.js.map +1 -1
- package/cjs/src/embed/app.d.ts +19 -15
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +23 -2
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +56 -8
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.d.ts +23 -7
- package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +31 -5
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.spec.js +8 -190
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +28 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/embedConfig.d.ts +9 -7
- package/cjs/src/embed/embedConfig.d.ts.map +1 -1
- package/cjs/src/embed/embedConfig.js +9 -7
- package/cjs/src/embed/embedConfig.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +0 -17
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +2 -4
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +12 -11
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +1 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +1 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/index.d.ts +2 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +2 -1
- 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 +3 -2
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/index.d.ts +73 -20
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +79 -42
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +438 -100
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +262 -6
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +228 -2
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/global-styles.js +1 -1
- package/cjs/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/cjs/src/utils/graphql/nlsService/conversation-service.js +7 -1
- package/cjs/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
- package/cjs/src/utils.spec.js +25 -0
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-CmEQfuE3.js → index-ZrE8YYq8.js} +1 -1
- package/dist/src/embed/app.d.ts +19 -15
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/bodyless-conversation.d.ts +23 -7
- package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/dist/src/embed/embedConfig.d.ts +9 -7
- package/dist/src/embed/embedConfig.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +0 -17
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- 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 +73 -20
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +262 -6
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +385 -71
- package/dist/tsembed-react.js +385 -69
- package/dist/tsembed.es.js +303 -24
- package/dist/tsembed.js +301 -22
- package/dist/visual-embed-sdk-react-full.d.ts +386 -72
- package/dist/visual-embed-sdk-react.d.ts +386 -72
- package/dist/visual-embed-sdk.d.ts +314 -53
- package/lib/package.json +1 -1
- package/lib/src/config.spec.js +9 -0
- package/lib/src/config.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +19 -15
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +22 -1
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +58 -10
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.d.ts +23 -7
- package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +30 -5
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.spec.js +9 -191
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +30 -2
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/embedConfig.d.ts +9 -7
- package/lib/src/embed/embedConfig.d.ts.map +1 -1
- package/lib/src/embed/embedConfig.js +9 -7
- package/lib/src/embed/embedConfig.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +0 -17
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +2 -4
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +12 -11
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/errors.d.ts +1 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +1 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts +2 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -2
- 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/index.d.ts +73 -20
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +79 -43
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +441 -103
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +262 -6
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +228 -2
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/global-styles.js +1 -1
- package/lib/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/lib/src/utils/graphql/nlsService/conversation-service.js +7 -1
- package/lib/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
- package/lib/src/utils.spec.js +26 -1
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +315 -54
- package/package.json +1 -1
- package/src/config.spec.ts +11 -0
- package/src/embed/app.spec.ts +90 -23
- package/src/embed/app.ts +27 -15
- package/src/embed/bodyless-conversation.spec.ts +9 -203
- package/src/embed/bodyless-conversation.ts +34 -10
- package/src/embed/conversation.spec.ts +40 -2
- package/src/embed/embedConfig.ts +10 -8
- package/src/embed/liveboard.spec.ts +5 -4
- package/src/embed/liveboard.ts +2 -22
- package/src/errors.ts +1 -0
- package/src/index.ts +2 -0
- package/src/react/all-types-export.ts +2 -1
- package/src/react/index.spec.tsx +558 -157
- package/src/react/index.tsx +117 -51
- package/src/types.ts +301 -44
- package/src/utils/global-styles.ts +1 -1
- package/src/utils/graphql/nlsService/conversation-service.ts +7 -1
- package/src/utils.spec.ts +29 -0
|
@@ -129,120 +129,458 @@ describe('React Components', () => {
|
|
|
129
129
|
expect((0, test_utils_1.getIFrameSrc)(container)).toBe(`http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${package_json_1.version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${types_1.Action.ReportError}%22]&preAuthCache=true&overrideConsoleLogs=true&clientLogLevel=ERROR&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`);
|
|
130
130
|
});
|
|
131
131
|
});
|
|
132
|
-
describe('
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
132
|
+
describe('SpotterMessage', () => {
|
|
133
|
+
const mockMessage = {
|
|
134
|
+
sessionId: "session123",
|
|
135
|
+
genNo: 1,
|
|
136
|
+
acSessionId: "acSession123",
|
|
137
|
+
acGenNo: 2,
|
|
138
|
+
worksheetId: "worksheet123",
|
|
139
|
+
convId: "conv123",
|
|
140
|
+
messageId: "message123"
|
|
141
|
+
};
|
|
142
|
+
it('Should render the SpotterMessage component with required props', async () => {
|
|
143
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.SpotterMessage, { message: mockMessage }));
|
|
144
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
145
|
+
expect((0, test_utils_1.getIFrameEl)(container)).not.toBe(null);
|
|
146
|
+
expect((0, test_utils_1.getIFrameSrc)(container)).toContain('sessionId=session123');
|
|
147
|
+
expect((0, test_utils_1.getIFrameSrc)(container)).toContain('genNo=1');
|
|
148
|
+
expect((0, test_utils_1.getIFrameSrc)(container)).toContain('acSessionId=acSession123');
|
|
149
|
+
expect((0, test_utils_1.getIFrameSrc)(container)).toContain('acGenNo=2');
|
|
150
150
|
});
|
|
151
|
-
it('Should
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
it('Should render the SpotterMessage component with optional query', async () => {
|
|
152
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.SpotterMessage, { message: mockMessage, query: "show me sales" }));
|
|
153
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
154
|
+
expect((0, test_utils_1.getIFrameEl)(container)).not.toBe(null);
|
|
155
|
+
expect((0, test_utils_1.getIFrameSrc)(container)).toContain('sessionId=session123');
|
|
156
|
+
});
|
|
157
|
+
it('Should have the correct container element with className', async () => {
|
|
158
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.SpotterMessage, { message: mockMessage, className: "custom-class" }));
|
|
159
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
160
|
+
expect((0, test_utils_1.getIFrameEl)(container).parentElement.classList.contains('custom-class')).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
// Note: insertAsSibling is not supported for SpotterMessage as it's not part of the allowed props
|
|
163
|
+
});
|
|
164
|
+
describe('Component Factory Coverage', () => {
|
|
165
|
+
it('Should test basic component creation', () => {
|
|
166
|
+
expect(() => {
|
|
167
|
+
(0, react_2.render)(react_1.default.createElement(index_1.LiveboardEmbed, { liveboardId: "test" }));
|
|
168
|
+
}).not.toThrow();
|
|
169
|
+
expect(() => {
|
|
170
|
+
(0, react_2.render)(react_1.default.createElement(index_1.SearchEmbed, { dataSource: "test" }));
|
|
171
|
+
}).not.toThrow();
|
|
172
|
+
expect(() => {
|
|
173
|
+
(0, react_2.render)(react_1.default.createElement(index_1.AppEmbed, { showPrimaryNavbar: false }));
|
|
174
|
+
}).not.toThrow();
|
|
175
|
+
});
|
|
176
|
+
it('Should test component factory existence', () => {
|
|
177
|
+
expect(index_1.PreRenderedLiveboardEmbed).toBeDefined();
|
|
178
|
+
expect(index_1.PreRenderedSearchEmbed).toBeDefined();
|
|
179
|
+
expect(index_1.PreRenderedAppEmbed).toBeDefined();
|
|
180
|
+
expect(typeof index_1.PreRenderedLiveboardEmbed).toBe('object');
|
|
181
|
+
expect(typeof index_1.PreRenderedSearchEmbed).toBe('object');
|
|
182
|
+
expect(typeof index_1.PreRenderedAppEmbed).toBe('object');
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
describe('Components with insertAsSibling', () => {
|
|
186
|
+
it('Should render LiveboardEmbed with insertAsSibling', async () => {
|
|
187
|
+
var _a;
|
|
188
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.LiveboardEmbed, { liveboardId: "test-liveboard", insertAsSibling: true }));
|
|
189
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
190
|
+
expect(container.querySelector('span')).not.toBe(null);
|
|
191
|
+
expect((_a = container.querySelector('span')) === null || _a === void 0 ? void 0 : _a.style.position).toBe('absolute');
|
|
192
|
+
});
|
|
193
|
+
it('Should render SearchEmbed with insertAsSibling', async () => {
|
|
194
|
+
var _a;
|
|
195
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.SearchEmbed, { dataSource: "test-datasource", insertAsSibling: true }));
|
|
196
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
197
|
+
expect(container.querySelector('span')).not.toBe(null);
|
|
198
|
+
expect((_a = container.querySelector('span')) === null || _a === void 0 ? void 0 : _a.style.position).toBe('absolute');
|
|
199
|
+
});
|
|
200
|
+
it('Should render AppEmbed with insertAsSibling', async () => {
|
|
201
|
+
var _a;
|
|
202
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.AppEmbed, { showPrimaryNavbar: false, insertAsSibling: true }));
|
|
203
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
204
|
+
expect(container.querySelector('span')).not.toBe(null);
|
|
205
|
+
expect((_a = container.querySelector('span')) === null || _a === void 0 ? void 0 : _a.style.position).toBe('absolute');
|
|
206
|
+
});
|
|
207
|
+
it('Should render SearchBarEmbed with insertAsSibling', async () => {
|
|
208
|
+
var _a;
|
|
209
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.SearchBarEmbed, { dataSource: "test-datasource", insertAsSibling: true }));
|
|
210
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
211
|
+
expect(container.querySelector('span')).not.toBe(null);
|
|
212
|
+
expect((_a = container.querySelector('span')) === null || _a === void 0 ? void 0 : _a.style.position).toBe('absolute');
|
|
213
|
+
});
|
|
214
|
+
it('Should render components with both insertAsSibling and className', async () => {
|
|
215
|
+
const { container } = (0, react_2.render)(react_1.default.createElement(index_1.LiveboardEmbed, { liveboardId: "test-liveboard", insertAsSibling: true, className: "custom-class" }));
|
|
216
|
+
await (0, react_2.waitFor)(() => (0, test_utils_1.getIFrameEl)(container));
|
|
217
|
+
expect(container.querySelector('span')).not.toBe(null);
|
|
218
|
+
expect((0, test_utils_1.getIFrameEl)(container).classList.contains('custom-class')).toBe(true);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe('useSpotterAgent', () => {
|
|
222
|
+
it('Should return an object with sendMessage function', () => {
|
|
156
223
|
const TestComponent = () => {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
conversationRef.current.sendMessage("Test message");
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
165
|
-
react_1.default.createElement(index_1.SpotterAgentEmbed, { ref: conversationRef, worksheetId: "test-worksheet-id" }),
|
|
166
|
-
react_1.default.createElement("button", { "data-testid": "test-button", onClick: handleClick }, "Send Message")));
|
|
224
|
+
const spotterAgent = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
225
|
+
expect(typeof spotterAgent).toBe('object');
|
|
226
|
+
expect(typeof spotterAgent.sendMessage).toBe('function');
|
|
227
|
+
return react_1.default.createElement("div", null, "Test");
|
|
167
228
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
229
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
230
|
+
});
|
|
231
|
+
it('Should have proper sendMessage callback structure', () => {
|
|
232
|
+
const TestComponent = () => {
|
|
233
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
234
|
+
// Test that sendMessage is a function that accepts a string
|
|
235
|
+
expect(typeof sendMessage).toBe('function');
|
|
236
|
+
expect(sendMessage.length).toBe(1); // Should accept one parameter
|
|
237
|
+
return react_1.default.createElement("div", null, "Test");
|
|
238
|
+
};
|
|
239
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
240
|
+
});
|
|
241
|
+
it('Should return error when service is not initialized', async () => {
|
|
242
|
+
let sendMessageResult;
|
|
243
|
+
const TestComponent = () => {
|
|
244
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
245
|
+
// Call sendMessage immediately before service has time to initialize
|
|
246
|
+
sendMessageResult = sendMessage('test query');
|
|
247
|
+
return react_1.default.createElement("div", null, "Test");
|
|
248
|
+
};
|
|
249
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
250
|
+
const result = await sendMessageResult;
|
|
251
|
+
expect(result).toEqual({
|
|
252
|
+
error: expect.any(Error)
|
|
176
253
|
});
|
|
254
|
+
expect(result.error.message).toBe('SpotterAgent not initialized');
|
|
255
|
+
});
|
|
256
|
+
it('Should call sendMessage and handle async behavior', async () => {
|
|
257
|
+
let sendMessageFunction;
|
|
177
258
|
const TestComponent = () => {
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
259
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
260
|
+
sendMessageFunction = sendMessage;
|
|
261
|
+
return react_1.default.createElement("div", null, "Test");
|
|
262
|
+
};
|
|
263
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
264
|
+
// Test that sendMessage is a function
|
|
265
|
+
expect(typeof sendMessageFunction).toBe('function');
|
|
266
|
+
// Call sendMessage - should not throw
|
|
267
|
+
expect(() => {
|
|
268
|
+
sendMessageFunction('test query');
|
|
269
|
+
}).not.toThrow();
|
|
270
|
+
});
|
|
271
|
+
it('Should handle multiple calls to sendMessage', async () => {
|
|
272
|
+
let sendMessageFunction;
|
|
273
|
+
const TestComponent = () => {
|
|
274
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
275
|
+
sendMessageFunction = sendMessage;
|
|
276
|
+
return react_1.default.createElement("div", null, "Test");
|
|
277
|
+
};
|
|
278
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
279
|
+
// Multiple calls should not throw
|
|
280
|
+
expect(() => {
|
|
281
|
+
sendMessageFunction('query 1');
|
|
282
|
+
sendMessageFunction('query 2');
|
|
283
|
+
sendMessageFunction('query 3');
|
|
284
|
+
}).not.toThrow();
|
|
285
|
+
});
|
|
286
|
+
it('Should handle config object changes', () => {
|
|
287
|
+
const TestComponent = ({ config }) => {
|
|
288
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)(config);
|
|
289
|
+
expect(sendMessage).toBeDefined();
|
|
290
|
+
return react_1.default.createElement("div", null, "Test");
|
|
291
|
+
};
|
|
292
|
+
const config1 = { worksheetId: 'test1' };
|
|
293
|
+
const config2 = { worksheetId: 'test2' };
|
|
294
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { config: config1 }));
|
|
295
|
+
// Should not throw when config changes
|
|
296
|
+
expect(() => {
|
|
297
|
+
rerender(react_1.default.createElement(TestComponent, { config: config2 }));
|
|
298
|
+
}).not.toThrow();
|
|
299
|
+
});
|
|
300
|
+
it('Should handle unmounting without errors', () => {
|
|
301
|
+
const TestComponent = () => {
|
|
302
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
303
|
+
expect(sendMessage).toBeDefined();
|
|
304
|
+
return react_1.default.createElement("div", null, "Test");
|
|
305
|
+
};
|
|
306
|
+
const { unmount } = (0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
307
|
+
// Should not throw when unmounting
|
|
308
|
+
expect(() => {
|
|
309
|
+
unmount();
|
|
310
|
+
}).not.toThrow();
|
|
311
|
+
});
|
|
312
|
+
it('Should create stable hook structure', () => {
|
|
313
|
+
let hookResult1, hookResult2;
|
|
314
|
+
const TestComponent = ({ counter }) => {
|
|
315
|
+
const result = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
316
|
+
if (counter === 1) {
|
|
317
|
+
hookResult1 = result;
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
hookResult2 = result;
|
|
321
|
+
}
|
|
322
|
+
return react_1.default.createElement("div", null, "Test");
|
|
323
|
+
};
|
|
324
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { counter: 1 }));
|
|
325
|
+
rerender(react_1.default.createElement(TestComponent, { counter: 2 }));
|
|
326
|
+
// Both should have same structure
|
|
327
|
+
expect(hookResult1).toEqual({ sendMessage: expect.any(Function) });
|
|
328
|
+
expect(hookResult2).toEqual({ sendMessage: expect.any(Function) });
|
|
329
|
+
});
|
|
330
|
+
it('Should handle different worksheet IDs', () => {
|
|
331
|
+
const TestComponent = ({ worksheetId }) => {
|
|
332
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId });
|
|
333
|
+
expect(sendMessage).toBeDefined();
|
|
334
|
+
return react_1.default.createElement("div", null, "Test");
|
|
335
|
+
};
|
|
336
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { worksheetId: "worksheet1" }));
|
|
337
|
+
// Should handle different worksheet IDs
|
|
338
|
+
expect(() => {
|
|
339
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "worksheet2" }));
|
|
340
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "worksheet3" }));
|
|
341
|
+
}).not.toThrow();
|
|
342
|
+
});
|
|
343
|
+
it('Should handle empty query strings', () => {
|
|
344
|
+
let sendMessageFunction;
|
|
345
|
+
const TestComponent = () => {
|
|
346
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
347
|
+
sendMessageFunction = sendMessage;
|
|
348
|
+
return react_1.default.createElement("div", null, "Test");
|
|
349
|
+
};
|
|
350
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
351
|
+
// Should handle empty strings
|
|
352
|
+
expect(() => {
|
|
353
|
+
sendMessageFunction('');
|
|
354
|
+
sendMessageFunction(' ');
|
|
355
|
+
}).not.toThrow();
|
|
356
|
+
});
|
|
357
|
+
it('Should handle complex config objects', () => {
|
|
358
|
+
const complexConfig = {
|
|
359
|
+
worksheetId: 'test-worksheet',
|
|
360
|
+
hiddenActions: [types_1.Action.ReportError],
|
|
361
|
+
className: 'test-class',
|
|
362
|
+
searchOptions: {
|
|
363
|
+
searchQuery: 'test query'
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
const TestComponent = () => {
|
|
367
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)(complexConfig);
|
|
368
|
+
expect(sendMessage).toBeDefined();
|
|
369
|
+
return react_1.default.createElement("div", null, "Test");
|
|
370
|
+
};
|
|
371
|
+
// Should not throw with complex config
|
|
372
|
+
expect(() => {
|
|
373
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
374
|
+
}).not.toThrow();
|
|
375
|
+
});
|
|
376
|
+
it('Should maintain function identity across re-renders with same config', () => {
|
|
377
|
+
let sendMessage1, sendMessage2;
|
|
378
|
+
const TestComponent = ({ forceRender }) => {
|
|
379
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
380
|
+
if (forceRender === 1) {
|
|
381
|
+
sendMessage1 = sendMessage;
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
sendMessage2 = sendMessage;
|
|
385
|
+
}
|
|
386
|
+
return react_1.default.createElement("div", null, "Test");
|
|
387
|
+
};
|
|
388
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { forceRender: 1 }));
|
|
389
|
+
rerender(react_1.default.createElement(TestComponent, { forceRender: 2 }));
|
|
390
|
+
// Functions should exist
|
|
391
|
+
expect(sendMessage1).toBeDefined();
|
|
392
|
+
expect(sendMessage2).toBeDefined();
|
|
393
|
+
expect(typeof sendMessage1).toBe('function');
|
|
394
|
+
expect(typeof sendMessage2).toBe('function');
|
|
395
|
+
});
|
|
396
|
+
it('Should handle sendMessage calls with null service ref', async () => {
|
|
397
|
+
let capturedSendMessage;
|
|
398
|
+
const TestComponent = () => {
|
|
399
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
400
|
+
capturedSendMessage = sendMessage;
|
|
401
|
+
return react_1.default.createElement("div", null, "Test");
|
|
402
|
+
};
|
|
403
|
+
const { unmount } = (0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
404
|
+
// Unmount to trigger cleanup
|
|
405
|
+
unmount();
|
|
406
|
+
// Now call sendMessage after unmount - should return error
|
|
407
|
+
const result = await capturedSendMessage('test query');
|
|
408
|
+
expect(result).toEqual({
|
|
409
|
+
error: expect.any(Error)
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
it('Should test service ref cleanup on config change', () => {
|
|
413
|
+
const TestComponent = ({ worksheetId }) => {
|
|
414
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId });
|
|
415
|
+
expect(sendMessage).toBeDefined();
|
|
416
|
+
return react_1.default.createElement("div", null, "Test");
|
|
417
|
+
};
|
|
418
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { worksheetId: "worksheet1" }));
|
|
419
|
+
// This should trigger the cleanup and create new service
|
|
420
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "worksheet2" }));
|
|
421
|
+
// Should still work after rerender
|
|
422
|
+
expect(() => {
|
|
423
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "worksheet3" }));
|
|
424
|
+
}).not.toThrow();
|
|
425
|
+
});
|
|
426
|
+
it('Should test different config variations', () => {
|
|
427
|
+
const configs = [
|
|
428
|
+
{ worksheetId: 'test1' },
|
|
429
|
+
{ worksheetId: 'test2', hiddenActions: [types_1.Action.ReportError] },
|
|
430
|
+
{ worksheetId: 'test3', className: 'test-class' },
|
|
431
|
+
{ worksheetId: 'test4', searchOptions: { searchQuery: 'test' } }
|
|
432
|
+
];
|
|
433
|
+
configs.forEach((config, index) => {
|
|
434
|
+
const TestComponent = () => {
|
|
435
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)(config);
|
|
436
|
+
expect(sendMessage).toBeDefined();
|
|
437
|
+
return react_1.default.createElement("div", null,
|
|
438
|
+
"Test ",
|
|
439
|
+
index);
|
|
185
440
|
};
|
|
186
|
-
|
|
187
|
-
react_1.default.createElement(
|
|
188
|
-
|
|
441
|
+
expect(() => {
|
|
442
|
+
const { unmount } = (0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
443
|
+
unmount();
|
|
444
|
+
}).not.toThrow();
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
it('Should handle rapid config changes', () => {
|
|
448
|
+
const TestComponent = ({ worksheetId }) => {
|
|
449
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId });
|
|
450
|
+
expect(sendMessage).toBeDefined();
|
|
451
|
+
return react_1.default.createElement("div", null, "Test");
|
|
189
452
|
};
|
|
190
|
-
const {
|
|
191
|
-
|
|
192
|
-
|
|
453
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { worksheetId: "worksheet1" }));
|
|
454
|
+
// Rapid config changes to test cleanup logic
|
|
455
|
+
for (let i = 2; i <= 10; i++) {
|
|
456
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: `worksheet${i}` }));
|
|
457
|
+
}
|
|
458
|
+
// Should still work after many changes
|
|
459
|
+
expect(() => {
|
|
460
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "final-worksheet" }));
|
|
461
|
+
}).not.toThrow();
|
|
193
462
|
});
|
|
194
|
-
it('Should
|
|
195
|
-
let
|
|
463
|
+
it('Should handle sendMessage with different query types', () => {
|
|
464
|
+
let sendMessageFunction;
|
|
196
465
|
const TestComponent = () => {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (capturedInstance) {
|
|
201
|
-
const mockConversationService = {
|
|
202
|
-
sendMessage: jest.fn().mockResolvedValue({
|
|
203
|
-
data: {
|
|
204
|
-
sessionId: 'test-session',
|
|
205
|
-
genNo: 1,
|
|
206
|
-
stateKey: {
|
|
207
|
-
transactionId: 'test-transaction',
|
|
208
|
-
generationNumber: 1
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
})
|
|
212
|
-
};
|
|
213
|
-
capturedInstance.conversationService = mockConversationService;
|
|
214
|
-
}
|
|
215
|
-
}, []);
|
|
216
|
-
return (react_1.default.createElement(index_1.SpotterAgentEmbed, { ref: embedRef, worksheetId: "test-worksheet-id", className: "embedClass" }));
|
|
466
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId: 'test-worksheet' });
|
|
467
|
+
sendMessageFunction = sendMessage;
|
|
468
|
+
return react_1.default.createElement("div", null, "Test");
|
|
217
469
|
};
|
|
218
470
|
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
471
|
+
// Test different query types
|
|
472
|
+
const queries = [
|
|
473
|
+
'simple query',
|
|
474
|
+
'query with numbers 123',
|
|
475
|
+
'query with special chars !@#$%',
|
|
476
|
+
'very long query that might test different code paths in the system when processing',
|
|
477
|
+
'',
|
|
478
|
+
' whitespace ',
|
|
479
|
+
'null',
|
|
480
|
+
'undefined'
|
|
481
|
+
];
|
|
482
|
+
queries.forEach(query => {
|
|
483
|
+
expect(() => {
|
|
484
|
+
sendMessageFunction(query);
|
|
485
|
+
}).not.toThrow();
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
it('Should handle service ref cleanup when it already exists', () => {
|
|
489
|
+
const TestComponent = ({ worksheetId }) => {
|
|
490
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)({ worksheetId });
|
|
491
|
+
expect(sendMessage).toBeDefined();
|
|
492
|
+
return react_1.default.createElement("div", null, "Test");
|
|
493
|
+
};
|
|
494
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { worksheetId: "worksheet1" }));
|
|
495
|
+
// This should trigger the "if (serviceRef.current)" branch in useEffect
|
|
496
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "worksheet1" }));
|
|
497
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "worksheet2" }));
|
|
498
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: "worksheet3" }));
|
|
499
|
+
// Multiple rapid changes should exercise the cleanup logic
|
|
500
|
+
for (let i = 0; i < 5; i++) {
|
|
501
|
+
rerender(react_1.default.createElement(TestComponent, { worksheetId: `worksheet${i}` }));
|
|
223
502
|
}
|
|
224
503
|
});
|
|
504
|
+
it('Should test various config combinations to hit all branches', () => {
|
|
505
|
+
const testConfigs = [
|
|
506
|
+
{ worksheetId: 'test1' },
|
|
507
|
+
{ worksheetId: 'test2', className: 'custom-class' },
|
|
508
|
+
{ worksheetId: 'test3', hiddenActions: [types_1.Action.ReportError] },
|
|
509
|
+
{ worksheetId: 'test4', searchOptions: { searchQuery: 'test' } },
|
|
510
|
+
{ worksheetId: 'test5', insertAsSibling: true },
|
|
511
|
+
{ worksheetId: 'test6', insertAsSibling: false },
|
|
512
|
+
];
|
|
513
|
+
testConfigs.forEach((config, index) => {
|
|
514
|
+
const TestComponent = () => {
|
|
515
|
+
const { sendMessage } = (0, index_1.useSpotterAgent)(config);
|
|
516
|
+
expect(sendMessage).toBeDefined();
|
|
517
|
+
return react_1.default.createElement("div", null,
|
|
518
|
+
"Test ",
|
|
519
|
+
index);
|
|
520
|
+
};
|
|
521
|
+
const { unmount } = (0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
522
|
+
unmount();
|
|
523
|
+
});
|
|
524
|
+
});
|
|
525
|
+
});
|
|
526
|
+
describe('Component Props and Functions', () => {
|
|
527
|
+
it('Should have PreRenderedLiveboardEmbed component', () => {
|
|
528
|
+
expect(index_1.PreRenderedLiveboardEmbed).toBeDefined();
|
|
529
|
+
expect(typeof index_1.PreRenderedLiveboardEmbed).toBe('object');
|
|
530
|
+
});
|
|
531
|
+
it('Should have useInit hook', () => {
|
|
532
|
+
expect(typeof index_1.useInit).toBe('function');
|
|
533
|
+
});
|
|
534
|
+
it('Should test basic component factory patterns', () => {
|
|
535
|
+
// Test that components can be created without errors
|
|
536
|
+
expect(() => {
|
|
537
|
+
const TestComponent = () => react_1.default.createElement("div", null, "Test");
|
|
538
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
539
|
+
}).not.toThrow();
|
|
540
|
+
});
|
|
225
541
|
});
|
|
226
|
-
describe('
|
|
227
|
-
it('
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
542
|
+
describe('Hook Coverage', () => {
|
|
543
|
+
it('Should have useInit function available', () => {
|
|
544
|
+
expect(typeof index_1.useInit).toBe('function');
|
|
545
|
+
});
|
|
546
|
+
it('Should test useInit hook basic functionality', () => {
|
|
547
|
+
const TestComponent = () => {
|
|
548
|
+
const authEE = (0, index_1.useInit)({
|
|
549
|
+
thoughtSpotHost: 'localhost',
|
|
550
|
+
authType: index_2.AuthType.None
|
|
551
|
+
});
|
|
552
|
+
expect(authEE).toBeDefined();
|
|
553
|
+
expect(authEE.current).toBeDefined();
|
|
554
|
+
return react_1.default.createElement("div", null, "Test");
|
|
555
|
+
};
|
|
556
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
557
|
+
});
|
|
558
|
+
it('Should handle useInit with different config changes', () => {
|
|
559
|
+
const TestComponent = ({ host }) => {
|
|
560
|
+
const authEE = (0, index_1.useInit)({
|
|
561
|
+
thoughtSpotHost: host,
|
|
562
|
+
authType: index_2.AuthType.None
|
|
563
|
+
});
|
|
564
|
+
expect(authEE).toBeDefined();
|
|
565
|
+
return react_1.default.createElement("div", null, "Test");
|
|
566
|
+
};
|
|
567
|
+
const { rerender } = (0, react_2.render)(react_1.default.createElement(TestComponent, { host: "localhost" }));
|
|
568
|
+
// Change config to test useDeepCompareEffect
|
|
569
|
+
rerender(react_1.default.createElement(TestComponent, { host: "localhost2" }));
|
|
570
|
+
rerender(react_1.default.createElement(TestComponent, { host: "localhost3" }));
|
|
571
|
+
});
|
|
572
|
+
it('Should test useInit with complex config objects', () => {
|
|
573
|
+
const TestComponent = () => {
|
|
574
|
+
const authEE = (0, index_1.useInit)({
|
|
575
|
+
thoughtSpotHost: 'localhost',
|
|
576
|
+
authType: index_2.AuthType.None,
|
|
577
|
+
suppressNoCookieAccessAlert: true,
|
|
578
|
+
suppressErrorAlerts: true
|
|
579
|
+
});
|
|
580
|
+
expect(authEE).toBeDefined();
|
|
581
|
+
return react_1.default.createElement("div", null, "Test");
|
|
582
|
+
};
|
|
583
|
+
(0, react_2.render)(react_1.default.createElement(TestComponent, null));
|
|
246
584
|
});
|
|
247
585
|
});
|
|
248
586
|
});
|