@openobserve/browser-core 0.3.2-beta.3 → 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,234 +0,0 @@
|
|
|
1
|
-
import { createFakeSessionStoreStrategy, mockClock } from '../../../test'
|
|
2
|
-
import type { SessionState } from './sessionState'
|
|
3
|
-
import { expandSessionState } from './sessionState'
|
|
4
|
-
import {
|
|
5
|
-
processSessionStoreOperations,
|
|
6
|
-
LOCK_MAX_TRIES,
|
|
7
|
-
LOCK_RETRY_DELAY,
|
|
8
|
-
createLock,
|
|
9
|
-
LOCK_EXPIRATION_DELAY,
|
|
10
|
-
} from './sessionStoreOperations'
|
|
11
|
-
|
|
12
|
-
const EXPIRED_SESSION: SessionState = { isExpired: '1', anonymousId: '0' }
|
|
13
|
-
|
|
14
|
-
describe('sessionStoreOperations', () => {
|
|
15
|
-
let initialSession: SessionState
|
|
16
|
-
let otherSession: SessionState
|
|
17
|
-
let processSpy: jasmine.Spy<jasmine.Func>
|
|
18
|
-
let afterSpy: jasmine.Spy<jasmine.Func>
|
|
19
|
-
const now = Date.now()
|
|
20
|
-
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
initialSession = { id: '123', created: String(now) }
|
|
23
|
-
otherSession = { id: '456', created: String(now + 100) }
|
|
24
|
-
processSpy = jasmine.createSpy('process')
|
|
25
|
-
afterSpy = jasmine.createSpy('after')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
describe('with lock access disabled', () => {
|
|
29
|
-
it('should persist session when process returns a value', () => {
|
|
30
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: false, initialSession })
|
|
31
|
-
processSpy.and.returnValue({ ...otherSession })
|
|
32
|
-
|
|
33
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
34
|
-
|
|
35
|
-
expect(processSpy).toHaveBeenCalledWith(initialSession)
|
|
36
|
-
const expectedSession = { ...otherSession, expire: jasmine.any(String) }
|
|
37
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(expectedSession)
|
|
38
|
-
expect(afterSpy).toHaveBeenCalledWith(expectedSession)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('should clear session when process returns an expired session', () => {
|
|
42
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: false, initialSession })
|
|
43
|
-
processSpy.and.returnValue(EXPIRED_SESSION)
|
|
44
|
-
|
|
45
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
46
|
-
|
|
47
|
-
expect(processSpy).toHaveBeenCalledWith(initialSession)
|
|
48
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(EXPIRED_SESSION)
|
|
49
|
-
expect(afterSpy).toHaveBeenCalledWith(EXPIRED_SESSION)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('should not persist session when process returns undefined', () => {
|
|
53
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: false, initialSession })
|
|
54
|
-
processSpy.and.returnValue(undefined)
|
|
55
|
-
|
|
56
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
57
|
-
|
|
58
|
-
expect(processSpy).toHaveBeenCalledWith(initialSession)
|
|
59
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(initialSession)
|
|
60
|
-
expect(afterSpy).toHaveBeenCalledWith(initialSession)
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('LOCK_MAX_TRIES value should not influence the behavior when lock mechanism is not enabled', () => {
|
|
64
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: false, initialSession })
|
|
65
|
-
processSpy.and.returnValue({ ...otherSession })
|
|
66
|
-
|
|
67
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy, LOCK_MAX_TRIES)
|
|
68
|
-
|
|
69
|
-
expect(processSpy).toHaveBeenCalledWith(initialSession)
|
|
70
|
-
const expectedSession = { ...otherSession, expire: jasmine.any(String) }
|
|
71
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(expectedSession)
|
|
72
|
-
expect(afterSpy).toHaveBeenCalledWith(expectedSession)
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
describe('with lock access enabled', () => {
|
|
77
|
-
it('should persist session when process returns a value', () => {
|
|
78
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: true, initialSession })
|
|
79
|
-
processSpy.and.returnValue({ ...otherSession })
|
|
80
|
-
|
|
81
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
82
|
-
|
|
83
|
-
expect(processSpy).toHaveBeenCalledWith(initialSession)
|
|
84
|
-
const expectedSession = { ...otherSession, expire: jasmine.any(String) }
|
|
85
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(expectedSession)
|
|
86
|
-
expect(afterSpy).toHaveBeenCalledWith(expectedSession)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('should clear session when process returns an expired session', () => {
|
|
90
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: true, initialSession })
|
|
91
|
-
processSpy.and.returnValue(EXPIRED_SESSION)
|
|
92
|
-
|
|
93
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
94
|
-
|
|
95
|
-
expect(processSpy).toHaveBeenCalledWith(initialSession)
|
|
96
|
-
|
|
97
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(EXPIRED_SESSION)
|
|
98
|
-
expect(afterSpy).toHaveBeenCalledWith(EXPIRED_SESSION)
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('should not persist session when process returns undefined', () => {
|
|
102
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: true, initialSession })
|
|
103
|
-
processSpy.and.returnValue(undefined)
|
|
104
|
-
|
|
105
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
106
|
-
|
|
107
|
-
expect(processSpy).toHaveBeenCalledWith(initialSession)
|
|
108
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(initialSession)
|
|
109
|
-
expect(afterSpy).toHaveBeenCalledWith(initialSession)
|
|
110
|
-
})
|
|
111
|
-
;[
|
|
112
|
-
{
|
|
113
|
-
description: 'should wait for lock to be free',
|
|
114
|
-
lockConflictOnRetrievedSessionIndex: 0,
|
|
115
|
-
},
|
|
116
|
-
{
|
|
117
|
-
description: 'should retry if lock was acquired before process',
|
|
118
|
-
lockConflictOnRetrievedSessionIndex: 1,
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
description: 'should retry if lock was acquired after process',
|
|
122
|
-
lockConflictOnRetrievedSessionIndex: 2,
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
description: 'should retry if lock was acquired after persist',
|
|
126
|
-
lockConflictOnRetrievedSessionIndex: 3,
|
|
127
|
-
},
|
|
128
|
-
].forEach(({ description, lockConflictOnRetrievedSessionIndex }) => {
|
|
129
|
-
it(description, (done) => {
|
|
130
|
-
expandSessionState(initialSession)
|
|
131
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({ isLockEnabled: true, initialSession })
|
|
132
|
-
sessionStoreStrategy.planRetrieveSession(lockConflictOnRetrievedSessionIndex, {
|
|
133
|
-
...initialSession,
|
|
134
|
-
lock: createLock(),
|
|
135
|
-
})
|
|
136
|
-
sessionStoreStrategy.planRetrieveSession(lockConflictOnRetrievedSessionIndex + 1, {
|
|
137
|
-
...initialSession,
|
|
138
|
-
other: 'other',
|
|
139
|
-
})
|
|
140
|
-
processSpy.and.callFake((session) => ({ ...session, processed: 'processed' }) as SessionState)
|
|
141
|
-
|
|
142
|
-
processSessionStoreOperations(
|
|
143
|
-
{
|
|
144
|
-
process: processSpy,
|
|
145
|
-
after: (afterSession) => {
|
|
146
|
-
// session with 'other' value on process
|
|
147
|
-
expect(processSpy).toHaveBeenCalledWith({
|
|
148
|
-
...initialSession,
|
|
149
|
-
other: 'other',
|
|
150
|
-
expire: jasmine.any(String),
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
// end state with session 'other' and 'processed' value
|
|
154
|
-
const expectedSession = {
|
|
155
|
-
...initialSession,
|
|
156
|
-
other: 'other',
|
|
157
|
-
processed: 'processed',
|
|
158
|
-
expire: jasmine.any(String),
|
|
159
|
-
}
|
|
160
|
-
expect(sessionStoreStrategy.retrieveSession()).toEqual(expectedSession)
|
|
161
|
-
expect(afterSession).toEqual(expectedSession)
|
|
162
|
-
done()
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
sessionStoreStrategy
|
|
166
|
-
)
|
|
167
|
-
})
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
it('should abort after a max number of retry', () => {
|
|
171
|
-
const clock = mockClock()
|
|
172
|
-
|
|
173
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({
|
|
174
|
-
isLockEnabled: true,
|
|
175
|
-
initialSession: { ...initialSession, lock: createLock() },
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
179
|
-
|
|
180
|
-
clock.tick(LOCK_MAX_TRIES * LOCK_RETRY_DELAY)
|
|
181
|
-
expect(processSpy).not.toHaveBeenCalled()
|
|
182
|
-
expect(afterSpy).not.toHaveBeenCalled()
|
|
183
|
-
expect(sessionStoreStrategy.persistSession).not.toHaveBeenCalled()
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
it('should execute cookie accesses in order', (done) => {
|
|
187
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({
|
|
188
|
-
isLockEnabled: true,
|
|
189
|
-
initialSession: { ...initialSession, lock: createLock() },
|
|
190
|
-
})
|
|
191
|
-
sessionStoreStrategy.planRetrieveSession(1, initialSession)
|
|
192
|
-
|
|
193
|
-
processSessionStoreOperations(
|
|
194
|
-
{
|
|
195
|
-
process: (session) => ({ ...session, value: 'foo' }),
|
|
196
|
-
after: afterSpy,
|
|
197
|
-
},
|
|
198
|
-
sessionStoreStrategy
|
|
199
|
-
)
|
|
200
|
-
processSessionStoreOperations(
|
|
201
|
-
{
|
|
202
|
-
process: (session) => ({ ...session, value: `${session.value || ''}bar` }),
|
|
203
|
-
after: (session) => {
|
|
204
|
-
expect(session.value).toBe('foobar')
|
|
205
|
-
expect(afterSpy).toHaveBeenCalled()
|
|
206
|
-
done()
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
sessionStoreStrategy
|
|
210
|
-
)
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('ignores locks set by an older version of the SDK (without creation date)', () => {
|
|
214
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({
|
|
215
|
-
isLockEnabled: true,
|
|
216
|
-
initialSession: { ...initialSession, lock: 'locked' },
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
220
|
-
expect(processSpy).toHaveBeenCalled()
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
it('ignores expired locks', () => {
|
|
224
|
-
const clock = mockClock()
|
|
225
|
-
const sessionStoreStrategy = createFakeSessionStoreStrategy({
|
|
226
|
-
isLockEnabled: true,
|
|
227
|
-
initialSession: { ...initialSession, lock: createLock() },
|
|
228
|
-
})
|
|
229
|
-
clock.tick(LOCK_EXPIRATION_DELAY + 1)
|
|
230
|
-
processSessionStoreOperations({ process: processSpy, after: afterSpy }, sessionStoreStrategy)
|
|
231
|
-
expect(processSpy).toHaveBeenCalled()
|
|
232
|
-
})
|
|
233
|
-
})
|
|
234
|
-
})
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { mockClock, getSessionState, registerCleanupTask } from '../../../../test'
|
|
2
|
-
import { setCookie, deleteCookie, getCookie, getCurrentSite } from '../../../browser/cookie'
|
|
3
|
-
import type { SessionState } from '../sessionState'
|
|
4
|
-
import { validateAndBuildConfiguration } from '../../configuration'
|
|
5
|
-
import type { InitConfiguration } from '../../configuration'
|
|
6
|
-
import { SESSION_COOKIE_EXPIRATION_DELAY, SESSION_EXPIRATION_DELAY, SESSION_TIME_OUT_DELAY } from '../sessionConstants'
|
|
7
|
-
import { buildCookieOptions, selectCookieStrategy, initCookieStrategy } from './sessionInCookie'
|
|
8
|
-
import { SESSION_STORE_KEY } from './sessionStoreStrategy'
|
|
9
|
-
|
|
10
|
-
const DEFAULT_INIT_CONFIGURATION = { clientToken: 'abc', trackAnonymousUser: true }
|
|
11
|
-
|
|
12
|
-
function setupCookieStrategy(partialInitConfiguration: Partial<InitConfiguration> = {}) {
|
|
13
|
-
const initConfiguration = {
|
|
14
|
-
...DEFAULT_INIT_CONFIGURATION,
|
|
15
|
-
...partialInitConfiguration,
|
|
16
|
-
} as InitConfiguration
|
|
17
|
-
|
|
18
|
-
const configuration = validateAndBuildConfiguration(initConfiguration)!
|
|
19
|
-
const cookieOptions = buildCookieOptions(initConfiguration)!
|
|
20
|
-
|
|
21
|
-
registerCleanupTask(() => deleteCookie(SESSION_STORE_KEY, cookieOptions))
|
|
22
|
-
|
|
23
|
-
return initCookieStrategy(configuration, cookieOptions)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
describe('session in cookie strategy', () => {
|
|
27
|
-
const sessionState: SessionState = { id: '123', created: '0' }
|
|
28
|
-
|
|
29
|
-
it('should persist a session in a cookie', () => {
|
|
30
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
31
|
-
cookieStorageStrategy.persistSession(sessionState)
|
|
32
|
-
const session = cookieStorageStrategy.retrieveSession()
|
|
33
|
-
expect(session).toEqual({ ...sessionState })
|
|
34
|
-
expect(getCookie(SESSION_STORE_KEY)).toBe('id=123&created=0')
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should set `isExpired=1` to the cookie holding the session', () => {
|
|
38
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
39
|
-
spyOn(Math, 'random').and.callFake(() => 0)
|
|
40
|
-
cookieStorageStrategy.persistSession(sessionState)
|
|
41
|
-
cookieStorageStrategy.expireSession(sessionState)
|
|
42
|
-
const session = cookieStorageStrategy.retrieveSession()
|
|
43
|
-
expect(session).toEqual({ isExpired: '1' })
|
|
44
|
-
expect(getSessionState(SESSION_STORE_KEY)).toEqual({ isExpired: '1' })
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should not generate an anonymousId if not present', () => {
|
|
48
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
49
|
-
cookieStorageStrategy.persistSession(sessionState)
|
|
50
|
-
const session = cookieStorageStrategy.retrieveSession()
|
|
51
|
-
expect(session).toEqual({ id: '123', created: '0' })
|
|
52
|
-
expect(getSessionState(SESSION_STORE_KEY)).toEqual({ id: '123', created: '0' })
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should return an empty object if session string is invalid', () => {
|
|
56
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
57
|
-
setCookie(SESSION_STORE_KEY, '{test:42}', 1000)
|
|
58
|
-
const session = cookieStorageStrategy.retrieveSession()
|
|
59
|
-
expect(session).toEqual({})
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
describe('build cookie options', () => {
|
|
63
|
-
const clientToken = 'abc'
|
|
64
|
-
|
|
65
|
-
it('should not be secure nor crossSite by default', () => {
|
|
66
|
-
const cookieOptions = buildCookieOptions({ clientToken })
|
|
67
|
-
expect(cookieOptions).toEqual({ secure: false, crossSite: false, partitioned: false })
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('should be secure when `useSecureSessionCookie` is truthy', () => {
|
|
71
|
-
const cookieOptions = buildCookieOptions({ clientToken, useSecureSessionCookie: true })
|
|
72
|
-
expect(cookieOptions).toEqual({ secure: true, crossSite: false, partitioned: false })
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('should be secure, crossSite and partitioned when `usePartitionedCrossSiteSessionCookie` is truthy', () => {
|
|
76
|
-
const cookieOptions = buildCookieOptions({ clientToken, usePartitionedCrossSiteSessionCookie: true })
|
|
77
|
-
expect(cookieOptions).toEqual({ secure: true, crossSite: true, partitioned: true })
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('should have domain when `trackSessionAcrossSubdomains` is truthy', () => {
|
|
81
|
-
const cookieOptions = buildCookieOptions({ clientToken, trackSessionAcrossSubdomains: true })
|
|
82
|
-
expect(cookieOptions).toEqual({
|
|
83
|
-
secure: false,
|
|
84
|
-
crossSite: false,
|
|
85
|
-
partitioned: false,
|
|
86
|
-
domain: jasmine.any(String),
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
describe('cookie options', () => {
|
|
92
|
-
;[
|
|
93
|
-
{
|
|
94
|
-
initConfiguration: { clientToken: 'abc' },
|
|
95
|
-
cookieOptions: {},
|
|
96
|
-
cookieString: /^oo_cookie_test_[\w-]+=[^;]*;expires=[^;]+;path=\/;samesite=strict$/,
|
|
97
|
-
description: 'should set samesite to strict by default',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
initConfiguration: { clientToken: 'abc', useSecureSessionCookie: true },
|
|
101
|
-
cookieOptions: { secure: true },
|
|
102
|
-
cookieString: /^oo_cookie_test_[\w-]+=[^;]*;expires=[^;]+;path=\/;samesite=strict;secure$/,
|
|
103
|
-
description: 'should add secure attribute when defined',
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
initConfiguration: { clientToken: 'abc', trackSessionAcrossSubdomains: true },
|
|
107
|
-
cookieOptions: { domain: 'foo.bar' },
|
|
108
|
-
cookieString: new RegExp(
|
|
109
|
-
`^oo_cookie_test_[\\w-]+=[^;]*;expires=[^;]+;path=\\/;samesite=strict;domain=${getCurrentSite()}$`
|
|
110
|
-
),
|
|
111
|
-
description: 'should set cookie domain when tracking accross subdomains',
|
|
112
|
-
},
|
|
113
|
-
].forEach(({ description, initConfiguration, cookieString }) => {
|
|
114
|
-
it(description, () => {
|
|
115
|
-
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
|
|
116
|
-
selectCookieStrategy(initConfiguration)
|
|
117
|
-
expect(cookieSetSpy.calls.argsFor(0)[0]).toMatch(cookieString)
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
describe('encode cookie options', () => {
|
|
123
|
-
const config: Partial<InitConfiguration> = { betaEncodeCookieOptions: true }
|
|
124
|
-
|
|
125
|
-
it('should encode cookie options in the cookie value', () => {
|
|
126
|
-
// Some older browsers don't support partitioned cross-site session cookies
|
|
127
|
-
// so instead of testing the cookie value, we test the call to the cookie setter
|
|
128
|
-
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
|
|
129
|
-
const cookieStorageStrategy = setupCookieStrategy({ usePartitionedCrossSiteSessionCookie: true, ...config })
|
|
130
|
-
cookieStorageStrategy.persistSession({ id: '123' })
|
|
131
|
-
|
|
132
|
-
const calls = cookieSetSpy.calls.all()
|
|
133
|
-
const lastCall = calls[calls.length - 1]
|
|
134
|
-
expect(lastCall.args[0]).toMatch(/^_oo_s=id=123&c=1/)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('should not encode cookie options in the cookie value if the session is empty (deleting the cookie)', () => {
|
|
138
|
-
const cookieStorageStrategy = setupCookieStrategy({ usePartitionedCrossSiteSessionCookie: true, ...config })
|
|
139
|
-
cookieStorageStrategy.persistSession({})
|
|
140
|
-
|
|
141
|
-
expect(getCookie(SESSION_STORE_KEY)).toBeUndefined()
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
it('should return the correct session state from the cookies', () => {
|
|
145
|
-
spyOnProperty(document, 'cookie', 'get').and.returnValue('_oo_s=id=123&c=0;_oo_s=id=456&c=1;_oo_s=id=789&c=2')
|
|
146
|
-
const cookieStorageStrategy = setupCookieStrategy({ usePartitionedCrossSiteSessionCookie: true, ...config })
|
|
147
|
-
|
|
148
|
-
expect(cookieStorageStrategy.retrieveSession()).toEqual({ id: '456' })
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
it('should return the session state from the first cookie if there is no match', () => {
|
|
152
|
-
spyOnProperty(document, 'cookie', 'get').and.returnValue('_oo_s=id=123&c=0;_oo_s=id=789&c=2')
|
|
153
|
-
const cookieStorageStrategy = setupCookieStrategy({ usePartitionedCrossSiteSessionCookie: true, ...config })
|
|
154
|
-
|
|
155
|
-
expect(cookieStorageStrategy.retrieveSession()).toEqual({ id: '123' })
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
describe('session in cookie strategy when opt-in anonymous user tracking', () => {
|
|
161
|
-
const anonymousId = 'device-123'
|
|
162
|
-
const sessionState: SessionState = { id: '123', created: '0' }
|
|
163
|
-
|
|
164
|
-
it('should persist with anonymous id', () => {
|
|
165
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
166
|
-
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
|
|
167
|
-
const session = cookieStorageStrategy.retrieveSession()
|
|
168
|
-
expect(session).toEqual({ ...sessionState, anonymousId })
|
|
169
|
-
expect(getCookie(SESSION_STORE_KEY)).toBe('id=123&created=0&aid=device-123')
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
it('should expire with anonymous id', () => {
|
|
173
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
174
|
-
cookieStorageStrategy.expireSession({ ...sessionState, anonymousId })
|
|
175
|
-
const session = cookieStorageStrategy.retrieveSession()
|
|
176
|
-
expect(session).toEqual({ isExpired: '1', anonymousId })
|
|
177
|
-
expect(getCookie(SESSION_STORE_KEY)).toBe('isExpired=1&aid=device-123')
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
it('should persist for one year when opt-in', () => {
|
|
181
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
182
|
-
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
|
|
183
|
-
const clock = mockClock()
|
|
184
|
-
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
|
|
185
|
-
expect(cookieSetSpy.calls.argsFor(0)[0]).toContain(
|
|
186
|
-
new Date(clock.timeStamp(SESSION_COOKIE_EXPIRATION_DELAY)).toUTCString()
|
|
187
|
-
)
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
it('should expire in one year when opt-in', () => {
|
|
191
|
-
const cookieStorageStrategy = setupCookieStrategy()
|
|
192
|
-
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
|
|
193
|
-
const clock = mockClock()
|
|
194
|
-
cookieStorageStrategy.expireSession({ ...sessionState, anonymousId })
|
|
195
|
-
expect(cookieSetSpy.calls.argsFor(0)[0]).toContain(
|
|
196
|
-
new Date(clock.timeStamp(SESSION_COOKIE_EXPIRATION_DELAY)).toUTCString()
|
|
197
|
-
)
|
|
198
|
-
})
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
describe('session in cookie strategy when opt-out anonymous user tracking', () => {
|
|
202
|
-
const anonymousId = 'device-123'
|
|
203
|
-
const sessionState: SessionState = { id: '123', created: '0' }
|
|
204
|
-
|
|
205
|
-
it('should not extend cookie expiration time when opt-out', () => {
|
|
206
|
-
const cookieStorageStrategy = setupCookieStrategy({ trackAnonymousUser: false })
|
|
207
|
-
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
|
|
208
|
-
const clock = mockClock()
|
|
209
|
-
cookieStorageStrategy.expireSession({ ...sessionState, anonymousId })
|
|
210
|
-
expect(cookieSetSpy.calls.argsFor(0)[0]).toContain(new Date(clock.timeStamp(SESSION_TIME_OUT_DELAY)).toUTCString())
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('should not persist with one year when opt-out', () => {
|
|
214
|
-
const cookieStorageStrategy = setupCookieStrategy({ trackAnonymousUser: false })
|
|
215
|
-
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
|
|
216
|
-
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
|
|
217
|
-
expect(cookieSetSpy.calls.argsFor(0)[0]).toContain(new Date(Date.now() + SESSION_EXPIRATION_DELAY).toUTCString())
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
it('should not persist or expire a session with anonymous id when opt-out', () => {
|
|
221
|
-
const cookieStorageStrategy = setupCookieStrategy({ trackAnonymousUser: false })
|
|
222
|
-
cookieStorageStrategy.persistSession({ ...sessionState, anonymousId })
|
|
223
|
-
cookieStorageStrategy.expireSession({ ...sessionState, anonymousId })
|
|
224
|
-
const session = cookieStorageStrategy.retrieveSession()
|
|
225
|
-
expect(session).toEqual({ isExpired: '1' })
|
|
226
|
-
expect(getCookie(SESSION_STORE_KEY)).toBe('isExpired=1')
|
|
227
|
-
})
|
|
228
|
-
})
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { Configuration } from '../../configuration'
|
|
2
|
-
import { SessionPersistence } from '../sessionConstants'
|
|
3
|
-
import { toSessionState } from '../sessionState'
|
|
4
|
-
import type { SessionState } from '../sessionState'
|
|
5
|
-
import { selectLocalStorageStrategy, initLocalStorageStrategy } from './sessionInLocalStorage'
|
|
6
|
-
import { SESSION_STORE_KEY } from './sessionStoreStrategy'
|
|
7
|
-
const DEFAULT_INIT_CONFIGURATION = { trackAnonymousUser: true } as Configuration
|
|
8
|
-
|
|
9
|
-
function getSessionStateFromLocalStorage(SESSION_STORE_KEY: string): SessionState {
|
|
10
|
-
return toSessionState(window.localStorage.getItem(SESSION_STORE_KEY))
|
|
11
|
-
}
|
|
12
|
-
describe('session in local storage strategy', () => {
|
|
13
|
-
const sessionState: SessionState = { id: '123', created: '0' }
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
spyOn(Math, 'random').and.returnValue(0)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
window.localStorage.clear()
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('should report local storage as available', () => {
|
|
23
|
-
const available = selectLocalStorageStrategy()
|
|
24
|
-
expect(available).toEqual({ type: SessionPersistence.LOCAL_STORAGE })
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should report local storage as not available', () => {
|
|
28
|
-
spyOn(Storage.prototype, 'getItem').and.throwError('Unavailable')
|
|
29
|
-
const available = selectLocalStorageStrategy()
|
|
30
|
-
expect(available).toBeUndefined()
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should persist a session in local storage', () => {
|
|
34
|
-
const localStorageStrategy = initLocalStorageStrategy(DEFAULT_INIT_CONFIGURATION)
|
|
35
|
-
localStorageStrategy.persistSession(sessionState)
|
|
36
|
-
const session = localStorageStrategy.retrieveSession()
|
|
37
|
-
expect(session).toEqual({ ...sessionState })
|
|
38
|
-
expect(getSessionStateFromLocalStorage(SESSION_STORE_KEY)).toEqual(sessionState)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('should set `isExpired=1` to the local storage item holding the session', () => {
|
|
42
|
-
const localStorageStrategy = initLocalStorageStrategy(DEFAULT_INIT_CONFIGURATION)
|
|
43
|
-
localStorageStrategy.persistSession(sessionState)
|
|
44
|
-
localStorageStrategy.expireSession(sessionState)
|
|
45
|
-
const session = localStorageStrategy?.retrieveSession()
|
|
46
|
-
expect(session).toEqual({ isExpired: '1' })
|
|
47
|
-
expect(getSessionStateFromLocalStorage(SESSION_STORE_KEY)).toEqual({
|
|
48
|
-
isExpired: '1',
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('should not generate an anonymousId if not present', () => {
|
|
53
|
-
const localStorageStrategy = initLocalStorageStrategy(DEFAULT_INIT_CONFIGURATION)
|
|
54
|
-
localStorageStrategy.persistSession(sessionState)
|
|
55
|
-
const session = localStorageStrategy.retrieveSession()
|
|
56
|
-
expect(session).toEqual({ id: '123', created: '0' })
|
|
57
|
-
expect(getSessionStateFromLocalStorage(SESSION_STORE_KEY)).toEqual({ id: '123', created: '0' })
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('should return an empty object if session string is invalid', () => {
|
|
61
|
-
const localStorageStrategy = initLocalStorageStrategy(DEFAULT_INIT_CONFIGURATION)
|
|
62
|
-
window.localStorage.setItem(SESSION_STORE_KEY, '{test:42}')
|
|
63
|
-
const session = localStorageStrategy.retrieveSession()
|
|
64
|
-
expect(session).toEqual({})
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('should not interfere with other keys present in local storage', () => {
|
|
68
|
-
window.localStorage.setItem('test', 'hello')
|
|
69
|
-
const localStorageStrategy = initLocalStorageStrategy(DEFAULT_INIT_CONFIGURATION)
|
|
70
|
-
localStorageStrategy.persistSession(sessionState)
|
|
71
|
-
localStorageStrategy.retrieveSession()
|
|
72
|
-
localStorageStrategy.expireSession(sessionState)
|
|
73
|
-
expect(window.localStorage.getItem('test')).toEqual('hello')
|
|
74
|
-
})
|
|
75
|
-
})
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { mockSyntheticsWorkerValues } from '../../../test'
|
|
2
|
-
import { getSyntheticsResultId, getSyntheticsTestId, willSyntheticsInjectRum } from './syntheticsWorkerValues'
|
|
3
|
-
|
|
4
|
-
describe('syntheticsWorkerValues', () => {
|
|
5
|
-
describe('willSyntheticsInjectRum', () => {
|
|
6
|
-
it('returns false if nothing is defined', () => {
|
|
7
|
-
mockSyntheticsWorkerValues({}, 'globals')
|
|
8
|
-
|
|
9
|
-
expect(willSyntheticsInjectRum()).toBeFalse()
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it('returns false if the INJECTS_RUM global variable is false', () => {
|
|
13
|
-
mockSyntheticsWorkerValues({ injectsRum: false }, 'globals')
|
|
14
|
-
|
|
15
|
-
expect(willSyntheticsInjectRum()).toBeFalse()
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('returns true if the INJECTS_RUM global variable is truthy', () => {
|
|
19
|
-
mockSyntheticsWorkerValues({ injectsRum: true }, 'globals')
|
|
20
|
-
|
|
21
|
-
expect(willSyntheticsInjectRum()).toBeTrue()
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('returns true if the INJECTS_RUM cookie is truthy', () => {
|
|
25
|
-
mockSyntheticsWorkerValues({ injectsRum: true }, 'cookies')
|
|
26
|
-
|
|
27
|
-
expect(willSyntheticsInjectRum()).toBeTrue()
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
describe('getSyntheticsTestId', () => {
|
|
32
|
-
it('returns undefined if nothing is defined', () => {
|
|
33
|
-
mockSyntheticsWorkerValues({}, 'globals')
|
|
34
|
-
|
|
35
|
-
expect(getSyntheticsTestId()).toBeUndefined()
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('returns the test id if the PUBLIC_ID global variable is defined', () => {
|
|
39
|
-
mockSyntheticsWorkerValues({ publicId: 'toto' }, 'globals')
|
|
40
|
-
|
|
41
|
-
expect(getSyntheticsTestId()).toBe('toto')
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('returns undefined if the PUBLIC_ID global variable is not a string', () => {
|
|
45
|
-
mockSyntheticsWorkerValues({ publicId: 1 }, 'globals')
|
|
46
|
-
|
|
47
|
-
expect(getSyntheticsTestId()).toBeUndefined()
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('returns undefined if the PUBLIC_ID cookie is defined', () => {
|
|
51
|
-
mockSyntheticsWorkerValues({ publicId: 'toto' }, 'cookies')
|
|
52
|
-
|
|
53
|
-
expect(getSyntheticsTestId()).toBe('toto')
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
describe('getSyntheticsResultId', () => {
|
|
58
|
-
it('returns undefined if nothing is defined', () => {
|
|
59
|
-
mockSyntheticsWorkerValues({}, 'globals')
|
|
60
|
-
|
|
61
|
-
expect(getSyntheticsResultId()).toBeUndefined()
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('returns the test id if the RESULT_ID global variable is defined', () => {
|
|
65
|
-
mockSyntheticsWorkerValues({ resultId: 'toto' }, 'globals')
|
|
66
|
-
|
|
67
|
-
expect(getSyntheticsResultId()).toBe('toto')
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('returns undefined if the RESULT_ID global variable is not a string', () => {
|
|
71
|
-
mockSyntheticsWorkerValues({ resultId: 1 }, 'globals')
|
|
72
|
-
|
|
73
|
-
expect(getSyntheticsResultId()).toBeUndefined()
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('returns undefined if the RESULT_ID cookie is defined', () => {
|
|
77
|
-
mockSyntheticsWorkerValues({ resultId: 'toto' }, 'cookies')
|
|
78
|
-
|
|
79
|
-
expect(getSyntheticsResultId()).toBe('toto')
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
})
|