coveo.analytics 2.30.55 → 2.31.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 (86) hide show
  1. package/README.md +37 -43
  2. package/dist/browser.mjs +525 -357
  3. package/dist/coveoua.browser.js +1 -1
  4. package/dist/coveoua.browser.js.map +1 -1
  5. package/dist/coveoua.debug.js +559 -359
  6. package/dist/coveoua.debug.js.map +1 -1
  7. package/dist/coveoua.js +1 -1
  8. package/dist/coveoua.js.map +1 -1
  9. package/dist/definitions/client/analytics.d.ts +3 -2
  10. package/dist/definitions/client/runtimeEnvironment.d.ts +1 -1
  11. package/dist/definitions/donottrack.d.ts +1 -0
  12. package/dist/definitions/react-native/index.d.ts +1 -1
  13. package/dist/definitions/searchPage/searchPageClient.d.ts +3 -1
  14. package/dist/definitions/searchPage/searchPageEvents.d.ts +6 -0
  15. package/dist/definitions/version.d.ts +1 -1
  16. package/dist/library.cjs +15367 -3699
  17. package/dist/library.es.js +525 -357
  18. package/dist/library.js +15367 -3699
  19. package/dist/library.mjs +15367 -3699
  20. package/dist/react-native.es.js +646 -460
  21. package/modules/package.json +9 -9
  22. package/package.json +60 -91
  23. package/react-native/package.json +7 -7
  24. package/src/caseAssist/caseAssistActions.ts +51 -50
  25. package/src/caseAssist/caseAssistClient.spec.ts +328 -297
  26. package/src/caseAssist/caseAssistClient.ts +201 -185
  27. package/src/client/analytics.spec.ts +724 -703
  28. package/src/client/analytics.ts +677 -602
  29. package/src/client/analyticsBeaconClient.spec.ts +195 -188
  30. package/src/client/analyticsBeaconClient.ts +99 -88
  31. package/src/client/analyticsFetchClient.ts +77 -61
  32. package/src/client/analyticsRequestClient.ts +17 -17
  33. package/src/client/location.ts +3 -3
  34. package/src/client/measurementProtocolMapper.ts +54 -45
  35. package/src/client/measurementProtocolMapping/baseMeasurementProtocolMapper.ts +48 -44
  36. package/src/client/measurementProtocolMapping/commerceMeasurementProtocolMapper.ts +133 -121
  37. package/src/client/measurementProtocolMapping/serviceMeasurementProtocolMapper.ts +17 -17
  38. package/src/client/noopAnalytics.ts +80 -68
  39. package/src/client/runtimeEnvironment.ts +50 -41
  40. package/src/client/utils.spec.ts +112 -97
  41. package/src/client/utils.ts +39 -39
  42. package/src/cookieutils.spec.ts +59 -0
  43. package/src/cookieutils.ts +40 -39
  44. package/src/coveoua/browser.ts +14 -12
  45. package/src/coveoua/library.ts +4 -4
  46. package/src/coveoua/plugins.ts +36 -34
  47. package/src/coveoua/simpleanalytics.spec.ts +467 -452
  48. package/src/coveoua/simpleanalytics.ts +146 -140
  49. package/src/detector.ts +17 -17
  50. package/src/donottrack.spec.ts +199 -121
  51. package/src/donottrack.ts +31 -8
  52. package/src/events.ts +86 -79
  53. package/src/formatting/format-array-for-coveo-custom-data.spec.ts +13 -12
  54. package/src/formatting/format-array-for-coveo-custom-data.ts +18 -18
  55. package/src/formatting/format-omnibox-metadata.ts +16 -12
  56. package/src/history.spec.ts +197 -195
  57. package/src/history.ts +143 -133
  58. package/src/hook/addDefaultValues.ts +13 -8
  59. package/src/hook/enhanceViewEvent.ts +17 -17
  60. package/src/insight/insightClient.spec.ts +1848 -1717
  61. package/src/insight/insightClient.ts +866 -761
  62. package/src/insight/insightEvents.ts +57 -56
  63. package/src/plugins/BasePlugin.ts +125 -121
  64. package/src/plugins/ec.spec.ts +457 -429
  65. package/src/plugins/ec.ts +202 -199
  66. package/src/plugins/link.spec.ts +183 -159
  67. package/src/plugins/link.ts +88 -85
  68. package/src/plugins/svc.spec.ts +161 -155
  69. package/src/plugins/svc.ts +93 -91
  70. package/src/react-native/index.ts +5 -1
  71. package/src/react-native/react-native-runtime.ts +33 -33
  72. package/src/react-native/react-native-utils.ts +1 -1
  73. package/src/react-native/react-native.spec.ts +22 -21
  74. package/src/searchPage/searchPageClient.spec.ts +1944 -1766
  75. package/src/searchPage/searchPageClient.ts +1261 -1029
  76. package/src/searchPage/searchPageEvents.ts +529 -500
  77. package/src/storage.spec.ts +51 -51
  78. package/src/storage.ts +47 -47
  79. package/dist/definitions/bundle/browser-fetch.d.ts +0 -1
  80. package/dist/definitions/src/coveoua/browser.d.ts +0 -6
  81. package/dist/definitions/src/coveoua/headless.d.ts +0 -6
  82. package/dist/definitions/src/coveoua/library.d.ts +0 -17
  83. package/dist/definitions/src/coveoua/plugins.d.ts +0 -10
  84. package/dist/definitions/src/coveoua/simpleanalytics.d.ts +0 -33
  85. package/dist/definitions/src/react-native/index.d.ts +0 -3
  86. package/dist/definitions/src/react-native/react-native-runtime.d.ts +0 -19
@@ -1,559 +1,587 @@
1
+ import {vi} from 'vitest';
1
2
  import {ECPlugin, ECPluginEventTypes, Product} from './ec';
2
3
  import {createAnalyticsClientMock} from '../../tests/analyticsClientMock';
3
4
 
4
5
  describe('EC plugin', () => {
5
- let ec: ECPlugin;
6
- let client: ReturnType<typeof createAnalyticsClientMock>;
7
-
8
- const someUUIDGenerator = jest.fn(() => someUUID);
9
- const someUUID = '13ccebdb-0138-45e8-bf70-884817ead190';
10
- const defaultResult = {
11
- pageViewId: someUUID,
12
- encoding: document.characterSet,
13
- location: 'http://localhost/',
14
- referrer: 'http://somewhere.over/thereferrer',
15
- title: 'MAH PAGE',
16
- screenColor: '24-bit',
17
- screenResolution: '0x0',
18
- time: expect.any(Number),
19
- userAgent: navigator.userAgent,
20
- language: 'en-US',
21
- hitType: ECPluginEventTypes.event,
22
- eventId: someUUID,
23
- };
24
-
25
- beforeEach(() => {
26
- jest.clearAllMocks();
27
- client = createAnalyticsClientMock();
28
- ec = new ECPlugin({client, uuidGenerator: someUUIDGenerator as any});
6
+ let ec: ECPlugin;
7
+ let client: ReturnType<typeof createAnalyticsClientMock>;
8
+
9
+ const someUUIDGenerator = vi.fn(() => someUUID);
10
+ const someUUID = '13ccebdb-0138-45e8-bf70-884817ead190';
11
+ const defaultResult = {
12
+ pageViewId: someUUID,
13
+ encoding: document.characterSet,
14
+ location: 'http://localhost/',
15
+ referrer: 'http://somewhere.over/thereferrer',
16
+ title: 'MAH PAGE',
17
+ screenColor: '24-bit',
18
+ screenResolution: '0x0',
19
+ time: expect.any(Number),
20
+ userAgent: navigator.userAgent,
21
+ language: 'en-US',
22
+ hitType: ECPluginEventTypes.event,
23
+ eventId: someUUID,
24
+ };
25
+
26
+ beforeEach(() => {
27
+ vi.clearAllMocks();
28
+ client = createAnalyticsClientMock();
29
+ ec = new ECPlugin({client, uuidGenerator: someUUIDGenerator as any});
30
+ });
31
+
32
+ it('should register a hook in the client', () => {
33
+ expect(client.registerBeforeSendEventHook).toHaveBeenCalledTimes(1);
34
+ });
35
+
36
+ it('should register a mapping for each EC type', () => {
37
+ expect(client.addEventTypeMapping).toHaveBeenCalledTimes(
38
+ Object.keys(ECPluginEventTypes).length
39
+ );
40
+ });
41
+
42
+ describe('products', () => {
43
+ it('should append the product with the specific format when the hook is called', () => {
44
+ ec.addProduct({id: 'C0V30'});
45
+
46
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
47
+
48
+ expect(result).toEqual({...defaultResult, pr1id: 'C0V30'});
29
49
  });
30
50
 
31
- it('should register a hook in the client', () => {
32
- expect(client.registerBeforeSendEventHook).toHaveBeenCalledTimes(1);
33
- });
51
+ it('should append the product with the pageview event', () => {
52
+ ec.addProduct({name: 'Relevance T-Shirt'});
34
53
 
35
- it('should register a mapping for each EC type', () => {
36
- expect(client.addEventTypeMapping).toHaveBeenCalledTimes(Object.keys(ECPluginEventTypes).length);
54
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
55
+
56
+ expect(result).toEqual({...defaultResult, pr1nm: 'Relevance T-Shirt'});
37
57
  });
38
58
 
39
- describe('products', () => {
40
- it('should append the product with the specific format when the hook is called', () => {
41
- ec.addProduct({id: 'C0V30'});
59
+ it('should not append the product with a random event type', () => {
60
+ ec.addProduct({id: ':testProductId:'});
42
61
 
43
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
62
+ const result = executeRegisteredHook('🎲', {});
44
63
 
45
- expect(result).toEqual({...defaultResult, pr1id: 'C0V30'});
46
- });
64
+ expect(result).toEqual({});
65
+ });
47
66
 
48
- it('should append the product with the pageview event', () => {
49
- ec.addProduct({name: 'Relevance T-Shirt'});
67
+ it('should keep the products until a valid event type is used', () => {
68
+ ec.addProduct({id: 'P12345'});
50
69
 
51
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
70
+ executeRegisteredHook('🎲', {});
71
+ executeRegisteredHook('🐟', {});
72
+ executeRegisteredHook('💀', {});
73
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
52
74
 
53
- expect(result).toEqual({...defaultResult, pr1nm: 'Relevance T-Shirt'});
54
- });
75
+ expect(result).toEqual({...defaultResult, pr1id: 'P12345'});
76
+ });
55
77
 
56
- it('should not append the product with a random event type', () => {
57
- ec.addProduct({id: ':sorandom:'});
78
+ it('should convert known product keys into the measurement protocol format', () => {
79
+ ec.addProduct({name: '🧀', price: 5.99});
58
80
 
59
- const result = executeRegisteredHook('🎲', {});
81
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
60
82
 
61
- expect(result).toEqual({});
62
- });
83
+ expect(result).toEqual({...defaultResult, pr1nm: '🧀', pr1pr: 5.99});
84
+ });
63
85
 
64
- it('should keep the products until a valid event type is used', () => {
65
- ec.addProduct({id: 'P12345'});
86
+ it('should keep custom metadata in the product', () => {
87
+ ec.addProduct({name: '🧀', price: 5.99, custom: {verycustom: 'value'}});
66
88
 
67
- executeRegisteredHook('🎲', {});
68
- executeRegisteredHook('🐟', {});
69
- executeRegisteredHook('💀', {});
70
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
89
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
71
90
 
72
- expect(result).toEqual({...defaultResult, pr1id: 'P12345'});
73
- });
91
+ expect(result).toEqual({
92
+ ...defaultResult,
93
+ pr1nm: '🧀',
94
+ pr1pr: 5.99,
95
+ pr1custom: {verycustom: 'value'},
96
+ });
97
+ });
74
98
 
75
- it('should convert known product keys into the measurement protocol format', () => {
76
- ec.addProduct({name: '🧀', price: 5.99});
99
+ it('should allow adding multiple products', () => {
100
+ ec.addProduct({name: '🍟', price: 1.99});
101
+ ec.addProduct({name: '🍿', price: 3});
102
+ ec.addProduct({name: '🥤', price: 2});
103
+
104
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
105
+
106
+ expect(result).toEqual({
107
+ ...defaultResult,
108
+ pr1nm: '🍟',
109
+ pr1pr: 1.99,
110
+ pr2nm: '🍿',
111
+ pr2pr: 3,
112
+ pr3nm: '🥤',
113
+ pr3pr: 2,
114
+ });
115
+ });
77
116
 
78
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
117
+ it('should flush the products once they are sent', () => {
118
+ ec.addProduct({name: '🍟', price: 1.99});
119
+ ec.addProduct({name: '🍿', price: 3});
79
120
 
80
- expect(result).toEqual({...defaultResult, pr1nm: '🧀', pr1pr: 5.99});
81
- });
121
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
82
122
 
83
- it('should keep custom metadata in the product', () => {
84
- ec.addProduct({name: '🧀', price: 5.99, custom: {verycustom: 'value'}});
123
+ expect(result).not.toEqual({});
85
124
 
86
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
125
+ const secondResult = executeRegisteredHook(ECPluginEventTypes.event, {});
87
126
 
88
- expect(result).toEqual({...defaultResult, pr1nm: '🧀', pr1pr: 5.99, pr1custom: {verycustom: 'value'}});
89
- });
127
+ expect(secondResult).toEqual({...defaultResult});
128
+ });
90
129
 
91
- it('should allow adding multiple products', () => {
92
- ec.addProduct({name: '🍟', price: 1.99});
93
- ec.addProduct({name: '🍿', price: 3});
94
- ec.addProduct({name: '🥤', price: 2});
95
-
96
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
97
-
98
- expect(result).toEqual({
99
- ...defaultResult,
100
- pr1nm: '🍟',
101
- pr1pr: 1.99,
102
- pr2nm: '🍿',
103
- pr2pr: 3,
104
- pr3nm: '🥤',
105
- pr3pr: 2,
106
- });
107
- });
130
+ it('should convert position to number if possible', () => {
131
+ const validValues = ['13', '5.5'];
132
+ for (const value of validValues) {
133
+ // @ts-ignore
134
+ ec.addProduct({name: 'product', position: value});
108
135
 
109
- it('should flush the products once they are sent', () => {
110
- ec.addProduct({name: '🍟', price: 1.99});
111
- ec.addProduct({name: '🍿', price: 3});
136
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
137
+ const expected: Record<string, any> = {
138
+ ...defaultResult,
139
+ pr1nm: 'product',
140
+ pr1ps: +value,
141
+ };
112
142
 
113
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
143
+ expect(result).toEqual(expected);
144
+ }
145
+ });
114
146
 
115
- expect(result).not.toEqual({});
147
+ it('should keep original value if position is not a number', () => {
148
+ const invalidValues = ['1-2-3', '.', '-', '123abc'];
149
+ for (const value of invalidValues) {
150
+ // @ts-ignore
151
+ ec.addProduct({name: 'product', position: value});
116
152
 
117
- const secondResult = executeRegisteredHook(ECPluginEventTypes.event, {});
153
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
154
+ const expected: Record<string, unknown> = {
155
+ ...defaultResult,
156
+ pr1nm: 'product',
157
+ pr1ps: value,
158
+ };
118
159
 
119
- expect(secondResult).toEqual({...defaultResult});
120
- });
160
+ expect(result).toEqual(expected);
161
+ }
162
+ });
121
163
 
122
- it('should convert position to number if possible', () => {
123
- const validValues = ['13', '5.5'];
124
- for (const value of validValues) {
125
- // @ts-ignore
126
- ec.addProduct({name: 'product', position: value});
164
+ it('should convert quantity to number if possible', () => {
165
+ const validValues = ['13', '0', '.0', '-10', '5.0', '-1.1', '3.124e7'];
166
+ for (const value of validValues) {
167
+ // @ts-ignore
168
+ ec.addProduct({name: 'product', quantity: value});
127
169
 
128
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
129
- const expected: Record<string, any> = {...defaultResult, pr1nm: 'product', pr1ps: +value};
170
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
171
+ const expected: Record<string, any> = {
172
+ ...defaultResult,
173
+ pr1nm: 'product',
174
+ pr1qt: +value,
175
+ };
130
176
 
131
- expect(result).toEqual(expected);
132
- }
133
- });
177
+ expect(result).toEqual(expected);
178
+ }
179
+ });
134
180
 
135
- it('should keep original value if position is not a number', () => {
136
- const invalidValues = ['1-2-3', '.', '-', '123abc'];
137
- for (const value of invalidValues) {
138
- // @ts-ignore
139
- ec.addProduct({name: 'product', position: value});
181
+ it('should keep original value if quantity is not a number', () => {
182
+ const invalidValues = ['1-2-3', '', '.', '5..', '-', '123abc', 'abc123'];
183
+ for (const value of invalidValues) {
184
+ // @ts-ignore
185
+ ec.addProduct({name: 'product', quantity: value});
140
186
 
141
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
142
- const expected: Record<string, unknown> = {...defaultResult, pr1nm: 'product', pr1ps: value};
187
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
188
+ const expected: Record<string, unknown> = {
189
+ ...defaultResult,
190
+ pr1nm: 'product',
191
+ pr1qt: value,
192
+ };
143
193
 
144
- expect(result).toEqual(expected);
145
- }
146
- });
194
+ expect(result).toEqual(expected);
195
+ }
196
+ });
147
197
 
148
- it('should convert quantity to number if possible', () => {
149
- const validValues = ['13', '0', '.0', '-10', '5.0', '-1.1', '3.124e7'];
150
- for (const value of validValues) {
151
- // @ts-ignore
152
- ec.addProduct({name: 'product', quantity: value});
198
+ describe('when the position is invalid', () => {
199
+ it('should warn when executing hook on added product', () => {
200
+ vi.spyOn(console, 'warn').mockImplementation();
153
201
 
154
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
155
- const expected: Record<string, any> = {...defaultResult, pr1nm: 'product', pr1qt: +value};
202
+ const aProductWithATooSmallPosition = {
203
+ name: 'A product with a too small position',
204
+ position: 0,
205
+ };
156
206
 
157
- expect(result).toEqual(expected);
158
- }
159
- });
207
+ ec.addProduct(aProductWithATooSmallPosition);
160
208
 
161
- it('should keep original value if quantity is not a number', () => {
162
- const invalidValues = ['1-2-3', '', '.', '5..', '-', '123abc', 'abc123'];
163
- for (const value of invalidValues) {
164
- // @ts-ignore
165
- ec.addProduct({name: 'product', quantity: value});
209
+ expect(console.warn).not.toHaveBeenCalled();
166
210
 
167
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
168
- const expected: Record<string, unknown> = {...defaultResult, pr1nm: 'product', pr1qt: value};
211
+ executeRegisteredHook(ECPluginEventTypes.event, {});
169
212
 
170
- expect(result).toEqual(expected);
171
- }
172
- });
213
+ expect(console.warn).toHaveBeenCalledWith(
214
+ `The position for product '${aProductWithATooSmallPosition.name}' must be greater than 0 when provided.`
215
+ );
216
+ expect(console.warn).toHaveBeenCalledTimes(1);
217
+ });
173
218
 
174
- describe('when the position is invalid', () => {
175
- it('should warn when executing hook on added product', () => {
176
- jest.spyOn(console, 'warn').mockImplementation();
219
+ it('should remove the position when executing hook on added product', () => {
220
+ vi.spyOn(console, 'warn').mockImplementation();
177
221
 
178
- const aProductWithATooSmallPosition = {
179
- name: 'A product with a too small position',
180
- position: 0,
181
- };
222
+ ec.addProduct({
223
+ name: 'A product with a too small position',
224
+ position: 0,
225
+ });
182
226
 
183
- ec.addProduct(aProductWithATooSmallPosition);
227
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
184
228
 
185
- expect(console.warn).not.toHaveBeenCalled();
229
+ const positionProperty = 'il1pi1ps';
230
+ expect(result).not.toHaveProperty(positionProperty);
231
+ });
186
232
 
187
- executeRegisteredHook(ECPluginEventTypes.event, {});
233
+ it('should warn first using the product name then the id', () => {
234
+ vi.spyOn(console, 'warn').mockImplementation();
188
235
 
189
- expect(console.warn).toHaveBeenCalledWith(
190
- `The position for product '${aProductWithATooSmallPosition.name}' must be greater than 0 when provided.`,
191
- );
192
- expect(console.warn).toHaveBeenCalledTimes(1);
193
- });
236
+ const aProductWithANameAndId = {
237
+ name: 'A product with a name and id',
238
+ id: 'A product id',
239
+ position: 0,
240
+ };
241
+ const aProductWithOnlyAnId = {
242
+ id: 'A product id',
243
+ position: 0,
244
+ };
194
245
 
195
- it('should remove the position when executing hook on added product', () => {
196
- jest.spyOn(console, 'warn').mockImplementation();
246
+ ec.addProduct(aProductWithANameAndId);
247
+ ec.addProduct(aProductWithOnlyAnId);
197
248
 
198
- ec.addProduct({
199
- name: 'A product with a too small position',
200
- position: 0,
201
- });
249
+ executeRegisteredHook(ECPluginEventTypes.event, {});
202
250
 
203
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
251
+ expect(console.warn).toHaveBeenNthCalledWith(
252
+ 1,
253
+ `The position for product '${aProductWithANameAndId.name}' must be greater than 0 when provided.`
254
+ );
255
+ expect(console.warn).toHaveBeenNthCalledWith(
256
+ 2,
257
+ `The position for product '${aProductWithOnlyAnId.id}' must be greater than 0 when provided.`
258
+ );
259
+ });
204
260
 
205
- const positionProperty = 'il1pi1ps';
206
- expect(result).not.toHaveProperty(positionProperty);
207
- });
261
+ it('should tolerate an absent or undefined position', () => {
262
+ vi.spyOn(console, 'warn').mockImplementation();
208
263
 
209
- it('should warn first using the product name then the id', () => {
210
- jest.spyOn(console, 'warn').mockImplementation();
264
+ ec.addProduct({
265
+ name: 'A product with no position',
266
+ });
211
267
 
212
- const aProductWithANameAndId = {
213
- name: 'A product with a name and id',
214
- id: 'A product id',
215
- position: 0,
216
- };
217
- const aProductWithOnlyAnId = {
218
- id: 'A product id',
219
- position: 0,
220
- };
268
+ ec.addProduct({
269
+ name: 'A product with an undefined position',
270
+ position: undefined,
271
+ });
221
272
 
222
- ec.addProduct(aProductWithANameAndId);
223
- ec.addProduct(aProductWithOnlyAnId);
273
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
224
274
 
225
- executeRegisteredHook(ECPluginEventTypes.event, {});
275
+ expect(console.warn).not.toHaveBeenCalled();
276
+ expect(result).not.toHaveProperty('pr1ps');
277
+ expect(result).toHaveProperty('pr2ps', undefined);
278
+ });
279
+ });
280
+ });
226
281
 
227
- expect(console.warn).toHaveBeenNthCalledWith(
228
- 1,
229
- `The position for product '${aProductWithANameAndId.name}' must be greater than 0 when provided.`,
230
- );
231
- expect(console.warn).toHaveBeenNthCalledWith(
232
- 2,
233
- `The position for product '${aProductWithOnlyAnId.id}' must be greater than 0 when provided.`,
234
- );
235
- });
282
+ describe('impressions', () => {
283
+ it('should append the impression with the specific format when the hook is called', () => {
284
+ ec.addImpression({id: 'C0V30'});
236
285
 
237
- it('should tolerate an absent or undefined position', () => {
238
- jest.spyOn(console, 'warn').mockImplementation();
286
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
239
287
 
240
- ec.addProduct({
241
- name: 'A product with no position',
242
- });
288
+ expect(result).toEqual({...defaultResult, il1pi1id: 'C0V30'});
289
+ });
243
290
 
244
- ec.addProduct({
245
- name: 'A product with an undefined position',
246
- position: undefined,
247
- });
291
+ it('should append the impression with the pageview event', () => {
292
+ ec.addImpression({name: 'Relevance T-Shirt'});
248
293
 
249
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
294
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
250
295
 
251
- expect(console.warn).not.toHaveBeenCalled();
252
- expect(result).not.toHaveProperty('pr1ps');
253
- expect(result).toHaveProperty('pr2ps', undefined);
254
- });
255
- });
296
+ expect(result).toEqual({
297
+ ...defaultResult,
298
+ il1pi1nm: 'Relevance T-Shirt',
299
+ });
256
300
  });
257
301
 
258
- describe('impressions', () => {
259
- it('should append the impression with the specific format when the hook is called', () => {
260
- ec.addImpression({id: 'C0V30'});
302
+ it('should not append the impression with a random event type', () => {
303
+ ec.addImpression({id: ':testProductId:'});
261
304
 
262
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
305
+ const result = executeRegisteredHook('🎲', {});
263
306
 
264
- expect(result).toEqual({...defaultResult, il1pi1id: 'C0V30'});
265
- });
307
+ expect(result).toEqual({});
308
+ });
266
309
 
267
- it('should append the impression with the pageview event', () => {
268
- ec.addImpression({name: 'Relevance T-Shirt'});
310
+ it('should keep the impressions until a valid event type is used', () => {
311
+ ec.addImpression({id: 'P12345'});
269
312
 
270
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
313
+ executeRegisteredHook('🎲', {});
314
+ executeRegisteredHook('🐟', {});
315
+ executeRegisteredHook('💀', {});
316
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
271
317
 
272
- expect(result).toEqual({
273
- ...defaultResult,
274
- il1pi1nm: 'Relevance T-Shirt',
275
- });
276
- });
318
+ expect(result).toEqual({...defaultResult, il1pi1id: 'P12345'});
319
+ });
277
320
 
278
- it('should not append the impression with a random event type', () => {
279
- ec.addImpression({id: ':sorandom:'});
321
+ it('should convert known impression keys into the measurement protocol format', () => {
322
+ ec.addImpression({name: '🧀', price: 5.99});
280
323
 
281
- const result = executeRegisteredHook('🎲', {});
324
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
282
325
 
283
- expect(result).toEqual({});
284
- });
326
+ expect(result).toEqual({
327
+ ...defaultResult,
328
+ il1pi1nm: '🧀',
329
+ il1pi1pr: 5.99,
330
+ });
331
+ });
285
332
 
286
- it('should keep the impressions until a valid event type is used', () => {
287
- ec.addImpression({id: 'P12345'});
333
+ it('should convert known impression keys that are extended for Coveo into the measurement protocol format', () => {
334
+ ec.addImpression({name: '🧀', group: 'testGroup'});
288
335
 
289
- executeRegisteredHook('🎲', {});
290
- executeRegisteredHook('🐟', {});
291
- executeRegisteredHook('💀', {});
292
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
336
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
293
337
 
294
- expect(result).toEqual({...defaultResult, il1pi1id: 'P12345'});
295
- });
338
+ expect(result).toEqual({
339
+ ...defaultResult,
340
+ il1pi1nm: '🧀',
341
+ il1pi1group: 'testGroup',
342
+ });
343
+ });
296
344
 
297
- it('should convert known impression keys into the measurement protocol format', () => {
298
- ec.addImpression({name: '🧀', price: 5.99});
345
+ it('should keep custom metadata in the impression', () => {
346
+ ec.addImpression({
347
+ name: '🧀',
348
+ price: 5.99,
349
+ custom: {verycustom: 'value'},
350
+ });
351
+
352
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
353
+
354
+ expect(result).toEqual({
355
+ ...defaultResult,
356
+ il1pi1nm: '🧀',
357
+ il1pi1pr: 5.99,
358
+ il1pi1custom: {verycustom: 'value'},
359
+ });
360
+ });
299
361
 
300
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
362
+ it('should allow adding multiple impressions', () => {
363
+ ec.addImpression({name: '🍟', price: 1.99});
364
+ ec.addImpression({name: '🍿', price: 3});
365
+ ec.addImpression({name: '🥤', price: 2});
366
+
367
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
368
+
369
+ expect(result).toEqual({
370
+ ...defaultResult,
371
+ il1pi1nm: '🍟',
372
+ il1pi1pr: 1.99,
373
+ il1pi2nm: '🍿',
374
+ il1pi2pr: 3,
375
+ il1pi3nm: '🥤',
376
+ il1pi3pr: 2,
377
+ });
378
+ });
301
379
 
302
- expect(result).toEqual({
303
- ...defaultResult,
304
- il1pi1nm: '🧀',
305
- il1pi1pr: 5.99,
306
- });
307
- });
380
+ it('should allow adding impressions from multiple lists', () => {
381
+ ec.addImpression({list: 'food', name: '🍟', price: 1.99});
382
+ ec.addImpression({list: 'food', name: '🍿', price: 3});
383
+ ec.addImpression({list: 'drinks', name: '🥤', price: 2});
384
+ ec.addImpression({list: 'drinks', name: '🧃', price: 0.99});
385
+
386
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
387
+
388
+ expect(result).toEqual({
389
+ ...defaultResult,
390
+ il1nm: 'food',
391
+ il1pi1nm: '🍟',
392
+ il1pi1pr: 1.99,
393
+ il1pi2nm: '🍿',
394
+ il1pi2pr: 3,
395
+ il2nm: 'drinks',
396
+ il2pi1nm: '🥤',
397
+ il2pi1pr: 2,
398
+ il2pi2nm: '🧃',
399
+ il2pi2pr: 0.99,
400
+ });
401
+ });
308
402
 
309
- it('should convert known impression keys that are extended for Coveo into the measurement protocol format', () => {
310
- ec.addImpression({name: '🧀', group: 'mahgroup'});
403
+ it('should flush the products once they are sent', () => {
404
+ ec.addImpression({name: '🍟', price: 1.99});
405
+ ec.addImpression({name: '🍿', price: 3});
311
406
 
312
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
407
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
313
408
 
314
- expect(result).toEqual({
315
- ...defaultResult,
316
- il1pi1nm: '🧀',
317
- il1pi1group: 'mahgroup',
318
- });
319
- });
409
+ expect(result).not.toEqual({});
320
410
 
321
- it('should keep custom metadata in the impression', () => {
322
- ec.addImpression({name: '🧀', price: 5.99, custom: {verycustom: 'value'}});
411
+ const secondResult = executeRegisteredHook(ECPluginEventTypes.event, {});
323
412
 
324
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
413
+ expect(secondResult).toEqual({...defaultResult});
414
+ });
325
415
 
326
- expect(result).toEqual({
327
- ...defaultResult,
328
- il1pi1nm: '🧀',
329
- il1pi1pr: 5.99,
330
- il1pi1custom: {verycustom: 'value'},
331
- });
332
- });
416
+ describe('when the position is invalid', () => {
417
+ it('should warn when executing hook on added impression', () => {
418
+ vi.spyOn(console, 'warn').mockImplementation();
333
419
 
334
- it('should allow adding multiple impressions', () => {
335
- ec.addImpression({name: '🍟', price: 1.99});
336
- ec.addImpression({name: '🍿', price: 3});
337
- ec.addImpression({name: '🥤', price: 2});
338
-
339
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
340
-
341
- expect(result).toEqual({
342
- ...defaultResult,
343
- il1pi1nm: '🍟',
344
- il1pi1pr: 1.99,
345
- il1pi2nm: '🍿',
346
- il1pi2pr: 3,
347
- il1pi3nm: '🥤',
348
- il1pi3pr: 2,
349
- });
350
- });
420
+ const anImpression = {
421
+ name: 'An impression with a too small position',
422
+ position: 0,
423
+ };
351
424
 
352
- it('should allow adding impressions from multiple lists', () => {
353
- ec.addImpression({list: 'food', name: '🍟', price: 1.99});
354
- ec.addImpression({list: 'food', name: '🍿', price: 3});
355
- ec.addImpression({list: 'drinks', name: '🥤', price: 2});
356
- ec.addImpression({list: 'drinks', name: '🧃', price: 0.99});
357
-
358
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
359
-
360
- expect(result).toEqual({
361
- ...defaultResult,
362
- il1nm: 'food',
363
- il1pi1nm: '🍟',
364
- il1pi1pr: 1.99,
365
- il1pi2nm: '🍿',
366
- il1pi2pr: 3,
367
- il2nm: 'drinks',
368
- il2pi1nm: '🥤',
369
- il2pi1pr: 2,
370
- il2pi2nm: '🧃',
371
- il2pi2pr: 0.99,
372
- });
373
- });
425
+ ec.addImpression(anImpression);
374
426
 
375
- it('should flush the products once they are sent', () => {
376
- ec.addImpression({name: '🍟', price: 1.99});
377
- ec.addImpression({name: '🍿', price: 3});
427
+ expect(console.warn).not.toHaveBeenCalled();
378
428
 
379
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
429
+ executeRegisteredHook(ECPluginEventTypes.event, {});
380
430
 
381
- expect(result).not.toEqual({});
431
+ expect(console.warn).toHaveBeenCalledWith(
432
+ `The position for impression '${anImpression.name}' must be greater than 0 when provided.`
433
+ );
434
+ expect(console.warn).toHaveBeenCalledTimes(1);
435
+ });
382
436
 
383
- const secondResult = executeRegisteredHook(ECPluginEventTypes.event, {});
437
+ it('should remove the position when executing hook on added impression', () => {
438
+ vi.spyOn(console, 'warn').mockImplementation();
384
439
 
385
- expect(secondResult).toEqual({...defaultResult});
440
+ ec.addImpression({
441
+ name: 'An impression with a too small position',
442
+ position: 0,
386
443
  });
387
444
 
388
- describe('when the position is invalid', () => {
389
- it('should warn when executing hook on added impression', () => {
390
- jest.spyOn(console, 'warn').mockImplementation();
391
-
392
- const anImpression = {
393
- name: 'An impression with a too small position',
394
- position: 0,
395
- };
396
-
397
- ec.addImpression(anImpression);
398
-
399
- expect(console.warn).not.toHaveBeenCalled();
400
-
401
- executeRegisteredHook(ECPluginEventTypes.event, {});
402
-
403
- expect(console.warn).toHaveBeenCalledWith(
404
- `The position for impression '${anImpression.name}' must be greater than 0 when provided.`,
405
- );
406
- expect(console.warn).toHaveBeenCalledTimes(1);
407
- });
408
-
409
- it('should remove the position when executing hook on added impression', () => {
410
- jest.spyOn(console, 'warn').mockImplementation();
411
-
412
- ec.addImpression({
413
- name: 'An impression with a too small position',
414
- position: 0,
415
- });
416
-
417
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
445
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
418
446
 
419
- const positionProperty = 'il1pi1ps';
420
- expect(result).not.toHaveProperty(positionProperty);
421
- });
447
+ const positionProperty = 'il1pi1ps';
448
+ expect(result).not.toHaveProperty(positionProperty);
449
+ });
422
450
 
423
- it('should warn first using the impression name then the id', () => {
424
- jest.spyOn(console, 'warn').mockImplementation();
451
+ it('should warn first using the impression name then the id', () => {
452
+ vi.spyOn(console, 'warn').mockImplementation();
425
453
 
426
- const anImpressionWithANameAndId = {
427
- name: 'An impression with a name and id',
428
- id: 'An id',
429
- position: 0,
430
- };
431
- const anImpressionWithOnlyAnId = {
432
- id: 'An id',
433
- position: 0,
434
- };
454
+ const anImpressionWithANameAndId = {
455
+ name: 'An impression with a name and id',
456
+ id: 'An id',
457
+ position: 0,
458
+ };
459
+ const anImpressionWithOnlyAnId = {
460
+ id: 'An id',
461
+ position: 0,
462
+ };
435
463
 
436
- ec.addImpression(anImpressionWithANameAndId);
437
- ec.addImpression(anImpressionWithOnlyAnId);
464
+ ec.addImpression(anImpressionWithANameAndId);
465
+ ec.addImpression(anImpressionWithOnlyAnId);
438
466
 
439
- executeRegisteredHook(ECPluginEventTypes.event, {});
467
+ executeRegisteredHook(ECPluginEventTypes.event, {});
440
468
 
441
- expect(console.warn).toHaveBeenNthCalledWith(
442
- 1,
443
- `The position for impression '${anImpressionWithANameAndId.name}' must be greater than 0 when provided.`,
444
- );
445
- expect(console.warn).toHaveBeenNthCalledWith(
446
- 2,
447
- `The position for impression '${anImpressionWithOnlyAnId.id}' must be greater than 0 when provided.`,
448
- );
449
- });
469
+ expect(console.warn).toHaveBeenNthCalledWith(
470
+ 1,
471
+ `The position for impression '${anImpressionWithANameAndId.name}' must be greater than 0 when provided.`
472
+ );
473
+ expect(console.warn).toHaveBeenNthCalledWith(
474
+ 2,
475
+ `The position for impression '${anImpressionWithOnlyAnId.id}' must be greater than 0 when provided.`
476
+ );
477
+ });
450
478
 
451
- it('should tolerate an absent or undefined position', () => {
452
- jest.spyOn(console, 'warn').mockImplementation();
479
+ it('should tolerate an absent or undefined position', () => {
480
+ vi.spyOn(console, 'warn').mockImplementation();
453
481
 
454
- ec.addImpression({
455
- name: 'An impression with no position',
456
- });
482
+ ec.addImpression({
483
+ name: 'An impression with no position',
484
+ });
457
485
 
458
- ec.addImpression({
459
- name: 'An impression with an undefined position',
460
- position: undefined,
461
- });
486
+ ec.addImpression({
487
+ name: 'An impression with an undefined position',
488
+ position: undefined,
489
+ });
462
490
 
463
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
491
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
464
492
 
465
- expect(console.warn).not.toHaveBeenCalled();
466
- expect(result).not.toHaveProperty('il1pi1ps');
467
- expect(result).toHaveProperty('il1pi2ps', undefined);
468
- });
469
- });
493
+ expect(console.warn).not.toHaveBeenCalled();
494
+ expect(result).not.toHaveProperty('il1pi1ps');
495
+ expect(result).toHaveProperty('il1pi2ps', undefined);
496
+ });
470
497
  });
498
+ });
471
499
 
472
- it('should be able to set an action', () => {
473
- ec.setAction('ok');
500
+ it('should be able to set an action', () => {
501
+ ec.setAction('ok');
474
502
 
475
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
503
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
476
504
 
477
- expect(result).toEqual({
478
- ...defaultResult,
479
- action: 'ok',
480
- });
505
+ expect(result).toEqual({
506
+ ...defaultResult,
507
+ action: 'ok',
481
508
  });
509
+ });
482
510
 
483
- it('should flush the action once it is sent', () => {
484
- ec.setAction('ok');
511
+ it('should flush the action once it is sent', () => {
512
+ ec.setAction('ok');
485
513
 
486
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
514
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
487
515
 
488
- expect(result).not.toEqual({});
516
+ expect(result).not.toEqual({});
489
517
 
490
- const secondResult = executeRegisteredHook(ECPluginEventTypes.event, {});
518
+ const secondResult = executeRegisteredHook(ECPluginEventTypes.event, {});
491
519
 
492
- expect(secondResult).toEqual({...defaultResult});
493
- });
520
+ expect(secondResult).toEqual({...defaultResult});
521
+ });
494
522
 
495
- it('should be able to clear all the data', () => {
496
- ec.addProduct({name: '🍨', price: 2.99});
497
- ec.addImpression({id: '🍦', price: 3.49});
498
- ec.clearData();
523
+ it('should be able to clear all the data', () => {
524
+ ec.addProduct({name: '🍨', price: 2.99});
525
+ ec.addImpression({id: '🍦', price: 3.49});
526
+ ec.clearData();
499
527
 
500
- const result = executeRegisteredHook(ECPluginEventTypes.event, {});
528
+ const result = executeRegisteredHook(ECPluginEventTypes.event, {});
501
529
 
502
- expect(result).toEqual({...defaultResult});
503
- });
530
+ expect(result).toEqual({...defaultResult});
531
+ });
504
532
 
505
- it('should convert known EC keys to the measurement protocol format in the hook', () => {
506
- const payload = {
507
- clientId: '1234',
508
- encoding: 'en-GB',
509
- action: 'bloup',
510
- };
533
+ it('should convert known EC keys to the measurement protocol format in the hook', () => {
534
+ const payload = {
535
+ clientId: '1234',
536
+ encoding: 'en-GB',
537
+ action: 'bloup',
538
+ };
511
539
 
512
- const result = executeRegisteredHook(ECPluginEventTypes.event, payload);
540
+ const result = executeRegisteredHook(ECPluginEventTypes.event, payload);
513
541
 
514
- expect(result).toEqual({
515
- ...defaultResult,
516
- clientId: payload.clientId,
517
- encoding: payload.encoding,
518
- action: payload.action,
519
- });
542
+ expect(result).toEqual({
543
+ ...defaultResult,
544
+ clientId: payload.clientId,
545
+ encoding: payload.encoding,
546
+ action: payload.action,
520
547
  });
548
+ });
521
549
 
522
- it('should call the uuidv4 method', async () => {
523
- await executeRegisteredHook(ECPluginEventTypes.event, {});
524
- await executeRegisteredHook(ECPluginEventTypes.event, {});
525
- await executeRegisteredHook(ECPluginEventTypes.event, {});
550
+ it('should call the uuidv4 method', async () => {
551
+ await executeRegisteredHook(ECPluginEventTypes.event, {});
552
+ await executeRegisteredHook(ECPluginEventTypes.event, {});
553
+ await executeRegisteredHook(ECPluginEventTypes.event, {});
526
554
 
527
- // One for generating pageViewId, one for each individual event.
528
- expect(someUUIDGenerator).toHaveBeenCalledTimes(1 + 3);
529
- });
555
+ // One for generating pageViewId, one for each individual event.
556
+ expect(someUUIDGenerator).toHaveBeenCalledTimes(1 + 3);
557
+ });
530
558
 
531
- it('should update the location when sending a pageview with the page parameter', () => {
532
- const payload = {
533
- page: '/somepage',
534
- };
559
+ it('should update the location when sending a pageview with the page parameter', () => {
560
+ const payload = {
561
+ page: '/somepage',
562
+ };
535
563
 
536
- const pageview = executeRegisteredHook(ECPluginEventTypes.pageview, payload);
537
- const event = executeRegisteredHook(ECPluginEventTypes.event, {});
564
+ const pageview = executeRegisteredHook(ECPluginEventTypes.pageview, payload);
565
+ const event = executeRegisteredHook(ECPluginEventTypes.event, {});
538
566
 
539
- expect(pageview).toEqual({
540
- ...defaultResult,
541
- hitType: ECPluginEventTypes.pageview,
542
- page: payload.page,
543
- location: `${defaultResult.location}${payload.page.substring(1)}`,
544
- });
545
- expect(event).toEqual({
546
- ...defaultResult,
547
- hitType: ECPluginEventTypes.event,
548
- location: `${defaultResult.location}${payload.page.substring(1)}`,
549
- });
567
+ expect(pageview).toEqual({
568
+ ...defaultResult,
569
+ hitType: ECPluginEventTypes.pageview,
570
+ page: payload.page,
571
+ location: `${defaultResult.location}${payload.page.substring(1)}`,
550
572
  });
551
-
552
- const executeRegisteredHook = (eventType: string, payload: any) => {
553
- const [beforeHook] = client.registerBeforeSendEventHook.mock.calls[0];
554
- const [afterHook] = client.registerAfterSendEventHook.mock.calls[0];
555
- const result = beforeHook(eventType, payload);
556
- afterHook(eventType, result);
557
- return result;
558
- };
573
+ expect(event).toEqual({
574
+ ...defaultResult,
575
+ hitType: ECPluginEventTypes.event,
576
+ location: `${defaultResult.location}${payload.page.substring(1)}`,
577
+ });
578
+ });
579
+
580
+ const executeRegisteredHook = (eventType: string, payload: any) => {
581
+ const [beforeHook] = client.registerBeforeSendEventHook.mock.calls[0];
582
+ const [afterHook] = client.registerAfterSendEventHook.mock.calls[0];
583
+ const result = beforeHook(eventType, payload);
584
+ afterHook(eventType, result);
585
+ return result;
586
+ };
559
587
  });