Skip to content

Commit

Permalink
Improve unit tests with getSessionState from cookie
Browse files Browse the repository at this point in the history
  • Loading branch information
cy-moi committed Jan 23, 2025
1 parent 23f3eb3 commit c1b513e
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 81 deletions.
24 changes: 12 additions & 12 deletions packages/core/src/domain/session/oldCookiesMigration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getCookie, resetInitCookies, setCookie } from '../../browser/cookie'
import { getSessionState } from '../../../test'
import type { Configuration } from '../configuration'
import {
OLD_LOGS_COOKIE_NAME,
Expand Down Expand Up @@ -39,20 +40,19 @@ describe('old cookies migration', () => {

tryOldCookiesMigration(sessionStoreStrategy)

expect(getCookie(SESSION_STORE_KEY)).toContain('id=abcde')
expect(getCookie(SESSION_STORE_KEY)).toContain('rum=0')
expect(getCookie(SESSION_STORE_KEY)).toContain('logs=1')
expect(getCookie(SESSION_STORE_KEY)).toMatch(/expire=\d+/)
expect(getSessionState(SESSION_STORE_KEY).id).toBe('id=abcde')
expect(getSessionState(SESSION_STORE_KEY).rum).toBe('0')
expect(getSessionState(SESSION_STORE_KEY).logs).toBe('1')
expect(getSessionState(SESSION_STORE_KEY).expire).toBe(jasmine.stringMatching(/\d+/))
})

it('should create new cookie from a single old cookie', () => {
setCookie(OLD_RUM_COOKIE_NAME, '0', SESSION_EXPIRATION_DELAY)

tryOldCookiesMigration(sessionStoreStrategy)

expect(getCookie(SESSION_STORE_KEY)).not.toContain('id=')
expect(getCookie(SESSION_STORE_KEY)).toContain('rum=0')
expect(getCookie(SESSION_STORE_KEY)).toMatch(/expire=\d+/)
expect(getSessionState(SESSION_STORE_KEY).id).not.toBeDefined()
expect(getSessionState(SESSION_STORE_KEY).rum).toBe('0')
expect(getSessionState(SESSION_STORE_KEY).expire).toBe(jasmine.stringMatching(/\d+/))
})

it('should not create a new cookie if no old cookie is present', () => {
Expand All @@ -68,9 +68,9 @@ describe('old cookies migration', () => {
tryOldCookiesMigration(sessionStoreStrategy)
tryOldCookiesMigration(sessionStoreStrategy)

expect(getCookie(SESSION_STORE_KEY)).toContain('id=abcde')
expect(getCookie(SESSION_STORE_KEY)).toContain('rum=0')
expect(getCookie(SESSION_STORE_KEY)).toContain('logs=1')
expect(getCookie(SESSION_STORE_KEY)).toMatch(/expire=\d+/)
expect(getSessionState(SESSION_STORE_KEY).id).toBe('abcde')
expect(getSessionState(SESSION_STORE_KEY).rum).toBe('0')
expect(getSessionState(SESSION_STORE_KEY).logs).toBe('1')
expect(getSessionState(SESSION_STORE_KEY).expire).toBe(jasmine.stringMatching(/\d+/))
})
})
29 changes: 15 additions & 14 deletions packages/core/src/domain/session/sessionManager.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
createNewEvent,
expireCookie,
getSessionState,
mockClock,
registerCleanupTask,
restorePageVisibility,
Expand Down Expand Up @@ -54,25 +55,25 @@ describe('startSessionManager', () => {

function expectSessionIdToBe(sessionManager: SessionManager<FakeTrackingType>, sessionId: string) {
expect(sessionManager.findSession()!.id).toBe(sessionId)
expect(getCookie(SESSION_STORE_KEY)).toContain(`id=${sessionId}`)
expect(getSessionState(SESSION_STORE_KEY).id).toBe(sessionId)
}

function expectSessionIdToBeDefined(sessionManager: SessionManager<FakeTrackingType>) {
expect(sessionManager.findSession()!.id).toMatch(/^[a-f0-9-]+$/)
expect(sessionManager.findSession()?.isExpired).toBeUndefined()

expect(getCookie(SESSION_STORE_KEY)).toMatch(/\bid=[a-f0-9-]+/)
expect(getCookie(SESSION_STORE_KEY)).not.toContain('isExpired=1')
expect(getSessionState(SESSION_STORE_KEY).id).toMatch(/^[a-f0-9-]+$/)
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBeUndefined()
}

function expectSessionToBeExpired(sessionManager: SessionManager<FakeTrackingType>) {
expect(sessionManager.findSession()).toBeUndefined()
expect(getCookie(SESSION_STORE_KEY)).toContain('isExpired=1')
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBe('1')
}

function expectSessionIdToNotBeDefined(sessionManager: SessionManager<FakeTrackingType>) {
expect(sessionManager.findSession()!.id).toBeUndefined()
expect(getCookie(SESSION_STORE_KEY)).not.toMatch(/\bid=/)
expect(getSessionState(SESSION_STORE_KEY).id).toBeUndefined()
}

function expectTrackingTypeToBe(
Expand All @@ -81,12 +82,12 @@ describe('startSessionManager', () => {
trackingType: FakeTrackingType
) {
expect(sessionManager.findSession()!.trackingType).toEqual(trackingType)
expect(getCookie(SESSION_STORE_KEY)).toContain(`${productKey}=${trackingType}`)
expect(getSessionState(SESSION_STORE_KEY)[productKey]).toEqual(trackingType)
}

function expectTrackingTypeToNotBeDefined(sessionManager: SessionManager<FakeTrackingType>, productKey: string) {
expect(sessionManager.findSession()?.trackingType).toBeUndefined()
expect(getCookie(SESSION_STORE_KEY)).not.toContain(`${productKey}=`)
expect(getSessionState(SESSION_STORE_KEY)[productKey]).toBeUndefined()
}

beforeEach(() => {
Expand Down Expand Up @@ -269,14 +270,14 @@ describe('startSessionManager', () => {
startSessionManagerWithDefaults({ productKey: SECOND_PRODUCT_KEY })

// cookie correctly set
expect(getCookie(SESSION_STORE_KEY)).toContain('first')
expect(getCookie(SESSION_STORE_KEY)).toContain('second')
expect(getSessionState(SESSION_STORE_KEY).first).toBeDefined()
expect(getSessionState(SESSION_STORE_KEY).second).toBeDefined()

clock.tick(STORAGE_POLL_DELAY / 2)

// scheduled expandOrRenewSession should not use cached value
expect(getCookie(SESSION_STORE_KEY)).toContain('first')
expect(getCookie(SESSION_STORE_KEY)).toContain('second')
expect(getSessionState(SESSION_STORE_KEY).first).toBeDefined()
expect(getSessionState(SESSION_STORE_KEY).second).toBeDefined()
})

it('should have independent tracking types', () => {
Expand Down Expand Up @@ -342,7 +343,7 @@ describe('startSessionManager', () => {
sessionManager.expireObservable.subscribe(expireSessionSpy)

expect(sessionManager.findSession()!.id).not.toBe('abcde')
expect(getCookie(SESSION_STORE_KEY)).toContain(`created=${Date.now()}`)
expect(getSessionState(SESSION_STORE_KEY).created).toEqual(Date.now().toString())
expect(expireSessionSpy).not.toHaveBeenCalled() // the session has not been active from the start
})

Expand All @@ -352,7 +353,7 @@ describe('startSessionManager', () => {
const sessionManager = startSessionManagerWithDefaults()

expect(sessionManager.findSession()!.id).toBe('abcde')
expect(getCookie(SESSION_STORE_KEY)).not.toContain('created=')
expect(getSessionState(SESSION_STORE_KEY).created).toBeUndefined()
})
})

Expand Down Expand Up @@ -598,7 +599,7 @@ describe('startSessionManager', () => {
trackingConsentState.update(TrackingConsent.NOT_GRANTED)

expectSessionToBeExpired(sessionManager)
expect(getCookie(SESSION_STORE_KEY)).toBe('isExpired=1')
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBe('1')
})

it('does not renew the session when tracking consent is withdrawn', () => {
Expand Down
24 changes: 12 additions & 12 deletions packages/core/src/domain/session/sessionStore.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Clock } from '../../../test'
import { expireCookie, mockClock } from '../../../test'
import { getCookie, setCookie } from '../../browser/cookie'
import { expireCookie, mockClock, getSessionState } from '../../../test'
import { setCookie } from '../../browser/cookie'
import type { InitConfiguration, Configuration } from '../configuration'
import { display } from '../../tools/display'
import type { SessionStore } from './sessionStore'
Expand Down Expand Up @@ -32,25 +32,25 @@ function setSessionInStore(trackingType: FakeTrackingType = FakeTrackingType.TRA
}

function expectTrackedSessionToBeInStore(id?: string) {
expect(getCookie(SESSION_STORE_KEY)).toMatch(new RegExp(`id=${id ? id : '[a-f0-9-]+'}`))
expect(getCookie(SESSION_STORE_KEY)).not.toContain('isExpired=1')
expect(getCookie(SESSION_STORE_KEY)).toContain(`${PRODUCT_KEY}=${FakeTrackingType.TRACKED}`)
expect(getSessionState(SESSION_STORE_KEY).id).toEqual(id ? id : jasmine.any(String))
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBeUndefined()
expect(getSessionState(SESSION_STORE_KEY)[PRODUCT_KEY]).toEqual(FakeTrackingType.TRACKED)
}

function expectNotTrackedSessionToBeInStore() {
expect(getCookie(SESSION_STORE_KEY)).not.toMatch(/\bid=/)
expect(getCookie(SESSION_STORE_KEY)).not.toContain('isExpired=1')
expect(getCookie(SESSION_STORE_KEY)).toContain(`${PRODUCT_KEY}=${FakeTrackingType.NOT_TRACKED}`)
expect(getSessionState(SESSION_STORE_KEY).id).toBeUndefined()
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBeUndefined()
expect(getSessionState(SESSION_STORE_KEY)[PRODUCT_KEY]).toEqual(FakeTrackingType.NOT_TRACKED)
}

function expectSessionToBeExpiredInStore() {
expect(getCookie(SESSION_STORE_KEY)).toContain('isExpired=1')
expect(getCookie(SESSION_STORE_KEY)).not.toMatch(/\bid=/)
expect(getCookie(SESSION_STORE_KEY)).not.toContain(`${PRODUCT_KEY}=`)
expect(getSessionState(SESSION_STORE_KEY).isExpired).toEqual(IS_EXPIRED)
expect(getSessionState(SESSION_STORE_KEY).id).toBeUndefined()
expect(getSessionState(SESSION_STORE_KEY)[PRODUCT_KEY]).toBeUndefined()
}

function getStoreExpiration() {
return /expire=(\d+)/.exec(getCookie(SESSION_STORE_KEY)!)?.[1]
return getSessionState(SESSION_STORE_KEY).expire
}

function resetSessionInStore() {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export {
export { CustomerDataType } from './domain/context/contextConstants'
export { createValueHistory, ValueHistory, ValueHistoryEntry, CLEAR_OLD_VALUES_INTERVAL } from './tools/valueHistory'
export { readBytesFromStream } from './tools/readBytesFromStream'
export type { SessionState } from './domain/session/sessionState'
export { STORAGE_POLL_DELAY } from './domain/session/sessionStore'
export { SESSION_STORE_KEY } from './domain/session/storeStrategies/sessionStoreStrategy'
export {
Expand Down
7 changes: 6 additions & 1 deletion packages/core/test/cookie.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { setCookie } from '../src/browser/cookie'
import { getCookie, setCookie } from '../src/browser/cookie'
import { toSessionState } from '../src/domain/session/sessionState'
import { SESSION_STORE_KEY } from '../src/domain/session/storeStrategies/sessionStoreStrategy'
import { ONE_MINUTE } from '../src/tools/utils/timeUtils'

export function expireCookie() {
setCookie(SESSION_STORE_KEY, 'isExpired=1', ONE_MINUTE)
}

export function getSessionState(sessionStoreKey: string) {
return toSessionState(getCookie(sessionStoreKey))
}
23 changes: 11 additions & 12 deletions packages/logs/src/domain/logsSessionManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { RelativeTime } from '@datadog/browser-core'
import {
STORAGE_POLL_DELAY,
SESSION_STORE_KEY,
getCookie,
setCookie,
stopSessionManager,
ONE_SECOND,
Expand All @@ -13,7 +12,7 @@ import {
SessionPersistence,
} from '@datadog/browser-core'
import type { Clock } from '@datadog/browser-core/test'
import { createNewEvent, expireCookie, mockClock } from '@datadog/browser-core/test'
import { createNewEvent, expireCookie, getSessionState, mockClock } from '@datadog/browser-core/test'

import type { LogsConfiguration } from './configuration'
import {
Expand Down Expand Up @@ -42,45 +41,45 @@ describe('logs session manager', () => {
it('when tracked should store tracking type and session id', () => {
startLogsSessionManagerWithDefaults()

expect(getCookie(SESSION_STORE_KEY)).toContain(`${LOGS_SESSION_KEY}=${LoggerTrackingType.TRACKED}`)
expect(getCookie(SESSION_STORE_KEY)).toMatch(/\bid=[a-f0-9-]+/)
expect(getSessionState(SESSION_STORE_KEY).id).toMatch(/[a-f0-9-]+/)
expect(getSessionState(SESSION_STORE_KEY)[LOGS_SESSION_KEY]).toBe(LoggerTrackingType.TRACKED)
})

it('when not tracked should store tracking type', () => {
startLogsSessionManagerWithDefaults({ configuration: { sessionSampleRate: 0 } })

expect(getCookie(SESSION_STORE_KEY)).toContain(`${LOGS_SESSION_KEY}=${LoggerTrackingType.NOT_TRACKED}`)
expect(getCookie(SESSION_STORE_KEY)).not.toContain('isExpired=1')
expect(getSessionState(SESSION_STORE_KEY)[LOGS_SESSION_KEY]).toBe(LoggerTrackingType.NOT_TRACKED)
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBeUndefined()
})

it('when tracked should keep existing tracking type and session id', () => {
setCookie(SESSION_STORE_KEY, 'id=abcdef&logs=1', DURATION)

startLogsSessionManagerWithDefaults()

expect(getCookie(SESSION_STORE_KEY)).toContain(`${LOGS_SESSION_KEY}=${LoggerTrackingType.TRACKED}`)
expect(getCookie(SESSION_STORE_KEY)).toContain('id=abcdef')
expect(getSessionState(SESSION_STORE_KEY).id).toBe('abcdef')
expect(getSessionState(SESSION_STORE_KEY)[LOGS_SESSION_KEY]).toBe(LoggerTrackingType.TRACKED)
})

it('when not tracked should keep existing tracking type', () => {
setCookie(SESSION_STORE_KEY, 'logs=0', DURATION)

startLogsSessionManagerWithDefaults()

expect(getCookie(SESSION_STORE_KEY)).toContain(`${LOGS_SESSION_KEY}=${LoggerTrackingType.NOT_TRACKED}`)
expect(getSessionState(SESSION_STORE_KEY)[LOGS_SESSION_KEY]).toBe(LoggerTrackingType.NOT_TRACKED)
})

it('should renew on activity after expiration', () => {
startLogsSessionManagerWithDefaults()

expireCookie()
expect(getCookie(SESSION_STORE_KEY)).toBe('isExpired=1')
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBe('1')
clock.tick(STORAGE_POLL_DELAY)

document.body.dispatchEvent(createNewEvent(DOM_EVENT.CLICK))

expect(getCookie(SESSION_STORE_KEY)).toMatch(/\bid=[a-f0-9-]+/)
expect(getCookie(SESSION_STORE_KEY)).toContain(`${LOGS_SESSION_KEY}=${LoggerTrackingType.TRACKED}`)
expect(getSessionState(SESSION_STORE_KEY).id).toMatch(/[a-f0-9-]+/)
expect(getSessionState(SESSION_STORE_KEY)[LOGS_SESSION_KEY]).toBe(LoggerTrackingType.TRACKED)
})

describe('findTrackedSession', () => {
Expand Down
37 changes: 15 additions & 22 deletions packages/rum-core/src/domain/rumSessionManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { RelativeTime } from '@datadog/browser-core'
import {
STORAGE_POLL_DELAY,
SESSION_STORE_KEY,
getCookie,
setCookie,
stopSessionManager,
ONE_SECOND,
Expand All @@ -15,6 +14,7 @@ import type { Clock } from '@datadog/browser-core/test'
import {
createNewEvent,
expireCookie,
getSessionState,
mockEventBridge,
mockClock,
registerCleanupTask,
Expand Down Expand Up @@ -61,31 +61,28 @@ describe('rum session manager', () => {

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()
expect(getCookie(SESSION_STORE_KEY)).toContain(
`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_WITH_SESSION_REPLAY}`
)
expect(getCookie(SESSION_STORE_KEY)).toMatch(/\bid=[a-f0-9-]/)

expect(getSessionState(SESSION_STORE_KEY).id).toMatch(/[a-f0-9-]/)
expect(getSessionState(SESSION_STORE_KEY)[RUM_SESSION_KEY]).toBe(RumTrackingType.TRACKED_WITH_SESSION_REPLAY)
})

it('when tracked without session replay should store session type and id', () => {
startRumSessionManagerWithDefaults({ configuration: { sessionSampleRate: 100, sessionReplaySampleRate: 0 } })

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()
expect(getCookie(SESSION_STORE_KEY)).toContain(
`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_WITHOUT_SESSION_REPLAY}`
)
expect(getCookie(SESSION_STORE_KEY)).toMatch(/\bid=[a-f0-9-]/)
expect(getSessionState(SESSION_STORE_KEY).id).toMatch(/[a-f0-9-]/)
expect(getSessionState(SESSION_STORE_KEY)[RUM_SESSION_KEY]).toBe(RumTrackingType.TRACKED_WITHOUT_SESSION_REPLAY)
})

it('when not tracked should store session type', () => {
startRumSessionManagerWithDefaults({ configuration: { sessionSampleRate: 0 } })

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()
expect(getCookie(SESSION_STORE_KEY)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.NOT_TRACKED}`)
expect(getCookie(SESSION_STORE_KEY)).not.toMatch(/\bid=/)
expect(getCookie(SESSION_STORE_KEY)).not.toContain('isExpired=1')
expect(getSessionState(SESSION_STORE_KEY)[RUM_SESSION_KEY]).toBe(RumTrackingType.NOT_TRACKED)
expect(getSessionState(SESSION_STORE_KEY).id).not.toBeDefined()
expect(getSessionState(SESSION_STORE_KEY).isExpired).not.toBeDefined()
})

it('when tracked should keep existing session type and id', () => {
Expand All @@ -95,10 +92,8 @@ describe('rum session manager', () => {

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()
expect(getCookie(SESSION_STORE_KEY)).toContain(
`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_WITH_SESSION_REPLAY}`
)
expect(getCookie(SESSION_STORE_KEY)).toContain('id=abcdef')
expect(getSessionState(SESSION_STORE_KEY).id).toBe('abcdef')
expect(getSessionState(SESSION_STORE_KEY)[RUM_SESSION_KEY]).toBe(RumTrackingType.TRACKED_WITH_SESSION_REPLAY)
})

it('when not tracked should keep existing session type', () => {
Expand All @@ -108,7 +103,7 @@ describe('rum session manager', () => {

expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()
expect(getCookie(SESSION_STORE_KEY)).toContain(`${RUM_SESSION_KEY}=${RumTrackingType.NOT_TRACKED}`)
expect(getSessionState(SESSION_STORE_KEY)[RUM_SESSION_KEY]).toBe(RumTrackingType.NOT_TRACKED)
})

it('should renew on activity after expiration', () => {
Expand All @@ -117,7 +112,7 @@ describe('rum session manager', () => {
startRumSessionManagerWithDefaults({ configuration: { sessionSampleRate: 100, sessionReplaySampleRate: 100 } })

expireCookie()
expect(getCookie(SESSION_STORE_KEY)).toEqual('isExpired=1')
expect(getSessionState(SESSION_STORE_KEY).isExpired).toBe('1')
expect(expireSessionSpy).not.toHaveBeenCalled()
expect(renewSessionSpy).not.toHaveBeenCalled()
clock.tick(STORAGE_POLL_DELAY)
Expand All @@ -126,10 +121,8 @@ describe('rum session manager', () => {

expect(expireSessionSpy).toHaveBeenCalled()
expect(renewSessionSpy).toHaveBeenCalled()
expect(getCookie(SESSION_STORE_KEY)).toContain(
`${RUM_SESSION_KEY}=${RumTrackingType.TRACKED_WITH_SESSION_REPLAY}`
)
expect(getCookie(SESSION_STORE_KEY)).toMatch(/\bid=[a-f0-9-]/)
expect(getSessionState(SESSION_STORE_KEY)[RUM_SESSION_KEY]).toBe(RumTrackingType.TRACKED_WITH_SESSION_REPLAY)
expect(getSessionState(SESSION_STORE_KEY).id).toMatch(/[a-f0-9-]/)
})
})

Expand Down
Loading

0 comments on commit c1b513e

Please sign in to comment.