Skip to content

Commit

Permalink
Merge branch 'main' into feat/safer-string-truncation
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldambra authored Oct 21, 2024
2 parents aa38206 + 81e97f1 commit c718cb6
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 27 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
## 1.174.2 - 2024-10-18

- fix: no need to swallow import errors (#1486)

## 1.174.1 - 2024-10-18

- fix: do not capture entire elements in web vitals (#1483)

## 1.174.0 - 2024-10-17

- Make entire cancel button area clickable (#1473)
- feat: swap the default to identified_only (#1468)

## 1.173.0 - 2024-10-17

- feat(web-analytics): Store nulls for unset campaign params (#1482)

## 1.172.1 - 2024-10-17

- chore: add crossOrigin='anonymous' to snippet script (#1481)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "posthog-js",
"version": "1.172.1",
"version": "1.174.2",
"description": "Posthog-js allows you to automatically capture usage and send events to PostHog.",
"repository": "https:/PostHog/posthog-js",
"author": "[email protected]",
Expand Down
141 changes: 138 additions & 3 deletions src/__tests__/personProcessing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,37 @@ import { createPosthogInstance } from './helpers/posthog-instance'
import { uuidv7 } from '../uuidv7'
import { logger } from '../utils/logger'
import { INITIAL_CAMPAIGN_PARAMS, INITIAL_REFERRER_INFO } from '../constants'
import { DecideResponse } from '../types'

jest.mock('../utils/logger')

const INITIAL_CAMPAIGN_PARAMS_NULL = {
$initial_current_url: null,
$initial_dclid: null,
$initial_fbclid: null,
$initial_gad_source: null,
$initial_gbraid: null,
$initial_gclid: null,
$initial_gclsrc: null,
$initial_host: null,
$initial_igshid: null,
$initial_li_fat_id: null,
$initial_mc_cid: null,
$initial_msclkid: null,
$initial_pathname: null,
$initial_rdt_cid: null,
$initial_referrer: null,
$initial_referring_domain: null,
$initial_ttclid: null,
$initial_twclid: null,
$initial_utm_campaign: null,
$initial_utm_content: null,
$initial_utm_medium: null,
$initial_utm_source: null,
$initial_utm_term: null,
$initial_wbraid: null,
}

jest.mock('../utils/globals', () => {
const orig = jest.requireActual('../utils/globals')
const mockURLGetter = jest.fn()
Expand Down Expand Up @@ -44,18 +72,23 @@ describe('person processing', () => {
mockURLGetter.mockReturnValue('https://example.com?utm_source=foo')
})

const setup = async (person_profiles: 'always' | 'identified_only' | 'never' | undefined, token?: string) => {
const setup = async (
person_profiles: 'always' | 'identified_only' | 'never' | undefined,
token?: string,
persistence_name?: string
) => {
token = token || uuidv7()
const onCapture = jest.fn()
const posthog = await createPosthogInstance(token, {
_onCapture: onCapture,
person_profiles,
persistence_name,
})
return { token, onCapture, posthog }
}

describe('init', () => {
it("should default to 'always' person_profiles", async () => {
it("should default to 'identified_only' person_profiles", async () => {
// arrange
const token = uuidv7()

Expand All @@ -65,7 +98,7 @@ describe('person processing', () => {
})

// assert
expect(posthog.config.person_profiles).toEqual('always')
expect(posthog.config.person_profiles).toEqual('identified_only')
})
it('should read person_profiles from init config', async () => {
// arrange
Expand Down Expand Up @@ -171,6 +204,7 @@ describe('person processing', () => {
const identifyCall = onCapture.mock.calls[0]
expect(identifyCall[0]).toEqual('$identify')
expect(identifyCall[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example.com?utm_source=foo',
$initial_host: 'example.com',
$initial_pathname: '/',
Expand Down Expand Up @@ -213,6 +247,7 @@ describe('person processing', () => {

expect(eventS2Identify[0]).toEqual('$identify')
expect(eventS2Identify[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example1.com/pathname1?utm_source=foo1',
$initial_host: 'example1.com',
$initial_pathname: '/pathname1',
Expand All @@ -223,6 +258,7 @@ describe('person processing', () => {

expect(eventS2After[0]).toEqual('event s2 after identify')
expect(eventS2After[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example1.com/pathname1?utm_source=foo1',
$initial_host: 'example1.com',
$initial_pathname: '/pathname1',
Expand All @@ -243,6 +279,7 @@ describe('person processing', () => {
const identifyCall = onCapture.mock.calls[0]
expect(identifyCall[0]).toEqual('$identify')
expect(identifyCall[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example.com?utm_source=foo',
$initial_host: 'example.com',
$initial_pathname: '/',
Expand All @@ -264,6 +301,7 @@ describe('person processing', () => {
const identifyCall = onCapture.mock.calls[0]
expect(identifyCall[0]).toEqual('$identify')
expect(identifyCall[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example.com?utm_source=foo',
$initial_host: 'example.com',
$initial_pathname: '/',
Expand Down Expand Up @@ -315,6 +353,7 @@ describe('person processing', () => {
expect(eventBeforeIdentify[1].$set_once).toBeUndefined()
const eventAfterIdentify = onCapture.mock.calls[2]
expect(eventAfterIdentify[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example.com?utm_source=foo',
$initial_host: 'example.com',
$initial_pathname: '/',
Expand All @@ -336,6 +375,7 @@ describe('person processing', () => {
// assert
const eventBeforeIdentify = onCapture.mock.calls[0]
expect(eventBeforeIdentify[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example.com?utm_source=foo',
$initial_host: 'example.com',
$initial_pathname: '/',
Expand All @@ -345,6 +385,7 @@ describe('person processing', () => {
})
const eventAfterIdentify = onCapture.mock.calls[2]
expect(eventAfterIdentify[1].$set_once).toEqual({
...INITIAL_CAMPAIGN_PARAMS_NULL,
$initial_current_url: 'https://example.com?utm_source=foo',
$initial_host: 'example.com',
$initial_pathname: '/',
Expand Down Expand Up @@ -547,4 +588,98 @@ describe('person processing', () => {
expect(onCapture.mock.calls[2][1].properties.$process_person_profile).toEqual(false)
})
})

describe('persistence', () => {
it('should remember that a user set the mode to always on a previous visit', async () => {
// arrange
const persistenceName = uuidv7()
const { posthog: posthog1, onCapture: onCapture1 } = await setup('always', undefined, persistenceName)
posthog1.capture('custom event 1')
const { posthog: posthog2, onCapture: onCapture2 } = await setup(
'identified_only',
undefined,
persistenceName
)

// act
posthog2.capture('custom event 2')

// assert
expect(onCapture1.mock.calls.length).toEqual(1)
expect(onCapture2.mock.calls.length).toEqual(1)
expect(onCapture1.mock.calls[0][1].properties.$process_person_profile).toEqual(true)
expect(onCapture2.mock.calls[0][1].properties.$process_person_profile).toEqual(true)
})

it('should work when always is set on a later visit', async () => {
// arrange
const persistenceName = uuidv7()
const { posthog: posthog1, onCapture: onCapture1 } = await setup(
'identified_only',
undefined,
persistenceName
)
posthog1.capture('custom event 1')
const { posthog: posthog2, onCapture: onCapture2 } = await setup('always', undefined, persistenceName)

// act
posthog2.capture('custom event 2')

// assert
expect(onCapture1.mock.calls.length).toEqual(1)
expect(onCapture2.mock.calls.length).toEqual(1)
expect(onCapture1.mock.calls[0][1].properties.$process_person_profile).toEqual(false)
expect(onCapture2.mock.calls[0][1].properties.$process_person_profile).toEqual(true)
})
})

describe('decide', () => {
it('should change the person mode from default when decide response is handled', async () => {
// arrange
const { posthog, onCapture } = await setup(undefined)
posthog.capture('startup page view')

// act
posthog._afterDecideResponse({ defaultIdentifiedOnly: false } as DecideResponse)
posthog.capture('custom event')

// assert
expect(onCapture.mock.calls.length).toEqual(2)
expect(onCapture.mock.calls[0][1].properties.$process_person_profile).toEqual(false)
expect(onCapture.mock.calls[1][1].properties.$process_person_profile).toEqual(true)
})

it('should NOT change the person mode from user-defined when decide response is handled', async () => {
// arrange
const { posthog, onCapture } = await setup('identified_only')
posthog.capture('startup page view')

// act
posthog._afterDecideResponse({ defaultIdentifiedOnly: false } as DecideResponse)
posthog.capture('custom event')

// assert
expect(onCapture.mock.calls.length).toEqual(2)
expect(onCapture.mock.calls[0][1].properties.$process_person_profile).toEqual(false)
expect(onCapture.mock.calls[1][1].properties.$process_person_profile).toEqual(false)
})

it('should persist when the default person mode is overridden by decide', async () => {
// arrange
const persistenceName = uuidv7()
const { posthog: posthog1, onCapture: onCapture1 } = await setup(undefined, undefined, persistenceName)

// act
posthog1._afterDecideResponse({ defaultIdentifiedOnly: false } as DecideResponse)
posthog1.capture('custom event 1')
const { posthog: posthog2, onCapture: onCapture2 } = await setup(undefined, undefined, persistenceName)
posthog2.capture('custom event 2')

// assert
expect(onCapture1.mock.calls.length).toEqual(1)
expect(onCapture2.mock.calls.length).toEqual(1)
expect(onCapture1.mock.calls[0][1].properties.$process_person_profile).toEqual(true)
expect(onCapture2.mock.calls[0][1].properties.$process_person_profile).toEqual(true)
})
})
})
4 changes: 4 additions & 0 deletions src/__tests__/posthog-core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ describe('posthog core', () => {
const { posthog, onCapture } = setup({
token,
persistence_name: token,
person_profiles: 'always',
})

// act
Expand All @@ -141,6 +142,7 @@ describe('posthog core', () => {
const { posthog: posthog1 } = setup({
token,
persistence_name: token,
person_profiles: 'always',
})
posthog1.capture(eventName, eventProperties)
mockReferrerGetter.mockReturnValue('https://referrer2.example.com/some/path')
Expand Down Expand Up @@ -171,6 +173,7 @@ describe('posthog core', () => {
const { posthog: posthog1 } = setup({
token,
persistence_name: token,
person_profiles: 'always',
})
posthog1.capture(eventName, eventProperties)
mockReferrerGetter.mockReturnValue('https://referrer2.example.com/some/path')
Expand Down Expand Up @@ -201,6 +204,7 @@ describe('posthog core', () => {
const { posthog, onCapture } = setup({
token,
persistence_name: token,
person_profiles: 'always',
})

// act
Expand Down
27 changes: 22 additions & 5 deletions src/__tests__/posthog-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Info } from '../utils/event-utils'
import { document, window } from '../utils/globals'
import { uuidv7 } from '../uuidv7'
import * as globals from '../utils/globals'
import { USER_STATE } from '../constants'
import { ENABLE_PERSON_PROCESSING, USER_STATE } from '../constants'
import { createPosthogInstance, defaultPostHog } from './helpers/posthog-instance'
import { logger } from '../utils/logger'
import { DecideResponse, PostHogConfig } from '../types'
Expand Down Expand Up @@ -345,6 +345,20 @@ describe('posthog core', () => {

expect(posthog.compression).toEqual('gzip-js')
})
it('uses defaultIdentifiedOnly from decide response', () => {
const posthog = posthogWith({})

posthog._afterDecideResponse({ defaultIdentifiedOnly: true } as DecideResponse)
expect(posthog.config.person_profiles).toEqual('identified_only')

posthog._afterDecideResponse({ defaultIdentifiedOnly: false } as DecideResponse)
expect(posthog.config.person_profiles).toEqual('always')
})
it('defaultIdentifiedOnly does not override person_profiles if already set', () => {
const posthog = posthogWith({ person_profiles: 'always' })
posthog._afterDecideResponse({ defaultIdentifiedOnly: true } as DecideResponse)
expect(posthog.config.person_profiles).toEqual('always')
})

it('enables compression from decide response when only one received', () => {
const posthog = posthogWith({})
Expand Down Expand Up @@ -387,6 +401,8 @@ describe('posthog core', () => {
properties: () => ({ distinct_id: 'abc', persistent: 'prop', $is_identified: false }),
remove_event_timer: jest.fn(),
get_property: () => 'anonymous',
props: {},
register: jest.fn(),
} as unknown as PostHogPersistence,
sessionPersistence: {
properties: () => ({ distinct_id: 'abc', persistent: 'prop' }),
Expand Down Expand Up @@ -425,7 +441,7 @@ describe('posthog core', () => {
$window_id: 'windowId',
$session_id: 'sessionId',
$is_identified: false,
$process_person_profile: true,
$process_person_profile: false,
})
})

Expand All @@ -447,7 +463,7 @@ describe('posthog core', () => {
$session_id: 'sessionId',
$lib_custom_api_host: 'https://custom.posthog.com',
$is_identified: false,
$process_person_profile: true,
$process_person_profile: false,
})
})

Expand All @@ -465,7 +481,7 @@ describe('posthog core', () => {
posthog._calculate_event_properties('custom_event', { event: 'prop' }, new Date())[
'$process_person_profile'
]
).toEqual(true)
).toEqual(false)
})

it('only adds token and distinct_id if event_name is $snapshot', () => {
Expand Down Expand Up @@ -496,7 +512,7 @@ describe('posthog core', () => {
expect(posthog._calculate_event_properties('custom_event', { event: 'prop' }, new Date())).toEqual({
event_name: 'custom_event',
token: 'testtoken',
$process_person_profile: true,
$process_person_profile: false,
})
})

Expand All @@ -510,6 +526,7 @@ describe('posthog core', () => {
)

posthog.persistence.get_initial_props = () => ({ initial: 'prop' })
posthog.persistence.props[ENABLE_PERSON_PROCESSING] = true // person processing is needed for $set_once
expect(posthog._calculate_set_once_properties({ key: 'prop' })).toEqual({
event_name: '$set_once',
token: undefined,
Expand Down
Loading

0 comments on commit c718cb6

Please sign in to comment.