• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thoughtspot / visual-embed-sdk / #1435

14 Jan 2025 09:42PM UTC coverage: 41.895% (-52.0%) from 93.86%
#1435

Pull #65

Prashant.patil
SCAL-233454-exp checking-mixpanel-error
Pull Request #65: test-exported memb

273 of 1106 branches covered (24.68%)

Branch coverage included in aggregate %.

84 of 356 new or added lines in 14 files covered. (23.6%)

1011 existing lines in 23 files now uncovered.

1301 of 2651 relevant lines covered (49.08%)

9.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.67
/src/embed/hostEventClient/host-event-client.ts
1
import { HostEvent } from '../../types';
14✔
2
import { processTrigger as processTriggerService } from '../../utils/processTrigger';
14✔
3
import { getEmbedConfig } from '../embedConfig';
14✔
4
import {
14✔
5
    UIPassthroughArrayResponse,
6
    UIPassthroughEvent, HostEventRequest, HostEventResponse,
7
    UIPassthroughRequest,
8
    UIPassthroughResponse,
9
    TriggerPayload,
10
    TriggerResponse,
11
} from './contracts';
12

13
export class HostEventClient {
14✔
14
  iFrame: HTMLIFrameElement;
15

16
  constructor(iFrame?: HTMLIFrameElement) {
17
      this.iFrame = iFrame;
10✔
18
  }
19

20
  /**
21
   * A wrapper over process trigger to
22
   * @param {HostEvent} message Host event to send
23
   * @param {any} data Data to send with the host event
24
   * @returns {Promise<any>} - the response from the process trigger
25
   */
26
  protected async processTrigger(message: HostEvent, data: any): Promise<any> {
27
      if (!this.iFrame) {
9!
28
          throw new Error('Iframe element is not set');
×
29
      }
30

31
      const thoughtspotHost = getEmbedConfig().thoughtSpotHost;
9✔
32
      return processTriggerService(
9✔
33
          this.iFrame,
34
          message,
35
          thoughtspotHost,
36
          data,
37
      );
38
  }
39

40
  public async handleHostEventWithParam<UIPassthroughEventT extends UIPassthroughEvent>(
41
      apiName: UIPassthroughEventT,
42
      parameters: UIPassthroughRequest<UIPassthroughEventT>,
43
  ): Promise<UIPassthroughResponse<UIPassthroughEventT>> {
44
      const response = (await this.triggerUIPassthroughApi(apiName, parameters))
6!
45
          ?.filter?.((r) => r.error || r.value)[0];
4✔
46

47
      if (!response) {
6✔
48
          const error = `No answer found${parameters.vizId ? ` for vizId: ${parameters.vizId}` : ''}.`;
2✔
49
          // eslint-disable-next-line no-throw-literal
50
          throw { error };
2✔
51
      }
52

53
      const errors = response.error
4✔
54
        || (response.value as any)?.errors
9!
55
        || (response.value as any)?.error;
9!
56

57
      if (errors) {
4✔
58
      // eslint-disable-next-line no-throw-literal
59
          throw { error: response.error };
1✔
60
      }
61

62
      return { ...response.value };
3✔
63
  }
64

65
  public async hostEventFallback(
66
      hostEvent: HostEvent,
67
      data: any,
68
  ): Promise<any> {
69
      return this.processTrigger(hostEvent, data);
2✔
70
  }
71

72
  /**
73
   * Setter for the iframe element used for host events
74
   * @param {HTMLIFrameElement} iFrame - the iframe element to set
75
   */
76
  public setIframeElement(iFrame: HTMLIFrameElement): void {
UNCOV
77
      this.iFrame = iFrame;
×
78
  }
79

80
  public async triggerUIPassthroughApi<UIPassthroughEventT extends UIPassthroughEvent>(
81
      apiName: UIPassthroughEventT,
82
      parameters: UIPassthroughRequest<UIPassthroughEventT>,
83
  ): Promise<UIPassthroughArrayResponse<UIPassthroughEventT>> {
84
      const res = await this.processTrigger(HostEvent.UIPassthrough, {
7✔
85
          type: apiName,
86
          parameters,
87
      });
88

89
      return res;
7✔
90
  }
91

92
  protected async handlePinEvent(
93
      payload: HostEventRequest<HostEvent.Pin>,
94
  ): Promise<HostEventResponse<HostEvent.Pin>> {
95
      if (!payload || !('newVizName' in payload)) {
2✔
96
          return this.hostEventFallback(HostEvent.Pin, payload);
1✔
97
      }
98

99
      return this.handleHostEventWithParam(
1✔
100
          UIPassthroughEvent.PinAnswerToLiveboard, payload,
101
      );
102
  }
103

104
  protected async handleSaveAnswerEvent(
105
      payload: HostEventRequest<HostEvent.SaveAnswer>,
106
  ): Promise<any> {
107
      if (!payload || !('name' in payload) || !('description' in payload)) {
2✔
108
          // Save is the fallback for SaveAnswer
109
          return this.hostEventFallback(HostEvent.Save, payload);
1✔
110
      }
111

112
      const data = await this.handleHostEventWithParam(
1✔
113
          UIPassthroughEvent.SaveAnswer, payload,
114
      );
115
      return {
1✔
116
          ...data,
117
          answerId: data?.saveResponse?.data?.Answer__save?.answer?.id,
15!
118
      };
119
  }
120

121
  public async triggerHostEvent<
122
    HostEventT extends HostEvent,
123
    PayloadT,
124
  >(
125
      hostEvent: HostEventT,
126
      payload?: TriggerPayload<PayloadT, HostEventT>,
127
  ): Promise<TriggerResponse<PayloadT, HostEventT>> {
128
      switch (hostEvent) {
5✔
129
          case HostEvent.Pin:
130
              return this.handlePinEvent(payload as HostEventRequest<HostEvent.Pin>) as any;
2✔
131
          case HostEvent.SaveAnswer:
132
              return this.handleSaveAnswerEvent(
2✔
133
                  payload as HostEventRequest<HostEvent.SaveAnswer>,
134
              ) as any;
135
          default:
136
              return this.hostEventFallback(hostEvent, payload);
1✔
137
      }
138
  }
139
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc