@thoughtspot/visual-embed-sdk 1.44.1 → 1.44.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.
Files changed (246) hide show
  1. package/cjs/package.json +6 -5
  2. package/cjs/src/api-intercept.d.ts.map +1 -1
  3. package/cjs/src/api-intercept.js +8 -3
  4. package/cjs/src/api-intercept.js.map +1 -1
  5. package/cjs/src/api-intercept.spec.js +19 -3
  6. package/cjs/src/api-intercept.spec.js.map +1 -1
  7. package/cjs/src/auth.spec.js +43 -42
  8. package/cjs/src/auth.spec.js.map +1 -1
  9. package/cjs/src/authToken.spec.js +3 -3
  10. package/cjs/src/authToken.spec.js.map +1 -1
  11. package/cjs/src/embed/app.d.ts +17 -0
  12. package/cjs/src/embed/app.d.ts.map +1 -1
  13. package/cjs/src/embed/app.js +9 -5
  14. package/cjs/src/embed/app.js.map +1 -1
  15. package/cjs/src/embed/app.spec.js +96 -6
  16. package/cjs/src/embed/app.spec.js.map +1 -1
  17. package/cjs/src/embed/base.d.ts +1 -1
  18. package/cjs/src/embed/base.d.ts.map +1 -1
  19. package/cjs/src/embed/base.js +4 -0
  20. package/cjs/src/embed/base.js.map +1 -1
  21. package/cjs/src/embed/base.spec.js +71 -15
  22. package/cjs/src/embed/base.spec.js.map +1 -1
  23. package/cjs/src/embed/bodyless-conversation.spec.js +2 -2
  24. package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
  25. package/cjs/src/embed/conversation.d.ts.map +1 -1
  26. package/cjs/src/embed/conversation.js +6 -1
  27. package/cjs/src/embed/conversation.js.map +1 -1
  28. package/cjs/src/embed/conversation.spec.js +8 -3
  29. package/cjs/src/embed/conversation.spec.js.map +1 -1
  30. package/cjs/src/embed/embed.spec.js +101 -2
  31. package/cjs/src/embed/embed.spec.js.map +1 -1
  32. package/cjs/src/embed/events.spec.js +2 -2
  33. package/cjs/src/embed/events.spec.js.map +1 -1
  34. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +1 -1
  35. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  36. package/cjs/src/embed/liveboard.d.ts +18 -0
  37. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  38. package/cjs/src/embed/liveboard.js +13 -6
  39. package/cjs/src/embed/liveboard.js.map +1 -1
  40. package/cjs/src/embed/liveboard.spec.js +114 -26
  41. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  42. package/cjs/src/embed/pinboard.spec.js +1 -1
  43. package/cjs/src/embed/pinboard.spec.js.map +1 -1
  44. package/cjs/src/embed/sage.spec.js +2 -2
  45. package/cjs/src/embed/sage.spec.js.map +1 -1
  46. package/cjs/src/embed/search.spec.js +118 -2
  47. package/cjs/src/embed/search.spec.js.map +1 -1
  48. package/cjs/src/embed/ts-embed-trigger.spec.js +2 -3
  49. package/cjs/src/embed/ts-embed-trigger.spec.js.map +1 -1
  50. package/cjs/src/embed/ts-embed.d.ts +3 -2
  51. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  52. package/cjs/src/embed/ts-embed.js +51 -17
  53. package/cjs/src/embed/ts-embed.js.map +1 -1
  54. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  55. package/cjs/src/embed/ts-embed.spec.js +335 -71
  56. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  57. package/cjs/src/errors.d.ts +8 -0
  58. package/cjs/src/errors.d.ts.map +1 -1
  59. package/cjs/src/errors.js +8 -0
  60. package/cjs/src/errors.js.map +1 -1
  61. package/cjs/src/mixpanel-service.spec.js +1 -1
  62. package/cjs/src/mixpanel-service.spec.js.map +1 -1
  63. package/cjs/src/react/index.spec.js +3 -4
  64. package/cjs/src/react/index.spec.js.map +1 -1
  65. package/cjs/src/test/test-utils.js +1 -1
  66. package/cjs/src/test/test-utils.js.map +1 -1
  67. package/cjs/src/types.d.ts +194 -1
  68. package/cjs/src/types.d.ts.map +1 -1
  69. package/cjs/src/types.js +94 -2
  70. package/cjs/src/types.js.map +1 -1
  71. package/cjs/src/utils/authService/authService.spec.js +8 -8
  72. package/cjs/src/utils/authService/authService.spec.js.map +1 -1
  73. package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  74. package/cjs/src/utils/graphql/answerService/answerService.spec.js +1 -1
  75. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  76. package/cjs/src/utils/graphql/graphql-request.spec.js +1 -1
  77. package/cjs/src/utils/graphql/graphql-request.spec.js.map +1 -1
  78. package/cjs/src/utils/graphql/sourceService.spec.js +1 -1
  79. package/cjs/src/utils/graphql/sourceService.spec.js.map +1 -1
  80. package/cjs/src/utils/logger.spec.d.ts +5 -20
  81. package/cjs/src/utils/logger.spec.d.ts.map +1 -1
  82. package/cjs/src/utils/processData.spec.js +17 -17
  83. package/cjs/src/utils/processData.spec.js.map +1 -1
  84. package/cjs/src/utils/processTrigger.spec.js +8 -8
  85. package/cjs/src/utils/processTrigger.spec.js.map +1 -1
  86. package/cjs/src/utils.d.ts +16 -3
  87. package/cjs/src/utils.d.ts.map +1 -1
  88. package/cjs/src/utils.js +60 -5
  89. package/cjs/src/utils.js.map +1 -1
  90. package/cjs/src/utils.spec.js +72 -10
  91. package/cjs/src/utils.spec.js.map +1 -1
  92. package/dist/{index-BE9gGzRX.js → index-D0n5LIka.js} +1 -1
  93. package/dist/src/api-intercept.d.ts.map +1 -1
  94. package/dist/src/embed/app.d.ts +17 -0
  95. package/dist/src/embed/app.d.ts.map +1 -1
  96. package/dist/src/embed/base.d.ts +1 -1
  97. package/dist/src/embed/base.d.ts.map +1 -1
  98. package/dist/src/embed/conversation.d.ts.map +1 -1
  99. package/dist/src/embed/liveboard.d.ts +18 -0
  100. package/dist/src/embed/liveboard.d.ts.map +1 -1
  101. package/dist/src/embed/ts-embed.d.ts +3 -2
  102. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  103. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  104. package/dist/src/errors.d.ts +8 -0
  105. package/dist/src/errors.d.ts.map +1 -1
  106. package/dist/src/types.d.ts +194 -1
  107. package/dist/src/types.d.ts.map +1 -1
  108. package/dist/src/utils/logger.spec.d.ts +5 -20
  109. package/dist/src/utils/logger.spec.d.ts.map +1 -1
  110. package/dist/src/utils.d.ts +16 -3
  111. package/dist/src/utils.d.ts.map +1 -1
  112. package/dist/tsembed-react.es.js +282 -74
  113. package/dist/tsembed-react.js +281 -73
  114. package/dist/tsembed.es.js +282 -74
  115. package/dist/tsembed.js +281 -73
  116. package/dist/visual-embed-sdk-react-full.d.ts +185 -3
  117. package/dist/visual-embed-sdk-react.d.ts +184 -2
  118. package/dist/visual-embed-sdk.d.ts +185 -3
  119. package/lib/package.json +6 -5
  120. package/lib/src/api-intercept.d.ts.map +1 -1
  121. package/lib/src/api-intercept.js +9 -4
  122. package/lib/src/api-intercept.js.map +1 -1
  123. package/lib/src/api-intercept.spec.js +20 -4
  124. package/lib/src/api-intercept.spec.js.map +1 -1
  125. package/lib/src/auth.spec.js +43 -42
  126. package/lib/src/auth.spec.js.map +1 -1
  127. package/lib/src/authToken.spec.js +3 -3
  128. package/lib/src/authToken.spec.js.map +1 -1
  129. package/lib/src/embed/app.d.ts +17 -0
  130. package/lib/src/embed/app.d.ts.map +1 -1
  131. package/lib/src/embed/app.js +10 -6
  132. package/lib/src/embed/app.js.map +1 -1
  133. package/lib/src/embed/app.spec.js +96 -6
  134. package/lib/src/embed/app.spec.js.map +1 -1
  135. package/lib/src/embed/base.d.ts +1 -1
  136. package/lib/src/embed/base.d.ts.map +1 -1
  137. package/lib/src/embed/base.js +5 -1
  138. package/lib/src/embed/base.js.map +1 -1
  139. package/lib/src/embed/base.spec.js +72 -16
  140. package/lib/src/embed/base.spec.js.map +1 -1
  141. package/lib/src/embed/bodyless-conversation.spec.js +2 -2
  142. package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
  143. package/lib/src/embed/conversation.d.ts.map +1 -1
  144. package/lib/src/embed/conversation.js +7 -2
  145. package/lib/src/embed/conversation.js.map +1 -1
  146. package/lib/src/embed/conversation.spec.js +9 -4
  147. package/lib/src/embed/conversation.spec.js.map +1 -1
  148. package/lib/src/embed/embed.spec.js +103 -4
  149. package/lib/src/embed/embed.spec.js.map +1 -1
  150. package/lib/src/embed/events.spec.js +2 -2
  151. package/lib/src/embed/events.spec.js.map +1 -1
  152. package/lib/src/embed/hostEventClient/host-event-client.spec.js +2 -2
  153. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  154. package/lib/src/embed/liveboard.d.ts +18 -0
  155. package/lib/src/embed/liveboard.d.ts.map +1 -1
  156. package/lib/src/embed/liveboard.js +15 -8
  157. package/lib/src/embed/liveboard.js.map +1 -1
  158. package/lib/src/embed/liveboard.spec.js +114 -26
  159. package/lib/src/embed/liveboard.spec.js.map +1 -1
  160. package/lib/src/embed/pinboard.spec.js +1 -1
  161. package/lib/src/embed/pinboard.spec.js.map +1 -1
  162. package/lib/src/embed/sage.spec.js +2 -2
  163. package/lib/src/embed/sage.spec.js.map +1 -1
  164. package/lib/src/embed/search.spec.js +118 -2
  165. package/lib/src/embed/search.spec.js.map +1 -1
  166. package/lib/src/embed/ts-embed-trigger.spec.js +2 -3
  167. package/lib/src/embed/ts-embed-trigger.spec.js.map +1 -1
  168. package/lib/src/embed/ts-embed.d.ts +3 -2
  169. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  170. package/lib/src/embed/ts-embed.js +52 -18
  171. package/lib/src/embed/ts-embed.js.map +1 -1
  172. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  173. package/lib/src/embed/ts-embed.spec.js +336 -72
  174. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  175. package/lib/src/errors.d.ts +8 -0
  176. package/lib/src/errors.d.ts.map +1 -1
  177. package/lib/src/errors.js +8 -0
  178. package/lib/src/errors.js.map +1 -1
  179. package/lib/src/mixpanel-service.spec.js +1 -1
  180. package/lib/src/mixpanel-service.spec.js.map +1 -1
  181. package/lib/src/react/index.spec.js +3 -4
  182. package/lib/src/react/index.spec.js.map +1 -1
  183. package/lib/src/test/test-utils.js +1 -1
  184. package/lib/src/test/test-utils.js.map +1 -1
  185. package/lib/src/types.d.ts +194 -1
  186. package/lib/src/types.d.ts.map +1 -1
  187. package/lib/src/types.js +93 -1
  188. package/lib/src/types.js.map +1 -1
  189. package/lib/src/utils/authService/authService.spec.js +8 -8
  190. package/lib/src/utils/authService/authService.spec.js.map +1 -1
  191. package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  192. package/lib/src/utils/graphql/answerService/answerService.spec.js +1 -1
  193. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  194. package/lib/src/utils/graphql/graphql-request.spec.js +1 -1
  195. package/lib/src/utils/graphql/graphql-request.spec.js.map +1 -1
  196. package/lib/src/utils/graphql/sourceService.spec.js +1 -1
  197. package/lib/src/utils/graphql/sourceService.spec.js.map +1 -1
  198. package/lib/src/utils/logger.spec.d.ts +5 -20
  199. package/lib/src/utils/logger.spec.d.ts.map +1 -1
  200. package/lib/src/utils/processData.spec.js +17 -17
  201. package/lib/src/utils/processData.spec.js.map +1 -1
  202. package/lib/src/utils/processTrigger.spec.js +8 -8
  203. package/lib/src/utils/processTrigger.spec.js.map +1 -1
  204. package/lib/src/utils.d.ts +16 -3
  205. package/lib/src/utils.d.ts.map +1 -1
  206. package/lib/src/utils.js +57 -4
  207. package/lib/src/utils.js.map +1 -1
  208. package/lib/src/utils.spec.js +73 -11
  209. package/lib/src/utils.spec.js.map +1 -1
  210. package/package.json +6 -5
  211. package/src/api-intercept.spec.ts +23 -10
  212. package/src/api-intercept.ts +9 -4
  213. package/src/auth.spec.ts +53 -51
  214. package/src/authToken.spec.ts +3 -3
  215. package/src/embed/app.spec.ts +128 -7
  216. package/src/embed/app.ts +30 -4
  217. package/src/embed/base.spec.ts +95 -21
  218. package/src/embed/base.ts +5 -2
  219. package/src/embed/bodyless-conversation.spec.ts +2 -2
  220. package/src/embed/conversation.spec.ts +9 -4
  221. package/src/embed/conversation.ts +7 -2
  222. package/src/embed/embed.spec.ts +122 -2
  223. package/src/embed/events.spec.ts +2 -2
  224. package/src/embed/hostEventClient/host-event-client.spec.ts +2 -2
  225. package/src/embed/liveboard.spec.ts +137 -29
  226. package/src/embed/liveboard.ts +36 -6
  227. package/src/embed/pinboard.spec.ts +1 -1
  228. package/src/embed/sage.spec.ts +2 -2
  229. package/src/embed/search.spec.ts +133 -2
  230. package/src/embed/ts-embed-trigger.spec.ts +2 -3
  231. package/src/embed/ts-embed.spec.ts +424 -91
  232. package/src/embed/ts-embed.ts +56 -19
  233. package/src/errors.ts +8 -0
  234. package/src/mixpanel-service.spec.ts +1 -1
  235. package/src/react/index.spec.tsx +4 -5
  236. package/src/test/test-utils.ts +2 -2
  237. package/src/types.ts +206 -1
  238. package/src/utils/authService/authService.spec.ts +17 -17
  239. package/src/utils/authService/tokenizedAuthService.spec.ts +4 -4
  240. package/src/utils/graphql/answerService/answerService.spec.ts +3 -3
  241. package/src/utils/graphql/graphql-request.spec.ts +2 -2
  242. package/src/utils/graphql/sourceService.spec.ts +1 -1
  243. package/src/utils/processData.spec.ts +26 -26
  244. package/src/utils/processTrigger.spec.ts +8 -8
  245. package/src/utils.spec.ts +100 -11
  246. package/src/utils.ts +59 -7
