@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.
- package/cjs/boot/init.js +1 -1
- package/cjs/domain/configuration/endpointBuilder.js +1 -1
- package/cjs/domain/tags.js +1 -1
- package/cjs/domain/telemetry/telemetry.js +1 -1
- package/cjs/domain/telemetry/telemetryEvent.types.d.ts +1 -1
- package/esm/boot/init.js +1 -1
- package/esm/domain/configuration/endpointBuilder.js +1 -1
- package/esm/domain/tags.js +1 -1
- package/esm/domain/telemetry/telemetry.js +1 -1
- package/esm/domain/telemetry/telemetryEvent.types.d.ts +1 -1
- package/package.json +2 -2
- package/src/domain/telemetry/telemetryEvent.types.ts +1 -1
- package/src/boot/displayAlreadyInitializedError.spec.ts +0 -18
- package/src/boot/init.spec.ts +0 -50
- package/src/browser/addEventListener.spec.ts +0 -141
- package/src/browser/cookie.spec.ts +0 -53
- package/src/browser/fetchObservable.spec.ts +0 -334
- package/src/browser/pageMayExitObservable.spec.ts +0 -56
- package/src/browser/xhrObservable.spec.ts +0 -405
- package/src/domain/allowedTrackingOrigins.spec.ts +0 -210
- package/src/domain/bufferedData.spec.ts +0 -34
- package/src/domain/configuration/configuration.spec.ts +0 -236
- package/src/domain/configuration/endpointBuilder.spec.ts +0 -173
- package/src/domain/configuration/transportConfiguration.spec.ts +0 -130
- package/src/domain/connectivity/connectivity.spec.ts +0 -50
- package/src/domain/console/consoleObservable.spec.ts +0 -151
- package/src/domain/context/contextManager.spec.ts +0 -152
- package/src/domain/context/contextUtils.spec.ts +0 -26
- package/src/domain/context/storeContextManager.spec.ts +0 -103
- package/src/domain/contexts/accountContext.spec.ts +0 -99
- package/src/domain/contexts/globalContext.spec.ts +0 -88
- package/src/domain/contexts/userContext.spec.ts +0 -156
- package/src/domain/error/error.spec.ts +0 -294
- package/src/domain/error/trackRuntimeError.spec.ts +0 -343
- package/src/domain/eventRateLimiter/createEventRateLimiter.spec.ts +0 -119
- package/src/domain/extension/extensionUtils.spec.ts +0 -47
- package/src/domain/report/reportObservable.spec.ts +0 -71
- package/src/domain/session/oldCookiesMigration.spec.ts +0 -76
- package/src/domain/session/sessionManager.spec.ts +0 -684
- package/src/domain/session/sessionState.spec.ts +0 -88
- package/src/domain/session/sessionStore.spec.ts +0 -647
- package/src/domain/session/sessionStoreOperations.spec.ts +0 -234
- package/src/domain/session/storeStrategies/sessionInCookie.spec.ts +0 -228
- package/src/domain/session/storeStrategies/sessionInLocalStorage.spec.ts +0 -75
- package/src/domain/synthetics/syntheticsWorkerValues.spec.ts +0 -82
- package/src/domain/tags.spec.ts +0 -74
- package/src/domain/telemetry/telemetry.spec.ts +0 -494
- package/src/domain/trackingConsent.spec.ts +0 -44
- package/src/tools/abstractHooks.spec.ts +0 -76
- package/src/tools/abstractLifeCycle.spec.ts +0 -46
- package/src/tools/boundedBuffer.spec.ts +0 -40
- package/src/tools/catchUserErrors.spec.ts +0 -20
- package/src/tools/encoder.spec.ts +0 -112
- package/src/tools/experimentalFeatures.spec.ts +0 -60
- package/src/tools/getZoneJsOriginalValue.spec.ts +0 -36
- package/src/tools/instrumentMethod.spec.ts +0 -381
- package/src/tools/matchOption.spec.ts +0 -41
- package/src/tools/mergeInto.spec.ts +0 -198
- package/src/tools/monitor.spec.ts +0 -172
- package/src/tools/observable.spec.ts +0 -259
- package/src/tools/queueMicrotask.spec.ts +0 -24
- package/src/tools/readBytesFromStream.spec.ts +0 -62
- package/src/tools/requestIdleCallback.spec.ts +0 -65
- package/src/tools/serialisation/jsonStringify.spec.ts +0 -76
- package/src/tools/serialisation/sanitize.spec.ts +0 -284
- package/src/tools/stackTrace/capturedExceptions.specHelper.ts +0 -316
- package/src/tools/stackTrace/computeStackTrace.spec.ts +0 -1007
- package/src/tools/stackTrace/handlingStack.spec.ts +0 -20
- package/src/tools/taskQueue.spec.ts +0 -60
- package/src/tools/timer.spec.ts +0 -76
- package/src/tools/utils/browserDetection.spec.ts +0 -120
- package/src/tools/utils/byteUtils.spec.ts +0 -29
- package/src/tools/utils/functionUtils.spec.ts +0 -229
- package/src/tools/utils/numberUtils.spec.ts +0 -27
- package/src/tools/utils/stringUtils.spec.ts +0 -74
- package/src/tools/utils/typeUtils.spec.ts +0 -25
- package/src/tools/utils/urlPolyfill.spec.ts +0 -55
- package/src/tools/valueHistory.spec.ts +0 -180
- package/src/transport/batch.spec.ts +0 -261
- package/src/transport/eventBridge.spec.ts +0 -90
- package/src/transport/flushController.spec.ts +0 -267
- package/src/transport/httpRequest.spec.ts +0 -400
- 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
|
-
})
|