@openobserve/browser-core 0.3.2 → 0.3.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 (83) hide show
  1. package/cjs/boot/init.js +1 -1
  2. package/cjs/domain/configuration/endpointBuilder.js +1 -1
  3. package/cjs/domain/tags.js +1 -1
  4. package/cjs/domain/telemetry/telemetry.js +1 -1
  5. package/cjs/domain/telemetry/telemetryEvent.types.d.ts +1 -1
  6. package/esm/boot/init.js +1 -1
  7. package/esm/domain/configuration/endpointBuilder.js +1 -1
  8. package/esm/domain/tags.js +1 -1
  9. package/esm/domain/telemetry/telemetry.js +1 -1
  10. package/esm/domain/telemetry/telemetryEvent.types.d.ts +1 -1
  11. package/package.json +2 -2
  12. package/src/domain/telemetry/telemetryEvent.types.ts +1 -1
  13. package/src/boot/displayAlreadyInitializedError.spec.ts +0 -18
  14. package/src/boot/init.spec.ts +0 -50
  15. package/src/browser/addEventListener.spec.ts +0 -141
  16. package/src/browser/cookie.spec.ts +0 -53
  17. package/src/browser/fetchObservable.spec.ts +0 -334
  18. package/src/browser/pageMayExitObservable.spec.ts +0 -56
  19. package/src/browser/xhrObservable.spec.ts +0 -405
  20. package/src/domain/allowedTrackingOrigins.spec.ts +0 -210
  21. package/src/domain/bufferedData.spec.ts +0 -34
  22. package/src/domain/configuration/configuration.spec.ts +0 -236
  23. package/src/domain/configuration/endpointBuilder.spec.ts +0 -173
  24. package/src/domain/configuration/transportConfiguration.spec.ts +0 -130
  25. package/src/domain/connectivity/connectivity.spec.ts +0 -50
  26. package/src/domain/console/consoleObservable.spec.ts +0 -151
  27. package/src/domain/context/contextManager.spec.ts +0 -152
  28. package/src/domain/context/contextUtils.spec.ts +0 -26
  29. package/src/domain/context/storeContextManager.spec.ts +0 -103
  30. package/src/domain/contexts/accountContext.spec.ts +0 -99
  31. package/src/domain/contexts/globalContext.spec.ts +0 -88
  32. package/src/domain/contexts/userContext.spec.ts +0 -156
  33. package/src/domain/error/error.spec.ts +0 -294
  34. package/src/domain/error/trackRuntimeError.spec.ts +0 -343
  35. package/src/domain/eventRateLimiter/createEventRateLimiter.spec.ts +0 -119
  36. package/src/domain/extension/extensionUtils.spec.ts +0 -47
  37. package/src/domain/report/reportObservable.spec.ts +0 -71
  38. package/src/domain/session/oldCookiesMigration.spec.ts +0 -76
  39. package/src/domain/session/sessionManager.spec.ts +0 -684
  40. package/src/domain/session/sessionState.spec.ts +0 -88
  41. package/src/domain/session/sessionStore.spec.ts +0 -647
  42. package/src/domain/session/sessionStoreOperations.spec.ts +0 -234
  43. package/src/domain/session/storeStrategies/sessionInCookie.spec.ts +0 -228
  44. package/src/domain/session/storeStrategies/sessionInLocalStorage.spec.ts +0 -75
  45. package/src/domain/synthetics/syntheticsWorkerValues.spec.ts +0 -82
  46. package/src/domain/tags.spec.ts +0 -74
  47. package/src/domain/telemetry/telemetry.spec.ts +0 -494
  48. package/src/domain/trackingConsent.spec.ts +0 -44
  49. package/src/tools/abstractHooks.spec.ts +0 -76
  50. package/src/tools/abstractLifeCycle.spec.ts +0 -46
  51. package/src/tools/boundedBuffer.spec.ts +0 -40
  52. package/src/tools/catchUserErrors.spec.ts +0 -20
  53. package/src/tools/encoder.spec.ts +0 -112
  54. package/src/tools/experimentalFeatures.spec.ts +0 -60
  55. package/src/tools/getZoneJsOriginalValue.spec.ts +0 -36
  56. package/src/tools/instrumentMethod.spec.ts +0 -381
  57. package/src/tools/matchOption.spec.ts +0 -41
  58. package/src/tools/mergeInto.spec.ts +0 -198
  59. package/src/tools/monitor.spec.ts +0 -172
  60. package/src/tools/observable.spec.ts +0 -259
  61. package/src/tools/queueMicrotask.spec.ts +0 -24
  62. package/src/tools/readBytesFromStream.spec.ts +0 -62
  63. package/src/tools/requestIdleCallback.spec.ts +0 -65
  64. package/src/tools/serialisation/jsonStringify.spec.ts +0 -76
  65. package/src/tools/serialisation/sanitize.spec.ts +0 -284
  66. package/src/tools/stackTrace/capturedExceptions.specHelper.ts +0 -316
  67. package/src/tools/stackTrace/computeStackTrace.spec.ts +0 -1007
  68. package/src/tools/stackTrace/handlingStack.spec.ts +0 -20
  69. package/src/tools/taskQueue.spec.ts +0 -60
  70. package/src/tools/timer.spec.ts +0 -76
  71. package/src/tools/utils/browserDetection.spec.ts +0 -120
  72. package/src/tools/utils/byteUtils.spec.ts +0 -29
  73. package/src/tools/utils/functionUtils.spec.ts +0 -229
  74. package/src/tools/utils/numberUtils.spec.ts +0 -27
  75. package/src/tools/utils/stringUtils.spec.ts +0 -74
  76. package/src/tools/utils/typeUtils.spec.ts +0 -25
  77. package/src/tools/utils/urlPolyfill.spec.ts +0 -55
  78. package/src/tools/valueHistory.spec.ts +0 -180
  79. package/src/transport/batch.spec.ts +0 -261
  80. package/src/transport/eventBridge.spec.ts +0 -90
  81. package/src/transport/flushController.spec.ts +0 -267
  82. package/src/transport/httpRequest.spec.ts +0 -400
  83. package/src/transport/sendWithRetryStrategy.spec.ts +0 -393
@@ -1,684 +0,0 @@
1
- import {
2
- createNewEvent,
3
- expireCookie,
4
- getSessionState,
5
- mockClock,
6
- registerCleanupTask,
7
- restorePageVisibility,
8
- setPageVisibility,
9
- } from '../../../test'
10
- import type { Clock } from '../../../test'
11
- import { getCookie, setCookie } from '../../browser/cookie'
12
- import { DOM_EVENT } from '../../browser/addEventListener'
13
- import { ONE_HOUR, ONE_SECOND } from '../../tools/utils/timeUtils'
14
- import type { Configuration } from '../configuration'
15
- import type { TrackingConsentState } from '../trackingConsent'
16
- import { TrackingConsent, createTrackingConsentState } from '../trackingConsent'
17
- import type { SessionManager } from './sessionManager'
18
- import { startSessionManager, stopSessionManager, VISIBILITY_CHECK_DELAY } from './sessionManager'
19
- import {
20
- SESSION_EXPIRATION_DELAY,
21
- SESSION_NOT_TRACKED,
22
- SESSION_TIME_OUT_DELAY,
23
- SessionPersistence,
24
- } from './sessionConstants'
25
- import type { SessionStoreStrategyType } from './storeStrategies/sessionStoreStrategy'
26
- import { SESSION_STORE_KEY } from './storeStrategies/sessionStoreStrategy'
27
- import { STORAGE_POLL_DELAY } from './sessionStore'
28
-
29
- const enum FakeTrackingType {
30
- NOT_TRACKED = SESSION_NOT_TRACKED,
31
- TRACKED = 'tracked',
32
- }
33
-
34
- describe('startSessionManager', () => {
35
- const DURATION = 123456
36
- const FIRST_PRODUCT_KEY = 'first'
37
- const SECOND_PRODUCT_KEY = 'second'
38
- const STORE_TYPE: SessionStoreStrategyType = { type: SessionPersistence.COOKIE, cookieOptions: {} }
39
- let clock: Clock
40
-
41
- function expireSessionCookie() {
42
- expireCookie()
43
- clock.tick(STORAGE_POLL_DELAY)
44
- }
45
-
46
- function deleteSessionCookie() {
47
- setCookie(SESSION_STORE_KEY, '', DURATION)
48
- clock.tick(STORAGE_POLL_DELAY)
49
- }
50
-
51
- function expectSessionIdToBe(sessionManager: SessionManager<FakeTrackingType>, sessionId: string) {
52
- expect(sessionManager.findSession()!.id).toBe(sessionId)
53
- expect(getSessionState(SESSION_STORE_KEY).id).toBe(sessionId)
54
- }
55
-
56
- function expectSessionIdToBeDefined(sessionManager: SessionManager<FakeTrackingType>) {
57
- expect(sessionManager.findSession()!.id).toMatch(/^[a-f0-9-]+$/)
58
- expect(sessionManager.findSession()?.isExpired).toBeUndefined()
59
-
60
- expect(getSessionState(SESSION_STORE_KEY).id).toMatch(/^[a-f0-9-]+$/)
61
- expect(getSessionState(SESSION_STORE_KEY).isExpired).toBeUndefined()
62
- }
63
-
64
- function expectSessionToBeExpired(sessionManager: SessionManager<FakeTrackingType>) {
65
- expect(sessionManager.findSession()).toBeUndefined()
66
- expect(getSessionState(SESSION_STORE_KEY).isExpired).toBe('1')
67
- }
68
-
69
- function expectSessionIdToNotBeDefined(sessionManager: SessionManager<FakeTrackingType>) {
70
- expect(sessionManager.findSession()!.id).toBeUndefined()
71
- expect(getSessionState(SESSION_STORE_KEY).id).toBeUndefined()
72
- }
73
-
74
- function expectTrackingTypeToBe(
75
- sessionManager: SessionManager<FakeTrackingType>,
76
- productKey: string,
77
- trackingType: FakeTrackingType
78
- ) {
79
- expect(sessionManager.findSession()!.trackingType).toEqual(trackingType)
80
- expect(getSessionState(SESSION_STORE_KEY)[productKey]).toEqual(trackingType)
81
- }
82
-
83
- function expectTrackingTypeToNotBeDefined(sessionManager: SessionManager<FakeTrackingType>, productKey: string) {
84
- expect(sessionManager.findSession()?.trackingType).toBeUndefined()
85
- expect(getSessionState(SESSION_STORE_KEY)[productKey]).toBeUndefined()
86
- }
87
-
88
- beforeEach(() => {
89
- clock = mockClock()
90
-
91
- registerCleanupTask(() => {
92
- // remove intervals first
93
- stopSessionManager()
94
- // flush pending callbacks to avoid random failures
95
- clock.tick(ONE_HOUR)
96
- })
97
- })
98
-
99
- describe('resume from a frozen tab ', () => {
100
- it('when session in store, do nothing', () => {
101
- setCookie(SESSION_STORE_KEY, 'id=abcdef&first=tracked', DURATION)
102
- const sessionManager = startSessionManagerWithDefaults()
103
-
104
- window.dispatchEvent(createNewEvent(DOM_EVENT.RESUME))
105
-
106
- expectSessionIdToBe(sessionManager, 'abcdef')
107
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.TRACKED)
108
- })
109
-
110
- it('when session not in store, reinitialize a session in store', () => {
111
- const sessionManager = startSessionManagerWithDefaults()
112
-
113
- deleteSessionCookie()
114
-
115
- expect(sessionManager.findSession()).toBeUndefined()
116
- expect(getCookie(SESSION_STORE_KEY)).toBeUndefined()
117
-
118
- window.dispatchEvent(createNewEvent(DOM_EVENT.RESUME))
119
-
120
- expectSessionToBeExpired(sessionManager)
121
- })
122
- })
123
-
124
- describe('cookie management', () => {
125
- it('when tracked, should store tracking type and session id', () => {
126
- const sessionManager = startSessionManagerWithDefaults()
127
-
128
- expectSessionIdToBeDefined(sessionManager)
129
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.TRACKED)
130
- })
131
-
132
- it('when not tracked should store tracking type', () => {
133
- const sessionManager = startSessionManagerWithDefaults({
134
- computeTrackingType: () => FakeTrackingType.NOT_TRACKED,
135
- })
136
-
137
- expectSessionIdToNotBeDefined(sessionManager)
138
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.NOT_TRACKED)
139
- })
140
-
141
- it('when tracked should keep existing tracking type and session id', () => {
142
- setCookie(SESSION_STORE_KEY, 'id=abcdef&first=tracked', DURATION)
143
-
144
- const sessionManager = startSessionManagerWithDefaults()
145
-
146
- expectSessionIdToBe(sessionManager, 'abcdef')
147
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.TRACKED)
148
- })
149
-
150
- it('when not tracked should keep existing tracking type', () => {
151
- setCookie(SESSION_STORE_KEY, `first=${SESSION_NOT_TRACKED}`, DURATION)
152
-
153
- const sessionManager = startSessionManagerWithDefaults({
154
- computeTrackingType: () => FakeTrackingType.NOT_TRACKED,
155
- })
156
-
157
- expectSessionIdToNotBeDefined(sessionManager)
158
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.NOT_TRACKED)
159
- })
160
- })
161
-
162
- describe('computeTrackingType', () => {
163
- let spy: (rawTrackingType?: string) => FakeTrackingType
164
-
165
- beforeEach(() => {
166
- spy = jasmine.createSpy().and.returnValue(FakeTrackingType.TRACKED)
167
- })
168
-
169
- it('should be called with an empty value if the cookie is not defined', () => {
170
- startSessionManagerWithDefaults({ computeTrackingType: spy })
171
- expect(spy).toHaveBeenCalledWith(undefined)
172
- })
173
-
174
- it('should be called with an invalid value if the cookie has an invalid value', () => {
175
- setCookie(SESSION_STORE_KEY, 'first=invalid', DURATION)
176
- startSessionManagerWithDefaults({ computeTrackingType: spy })
177
- expect(spy).toHaveBeenCalledWith('invalid')
178
- })
179
-
180
- it('should be called with TRACKED', () => {
181
- setCookie(SESSION_STORE_KEY, 'first=tracked', DURATION)
182
- startSessionManagerWithDefaults({ computeTrackingType: spy })
183
- expect(spy).toHaveBeenCalledWith(FakeTrackingType.TRACKED)
184
- })
185
-
186
- it('should be called with NOT_TRACKED', () => {
187
- setCookie(SESSION_STORE_KEY, `first=${SESSION_NOT_TRACKED}`, DURATION)
188
- startSessionManagerWithDefaults({ computeTrackingType: spy })
189
- expect(spy).toHaveBeenCalledWith(FakeTrackingType.NOT_TRACKED)
190
- })
191
- })
192
-
193
- describe('session renewal', () => {
194
- it('should renew on activity after expiration', () => {
195
- const sessionManager = startSessionManagerWithDefaults()
196
- const renewSessionSpy = jasmine.createSpy()
197
- sessionManager.renewObservable.subscribe(renewSessionSpy)
198
-
199
- expireSessionCookie()
200
-
201
- expect(renewSessionSpy).not.toHaveBeenCalled()
202
-
203
- expectSessionToBeExpired(sessionManager)
204
- expectTrackingTypeToNotBeDefined(sessionManager, FIRST_PRODUCT_KEY)
205
-
206
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
207
-
208
- expect(renewSessionSpy).toHaveBeenCalled()
209
- expectSessionIdToBeDefined(sessionManager)
210
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.TRACKED)
211
- })
212
-
213
- it('should not renew on visibility after expiration', () => {
214
- const sessionManager = startSessionManagerWithDefaults()
215
- const renewSessionSpy = jasmine.createSpy()
216
- sessionManager.renewObservable.subscribe(renewSessionSpy)
217
-
218
- expireSessionCookie()
219
-
220
- clock.tick(VISIBILITY_CHECK_DELAY)
221
-
222
- expect(renewSessionSpy).not.toHaveBeenCalled()
223
- expectSessionToBeExpired(sessionManager)
224
- })
225
-
226
- it('should not renew on activity if cookie is deleted by a 3rd party', () => {
227
- const sessionManager = startSessionManagerWithDefaults()
228
- const renewSessionSpy = jasmine.createSpy('renewSessionSpy')
229
- sessionManager.renewObservable.subscribe(renewSessionSpy)
230
-
231
- deleteSessionCookie()
232
-
233
- expect(renewSessionSpy).not.toHaveBeenCalled()
234
-
235
- expect(sessionManager.findSession()).toBeUndefined()
236
- expect(getCookie(SESSION_STORE_KEY)).toBeUndefined()
237
-
238
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
239
-
240
- expect(renewSessionSpy).not.toHaveBeenCalled()
241
- expect(sessionManager.findSession()).toBeUndefined()
242
- expect(getCookie(SESSION_STORE_KEY)).toBeUndefined()
243
- })
244
- })
245
-
246
- describe('multiple startSessionManager calls', () => {
247
- it('should re-use the same session id', () => {
248
- const firstSessionManager = startSessionManagerWithDefaults({ productKey: FIRST_PRODUCT_KEY })
249
- const idA = firstSessionManager.findSession()!.id
250
-
251
- const secondSessionManager = startSessionManagerWithDefaults({ productKey: SECOND_PRODUCT_KEY })
252
- const idB = secondSessionManager.findSession()!.id
253
-
254
- expect(idA).toBe(idB)
255
- })
256
-
257
- it('should not erase other session type', () => {
258
- startSessionManagerWithDefaults({ productKey: FIRST_PRODUCT_KEY })
259
-
260
- // schedule an expandOrRenewSession
261
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
262
-
263
- clock.tick(STORAGE_POLL_DELAY / 2)
264
-
265
- // expand first session cookie cache
266
- document.dispatchEvent(createNewEvent(DOM_EVENT.VISIBILITY_CHANGE))
267
-
268
- startSessionManagerWithDefaults({ productKey: SECOND_PRODUCT_KEY })
269
-
270
- // cookie correctly set
271
- expect(getSessionState(SESSION_STORE_KEY).first).toBeDefined()
272
- expect(getSessionState(SESSION_STORE_KEY).second).toBeDefined()
273
-
274
- clock.tick(STORAGE_POLL_DELAY / 2)
275
-
276
- // scheduled expandOrRenewSession should not use cached value
277
- expect(getSessionState(SESSION_STORE_KEY).first).toBeDefined()
278
- expect(getSessionState(SESSION_STORE_KEY).second).toBeDefined()
279
- })
280
-
281
- it('should have independent tracking types', () => {
282
- const firstSessionManager = startSessionManagerWithDefaults({
283
- productKey: FIRST_PRODUCT_KEY,
284
- computeTrackingType: () => FakeTrackingType.TRACKED,
285
- })
286
- const secondSessionManager = startSessionManagerWithDefaults({
287
- productKey: SECOND_PRODUCT_KEY,
288
- computeTrackingType: () => FakeTrackingType.NOT_TRACKED,
289
- })
290
-
291
- expect(firstSessionManager.findSession()!.trackingType).toEqual(FakeTrackingType.TRACKED)
292
- expect(secondSessionManager.findSession()!.trackingType).toEqual(FakeTrackingType.NOT_TRACKED)
293
- })
294
-
295
- it('should notify each expire and renew observables', () => {
296
- const firstSessionManager = startSessionManagerWithDefaults({ productKey: FIRST_PRODUCT_KEY })
297
- const expireSessionASpy = jasmine.createSpy()
298
- firstSessionManager.expireObservable.subscribe(expireSessionASpy)
299
- const renewSessionASpy = jasmine.createSpy()
300
- firstSessionManager.renewObservable.subscribe(renewSessionASpy)
301
-
302
- const secondSessionManager = startSessionManagerWithDefaults({ productKey: SECOND_PRODUCT_KEY })
303
- const expireSessionBSpy = jasmine.createSpy()
304
- secondSessionManager.expireObservable.subscribe(expireSessionBSpy)
305
- const renewSessionBSpy = jasmine.createSpy()
306
- secondSessionManager.renewObservable.subscribe(renewSessionBSpy)
307
-
308
- expireSessionCookie()
309
-
310
- expect(expireSessionASpy).toHaveBeenCalled()
311
- expect(expireSessionBSpy).toHaveBeenCalled()
312
- expect(renewSessionASpy).not.toHaveBeenCalled()
313
- expect(renewSessionBSpy).not.toHaveBeenCalled()
314
-
315
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
316
-
317
- expect(renewSessionASpy).toHaveBeenCalled()
318
- expect(renewSessionBSpy).toHaveBeenCalled()
319
- })
320
- })
321
-
322
- describe('session timeout', () => {
323
- it('should expire the session when the time out delay is reached', () => {
324
- const sessionManager = startSessionManagerWithDefaults()
325
- const expireSessionSpy = jasmine.createSpy()
326
- sessionManager.expireObservable.subscribe(expireSessionSpy)
327
-
328
- expect(sessionManager.findSession()).toBeDefined()
329
- expect(getCookie(SESSION_STORE_KEY)).toBeDefined()
330
-
331
- clock.tick(SESSION_TIME_OUT_DELAY)
332
- expectSessionToBeExpired(sessionManager)
333
- expect(expireSessionSpy).toHaveBeenCalled()
334
- })
335
-
336
- it('should renew an existing timed out session', () => {
337
- setCookie(SESSION_STORE_KEY, `id=abcde&first=tracked&created=${Date.now() - SESSION_TIME_OUT_DELAY}`, DURATION)
338
-
339
- const sessionManager = startSessionManagerWithDefaults()
340
- const expireSessionSpy = jasmine.createSpy()
341
- sessionManager.expireObservable.subscribe(expireSessionSpy)
342
-
343
- expect(sessionManager.findSession()!.id).not.toBe('abcde')
344
- expect(getSessionState(SESSION_STORE_KEY).created).toEqual(Date.now().toString())
345
- expect(expireSessionSpy).not.toHaveBeenCalled() // the session has not been active from the start
346
- })
347
-
348
- it('should not add created date to an existing session from an older versions', () => {
349
- setCookie(SESSION_STORE_KEY, 'id=abcde&first=tracked', DURATION)
350
-
351
- const sessionManager = startSessionManagerWithDefaults()
352
-
353
- expect(sessionManager.findSession()!.id).toBe('abcde')
354
- expect(getSessionState(SESSION_STORE_KEY).created).toBeUndefined()
355
- })
356
- })
357
-
358
- describe('automatic session expiration', () => {
359
- beforeEach(() => {
360
- setPageVisibility('hidden')
361
- })
362
-
363
- afterEach(() => {
364
- restorePageVisibility()
365
- })
366
-
367
- it('should expire the session after expiration delay', () => {
368
- const sessionManager = startSessionManagerWithDefaults()
369
- const expireSessionSpy = jasmine.createSpy()
370
- sessionManager.expireObservable.subscribe(expireSessionSpy)
371
-
372
- expectSessionIdToBeDefined(sessionManager)
373
-
374
- clock.tick(SESSION_EXPIRATION_DELAY)
375
- expectSessionToBeExpired(sessionManager)
376
- expect(expireSessionSpy).toHaveBeenCalled()
377
- })
378
-
379
- it('should expand duration on activity', () => {
380
- const sessionManager = startSessionManagerWithDefaults()
381
- const expireSessionSpy = jasmine.createSpy()
382
- sessionManager.expireObservable.subscribe(expireSessionSpy)
383
-
384
- expectSessionIdToBeDefined(sessionManager)
385
-
386
- clock.tick(SESSION_EXPIRATION_DELAY - 10)
387
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
388
-
389
- clock.tick(10)
390
- expectSessionIdToBeDefined(sessionManager)
391
- expect(expireSessionSpy).not.toHaveBeenCalled()
392
-
393
- clock.tick(SESSION_EXPIRATION_DELAY)
394
- expectSessionToBeExpired(sessionManager)
395
- expect(expireSessionSpy).toHaveBeenCalled()
396
- })
397
-
398
- it('should expand not tracked session duration on activity', () => {
399
- const sessionManager = startSessionManagerWithDefaults({
400
- computeTrackingType: () => FakeTrackingType.NOT_TRACKED,
401
- })
402
- const expireSessionSpy = jasmine.createSpy()
403
- sessionManager.expireObservable.subscribe(expireSessionSpy)
404
-
405
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.NOT_TRACKED)
406
-
407
- clock.tick(SESSION_EXPIRATION_DELAY - 10)
408
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
409
-
410
- clock.tick(10)
411
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.NOT_TRACKED)
412
- expect(expireSessionSpy).not.toHaveBeenCalled()
413
-
414
- clock.tick(SESSION_EXPIRATION_DELAY)
415
- expectTrackingTypeToNotBeDefined(sessionManager, FIRST_PRODUCT_KEY)
416
- expect(expireSessionSpy).toHaveBeenCalled()
417
- })
418
-
419
- it('should expand session on visibility', () => {
420
- setPageVisibility('visible')
421
-
422
- const sessionManager = startSessionManagerWithDefaults()
423
- const expireSessionSpy = jasmine.createSpy()
424
- sessionManager.expireObservable.subscribe(expireSessionSpy)
425
-
426
- clock.tick(3 * VISIBILITY_CHECK_DELAY)
427
- setPageVisibility('hidden')
428
- expectSessionIdToBeDefined(sessionManager)
429
- expect(expireSessionSpy).not.toHaveBeenCalled()
430
-
431
- clock.tick(SESSION_EXPIRATION_DELAY - 10)
432
- expectSessionIdToBeDefined(sessionManager)
433
- expect(expireSessionSpy).not.toHaveBeenCalled()
434
-
435
- clock.tick(10)
436
- expectSessionToBeExpired(sessionManager)
437
- expect(expireSessionSpy).toHaveBeenCalled()
438
- })
439
-
440
- it('should expand not tracked session on visibility', () => {
441
- setPageVisibility('visible')
442
-
443
- const sessionManager = startSessionManagerWithDefaults({
444
- computeTrackingType: () => FakeTrackingType.NOT_TRACKED,
445
- })
446
- const expireSessionSpy = jasmine.createSpy()
447
- sessionManager.expireObservable.subscribe(expireSessionSpy)
448
-
449
- clock.tick(3 * VISIBILITY_CHECK_DELAY)
450
- setPageVisibility('hidden')
451
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.NOT_TRACKED)
452
- expect(expireSessionSpy).not.toHaveBeenCalled()
453
-
454
- clock.tick(SESSION_EXPIRATION_DELAY - 10)
455
- expectTrackingTypeToBe(sessionManager, FIRST_PRODUCT_KEY, FakeTrackingType.NOT_TRACKED)
456
- expect(expireSessionSpy).not.toHaveBeenCalled()
457
-
458
- clock.tick(10)
459
- expectTrackingTypeToNotBeDefined(sessionManager, FIRST_PRODUCT_KEY)
460
- expect(expireSessionSpy).toHaveBeenCalled()
461
- })
462
- })
463
-
464
- describe('manual session expiration', () => {
465
- it('expires the session when calling expire()', () => {
466
- const sessionManager = startSessionManagerWithDefaults()
467
- const expireSessionSpy = jasmine.createSpy()
468
- sessionManager.expireObservable.subscribe(expireSessionSpy)
469
-
470
- sessionManager.expire()
471
-
472
- expectSessionToBeExpired(sessionManager)
473
- expect(expireSessionSpy).toHaveBeenCalled()
474
- })
475
-
476
- it('notifies expired session only once when calling expire() multiple times', () => {
477
- const sessionManager = startSessionManagerWithDefaults()
478
- const expireSessionSpy = jasmine.createSpy()
479
- sessionManager.expireObservable.subscribe(expireSessionSpy)
480
-
481
- sessionManager.expire()
482
- sessionManager.expire()
483
-
484
- expectSessionToBeExpired(sessionManager)
485
- expect(expireSessionSpy).toHaveBeenCalledTimes(1)
486
- })
487
-
488
- it('notifies expired session only once when calling expire() after the session has been expired', () => {
489
- const sessionManager = startSessionManagerWithDefaults()
490
- const expireSessionSpy = jasmine.createSpy()
491
- sessionManager.expireObservable.subscribe(expireSessionSpy)
492
-
493
- clock.tick(SESSION_EXPIRATION_DELAY)
494
- sessionManager.expire()
495
-
496
- expectSessionToBeExpired(sessionManager)
497
- expect(expireSessionSpy).toHaveBeenCalledTimes(1)
498
- })
499
-
500
- it('renew the session on user activity', () => {
501
- const sessionManager = startSessionManagerWithDefaults()
502
- clock.tick(STORAGE_POLL_DELAY)
503
-
504
- sessionManager.expire()
505
-
506
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
507
-
508
- expectSessionIdToBeDefined(sessionManager)
509
- })
510
- })
511
-
512
- describe('session history', () => {
513
- it('should return undefined when there is no current session and no startTime', () => {
514
- const sessionManager = startSessionManagerWithDefaults()
515
- expireSessionCookie()
516
-
517
- expect(sessionManager.findSession()).toBeUndefined()
518
- })
519
-
520
- it('should return the current session context when there is no start time', () => {
521
- const sessionManager = startSessionManagerWithDefaults()
522
-
523
- expect(sessionManager.findSession()!.id).toBeDefined()
524
- expect(sessionManager.findSession()!.trackingType).toBeDefined()
525
- })
526
-
527
- it('should return the session context corresponding to startTime', () => {
528
- const sessionManager = startSessionManagerWithDefaults()
529
-
530
- // 0s to 10s: first session
531
- clock.tick(10 * ONE_SECOND - STORAGE_POLL_DELAY)
532
- const firstSessionId = sessionManager.findSession()!.id
533
- const firstSessionTrackingType = sessionManager.findSession()!.trackingType
534
- expireSessionCookie()
535
-
536
- // 10s to 20s: no session
537
- clock.tick(10 * ONE_SECOND)
538
-
539
- // 20s to end: second session
540
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
541
- clock.tick(10 * ONE_SECOND)
542
- const secondSessionId = sessionManager.findSession()!.id
543
- const secondSessionTrackingType = sessionManager.findSession()!.trackingType
544
-
545
- expect(sessionManager.findSession(clock.relative(5 * ONE_SECOND))!.id).toBe(firstSessionId)
546
- expect(sessionManager.findSession(clock.relative(5 * ONE_SECOND))!.trackingType).toBe(firstSessionTrackingType)
547
- expect(sessionManager.findSession(clock.relative(15 * ONE_SECOND))).toBeUndefined()
548
- expect(sessionManager.findSession(clock.relative(25 * ONE_SECOND))!.id).toBe(secondSessionId)
549
- expect(sessionManager.findSession(clock.relative(25 * ONE_SECOND))!.trackingType).toBe(secondSessionTrackingType)
550
- })
551
-
552
- describe('option `returnInactive` is true', () => {
553
- it('should return the session context even when the session is expired', () => {
554
- const sessionManager = startSessionManagerWithDefaults()
555
-
556
- // 0s to 10s: first session
557
- clock.tick(10 * ONE_SECOND - STORAGE_POLL_DELAY)
558
-
559
- expireSessionCookie()
560
-
561
- // 10s to 20s: no session
562
- clock.tick(10 * ONE_SECOND)
563
-
564
- expect(sessionManager.findSession(clock.relative(15 * ONE_SECOND), { returnInactive: true })).toBeDefined()
565
-
566
- expect(sessionManager.findSession(clock.relative(15 * ONE_SECOND), { returnInactive: false })).toBeUndefined()
567
- })
568
- })
569
-
570
- it('should return the current session context in the renewObservable callback', () => {
571
- const sessionManager = startSessionManagerWithDefaults()
572
- let currentSession
573
- sessionManager.renewObservable.subscribe(() => (currentSession = sessionManager.findSession()))
574
-
575
- // new session
576
- expireSessionCookie()
577
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
578
- clock.tick(STORAGE_POLL_DELAY)
579
-
580
- expect(currentSession).toBeDefined()
581
- })
582
-
583
- it('should return the current session context in the expireObservable callback', () => {
584
- const sessionManager = startSessionManagerWithDefaults()
585
- let currentSession
586
- sessionManager.expireObservable.subscribe(() => (currentSession = sessionManager.findSession()))
587
-
588
- // new session
589
- expireSessionCookie()
590
- clock.tick(STORAGE_POLL_DELAY)
591
-
592
- expect(currentSession).toBeDefined()
593
- })
594
- })
595
-
596
- describe('tracking consent', () => {
597
- it('expires the session when tracking consent is withdrawn', () => {
598
- const trackingConsentState = createTrackingConsentState(TrackingConsent.GRANTED)
599
- const sessionManager = startSessionManagerWithDefaults({ trackingConsentState })
600
-
601
- trackingConsentState.update(TrackingConsent.NOT_GRANTED)
602
-
603
- expectSessionToBeExpired(sessionManager)
604
- expect(getSessionState(SESSION_STORE_KEY).isExpired).toBe('1')
605
- })
606
-
607
- it('does not renew the session when tracking consent is withdrawn', () => {
608
- const trackingConsentState = createTrackingConsentState(TrackingConsent.GRANTED)
609
- const sessionManager = startSessionManagerWithDefaults({ trackingConsentState })
610
-
611
- trackingConsentState.update(TrackingConsent.NOT_GRANTED)
612
-
613
- document.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))
614
-
615
- expectSessionToBeExpired(sessionManager)
616
- })
617
-
618
- it('renews the session when tracking consent is granted', () => {
619
- const trackingConsentState = createTrackingConsentState(TrackingConsent.GRANTED)
620
- const sessionManager = startSessionManagerWithDefaults({ trackingConsentState })
621
- const initialSessionId = sessionManager.findSession()!.id
622
-
623
- trackingConsentState.update(TrackingConsent.NOT_GRANTED)
624
-
625
- expectSessionToBeExpired(sessionManager)
626
-
627
- trackingConsentState.update(TrackingConsent.GRANTED)
628
-
629
- clock.tick(STORAGE_POLL_DELAY)
630
-
631
- expectSessionIdToBeDefined(sessionManager)
632
- expect(sessionManager.findSession()!.id).not.toBe(initialSessionId)
633
- })
634
-
635
- it('Remove anonymousId when tracking consent is withdrawn', () => {
636
- const trackingConsentState = createTrackingConsentState(TrackingConsent.GRANTED)
637
- const sessionManager = startSessionManagerWithDefaults({ trackingConsentState })
638
- const session = sessionManager.findSession()!
639
-
640
- trackingConsentState.update(TrackingConsent.NOT_GRANTED)
641
-
642
- expect(session.anonymousId).toBeUndefined()
643
- })
644
- })
645
-
646
- describe('session state update', () => {
647
- it('should notify session manager update observable', () => {
648
- const sessionStateUpdateSpy = jasmine.createSpy()
649
- const sessionManager = startSessionManagerWithDefaults()
650
- sessionManager.sessionStateUpdateObservable.subscribe(sessionStateUpdateSpy)
651
-
652
- sessionManager.updateSessionState({ extra: 'extra' })
653
-
654
- expectSessionIdToBeDefined(sessionManager)
655
- expect(sessionStateUpdateSpy).toHaveBeenCalledTimes(1)
656
-
657
- const callArgs = sessionStateUpdateSpy.calls.argsFor(0)[0]
658
- expect(callArgs.previousState.extra).toBeUndefined()
659
- expect(callArgs.newState.extra).toBe('extra')
660
- })
661
- })
662
-
663
- function startSessionManagerWithDefaults({
664
- configuration,
665
- productKey = FIRST_PRODUCT_KEY,
666
- computeTrackingType = () => FakeTrackingType.TRACKED,
667
- trackingConsentState = createTrackingConsentState(TrackingConsent.GRANTED),
668
- }: {
669
- configuration?: Partial<Configuration>
670
- productKey?: string
671
- computeTrackingType?: () => FakeTrackingType
672
- trackingConsentState?: TrackingConsentState
673
- } = {}) {
674
- return startSessionManager(
675
- {
676
- sessionStoreStrategyType: STORE_TYPE,
677
- ...configuration,
678
- } as Configuration,
679
- productKey,
680
- computeTrackingType,
681
- trackingConsentState
682
- )
683
- }
684
- })