@@ -20,7 +20,7 @@ describe('graphQl tests', () => {
20
20
  json: jest.fn().mockResolvedValue({
21
21
  data: {},
22
22
  }),
23
- });
23
+ } as any);
24
24
 
25
25
  const details = await graphqlQuery({
26
26
  query: getSourceDetailQuery,
@@ -30,7 +30,7 @@ describe('graphQl tests', () => {
30
30
  thoughtSpotHost,
31
31
  });
32
32
 
33
- expect(tokenizedFetchUtil.tokenizedFetch).toBeCalledWith('TSHOST/prism/?op=GetSourceDetail', {
33
+ expect(tokenizedFetchUtil.tokenizedFetch).toHaveBeenCalledWith('TSHOST/prism/?op=GetSourceDetail', {
34
34
  body: '{"operationName":"GetSourceDetail","query":"\\n query GetSourceDetail($ids: [GUID!]!) {\\n getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {\\n id\\n name\\n }\\n } \\n","variables":{"ids":[2]}}',
35
35
  credentials: 'include',
36
36
  headers: {
@@ -14,6 +14,6 @@ describe('Source service tests', () => {
14
14
  }));
15
15
  await getSourceDetail('https://tshost', 'id');
16
16
  await getSourceDetail('https://tshost', 'id');
17
- expect(fetchMock).toBeCalledTimes(1);
17
+ expect(fetchMock).toHaveBeenCalledTimes(1);
18
18
  });
19
19
  });
@@ -10,7 +10,7 @@ import { logger } from './logger';
10
10
 
11
11
  describe('Unit test for process data', () => {
12
12
  beforeAll(() => {
13
- jest.spyOn(auth, 'postLoginService').mockImplementation(() => Promise.resolve({}));
13
+ jest.spyOn(auth, 'postLoginService').mockImplementation(() => Promise.resolve(undefined));
14
14
  base.init({
15
15
  thoughtSpotHost: 'https://tshost',
16
16
  authType: AuthType.None,
@@ -84,7 +84,7 @@ describe('Unit test for process data', () => {
84
84
  const processedData = { type: EmbedEvent.Data };
85
85
  jest.spyOn(processDataInstance, 'processCustomAction').mockImplementation(async () => ({}));
86
86
  processDataInstance.processEventData(EmbedEvent.Data, processedData, thoughtSpotHost, null);
87
- expect(processDataInstance.processCustomAction).not.toBeCalled();
87
+ expect(processDataInstance.processCustomAction).not.toHaveBeenCalled();
88
88
  });
89
89
 
90
90
  test('AuthInit', () => {
@@ -95,14 +95,14 @@ describe('Unit test for process data', () => {
95
95
  };
96
96
  const e = { type: EmbedEvent.AuthInit, data: sessionInfo };
97
97
  jest.spyOn(base, 'notifyAuthSuccess');
98
- jest.spyOn(sessionInfoService, 'getSessionInfo').mockReturnValue(sessionInfo);
98
+ jest.spyOn(sessionInfoService, 'getSessionInfo').mockImplementation(() => Promise.resolve(sessionInfo as any));
99
99
  expect(processDataInstance.processEventData(e.type, e, '', null)).toEqual({
100
100
  type: e.type,
101
101
  data: {
102
102
  userGUID: sessionInfo.userGUID,
103
103
  },
104
104
  });
105
- expect(base.notifyAuthSuccess).toBeCalled();
105
+ expect(base.notifyAuthSuccess).toHaveBeenCalled();
106
106
  });
107
107
 
108
108
  test('NoCookieAccess no suppress alert', () => {
@@ -111,14 +111,14 @@ describe('Unit test for process data', () => {
111
111
  jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue({
112
112
  loginFailedMessage: 'Hello',
113
113
  suppressNoCookieAccessAlert: false,
114
- });
114
+ } as any);
115
115
  jest.spyOn(window, 'alert').mockImplementation(() => undefined);
116
116
  const el: any = {};
117
117
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
118
118
  type: e.type,
119
119
  });
120
- expect(base.notifyAuthFailure).toBeCalledWith(auth.AuthFailureType.NO_COOKIE_ACCESS);
121
- expect(window.alert).toBeCalled();
120
+ expect(base.notifyAuthFailure).toHaveBeenCalledWith(auth.AuthFailureType.NO_COOKIE_ACCESS);
121
+ expect(window.alert).toHaveBeenCalled();
122
122
  expect(el.innerHTML).toBe('Hello');
123
123
  });
124
124
 
@@ -128,15 +128,15 @@ describe('Unit test for process data', () => {
128
128
  jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue({
129
129
  loginFailedMessage: 'Hello',
130
130
  suppressNoCookieAccessAlert: true,
131
- });
131
+ } as any);
132
132
  jest.spyOn(window, 'alert').mockReset();
133
133
  jest.spyOn(window, 'alert').mockImplementation(() => undefined);
134
134
  const el: any = {};
135
135
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
136
136
  type: e.type,
137
137
  });
138
- expect(base.notifyAuthFailure).toBeCalledWith(auth.AuthFailureType.NO_COOKIE_ACCESS);
139
- expect(window.alert).not.toBeCalled();
138
+ expect(base.notifyAuthFailure).toHaveBeenCalledWith(auth.AuthFailureType.NO_COOKIE_ACCESS);
139
+ expect(window.alert).not.toHaveBeenCalled();
140
140
  expect(el.innerHTML).toBe('Hello');
141
141
  });
142
142
 
@@ -146,15 +146,15 @@ describe('Unit test for process data', () => {
146
146
  jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue({
147
147
  loginFailedMessage: 'Hello',
148
148
  ignoreNoCookieAccess: true,
149
- });
149
+ } as any);
150
150
  jest.spyOn(window, 'alert').mockReset();
151
151
  jest.spyOn(window, 'alert').mockImplementation(() => undefined);
152
152
  const el: any = {};
153
153
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
154
154
  type: e.type,
155
155
  });
156
- expect(base.notifyAuthFailure).toBeCalledWith(auth.AuthFailureType.NO_COOKIE_ACCESS);
157
- expect(window.alert).not.toBeCalled();
156
+ expect(base.notifyAuthFailure).toHaveBeenCalledWith(auth.AuthFailureType.NO_COOKIE_ACCESS);
157
+ expect(window.alert).not.toHaveBeenCalled();
158
158
  expect(el.innerHTML).not.toBe('Hello');
159
159
  });
160
160
 
@@ -163,12 +163,12 @@ describe('Unit test for process data', () => {
163
163
  jest.spyOn(base, 'notifyAuthFailure');
164
164
  jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue({
165
165
  loginFailedMessage: 'Hello',
166
- });
166
+ } as any);
167
167
  const el: any = {};
168
168
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
169
169
  type: e.type,
170
170
  });
171
- expect(base.notifyAuthFailure).toBeCalledWith(auth.AuthFailureType.OTHER);
171
+ expect(base.notifyAuthFailure).toHaveBeenCalledWith(auth.AuthFailureType.OTHER);
172
172
  expect(el.innerHTML).toBe('Hello');
173
173
  });
174
174
 
@@ -178,12 +178,12 @@ describe('Unit test for process data', () => {
178
178
  jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue({
179
179
  loginFailedMessage: 'Hello',
180
180
  authType: AuthType.None,
181
- });
181
+ } as any);
182
182
  const el: any = {};
183
183
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
184
184
  type: e.type,
185
185
  });
186
- expect(base.notifyAuthFailure).not.toBeCalled();
186
+ expect(base.notifyAuthFailure).not.toHaveBeenCalled();
187
187
  expect(el.innerHTML).not.toBe('Hello');
188
188
  });
189
189
 
