@simplybusiness/services 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/mocks/eventDefinitions.js +5 -21
  3. package/dist/cjs/mocks/eventDefinitions.js.map +1 -1
  4. package/dist/cjs/snowplow/Snowplow.js +41 -28
  5. package/dist/cjs/snowplow/Snowplow.js.map +1 -1
  6. package/dist/cjs/snowplow/contexts.js +52 -12
  7. package/dist/cjs/snowplow/contexts.js.map +1 -1
  8. package/dist/cjs/snowplow/event-definitions/qcp.js +8 -2
  9. package/dist/cjs/snowplow/event-definitions/qcp.js.map +1 -1
  10. package/dist/cjs/snowplow/event-definitions/questionnaire.js +4 -1
  11. package/dist/cjs/snowplow/event-definitions/questionnaire.js.map +1 -1
  12. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  13. package/dist/esm/mocks/eventDefinitions.js +5 -21
  14. package/dist/esm/mocks/eventDefinitions.js.map +1 -1
  15. package/dist/esm/snowplow/Snowplow.js +41 -28
  16. package/dist/esm/snowplow/Snowplow.js.map +1 -1
  17. package/dist/esm/snowplow/contexts.js +38 -9
  18. package/dist/esm/snowplow/contexts.js.map +1 -1
  19. package/dist/esm/snowplow/event-definitions/qcp.js +9 -22
  20. package/dist/esm/snowplow/event-definitions/qcp.js.map +1 -1
  21. package/dist/esm/snowplow/event-definitions/questionnaire.js +4 -1
  22. package/dist/esm/snowplow/event-definitions/questionnaire.js.map +1 -1
  23. package/dist/esm/snowplow/types.js.map +1 -1
  24. package/dist/types/mocks/eventDefinitions.d.ts +4 -19
  25. package/dist/types/snowplow/Snowplow.d.ts +7 -5
  26. package/dist/types/snowplow/contexts.d.ts +4 -3
  27. package/dist/types/snowplow/event-definitions/qcp.d.ts +0 -20
  28. package/dist/types/snowplow/types.d.ts +3 -1
  29. package/package.json +2 -2
  30. package/src/mocks/eventDefinitions.ts +2 -25
  31. package/src/snowplow/Snowplow.ts +46 -29
  32. package/src/snowplow/contexts.test.ts +134 -6
  33. package/src/snowplow/contexts.ts +44 -14
  34. package/src/snowplow/event-definitions/qcp.ts +2 -21
  35. package/src/snowplow/event-definitions/questionnaire.ts +1 -0
  36. package/src/snowplow/index.test.ts +40 -30
  37. package/src/snowplow/types.ts +4 -1
@@ -1,5 +1,5 @@
1
1
  import { pageData } from "../mocks/scripts-mock";
2
- import { getContexts } from "./contexts";
2
+ import { getContexts, makeContexts, updateIdentityContext } from "./contexts";
3
3
  import { getSnowplowConfig } from "./getSnowplowConfig";
4
4
  import { PageDataProps, TrackingProps } from "./types";
5
5
 
@@ -7,9 +7,15 @@ describe("Snowplow Contexts", () => {
7
7
  it("should extract all context records from snowplow props", () => {
8
8
  const snowplowProps = getSnowplowConfig(pageData as PageDataProps);
9
9
  const contexts = getContexts(snowplowProps as TrackingProps);
10
+ const keys = Object.keys(contexts);
10
11
 
11
- expect(contexts).toHaveLength(3);
12
- expect(contexts[0]).toEqual({
12
+ expect(keys).toEqual([
13
+ "pageViewContext",
14
+ "distributionChannelContext",
15
+ "serviceChannelContext",
16
+ ]);
17
+
18
+ expect(contexts["pageViewContext"]).toEqual({
13
19
  schema: "iglu:uk.co.simplybusiness/journey_context/jsonschema/1-0-0",
14
20
  data: {
15
21
  site: "simplybusiness_us",
@@ -22,14 +28,136 @@ describe("Snowplow Contexts", () => {
22
28
  page_step_depth: -1,
23
29
  },
24
30
  });
25
- expect(contexts[1]).toEqual({
31
+
32
+ expect(contexts["distributionChannelContext"]).toEqual({
26
33
  schema:
27
34
  "iglu:com.simplybusiness/distribution_channel_context/jsonschema/1-0-0",
28
35
  data: { service_channel_identifier: "simplybusiness_us" },
29
36
  });
30
- expect(contexts[2]).toEqual({
31
- schema: "iglu:com.simplybusiness/service_channel_context/jsonschema/1-0-0",
37
+
38
+ expect(contexts["serviceChannelContext"]).toEqual({
39
+ schema:
40
+ "iglu:com.simplybusiness/service_channel_context/jsonschema/1-0-0",
32
41
  data: { service_channel_identifier: "simplybusiness_us" },
33
42
  });
34
43
  });
44
+
45
+ it("should extract empty contexts when config is null", () => {
46
+ const contexts = getContexts(null as unknown as TrackingProps);
47
+ expect(Object.keys(contexts)).toEqual([]);
48
+ });
49
+
50
+ it("should handle primitive values in context", () => {
51
+ const props = {
52
+ someContext: "primitive-value",
53
+ } as unknown as TrackingProps;
54
+
55
+ const contexts = getContexts(props);
56
+ expect(contexts["someContext"]).toEqual({
57
+ data: { service_channel_identifier: "primitive-value" },
58
+ });
59
+ });
60
+
61
+ describe("makeContexts", () => {
62
+ it("should return only the contexts that are present in the keys", () => {
63
+ const contexts = {
64
+ context1: {
65
+ schema: "iglu:com.simplybusiness/context1/jsonschema/1-0-0",
66
+ data: {
67
+ some_field: "some_value",
68
+ },
69
+ },
70
+ context2: {
71
+ schema: "iglu:com.simplybusiness/context2/jsonschema/1-0-0",
72
+ data: {
73
+ some_field: "some_value",
74
+ },
75
+ },
76
+ };
77
+
78
+ const keys = ["context1"];
79
+ const result = makeContexts(keys, contexts);
80
+
81
+ expect(result).toEqual([contexts.context1]);
82
+ });
83
+
84
+ it("should return multiple contexts if present in the keys", () => {
85
+ const contexts = {
86
+ context1: {
87
+ schema: "iglu:com.simplybusiness/context1/jsonschema/1-0-0",
88
+ data: {
89
+ some_field: "some_value",
90
+ },
91
+ },
92
+ context2: {
93
+ schema: "iglu:com.simplybusiness/context2/jsonschema/1-0-0",
94
+ data: {
95
+ some_field: "some_value",
96
+ },
97
+ },
98
+ };
99
+
100
+ const keys = ["context1", "context2"];
101
+ const result = makeContexts(keys, contexts);
102
+
103
+ expect(result).toEqual([contexts.context1, contexts.context2]);
104
+ });
105
+
106
+ it("should return an empty object when no contexts are present in the keys", () => {
107
+ const contexts = {
108
+ context1: {
109
+ schema: "iglu:com.simplybusiness/context1/jsonschema/1-0-0",
110
+ data: {
111
+ some_field: "some_value",
112
+ },
113
+ },
114
+ context2: {
115
+ schema: "iglu:com.simplybusiness/context2/jsonschema/1-0-0",
116
+ data: {
117
+ some_field: "some_value",
118
+ },
119
+ },
120
+ };
121
+
122
+ const result = makeContexts([], contexts);
123
+
124
+ expect(Object.keys(result)).toEqual([]);
125
+ });
126
+ });
127
+
128
+ describe("updateIdentityContext", () => {
129
+ it("should update the domain_userid when identity context exists", () => {
130
+ const contexts = {
131
+ identityContext: {
132
+ schema: "iglu:uk.co.simplybusiness/identity_context/jsonschema/1-0-0",
133
+ data: {
134
+ user_id: "123",
135
+ domain_userid: "old-uid",
136
+ },
137
+ },
138
+ };
139
+
140
+ const updatedContexts = updateIdentityContext(contexts, "new-uid");
141
+
142
+ expect(updatedContexts.identityContext.data.domain_userid).toEqual(
143
+ "new-uid",
144
+ );
145
+ expect(updatedContexts.identityContext.data.user_id).toEqual("123");
146
+ });
147
+
148
+ it("should return the original contexts when identity context doesn't exist", () => {
149
+ const contexts = {
150
+ someOtherContext: {
151
+ schema: "iglu:uk.co.simplybusiness/other_context/jsonschema/1-0-0",
152
+ data: {
153
+ some_field: "some_value",
154
+ },
155
+ },
156
+ };
157
+
158
+ const updatedContexts = updateIdentityContext(contexts, "new-uid");
159
+
160
+ expect(updatedContexts).toEqual(contexts);
161
+ });
162
+ });
35
163
  });
@@ -1,20 +1,50 @@
1
- import { SelfDescribingJson } from "@snowplow/browser-tracker";
2
- import { TrackingProps } from "./types";
3
1
  import { snakeCaseKeys } from "../utils";
2
+ import { SerialisedEvent, TrackingProps } from "./types";
4
3
 
5
4
  export const getContexts = (
6
5
  config: TrackingProps,
7
- ): SelfDescribingJson<Record<string, unknown>>[] => {
8
- const contexts =
9
- config &&
10
- Object.entries(config)
11
- .filter(([key]) => key.includes("Context") && key !== "includeGAContext")
12
- .map(([_key, value]) => {
13
- if (typeof value === "object") {
14
- return snakeCaseKeys(({ ...value }));
15
- }
16
- return snakeCaseKeys({ data: { service_channel_identifier: value } });
17
- });
6
+ ): Record<string, SerialisedEvent> => {
7
+ // Create an object that only contains Context keys
8
+ // and snake_case the keys
9
+ const contextEntries = Object.entries(config || {})
10
+ .filter(([key]) => key.includes("Context") && key !== "includeGAContext")
11
+ .reduce((acc, [key, value]) => {
12
+ if (typeof value === "object") {
13
+ return { ...acc, [key]: snakeCaseKeys({ ...value }) };
14
+ }
15
+ return {
16
+ ...acc,
17
+ [key]: snakeCaseKeys({ data: { service_channel_identifier: value } }),
18
+ };
19
+ }, {});
18
20
 
19
- return contexts as unknown as SelfDescribingJson<Record<string, unknown>>[];
21
+ return contextEntries as Record<string, SerialisedEvent>;
20
22
  };
23
+
24
+ export const updateIdentityContext = (
25
+ contexts: Record<string, SerialisedEvent>,
26
+ uid: unknown,
27
+ ): Record<string, SerialisedEvent> => {
28
+ const index = Object.keys(contexts).findIndex(ctx =>
29
+ contexts[ctx].schema?.includes("identity_context"),
30
+ );
31
+ if (index > -1) {
32
+ const key = Object.keys(contexts)[index];
33
+ return {
34
+ ...contexts,
35
+ [key]: {
36
+ ...contexts[key],
37
+ data: {
38
+ ...contexts[key].data,
39
+ domain_userid: uid,
40
+ },
41
+ },
42
+ };
43
+ }
44
+ return contexts;
45
+ };
46
+
47
+ export const makeContexts = (
48
+ keys: string[],
49
+ config: Record<string, SerialisedEvent>,
50
+ ): SerialisedEvent[] => (keys || []).map(key => config[key]);
@@ -1,27 +1,6 @@
1
1
  import { snakeCase } from "../../utils";
2
2
  import { EventDefinition, LinkType, ParamsType } from "../types";
3
3
 
4
- /**
5
- * Event definitions for Snowplow
6
- * @type {EventDefinition[]}
7
- * @property {string} name - The name of the event, to use when triggering
8
- * @property {string} type - The type of the event (structured | unstructured)
9
- * @property {makePayload} makePayload
10
- * - Function that creates the payload for the event;
11
- * - Allows optional params object to be passed in
12
- *
13
- * @example
14
- * Parent
15
- * import { getSnowplowConfig, SnowplowProvider } from "@simplybusiness/services";
16
- * const snowplowProps = getSnowplowConfig(pageData);
17
- * <SnowplowProvider scripts={snowplowProps!}>{children}</SnowplowProvider>
18
- *
19
- * Child
20
- * import { useSnowplowContext } from "@simplybusiness/services";
21
- * const { snowplow } = useSnowplowContext();
22
- * const handlerFunction = () => snowplow?.trigger("eventNameHere");
23
- */
24
-
25
4
  // QCP page events
26
5
  export const qcpEventDefinitions: EventDefinition[] = [
27
6
  {
@@ -143,6 +122,7 @@ export const qcpEventDefinitions: EventDefinition[] = [
143
122
  },
144
123
  };
145
124
  },
125
+ contexts: ["distributionChannelContext"],
146
126
  },
147
127
  {
148
128
  name: "ratingsModalOpened",
@@ -250,6 +230,7 @@ export const qcpEventDefinitions: EventDefinition[] = [
250
230
  },
251
231
  };
252
232
  },
233
+ contexts: ["serviceChannelContext"],
253
234
  },
254
235
  {
255
236
  name: "helpChatLinkClicked",
@@ -54,6 +54,7 @@ export const questionnaireEventDefinitions: EventDefinition[] = [
54
54
  },
55
55
  };
56
56
  },
57
+ contexts: ["distributionChannelContext"],
57
58
  },
58
59
  {
59
60
  name: "helpTextOpened",
@@ -2,13 +2,14 @@ import * as SnowplowLib from "@snowplow/browser-tracker";
2
2
  import { waitFor } from "@testing-library/dom";
3
3
  import eventDefinitions from "../mocks/eventDefinitions";
4
4
  import { pageData } from "../mocks/scripts-mock";
5
- import { getContexts } from "./contexts";
5
+ import { getContexts, makeContexts } from "./contexts";
6
6
  import { getSnowplowConfig } from "./getSnowplowConfig";
7
7
  import { Snowplow } from "./Snowplow";
8
8
  import { EventDefinition, PageDataProps, TrackingProps } from "./types";
9
9
 
10
10
  const snowplowProps = getSnowplowConfig(pageData as PageDataProps);
11
11
  const contexts = getContexts(snowplowProps as TrackingProps);
12
+ const fqaContext = makeContexts(["distributionChannelContext"], contexts);
12
13
 
13
14
  let testSnowplow = new Snowplow(snowplowProps as TrackingProps);
14
15
  testSnowplow.setContexts(contexts);
@@ -39,13 +40,14 @@ describe("Snowplow Analytics Class", () => {
39
40
 
40
41
  it("sets contexts on instantiation", () => {
41
42
  expect(testSnowplow.contexts).toEqual(contexts);
43
+ expect(testSnowplow.pvContext).toEqual(Object.values(contexts));
42
44
  });
43
45
 
44
46
  it("tracks page view event and adds contexts", async () => {
45
47
  const trackViewSpy = jest.spyOn(testSnowplow, "trackView");
46
48
  const innerSpy = jest
47
49
  .spyOn(SnowplowLib, "trackPageView")
48
- .mockImplementation(() => { });
50
+ .mockImplementation(() => {});
49
51
 
50
52
  await testSnowplow.trackView();
51
53
 
@@ -53,7 +55,7 @@ describe("Snowplow Analytics Class", () => {
53
55
  expect(trackViewSpy).toHaveBeenCalledTimes(1);
54
56
  expect(trackViewSpy).toHaveBeenCalledWith();
55
57
  expect(innerSpy).toHaveBeenCalledTimes(1);
56
- expect(innerSpy).toHaveBeenCalledWith({ context: contexts });
58
+ expect(innerSpy).toHaveBeenCalledWith({});
57
59
  });
58
60
  });
59
61
 
@@ -61,7 +63,7 @@ describe("Snowplow Analytics Class", () => {
61
63
  const trackStructEventSpy = jest.spyOn(testSnowplow, "trackEvent");
62
64
  const innerSpy = jest
63
65
  .spyOn(SnowplowLib, "trackStructEvent")
64
- .mockImplementation(() => { });
66
+ .mockImplementation(() => {});
65
67
 
66
68
  const payload = {
67
69
  category: "mobile-link",
@@ -74,9 +76,10 @@ describe("Snowplow Analytics Class", () => {
74
76
  expect(trackStructEventSpy).toHaveBeenCalledTimes(1);
75
77
  expect(trackStructEventSpy).toHaveBeenCalledWith(payload);
76
78
  expect(innerSpy).toHaveBeenCalledTimes(1);
77
- expect(innerSpy).toHaveBeenCalledWith({ ...payload, context: contexts }, [
78
- "sb-ava-br",
79
- ]);
79
+ expect(innerSpy).toHaveBeenCalledWith(
80
+ { ...payload, context: testSnowplow.structContext },
81
+ ["sb-ava-br"],
82
+ );
80
83
  });
81
84
 
82
85
  it("tracks self-describing event and adds contexts", async () => {
@@ -86,7 +89,7 @@ describe("Snowplow Analytics Class", () => {
86
89
  );
87
90
  const innerSpy = jest
88
91
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
89
- .mockImplementation(() => { });
92
+ .mockImplementation(() => {});
90
93
 
91
94
  const testEvent = {
92
95
  schema:
@@ -106,7 +109,6 @@ describe("Snowplow Analytics Class", () => {
106
109
  expect(innerSpy).toHaveBeenCalledWith(
107
110
  {
108
111
  event: testEvent,
109
- context: contexts,
110
112
  },
111
113
  ["sb-ava"],
112
114
  );
@@ -129,7 +131,7 @@ describe("Snowplow Analytics Class", () => {
129
131
  const trackStructEventSpy = jest.spyOn(testSnowplow, "trackEvent");
130
132
  const innerSpy = jest
131
133
  .spyOn(SnowplowLib, "trackStructEvent")
132
- .mockImplementation(() => { });
134
+ .mockImplementation(() => {});
133
135
 
134
136
  await testSnowplow.trigger("navButtonClicked", { label: "test-label" });
135
137
 
@@ -144,7 +146,7 @@ describe("Snowplow Analytics Class", () => {
144
146
  expect(trackStructEventSpy).toHaveBeenCalledWith(expectedPayload);
145
147
  expect(innerSpy).toHaveBeenCalledTimes(1);
146
148
  expect(innerSpy).toHaveBeenCalledWith(
147
- { ...expectedPayload, context: contexts },
149
+ { ...expectedPayload, context: testSnowplow.structContext },
148
150
  ["sb-ava-br"],
149
151
  );
150
152
  });
@@ -158,7 +160,7 @@ describe("Snowplow Analytics Class", () => {
158
160
  );
159
161
  const innerSpy = jest
160
162
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
161
- .mockImplementation(() => { });
163
+ .mockImplementation(() => {});
162
164
 
163
165
  await testSnowplow.trigger("questionAnswered", {
164
166
  question: "test-question",
@@ -182,12 +184,14 @@ describe("Snowplow Analytics Class", () => {
182
184
  };
183
185
 
184
186
  expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
185
- expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
187
+ expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload, [
188
+ "distributionChannelContext",
189
+ ]);
186
190
  expect(innerSpy).toHaveBeenCalledTimes(1);
187
191
  expect(innerSpy).toHaveBeenCalledWith(
188
192
  {
189
193
  event: expectedPayload,
190
- context: contexts,
194
+ context: fqaContext,
191
195
  },
192
196
  ["sb-ava"],
193
197
  );
@@ -202,7 +206,7 @@ describe("Snowplow Analytics Class", () => {
202
206
  );
203
207
  const innerSpy = jest
204
208
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
205
- .mockImplementation(() => { });
209
+ .mockImplementation(() => {});
206
210
 
207
211
  await testSnowplow.trigger("questionAnswered", {
208
212
  question: "sof_bankrupt_yes",
@@ -226,12 +230,14 @@ describe("Snowplow Analytics Class", () => {
226
230
  };
227
231
 
228
232
  expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
229
- expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
233
+ expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload, [
234
+ "distributionChannelContext",
235
+ ]);
230
236
  expect(innerSpy).toHaveBeenCalledTimes(1);
231
237
  expect(innerSpy).toHaveBeenCalledWith(
232
238
  {
233
239
  event: expectedPayload,
234
- context: contexts,
240
+ context: fqaContext,
235
241
  },
236
242
  ["sb-ava"],
237
243
  );
@@ -246,7 +252,7 @@ describe("Snowplow Analytics Class", () => {
246
252
  );
247
253
  const innerSpy = jest
248
254
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
249
- .mockImplementation(() => { });
255
+ .mockImplementation(() => {});
250
256
 
251
257
  await testSnowplow.trigger("questionAnswered", {
252
258
  question: "have_secondary_trade_yes",
@@ -270,12 +276,14 @@ describe("Snowplow Analytics Class", () => {
270
276
  };
271
277
 
272
278
  expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
273
- expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
279
+ expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload, [
280
+ "distributionChannelContext",
281
+ ]);
274
282
  expect(innerSpy).toHaveBeenCalledTimes(1);
275
283
  expect(innerSpy).toHaveBeenCalledWith(
276
284
  {
277
285
  event: expectedPayload,
278
- context: contexts,
286
+ context: fqaContext,
279
287
  },
280
288
  ["sb-ava"],
281
289
  );
@@ -290,7 +298,7 @@ describe("Snowplow Analytics Class", () => {
290
298
  );
291
299
  const innerSpy = jest
292
300
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
293
- .mockImplementation(() => { });
301
+ .mockImplementation(() => {});
294
302
 
295
303
  await testSnowplow.trigger("questionAnswered", {
296
304
  question: "address_lookup",
@@ -314,12 +322,14 @@ describe("Snowplow Analytics Class", () => {
314
322
  };
315
323
 
316
324
  expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
317
- expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
325
+ expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload, [
326
+ "distributionChannelContext",
327
+ ]);
318
328
  expect(innerSpy).toHaveBeenCalledTimes(1);
319
329
  expect(innerSpy).toHaveBeenCalledWith(
320
330
  {
321
331
  event: expectedPayload,
322
- context: contexts,
332
+ context: fqaContext,
323
333
  },
324
334
  ["sb-ava"],
325
335
  );
@@ -347,7 +357,7 @@ describe("Snowplow Analytics Class", () => {
347
357
  );
348
358
  const innerSpy = jest
349
359
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
350
- .mockImplementation(() => { });
360
+ .mockImplementation(() => {});
351
361
 
352
362
  await testSnowplow.trigger("primaryDetailSelected", {
353
363
  answer,
@@ -370,7 +380,6 @@ describe("Snowplow Analytics Class", () => {
370
380
  expect(innerSpy).toHaveBeenCalledWith(
371
381
  {
372
382
  event: expectedPayload,
373
- context: contexts,
374
383
  },
375
384
  ["sb-ava"],
376
385
  );
@@ -386,7 +395,7 @@ describe("Snowplow Analytics Class", () => {
386
395
  );
387
396
  const innerSpy = jest
388
397
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
389
- .mockImplementation(() => { });
398
+ .mockImplementation(() => {});
390
399
 
391
400
  await testSnowplow.trigger("helpTextOpened", {
392
401
  primaryText: "Sample text",
@@ -412,7 +421,6 @@ describe("Snowplow Analytics Class", () => {
412
421
  expect(innerSpy).toHaveBeenCalledWith(
413
422
  {
414
423
  event: expectedPayload,
415
- context: contexts,
416
424
  },
417
425
  ["sb-ava"],
418
426
  );
@@ -427,7 +435,7 @@ describe("Snowplow Analytics Class", () => {
427
435
  );
428
436
  const innerSpy = jest
429
437
  .spyOn(SnowplowLib, "trackSelfDescribingEvent")
430
- .mockImplementation(() => { });
438
+ .mockImplementation(() => {});
431
439
 
432
440
  await testSnowplow.trigger("questionAnswered", {
433
441
  question: "test-question",
@@ -451,12 +459,14 @@ describe("Snowplow Analytics Class", () => {
451
459
  };
452
460
 
453
461
  expect(trackUnstructEventSpy).toHaveBeenCalledTimes(1);
454
- expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload);
462
+ expect(trackUnstructEventSpy).toHaveBeenCalledWith(expectedPayload, [
463
+ "distributionChannelContext",
464
+ ]);
455
465
  expect(innerSpy).toHaveBeenCalledTimes(1);
456
466
  expect(innerSpy).toHaveBeenCalledWith(
457
467
  {
458
468
  event: expectedPayload,
459
- context: contexts,
469
+ context: fqaContext,
460
470
  },
461
471
  ["sb-ava"],
462
472
  );
@@ -50,12 +50,15 @@ export type LinkType = Record<string, string> & {
50
50
  elementContent: string;
51
51
  };
52
52
 
53
+ export type SerialisedEvent = SelfDescribingJson<Record<string, unknown>>;
54
+
53
55
  export type EventDefinition = {
54
56
  name: string;
55
57
  type: "structured" | "unstructured";
56
58
  makePayload: (
57
59
  params?: Record<string, unknown>,
58
- ) => StructuredEvent | SelfDescribingJson<Record<string, unknown>>;
60
+ ) => StructuredEvent | SerialisedEvent;
61
+ contexts?: string[];
59
62
  };
60
63
 
61
64
  export interface PageDataProps