Skip to content

Commit

Permalink
Merge branch 'master' into fix/optional-values
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/posthog-core.ts
  • Loading branch information
benjackwhite committed Aug 10, 2023
2 parents d80f427 + fd04266 commit ab43482
Show file tree
Hide file tree
Showing 25 changed files with 312 additions and 395 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.75.4 - 2023-08-09

- feat: remove old UUID code (#755)

## 1.75.3 - 2023-08-02

- chore: remove unused capture metrics (#766)
Expand Down
136 changes: 59 additions & 77 deletions cypress/e2e/identify.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,93 +10,75 @@ function setup(initOptions) {
}

describe('identify()', () => {
describe('with OG uuid config', () => {
beforeEach(() => {
setup({ uuid_version: 'og' })
})

it('uses the OG uuid format when configured', () => {
cy.posthog().invoke('capture', '$pageview')
cy.phCaptures({ full: true }).then((events) => {
let deviceIds = new Set(events.map((e) => e.properties['$device_id']))
expect(deviceIds.size).to.eql(1)
const [deviceId] = deviceIds
expect(deviceId.length).to.be.greaterThan(51)
})
})
beforeEach(() => {
setup()
})

describe('with default config', () => {
beforeEach(() => {
setup()
})

it('uses the v7 uuid format by default', () => {
cy.posthog().invoke('capture', 'an-anonymous-event')
cy.phCaptures({ full: true }).then((events) => {
cy.log(events)
let deviceIds = new Set(events.map((e) => e.properties['$device_id']))
expect(deviceIds.size).to.eql(1)
const [deviceId] = deviceIds
expect(deviceId.length).to.be.eql(36)
})
it('uses the v7 uuid format', () => {
cy.posthog().invoke('capture', 'an-anonymous-event')
cy.phCaptures({ full: true }).then((events) => {
cy.log(events)
let deviceIds = new Set(events.map((e) => e.properties['$device_id']))
expect(deviceIds.size).to.eql(1)
const [deviceId] = deviceIds
expect(deviceId.length).to.be.eql(36)
})
})

it('opt_out_capturing() does not fail after identify()', () => {
cy.posthog().invoke('identify', 'some-id')
cy.posthog().invoke('opt_out_capturing')
})
it('opt_out_capturing() does not fail after identify()', () => {
cy.posthog().invoke('identify', 'some-id')
cy.posthog().invoke('opt_out_capturing')
})

it('merges people as expected when reset is called', () => {
cy.posthog().invoke('capture', 'an-anonymous-event')
cy.posthog().invoke('identify', 'first-identify') // test identify merges with previous events after init
cy.posthog().invoke('capture', 'an-identified-event')
cy.posthog().invoke('identify', 'second-identify-should-not-be-merged') // test identify is not sent after previous identify
cy.posthog().invoke('capture', 'another-identified-event') // but does change the distinct id
cy.posthog().invoke('reset')
cy.posthog().invoke('capture', 'an-anonymous-event')
cy.posthog().invoke('identify', 'third-identify')
cy.posthog().invoke('capture', 'an-identified-event')
it('merges people as expected when reset is called', () => {
cy.posthog().invoke('capture', 'an-anonymous-event')
cy.posthog().invoke('identify', 'first-identify') // test identify merges with previous events after init
cy.posthog().invoke('capture', 'an-identified-event')
cy.posthog().invoke('identify', 'second-identify-should-not-be-merged') // test identify is not sent after previous identify
cy.posthog().invoke('capture', 'another-identified-event') // but does change the distinct id
cy.posthog().invoke('reset')
cy.posthog().invoke('capture', 'an-anonymous-event')
cy.posthog().invoke('identify', 'third-identify')
cy.posthog().invoke('capture', 'an-identified-event')

cy.phCaptures({ full: true }).then((events) => {
const eventsSeen = events.map((e) => e.event)
cy.phCaptures({ full: true }).then((events) => {
const eventsSeen = events.map((e) => e.event)

expect(eventsSeen.filter((e) => e === '$identify').length).to.eq(2)
expect(eventsSeen.filter((e) => e === '$identify').length).to.eq(2)

expect(eventsSeen).to.deep.eq([
'$pageview',
'an-anonymous-event',
'$identify',
'an-identified-event',
'another-identified-event',
'an-anonymous-event',
'$identify',
'an-identified-event',
])
expect(eventsSeen).to.deep.eq([
'$pageview',
'an-anonymous-event',
'$identify',
'an-identified-event',
'another-identified-event',
'an-anonymous-event',
'$identify',
'an-identified-event',
])

expect(new Set(events.map((e) => e.properties['$device_id'])).size).to.eql(1)
expect(new Set(events.map((e) => e.properties['$device_id'])).size).to.eql(1)

// the first two events share a distinct id
expect(events[0].properties.distinct_id).to.eql(events[1].properties.distinct_id)
// then first identify is called and sends that distinct id as its anon to merge
expect(events[2].properties.distinct_id).to.eql('first-identify')
expect(events[2].properties['$anon_distinct_id']).to.eql(events[0].properties.distinct_id)
// and an event is sent with that distinct id
expect(events[3].properties.distinct_id).to.eql('first-identify')
// then second identify is called and is ignored but does change the distinct id
expect(events[4].event).to.eql('another-identified-event')
expect(events[4].properties.distinct_id).to.eql('second-identify-should-not-be-merged')
// then reset is called and the next event has a new distinct id
expect(events[5].event).to.eql('an-anonymous-event')
expect(events[5].properties.distinct_id)
.not.to.eql('first-identify')
.and.not.to.eql('second-identify-should-not-be-merged')
// then an identify merges that distinct id with the new distinct id
expect(events[6].properties.distinct_id).to.eql('third-identify')
expect(events[6].properties['$anon_distinct_id']).to.eql(events[5].properties.distinct_id)
// then a final identified event includes that identified distinct id
expect(events[7].properties.distinct_id).to.eql('third-identify')
})
// the first two events share a distinct id
expect(events[0].properties.distinct_id).to.eql(events[1].properties.distinct_id)
// then first identify is called and sends that distinct id as its anon to merge
expect(events[2].properties.distinct_id).to.eql('first-identify')
expect(events[2].properties['$anon_distinct_id']).to.eql(events[0].properties.distinct_id)
// and an event is sent with that distinct id
expect(events[3].properties.distinct_id).to.eql('first-identify')
// then second identify is called and is ignored but does change the distinct id
expect(events[4].event).to.eql('another-identified-event')
expect(events[4].properties.distinct_id).to.eql('second-identify-should-not-be-merged')
// then reset is called and the next event has a new distinct id
expect(events[5].event).to.eql('an-anonymous-event')
expect(events[5].properties.distinct_id)
.not.to.eql('first-identify')
.and.not.to.eql('second-identify-should-not-be-merged')
// then an identify merges that distinct id with the new distinct id
expect(events[6].properties.distinct_id).to.eql('third-identify')
expect(events[6].properties['$anon_distinct_id']).to.eql(events[5].properties.distinct_id)
// then a final identified event includes that identified distinct id
expect(events[7].properties.distinct_id).to.eql('third-identify')
})
})
})
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.75.3",
"version": "1.75.4",
"description": "Posthog-js allows you to automatically capture usage and send events to PostHog.",
"repository": "https://github.com/PostHog/posthog-js",
"author": "[email protected]",
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/autocapture.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import sinon from 'sinon'

import { autocapture } from '../autocapture'
import { shouldCaptureDomEvent } from '../autocapture-utils'
import { AUTOCAPTURE_DISABLED_SERVER_SIDE } from '../posthog-persistence'
import { AUTOCAPTURE_DISABLED_SERVER_SIDE } from '../constants'

const triggerMouseEvent = function (node, eventType) {
node.dispatchEvent(
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/compression.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import sinon from 'sinon'
import { autocapture } from '../autocapture'
import { decideCompression, compressData } from '../compression'
import { Decide } from '../decide'
import { AUTOCAPTURE_DISABLED_SERVER_SIDE } from '../posthog-persistence'
import { AUTOCAPTURE_DISABLED_SERVER_SIDE } from '../constants'

describe('decideCompression()', () => {
given('subject', () => decideCompression(given.compressionSupport))
Expand Down
16 changes: 6 additions & 10 deletions src/__tests__/extensions/sessionrecording.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { _UUID, loadScript } from '../../utils'
import { loadScript } from '../../utils'
import {
SessionRecording,
RECORDING_IDLE_ACTIVITY_TIMEOUT_MS,
RECORDING_MAX_EVENT_SIZE,
SessionRecording,
} from '../../extensions/sessionrecording'
import {
PostHogPersistence,
SESSION_RECORDING_ENABLED_SERVER_SIDE,
SESSION_RECORDING_RECORDER_VERSION_SERVER_SIDE,
} from '../../posthog-persistence'
import { PostHogPersistence } from '../../posthog-persistence'
import { SESSION_RECORDING_ENABLED_SERVER_SIDE, SESSION_RECORDING_RECORDER_VERSION_SERVER_SIDE } from '../../constants'
import { SessionIdManager } from '../../sessionid'
import {
INCREMENTAL_SNAPSHOT_EVENT_TYPE,
Expand Down Expand Up @@ -73,7 +70,6 @@ describe('SessionRecording', () => {
given('$session_recording_recorder_version_server_side', () => undefined)
given('disabled', () => false)
given('__loaded_recorder_version', () => undefined)
given('uuidFn', () => _UUID('v7'))

beforeEach(() => {
window.rrwebRecord = jest.fn()
Expand Down Expand Up @@ -554,7 +550,7 @@ describe('SessionRecording', () => {
beforeEach(() => {
given(
'sessionManager',
() => new SessionIdManager(given.config, new PostHogPersistence(given.config), given.uuidFn)
() => new SessionIdManager(given.config, new PostHogPersistence(given.config))
)

mockCallback = jest.fn()
Expand Down Expand Up @@ -633,7 +629,7 @@ describe('SessionRecording', () => {
beforeEach(() => {
given(
'sessionManager',
() => new SessionIdManager(given.config, new PostHogPersistence(given.config), given.uuidFn)
() => new SessionIdManager(given.config, new PostHogPersistence(given.config))
)
given.sessionRecording.startRecordingIfEnabled()
given.sessionRecording.startCaptureAndTrySendingQueuedSnapshots()
Expand Down
20 changes: 11 additions & 9 deletions src/__tests__/gdpr-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ const TOKENS = [
const DEFAULT_PERSISTENCE_PREFIX = `__ph_opt_in_out_`
const CUSTOM_PERSISTENCE_PREFIX = `𝓶𝓶𝓶𝓬𝓸𝓸𝓴𝓲𝓮𝓼`

function deleteAllCookies() {
var cookies = document.cookie.split(';')

for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i]
var eqPos = cookie.indexOf('=')
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie
document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT'
}
}

function forPersistenceTypes(runTests) {
;[`cookie`, `localStorage`, `localStorage+cookie`].forEach(function (persistenceType) {
describe(persistenceType, runTests.bind(null, persistenceType))
Expand All @@ -31,16 +42,7 @@ function assertPersistenceValue(persistenceType, token, value, persistencePrefix
}
}
}
function deleteAllCookies() {
var cookies = document.cookie.split(';')

for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i]
var eqPos = cookie.indexOf('=')
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie
document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT'
}
}
describe(`GDPR utils`, () => {
// these imports must be re-required before each test
// so that they reference the correct jsdom document
Expand Down
12 changes: 4 additions & 8 deletions src/__tests__/page-view-id.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import { PageViewIdManager } from '../page-view-id'

jest.mock('../utils')
import { uuidv7 } from '../uuidv7'
jest.mock('../uuidv7')

describe('PageView ID manager', () => {
given('uuidFn', () => jest.fn())
given('pageViewIdManager', () => new PageViewIdManager(given.uuidFn))
given('pageViewIdManager', () => new PageViewIdManager())

beforeEach(() => {
given.uuidFn
.mockReturnValue('subsequentUUIDs')
.mockReturnValueOnce('firstUUID')
.mockReturnValueOnce('secondUUID')
uuidv7.mockReturnValue('subsequentUUIDs').mockReturnValueOnce('firstUUID').mockReturnValueOnce('secondUUID')
})

it('generates a page view id and resets page view id', () => {
Expand Down
Loading

0 comments on commit ab43482

Please sign in to comment.