@@ -201,7 +201,7 @@ describe('Unit test for process data', () => {
201
201
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
202
202
  type: e.type,
203
203
  });
204
- expect(base.notifyLogout).toBeCalled();
204
+ expect(base.notifyLogout).toHaveBeenCalled();
205
205
  expect(el.innerHTML).toBe('Hello');
206
206
  expect(embedConfigInstance.getEmbedConfig().autoLogin).toBe(false);
207
207
  });
@@ -212,12 +212,12 @@ describe('Unit test for process data', () => {
212
212
  loginFailedMessage: 'Hello',
213
213
  authType: AuthType.EmbeddedSSO,
214
214
  disableLoginFailurePage: true,
215
- });
215
+ } as any);
216
216
  const el: any = {};
217
217
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
218
218
  type: e.type,
219
219
  });
220
- expect(base.notifyAuthFailure).not.toBeCalled();
220
+ expect(base.notifyAuthFailure).not.toHaveBeenCalled();
221
221
  expect(el.innerHTML).not.toBe('Hello');
222
222
  });
223
223
 
@@ -228,12 +228,12 @@ describe('Unit test for process data', () => {
228
228
  loginFailedMessage: 'Hello',
229
229
  authType: AuthType.TrustedAuthToken,
230
230
  autoLogin: true,
231
- });
231
+ } as any);
232
232
  const el: any = {};
233
233
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
234
234
  type: e.type,
235
235
  });
236
- expect(base.notifyAuthFailure).toBeCalledWith(auth.AuthFailureType.IDLE_SESSION_TIMEOUT);
236
+ expect(base.notifyAuthFailure).toHaveBeenCalledWith(auth.AuthFailureType.IDLE_SESSION_TIMEOUT);
237
237
  expect(el.innerHTML).toBe('Hello');
238
238
  });
239
239
 
@@ -244,12 +244,12 @@ describe('Unit test for process data', () => {
244
244
  loginFailedMessage: 'Hello',
245
245
  authType: AuthType.TrustedAuthTokenCookieless,
246
246
  autoLogin: true,
247
- });
247
+ } as any);
248
248
  const el: any = {};
249
249
  expect(processDataInstance.processEventData(e.type, e, '', el)).toEqual({
250
250
  type: e.type,
251
251
  });
252
- expect(base.notifyAuthFailure).toBeCalledWith(auth.AuthFailureType.IDLE_SESSION_TIMEOUT);
252
+ expect(base.notifyAuthFailure).toHaveBeenCalledWith(auth.AuthFailureType.IDLE_SESSION_TIMEOUT);
253
253
  expect(el.innerHTML).toBe('Hello');
254
254
  });
255
255
 
