Skip to content

Commit

Permalink
feat: Added client side capture rate limiting (#1051)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjackwhite authored Apr 18, 2024
1 parent 08a80bb commit 5e1b371
Show file tree
Hide file tree
Showing 10 changed files with 341 additions and 133 deletions.
17 changes: 9 additions & 8 deletions src/__tests__/posthog-core.identify.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { USER_STATE } from '../constants'
import _posthog from '../loader-module'
import { PostHogPersistence } from '../posthog-persistence'
import { uuidv7 } from '../uuidv7'
Expand Down Expand Up @@ -48,7 +49,7 @@ describe('identify()', () => {
given('deviceId', () => given.oldIdentity)

beforeEach(() => {
given.lib.persistence.set_user_state('anonymous')
given.lib.persistence.set_property(USER_STATE, 'anonymous')
})

it('registers new user id and updates alias', () => {
Expand Down Expand Up @@ -81,7 +82,7 @@ describe('identify()', () => {

given.subject()

expect(given.lib.persistence.get_user_state()).toEqual('identified')
expect(given.lib.persistence.get_property(USER_STATE)).toEqual('identified')
})

it('calls capture when there is no device id', () => {
Expand All @@ -101,7 +102,7 @@ describe('identify()', () => {
})

it('calls capture when there is no device id (on first check) even if user is not set to anonymous', () => {
given.lib.persistence.set_user_state(undefined)
given.lib.persistence.set_property(USER_STATE, undefined)
given('oldIdentity', () => 'oldIdentity')
// if null deviceId is set inside identify, but given doesn't reflect that change so....
let wasCalled = false
Expand Down Expand Up @@ -133,7 +134,7 @@ describe('identify()', () => {
*/
given('deviceId', () => 'not the oldIdentity')
// now this is set explicitly by identify
given.lib.persistence.set_user_state('identified')
given.lib.persistence.set_property(USER_STATE, 'identified')

given('identity', () => 'a-new-id')
given('oldIdentity', () => 'oldIdentity')
Expand All @@ -152,7 +153,7 @@ describe('identify()', () => {
given('oldIdentity', () => 'oldIdentity')
given('deviceId', () => 'not the oldIdentity')

given.lib.persistence.set_user_state('identified')
given.lib.persistence.set_property(USER_STATE, 'identified')

given.subject()

Expand All @@ -164,7 +165,7 @@ describe('identify()', () => {
given('identity', () => 'a-new-id')
given('oldIdentity', () => 'oldIdentity')
given('deviceId', () => 'not the oldIdentity')
given.lib.persistence.set_user_state('anonymous')
given.lib.persistence.set_property(USER_STATE, 'anonymous')

given.subject()

Expand Down Expand Up @@ -363,11 +364,11 @@ describe('reset()', () => {
})

it('sets the user as anonymous', () => {
given.lib.persistence.set_user_state('identified')
given.lib.persistence.set_property(USER_STATE, 'identified')

given.subject()

expect(given.lib.persistence.get_user_state()).toEqual('anonymous')
expect(given.lib.persistence.get_property(USER_STATE)).toEqual('anonymous')
})

it('does not reset the device id', () => {
Expand Down
16 changes: 9 additions & 7 deletions src/__tests__/posthog-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,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'

jest.mock('../gdpr-utils', () => ({
...jest.requireActual('../gdpr-utils'),
Expand Down Expand Up @@ -59,7 +60,7 @@ describe('posthog core', () => {
Object.assign(this.props, properties)
},
props: {},
get_user_state: () => 'anonymous',
get_property: () => 'anonymous',
set_initial_campaign_params: jest.fn(),
set_initial_referrer_info: jest.fn(),
get_initial_props: () => ({}),
Expand All @@ -70,13 +71,14 @@ describe('posthog core', () => {
update_referrer_info: jest.fn(),
update_config: jest.fn(),
properties: jest.fn(),
get_user_state: () => 'anonymous',
get_property: () => 'anonymous',
},
_send_request: jest.fn(),
compression: {},
__captureHooks: [],
rateLimiter: {
isRateLimited: () => false,
isServerRateLimited: () => false,
isCaptureClientSideRateLimited: () => false,
},
}))

Expand Down Expand Up @@ -368,11 +370,11 @@ describe('posthog core', () => {
persistence: {
properties: () => ({ distinct_id: 'abc', persistent: 'prop', $is_identified: false }),
remove_event_timer: jest.fn(),
get_user_state: () => 'anonymous',
get_property: () => 'anonymous',
},
sessionPersistence: {
properties: () => ({ distinct_id: 'abc', persistent: 'prop' }),
get_user_state: () => 'anonymous',
get_property: () => 'anonymous',
},
sessionManager: {
checkAndGetSessionAndWindowId: jest.fn().mockReturnValue({
Expand Down Expand Up @@ -581,7 +583,7 @@ describe('posthog core', () => {

expect(given.lib.get_distinct_id()).toBe('abcd')
expect(given.lib.get_property('$device_id')).toBe('abcd')
expect(given.lib.persistence.get_user_state()).toBe('anonymous')
expect(given.lib.persistence.get_property(USER_STATE)).toBe('anonymous')

given.lib.identify('efgh')

Expand All @@ -606,7 +608,7 @@ describe('posthog core', () => {

expect(given.lib.get_distinct_id()).toBe('abcd')
expect(given.lib.get_property('$device_id')).toBe('og-device-id')
expect(given.lib.persistence.get_user_state()).toBe('identified')
expect(given.lib.persistence.get_property(USER_STATE)).toBe('identified')

given.lib.identify('efgh')
expect(given.overrides.capture).not.toHaveBeenCalled()
Expand Down
8 changes: 4 additions & 4 deletions src/__tests__/posthog-persistence.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,20 @@ describe('persistence', () => {

it('should save user state', () => {
const lib = new PostHogPersistence(makePostHogConfig('bla', persistenceMode))
lib.set_user_state('identified')
lib.set_property(USER_STATE, 'identified')
expect(lib.props[USER_STATE]).toEqual('identified')
})

it('can load user state', () => {
const lib = new PostHogPersistence(makePostHogConfig('bla', persistenceMode))
lib.set_user_state('identified')
expect(lib.get_user_state()).toEqual('identified')
lib.set_property(USER_STATE, 'identified')
expect(lib.get_property(USER_STATE)).toEqual('identified')
})

it('has user state as a reserved property key', () => {
const lib = new PostHogPersistence(makePostHogConfig('bla', persistenceMode))
lib.register({ distinct_id: 'testy', test_prop: 'test_value' })
lib.set_user_state('identified')
lib.set_property(USER_STATE, 'identified')
expect(lib.properties()).toEqual({ distinct_id: 'testy', test_prop: 'test_value' })
})

Expand Down
Loading

0 comments on commit 5e1b371

Please sign in to comment.