@@ -258,9 +258,9 @@ describe('Unit test for process data', () => {
258
258
  disableFullscreenPresentation: false,
259
259
  };
260
260
 
261
- const mockHandleExitPresentMode = jest.spyOn(utilsModule, 'handleExitPresentMode').mockImplementation(() => {});
261
+ const mockHandleExitPresentMode = jest.spyOn(utilsModule, 'handleExitPresentMode').mockImplementation(() => Promise.resolve(undefined));
262
262
 
263
- jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue(mockConfig);
263
+ jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValue(mockConfig as any);
264
264
 
265
265
  const processedData = {
266
266
  type: EmbedEvent.ExitPresentMode,
@@ -29,7 +29,7 @@ describe('Unit test for processTrigger', () => {
29
29
  const data = {};
30
30
  _processTriggerInstance.processTrigger(iFrameElement, messageType, thoughtSpotHost, data);
31
31
  jest.advanceTimersByTime(200);
32
- expect(spyReload).toBeCalledWith(iFrameElement);
32
+ expect(spyReload).toHaveBeenCalledWith(iFrameElement);
33
33
  });
34
34
 
35
35
  test('when hostevent is search, postMessage should be called', async () => {
@@ -43,14 +43,14 @@ describe('Unit test for processTrigger', () => {
43
43
  thoughtSpotHost,
44
44
  data,
45
45
  );
46
- expect(iFrame.contentWindow.postMessage).toBeCalled();
46
+ expect(iFrame.contentWindow.postMessage).toHaveBeenCalled();
47
47
  const res = {
48
48
  data: {
49
49
  test: '123',
50
50
  },
51
51
  };
52
52
  messageChannelMock.port1.onmessage(res);
53
- expect(messageChannelMock.port1.close).toBeCalled();
53
+ expect(messageChannelMock.port1.close).toHaveBeenCalled();
54
54
  expect(triggerPromise).resolves.toEqual(res.data);
55
55
  });
56
56
 
@@ -65,14 +65,14 @@ describe('Unit test for processTrigger', () => {
65
65
  thoughtSpotHost,
66
66
  data,
67
67
  );
68
- expect(iFrame.contentWindow.postMessage).toBeCalled();
68
+ expect(iFrame.contentWindow.postMessage).toHaveBeenCalled();
69
69
  const res = {
70
70
  data: {
71
71
  error: 'error',
72
72
  },
73
73
  };
74
74
  messageChannelMock.port1.onmessage(res);
75
- expect(messageChannelMock.port1.close).toBeCalled();
75
+ expect(messageChannelMock.port1.close).toHaveBeenCalled();
76
76
  expect(triggerPromise).rejects.toEqual(res.data.error);
77
77
  });
78
78
 
@@ -91,7 +91,7 @@ describe('Unit test for processTrigger', () => {
91
91
 
92
92
  jest.advanceTimersByTime(_processTriggerInstance.TRIGGER_TIMEOUT);
93
93
 
94
- expect(messageChannelMock.port1.close).toBeCalled();
94
+ expect(messageChannelMock.port1.close).toHaveBeenCalled();
95
95
  await expect(triggerPromise).resolves.toBeInstanceOf(Error);
96
96
  });
97
97
 
@@ -101,9 +101,9 @@ describe('Unit test for processTrigger', () => {
101
101
  let mockGetEmbedConfig: any;
102
102
 
103
103
  beforeEach(() => {
104
- mockHandlePresentEvent = jest.spyOn(utilsModule, 'handlePresentEvent').mockImplementation(() => {});
104
+ mockHandlePresentEvent = jest.spyOn(utilsModule, 'handlePresentEvent').mockImplementation(() => Promise.resolve(undefined));
105
105
  mockLoggerWarn = jest.spyOn(logger, 'warn').mockImplementation(() => {});
106
- mockGetEmbedConfig = jest.spyOn(embedConfigModule, 'getEmbedConfig').mockImplementation(() => ({}));
106
+ mockGetEmbedConfig = jest.spyOn(embedConfigModule, 'getEmbedConfig').mockImplementation(() => ({ disableFullscreenPresentation: false } as any));
107
107
  });
108
108
 
109
109
  afterEach(() => {
package/src/utils.spec.ts CHANGED
@@ -19,9 +19,12 @@ import {
19
19
  arrayIncludesString,
20
20
  calculateVisibleElementData,
21
21
  formatTemplate,
22
+ isValidCssMargin,
23
+ resetValueFromWindow,
22
24
  } from './utils';
23
25
  import { RuntimeFilterOp } from './types';
24
26
  import { logger } from './utils/logger';
27
+ import { ERROR_MESSAGE } from './errors';
25
28
 
26
29
  // Mock logger
27
30
  jest.mock('./utils/logger', () => ({
@@ -142,12 +145,12 @@ describe('unit test for utils', () => {
142
145
  });
143
146
 
144
147
  describe('getRedirectURL', () => {
145
- let windowSpy: any;
148
+ let originalLocation: Location;
146
149
  beforeEach(() => {
147
- windowSpy = jest.spyOn(window, 'window', 'get');
150
+ originalLocation = window.location;
148
151
  });
149
152
  afterEach(() => {
150
- windowSpy.mockRestore();
153
+ window.location.hash = '';
151
154
  });
152
155
 
153
156
  test('Should return correct value when path is undefined', () => {
@@ -158,18 +161,12 @@ describe('unit test for utils', () => {
158
161
  });
159
162
 
160
163
  test('Should return correct value when path is set', () => {
161
- windowSpy.mockImplementation(() => ({
162
- location: {
163
- origin: 'http://myhost:3000',
164
- },
165
- }));
166
-
167
164
  expect(getRedirectUrl('http://myhost:3000/', 'hashFrag', '/bar')).toBe(
168
- 'http://myhost:3000/bar#?tsSSOMarker=hashFrag',
165
+ 'http://localhost/bar#?tsSSOMarker=hashFrag',
169
166
  );
170
167
 
171
168
  expect(getRedirectUrl('http://myhost:3000/#/foo', 'hashFrag', '#/bar')).toBe(
172
- 'http://myhost:3000/#/bar?tsSSOMarker=hashFrag',
169
+ 'http://localhost/#/bar?tsSSOMarker=hashFrag',
173
170
  );
174
171
  });
175
172
  });
@@ -736,3 +733,95 @@ describe('formatTemplate', () => {
736
733
  ).toBe('Hello John, you are {age} years old');
737
734
  });
738
735
  });
736
+
737
+ describe('isValidCssMargin', () => {
738
+ it('should return true for valid CSS margin values', () => {
739
+ expect(isValidCssMargin('10px')).toBe(true);
740
+ expect(isValidCssMargin('0px')).toBe(true);
741
+ expect(isValidCssMargin('20%')).toBe(true);
742
+ expect(isValidCssMargin('0')).toBe(true);
743
+ });
744
+
745
+ it('should return false for invalid CSS margin values', () => {
746
+ expect(isValidCssMargin('')).toBe(false);
747
+ expect(isValidCssMargin(' ')).toBe(false);
748
+ expect(isValidCssMargin('invalid')).toBe(false);
749
+ expect(isValidCssMargin('10')).toBe(false); // missing unit
750
+ });
751
+ });
752
+
753
+ describe('getValueFromWindow and storeValueInWindow', () => {
754
+ describe('SSR environment handling', () => {
755
+ let originalWindow: typeof globalThis.window;
756
+ beforeEach(() => {
757
+ originalWindow = global.window;
758
+ });
759
+
760
+ afterEach(() => {
761
+ global.window = originalWindow;
762
+ });
763
+
764
+ test('storeValueInWindow should log error in SSR environment', () => {
765
+ delete global.window;
766
+
767
+ const result = storeValueInWindow('testKey', 'testValue');
768
+
769
+ expect(logger.error).toHaveBeenCalledWith(
770
+ ERROR_MESSAGE.SSR_ENVIRONMENT_ERROR
771
+ );
772
+ expect(result).toBe('testValue');
773
+ });
774
+
775
+ test('getValueFromWindow should log error in SSR environment', () => {
776
+ delete global.window;
777
+
778
+ const result = getValueFromWindow('testKey');
779
+
780
+ expect(logger.error).toHaveBeenCalledWith(
781
+ ERROR_MESSAGE.SSR_ENVIRONMENT_ERROR
782
+ );
783
+ expect(result).toBeUndefined();
784
+ });
785
+
786
+ test('resetValueFromWindow should log error in SSR environment', () => {
787
+ delete global.window;
788
+
789
+ const result = resetValueFromWindow('testKey');
790
+
791
+ expect(logger.error).toHaveBeenCalledWith(
792
+ ERROR_MESSAGE.SSR_ENVIRONMENT_ERROR
793
+ );
794
+ expect(result).toBe(false);
795
+ });
796
+ });
797
+ describe('resetValueFromWindow', () => {
798
+ beforeEach(() => {
799
+ (window as any)._tsEmbedSDK = {};
800
+ });
801
+
802
+ test('should reset existing key and return true', () => {
803
+ storeValueInWindow('keyToReset', 'someValue');
804
+ expect(getValueFromWindow('keyToReset')).toBe('someValue');
805
+
806
+ const result = resetValueFromWindow('keyToReset');
807
+
808
+ expect(result).toBe(true);
809
+ expect(getValueFromWindow('keyToReset')).toBe(undefined);
810
+ });
811
+
812
+ test('should return false when key does not exist', () => {
813
+ const result = resetValueFromWindow('nonExistentKey');
814
+ expect(result).toBe(false);
815
+ });
816
+
817
+ test('should only reset the specified key', () => {
818
+ storeValueInWindow('key1', 'value1');
819
+ storeValueInWindow('key2', 'value2');
820
+
821
+ resetValueFromWindow('key1');
822
+
823
+ expect(getValueFromWindow('key1')).toBe(undefined);
824
+ expect(getValueFromWindow('key2')).toBe('value2');
825
+ });
826
+ });
827
+ });
package/src/utils.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  AllEmbedViewConfig,
18
18
  } from './types';
19
19
  import { logger } from './utils/logger';
20
+ import { ERROR_MESSAGE } from './errors';
20
21
 
21
22
  /**
22
23
  * Construct a runtime filters query string from the given filters.
@@ -132,6 +133,40 @@ export const getCssDimension = (value: number | string): string => {
132
133
  return value;
133
134
  };
134
135
 
136
+ /**
137
+ * Validates if a string is a valid CSS margin value.
138
+ * @param value - The string to validate
139
+ * @returns true if the value is a valid CSS margin value, false otherwise
140
+ */
141
+ export const isValidCssMargin = (value: string): boolean => {
142
+ if(isUndefined(value)) {
143
+ return false;
144
+ }
145
+ if (typeof value !== 'string') {
146
+ logger.error('Please provide a valid lazyLoadingMargin value (e.g., "10px")');
147
+ return false;
148
+ }
149
+
150
+ // This pattern allows for an optional negative sign, and numbers that can be integers or decimals (including leading dot).
151
+ const cssUnitPattern = /^-?(\d+(\.\d*)?|\.\d+)(px|em|rem|%|vh|vw)$/i;
152
+ const parts = value.trim().split(/\s+/);
153
+
154
+ if (parts.length > 4) {
155
+ logger.error('Please provide a valid lazyLoadingMargin value (e.g., "10px")');
156
+ return false;
157
+ }
158
+
159
+ const isValid = parts.every(part => {
160
+ const trimmedPart = part.trim();
161
+ return trimmedPart.toLowerCase() === 'auto' || trimmedPart === '0' || cssUnitPattern.test(trimmedPart);
162
+ });
163
+ if (!isValid) {
164
+ logger.error('Please provide a valid lazyLoadingMargin value (e.g., "10px")');
165
+ return false;
166
+ }
167
+ return true;
168
+ };
169
+
135
170
  export const getSSOMarker = (markerId: string) => {
136
171
  const encStringToAppend = encodeURIComponent(markerId);
137
172
  return `tsSSOMarker=${encStringToAppend}`;
@@ -359,6 +394,7 @@ export function storeValueInWindow<T>(
359
394
  value: T,
360
395
  options: { ignoreIfAlreadyExists?: boolean } = {},
361
396
  ): T {
397
+ if (isWindowUndefined()) return value;
362
398
  if (!window[sdkWindowKey]) {
363
399
  (window as any)[sdkWindowKey] = {};
364
400
  }
@@ -372,13 +408,14 @@ export function storeValueInWindow<T>(
372
408
  }
373
409
 
374
410
  /**
375
- * Retrieves a stored value from the global `window` object under the `_tsEmbedSDK` namespace.
376
- * @param key - The key whose value needs to be retrieved.
377
- * @returns The stored value or `undefined` if the key is not found.
411
+ * Retrieves a stored value from the global
412
+ * `window` object under the `_tsEmbedSDK` namespace.
413
+ * Returns undefined in SSR environment.
378
414
  */
379
- export const getValueFromWindow = <T = any>
380
- (key: string): T => (window as any)?.[sdkWindowKey]?.[key];
381
-
415
+ export const getValueFromWindow = <T = any>(key: string): T | undefined => {
416
+ if (isWindowUndefined()) return undefined;
417
+ return (window as any)?.[sdkWindowKey]?.[key];
418
+ };
382
419
  /**
383
420
  * Check if an array includes a string value
384
421
  * @param arr - The array to check
@@ -396,6 +433,7 @@ export const arrayIncludesString = (arr: readonly unknown[], key: string): boole
396
433
  * @returns - boolean indicating if the key was reset
397
434
  */
398
435
  export function resetValueFromWindow(key: string): boolean {
436
+ if (isWindowUndefined()) return false;
399
437
  if (key in window[sdkWindowKey]) {
400
438
  delete (window as any)[sdkWindowKey][key];
401
439
  return true;
@@ -519,4 +557,18 @@ export const formatTemplate = (template: string, values: Record<string, any>): s
519
557
  return template.replace(/\{(\w+)\}/g, (match, key) => {
520
558
  return values[key] !== undefined ? String(values[key]) : match;
521
559
  });
522
- };
560
+ };
561
+
562
+ /**
563
+ * Check if the window is undefined
564
+ * If the window is undefined, it means the code is running in a SSR environment.
565
+ * @returns true if the window is undefined, false otherwise
566
+ *
567
+ */
568
+ export const isWindowUndefined = (): boolean => {
569
+ if(typeof window === 'undefined') {
570
+ logger.error(ERROR_MESSAGE.SSR_ENVIRONMENT_ERROR);
571
+ return true;
572
+ }
573
+ return false;
574
+ }