@posthog/core 1.0.2 → 1.2.0
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/dist/error-tracking/chunk-ids.d.ts +5 -0
- package/dist/error-tracking/chunk-ids.d.ts.map +1 -0
- package/dist/error-tracking/chunk-ids.js +68 -0
- package/dist/error-tracking/chunk-ids.mjs +34 -0
- package/dist/error-tracking/coercers/dom-exception-coercer.d.ts +10 -0
- package/dist/error-tracking/coercers/dom-exception-coercer.d.ts.map +1 -0
- package/dist/error-tracking/coercers/dom-exception-coercer.js +65 -0
- package/dist/error-tracking/coercers/dom-exception-coercer.mjs +31 -0
- package/dist/error-tracking/coercers/error-coercer.d.ts +9 -0
- package/dist/error-tracking/coercers/error-coercer.d.ts.map +1 -0
- package/dist/error-tracking/coercers/error-coercer.js +61 -0
- package/dist/error-tracking/coercers/error-coercer.mjs +27 -0
- package/dist/error-tracking/coercers/error-event-coercer.d.ts +7 -0
- package/dist/error-tracking/coercers/error-event-coercer.d.ts.map +1 -0
- package/dist/error-tracking/coercers/error-event-coercer.js +52 -0
- package/dist/error-tracking/coercers/error-event-coercer.mjs +18 -0
- package/dist/error-tracking/coercers/event-coercer.d.ts +6 -0
- package/dist/error-tracking/coercers/event-coercer.d.ts.map +1 -0
- package/dist/error-tracking/coercers/event-coercer.js +51 -0
- package/dist/error-tracking/coercers/event-coercer.mjs +17 -0
- package/dist/error-tracking/coercers/index.d.ts +9 -0
- package/dist/error-tracking/coercers/index.d.ts.map +1 -0
- package/dist/error-tracking/coercers/index.js +123 -0
- package/dist/error-tracking/coercers/index.mjs +8 -0
- package/dist/error-tracking/coercers/object-coercer.d.ts +14 -0
- package/dist/error-tracking/coercers/object-coercer.d.ts.map +1 -0
- package/dist/error-tracking/coercers/object-coercer.js +85 -0
- package/dist/error-tracking/coercers/object-coercer.mjs +51 -0
- package/dist/error-tracking/coercers/primitive-coercer.d.ts +7 -0
- package/dist/error-tracking/coercers/primitive-coercer.d.ts.map +1 -0
- package/dist/error-tracking/coercers/primitive-coercer.js +49 -0
- package/dist/error-tracking/coercers/primitive-coercer.mjs +15 -0
- package/dist/error-tracking/coercers/promise-rejection-event.d.ts +7 -0
- package/dist/error-tracking/coercers/promise-rejection-event.d.ts.map +1 -0
- package/dist/error-tracking/coercers/promise-rejection-event.js +59 -0
- package/dist/error-tracking/coercers/promise-rejection-event.mjs +25 -0
- package/dist/error-tracking/coercers/string-coercer.d.ts +7 -0
- package/dist/error-tracking/coercers/string-coercer.d.ts.map +1 -0
- package/dist/error-tracking/coercers/string-coercer.js +63 -0
- package/dist/error-tracking/coercers/string-coercer.mjs +29 -0
- package/dist/error-tracking/coercers/utils.d.ts +8 -0
- package/dist/error-tracking/coercers/utils.d.ts.map +1 -0
- package/dist/error-tracking/coercers/utils.js +55 -0
- package/dist/error-tracking/coercers/utils.mjs +18 -0
- package/dist/error-tracking/error-properties-builder.d.ts +18 -0
- package/dist/error-tracking/error-properties-builder.d.ts.map +1 -0
- package/dist/error-tracking/error-properties-builder.js +152 -0
- package/dist/error-tracking/error-properties-builder.mjs +118 -0
- package/dist/error-tracking/index.d.ts +6 -0
- package/dist/error-tracking/index.d.ts.map +1 -0
- package/dist/error-tracking/index.js +87 -0
- package/dist/error-tracking/index.mjs +4 -0
- package/dist/error-tracking/parsers/base.d.ts +9 -0
- package/dist/error-tracking/parsers/base.d.ts.map +1 -0
- package/dist/error-tracking/parsers/base.js +71 -0
- package/dist/error-tracking/parsers/base.mjs +19 -0
- package/dist/error-tracking/parsers/chrome.d.ts +3 -0
- package/dist/error-tracking/parsers/chrome.d.ts.map +1 -0
- package/dist/error-tracking/parsers/chrome.js +61 -0
- package/dist/error-tracking/parsers/chrome.mjs +27 -0
- package/dist/error-tracking/parsers/gecko.d.ts +3 -0
- package/dist/error-tracking/parsers/gecko.d.ts.map +1 -0
- package/dist/error-tracking/parsers/gecko.js +58 -0
- package/dist/error-tracking/parsers/gecko.mjs +24 -0
- package/dist/error-tracking/parsers/index.d.ts +9 -0
- package/dist/error-tracking/parsers/index.d.ts.map +1 -0
- package/dist/error-tracking/parsers/index.js +99 -0
- package/dist/error-tracking/parsers/index.mjs +44 -0
- package/dist/error-tracking/parsers/node.d.ts +3 -0
- package/dist/error-tracking/parsers/node.d.ts.map +1 -0
- package/dist/error-tracking/parsers/node.js +99 -0
- package/dist/error-tracking/parsers/node.mjs +65 -0
- package/dist/error-tracking/parsers/opera.d.ts +4 -0
- package/dist/error-tracking/parsers/opera.d.ts.map +1 -0
- package/dist/error-tracking/parsers/opera.js +49 -0
- package/dist/error-tracking/parsers/opera.mjs +12 -0
- package/dist/error-tracking/parsers/react-native.d.ts +1 -0
- package/dist/error-tracking/parsers/react-native.d.ts.map +1 -0
- package/dist/error-tracking/parsers/react-native.js +5 -0
- package/dist/error-tracking/parsers/react-native.mjs +0 -0
- package/dist/error-tracking/parsers/safari.d.ts +22 -0
- package/dist/error-tracking/parsers/safari.d.ts.map +1 -0
- package/dist/error-tracking/parsers/safari.js +47 -0
- package/dist/error-tracking/parsers/safari.mjs +13 -0
- package/dist/error-tracking/parsers/winjs.d.ts +3 -0
- package/dist/error-tracking/parsers/winjs.d.ts.map +1 -0
- package/dist/error-tracking/parsers/winjs.js +41 -0
- package/dist/error-tracking/parsers/winjs.mjs +7 -0
- package/dist/error-tracking/types.d.ts +87 -0
- package/dist/error-tracking/types.d.ts.map +1 -0
- package/dist/error-tracking/types.js +43 -0
- package/dist/error-tracking/types.mjs +9 -0
- package/dist/error-tracking/utils.d.ts +13 -0
- package/dist/error-tracking/utils.d.ts.map +1 -0
- package/dist/error-tracking/utils.js +57 -0
- package/dist/error-tracking/utils.mjs +23 -0
- package/dist/eventemitter.js +4 -4
- package/dist/eventemitter.mjs +4 -4
- package/dist/featureFlagUtils.js +20 -45
- package/dist/featureFlagUtils.mjs +20 -45
- package/dist/gzip.js +1 -2
- package/dist/gzip.mjs +1 -2
- package/dist/index.d.ts +5 -255
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -1223
- package/dist/index.mjs +6 -1190
- package/dist/posthog-core-stateless.d.ts +204 -0
- package/dist/posthog-core-stateless.d.ts.map +1 -0
- package/dist/posthog-core-stateless.js +675 -0
- package/dist/posthog-core-stateless.mjs +632 -0
- package/dist/posthog-core.d.ts +171 -0
- package/dist/posthog-core.d.ts.map +1 -0
- package/dist/posthog-core.js +554 -0
- package/dist/posthog-core.mjs +520 -0
- package/dist/testing/PostHogCoreTestClient.d.ts +2 -1
- package/dist/testing/PostHogCoreTestClient.d.ts.map +1 -1
- package/dist/testing/PostHogCoreTestClient.js +9 -11
- package/dist/testing/PostHogCoreTestClient.mjs +8 -10
- package/dist/testing/test-utils.d.ts +2 -0
- package/dist/testing/test-utils.d.ts.map +1 -1
- package/dist/testing/test-utils.js +13 -1
- package/dist/testing/test-utils.mjs +11 -2
- package/dist/utils/bucketed-rate-limiter.d.ts.map +1 -1
- package/dist/utils/bucketed-rate-limiter.js +8 -12
- package/dist/utils/bucketed-rate-limiter.mjs +8 -12
- package/dist/utils/index.js +3 -3
- package/dist/utils/index.mjs +3 -3
- package/dist/utils/number-utils.d.ts.map +1 -1
- package/dist/utils/type-utils.d.ts +8 -1
- package/dist/utils/type-utils.d.ts.map +1 -1
- package/dist/utils/type-utils.js +61 -6
- package/dist/utils/type-utils.mjs +36 -2
- package/dist/vendor/uuidv7.js +12 -16
- package/dist/vendor/uuidv7.mjs +12 -16
- package/package.json +10 -4
- package/src/__tests__/featureFlagUtils.spec.ts +427 -0
- package/src/__tests__/gzip.spec.ts +69 -0
- package/src/__tests__/posthog.ai.spec.ts +110 -0
- package/src/__tests__/posthog.capture.spec.ts +91 -0
- package/src/__tests__/posthog.core.spec.ts +135 -0
- package/src/__tests__/posthog.debug.spec.ts +36 -0
- package/src/__tests__/posthog.enqueue.spec.ts +93 -0
- package/src/__tests__/posthog.featureflags.spec.ts +1106 -0
- package/src/__tests__/posthog.featureflags.v1.spec.ts +922 -0
- package/src/__tests__/posthog.flush.spec.ts +237 -0
- package/src/__tests__/posthog.gdpr.spec.ts +50 -0
- package/src/__tests__/posthog.groups.spec.ts +96 -0
- package/src/__tests__/posthog.identify.spec.ts +194 -0
- package/src/__tests__/posthog.init.spec.ts +110 -0
- package/src/__tests__/posthog.listeners.spec.ts +51 -0
- package/src/__tests__/posthog.register.spec.ts +47 -0
- package/src/__tests__/posthog.reset.spec.ts +76 -0
- package/src/__tests__/posthog.sessions.spec.ts +63 -0
- package/src/__tests__/posthog.setProperties.spec.ts +102 -0
- package/src/__tests__/posthog.shutdown.spec.ts +88 -0
- package/src/__tests__/utils.spec.ts +36 -0
- package/src/error-tracking/chunk-ids.ts +58 -0
- package/src/error-tracking/coercers/dom-exception-coercer.ts +38 -0
- package/src/error-tracking/coercers/error-coercer.ts +36 -0
- package/src/error-tracking/coercers/error-event-coercer.ts +24 -0
- package/src/error-tracking/coercers/event-coercer.ts +19 -0
- package/src/error-tracking/coercers/index.ts +8 -0
- package/src/error-tracking/coercers/object-coercer.ts +76 -0
- package/src/error-tracking/coercers/primitive-coercer.ts +19 -0
- package/src/error-tracking/coercers/promise-rejection-event.spec.ts +77 -0
- package/src/error-tracking/coercers/promise-rejection-event.ts +53 -0
- package/src/error-tracking/coercers/string-coercer.spec.ts +26 -0
- package/src/error-tracking/coercers/string-coercer.ts +31 -0
- package/src/error-tracking/coercers/utils.ts +33 -0
- package/src/error-tracking/error-properties-builder.coerce.spec.ts +202 -0
- package/src/error-tracking/error-properties-builder.parse.spec.ts +30 -0
- package/src/error-tracking/error-properties-builder.ts +169 -0
- package/src/error-tracking/index.ts +5 -0
- package/src/error-tracking/parsers/base.ts +29 -0
- package/src/error-tracking/parsers/chrome.ts +53 -0
- package/src/error-tracking/parsers/gecko.ts +38 -0
- package/src/error-tracking/parsers/index.ts +104 -0
- package/src/error-tracking/parsers/node.ts +111 -0
- package/src/error-tracking/parsers/opera.ts +18 -0
- package/src/error-tracking/parsers/react-native.ts +0 -0
- package/src/error-tracking/parsers/safari.ts +33 -0
- package/src/error-tracking/parsers/winjs.ts +12 -0
- package/src/error-tracking/types.ts +107 -0
- package/src/error-tracking/utils.ts +39 -0
- package/src/eventemitter.ts +27 -0
- package/src/featureFlagUtils.ts +192 -0
- package/src/gzip.ts +29 -0
- package/src/index.ts +8 -0
- package/src/posthog-core-stateless.ts +1226 -0
- package/src/posthog-core.ts +958 -0
- package/src/testing/PostHogCoreTestClient.ts +91 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/test-utils.ts +47 -0
- package/src/types.ts +544 -0
- package/src/utils/bucketed-rate-limiter.spec.ts +33 -0
- package/src/utils/bucketed-rate-limiter.ts +85 -0
- package/src/utils/index.ts +98 -0
- package/src/utils/number-utils.spec.ts +89 -0
- package/src/utils/number-utils.ts +30 -0
- package/src/utils/promise-queue.spec.ts +55 -0
- package/src/utils/promise-queue.ts +30 -0
- package/src/utils/string-utils.ts +23 -0
- package/src/utils/type-utils.ts +134 -0
- package/src/vendor/uuidv7.ts +479 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { delay, waitForPromises, createTestClient, PostHogCoreTestClient, PostHogCoreTestClientMocks } from '@/testing'
|
|
2
|
+
import { PostHogPersistedProperty } from '@/types'
|
|
3
|
+
|
|
4
|
+
describe('PostHog Core', () => {
|
|
5
|
+
let posthog: PostHogCoreTestClient
|
|
6
|
+
let mocks: PostHogCoreTestClientMocks
|
|
7
|
+
|
|
8
|
+
describe('flush', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
jest.useFakeTimers()
|
|
11
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', {
|
|
12
|
+
flushAt: 5,
|
|
13
|
+
fetchRetryCount: 3,
|
|
14
|
+
fetchRetryDelay: 100,
|
|
15
|
+
preloadFeatureFlags: false,
|
|
16
|
+
})
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it("doesn't fail when queue is empty", async () => {
|
|
20
|
+
jest.useRealTimers()
|
|
21
|
+
await expect(posthog.flush()).resolves.not.toThrow()
|
|
22
|
+
expect(mocks.fetch).not.toHaveBeenCalled()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('flush messages once called', async () => {
|
|
26
|
+
const successfulMessages: any[] = []
|
|
27
|
+
|
|
28
|
+
mocks.fetch.mockImplementation(async (_, options) => {
|
|
29
|
+
const batch = JSON.parse((options.body || '') as string).batch
|
|
30
|
+
|
|
31
|
+
successfulMessages.push(...batch)
|
|
32
|
+
return Promise.resolve({
|
|
33
|
+
status: 200,
|
|
34
|
+
text: () => Promise.resolve('ok'),
|
|
35
|
+
json: () => Promise.resolve({ status: 'ok' }),
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
posthog.capture('test-event-1')
|
|
40
|
+
posthog.capture('test-event-2')
|
|
41
|
+
posthog.capture('test-event-3')
|
|
42
|
+
expect(mocks.fetch).not.toHaveBeenCalled()
|
|
43
|
+
await expect(posthog.flush()).resolves.not.toThrow()
|
|
44
|
+
expect(mocks.fetch).toHaveBeenCalled()
|
|
45
|
+
expect(successfulMessages).toMatchObject([
|
|
46
|
+
{ event: 'test-event-1' },
|
|
47
|
+
{ event: 'test-event-2' },
|
|
48
|
+
{ event: 'test-event-3' },
|
|
49
|
+
])
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it.each([400, 500])('responds with an error after retries with %s error', async (status) => {
|
|
53
|
+
mocks.fetch.mockImplementation(() => {
|
|
54
|
+
return Promise.resolve({
|
|
55
|
+
status: status,
|
|
56
|
+
text: async () => 'err',
|
|
57
|
+
json: async () => ({ status: 'err' }),
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
posthog.capture('test-event-1')
|
|
61
|
+
|
|
62
|
+
const time = Date.now()
|
|
63
|
+
jest.useRealTimers()
|
|
64
|
+
await expect(posthog.flush()).rejects.toHaveProperty('name', 'PostHogFetchHttpError')
|
|
65
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(4)
|
|
66
|
+
expect(Date.now() - time).toBeGreaterThan(300)
|
|
67
|
+
expect(Date.now() - time).toBeLessThan(500)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('responds with an error after retries with network error ', async () => {
|
|
71
|
+
mocks.fetch.mockImplementation(() => {
|
|
72
|
+
return Promise.reject(new Error('network problems'))
|
|
73
|
+
})
|
|
74
|
+
posthog.capture('test-event-1')
|
|
75
|
+
|
|
76
|
+
const time = Date.now()
|
|
77
|
+
jest.useRealTimers()
|
|
78
|
+
await expect(posthog.flush()).rejects.toHaveProperty('name', 'PostHogFetchNetworkError')
|
|
79
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(4)
|
|
80
|
+
expect(Date.now() - time).toBeGreaterThan(300)
|
|
81
|
+
expect(Date.now() - time).toBeLessThan(500)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('skips when client is disabled', async () => {
|
|
85
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 2 })
|
|
86
|
+
|
|
87
|
+
posthog.capture('test-event-1')
|
|
88
|
+
await waitForPromises()
|
|
89
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(0)
|
|
90
|
+
posthog.capture('test-event-2')
|
|
91
|
+
await waitForPromises()
|
|
92
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(1)
|
|
93
|
+
posthog.optOut()
|
|
94
|
+
posthog.capture('test-event-3')
|
|
95
|
+
posthog.capture('test-event-4')
|
|
96
|
+
await waitForPromises()
|
|
97
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(1)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('does not get stuck in a loop when new events are added while flushing', async () => {
|
|
101
|
+
jest.useRealTimers()
|
|
102
|
+
mocks.fetch.mockImplementation(async () => {
|
|
103
|
+
posthog.capture('another-event')
|
|
104
|
+
await delay(10)
|
|
105
|
+
return Promise.resolve({
|
|
106
|
+
status: 200,
|
|
107
|
+
text: () => Promise.resolve('ok'),
|
|
108
|
+
json: () => Promise.resolve({ status: 'ok' }),
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
posthog.capture('test-event-1')
|
|
113
|
+
await posthog.flush()
|
|
114
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(1)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('should flush all events even if larger than batch size', async () => {
|
|
118
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 10 })
|
|
119
|
+
|
|
120
|
+
const successfulMessages: any[] = []
|
|
121
|
+
|
|
122
|
+
mocks.fetch.mockImplementation(async (_, options) => {
|
|
123
|
+
const batch = JSON.parse((options.body || '') as string).batch
|
|
124
|
+
|
|
125
|
+
successfulMessages.push(...batch)
|
|
126
|
+
return Promise.resolve({
|
|
127
|
+
status: 200,
|
|
128
|
+
text: () => Promise.resolve('ok'),
|
|
129
|
+
json: () => Promise.resolve({ status: 'ok' }),
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
posthog['maxBatchSize'] = 2 // a bit contrived because usually maxBatchSize >= flushAt
|
|
134
|
+
posthog.capture('test-event-1')
|
|
135
|
+
posthog.capture('test-event-2')
|
|
136
|
+
posthog.capture('test-event-3')
|
|
137
|
+
posthog.capture('test-event-4')
|
|
138
|
+
await expect(posthog.flush()).resolves.not.toThrow()
|
|
139
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
140
|
+
expect(successfulMessages).toMatchObject([
|
|
141
|
+
{ event: 'test-event-1' },
|
|
142
|
+
{ event: 'test-event-2' },
|
|
143
|
+
{ event: 'test-event-3' },
|
|
144
|
+
{ event: 'test-event-4' },
|
|
145
|
+
])
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('should reduce the batch size without dropping events if received 413', async () => {
|
|
149
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 10 })
|
|
150
|
+
const successfulMessages: any[] = []
|
|
151
|
+
|
|
152
|
+
mocks.fetch.mockImplementation(async (_, options) => {
|
|
153
|
+
const batch = JSON.parse((options.body || '') as string).batch
|
|
154
|
+
|
|
155
|
+
if (batch.length > 1) {
|
|
156
|
+
return Promise.resolve({
|
|
157
|
+
status: 413,
|
|
158
|
+
text: () => Promise.resolve('Content Too Large'),
|
|
159
|
+
json: () => Promise.resolve({ status: 'Content Too Large' }),
|
|
160
|
+
})
|
|
161
|
+
} else {
|
|
162
|
+
successfulMessages.push(...batch)
|
|
163
|
+
return Promise.resolve({
|
|
164
|
+
status: 200,
|
|
165
|
+
text: () => Promise.resolve('ok'),
|
|
166
|
+
json: () => Promise.resolve({ status: 'ok' }),
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
posthog.capture('test-event-1')
|
|
172
|
+
posthog.capture('test-event-2')
|
|
173
|
+
posthog.capture('test-event-3')
|
|
174
|
+
posthog.capture('test-event-4')
|
|
175
|
+
await expect(posthog.flush()).resolves.not.toThrow()
|
|
176
|
+
expect(successfulMessages).toMatchObject([
|
|
177
|
+
{ event: 'test-event-1' },
|
|
178
|
+
{ event: 'test-event-2' },
|
|
179
|
+
{ event: 'test-event-3' },
|
|
180
|
+
{ event: 'test-event-4' },
|
|
181
|
+
])
|
|
182
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(6) // 2 failures with size 4 then 2, then 4 successes with size 1
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
it('should treat a 413 at batchSize 1 as a regular error', async () => {
|
|
186
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 10 })
|
|
187
|
+
|
|
188
|
+
mocks.fetch.mockImplementation(async () => {
|
|
189
|
+
return Promise.resolve({
|
|
190
|
+
status: 413,
|
|
191
|
+
text: () => Promise.resolve('Content Too Large'),
|
|
192
|
+
json: () => Promise.resolve({ status: 'Content Too Large' }),
|
|
193
|
+
})
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
posthog.capture('test-event-1')
|
|
197
|
+
await expect(posthog.flush()).rejects.toHaveProperty('name', 'PostHogFetchHttpError')
|
|
198
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(1)
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it('should stop at first error', async () => {
|
|
202
|
+
jest.useRealTimers()
|
|
203
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 10, fetchRetryDelay: 1 })
|
|
204
|
+
posthog['maxBatchSize'] = 1 // a bit contrived because usually maxBatchSize >= flushAt
|
|
205
|
+
const successfulMessages: any[] = []
|
|
206
|
+
|
|
207
|
+
mocks.fetch.mockImplementation(async (_, options) => {
|
|
208
|
+
const batch = JSON.parse((options.body || '') as string).batch
|
|
209
|
+
|
|
210
|
+
if (batch.some((msg: any) => msg.event.includes('cursed'))) {
|
|
211
|
+
return Promise.resolve({
|
|
212
|
+
status: 500,
|
|
213
|
+
text: () => Promise.resolve('Cursed'),
|
|
214
|
+
json: () => Promise.resolve({ status: 'Cursed' }),
|
|
215
|
+
})
|
|
216
|
+
} else {
|
|
217
|
+
successfulMessages.push(...batch)
|
|
218
|
+
return Promise.resolve({
|
|
219
|
+
status: 200,
|
|
220
|
+
text: () => Promise.resolve('ok'),
|
|
221
|
+
json: () => Promise.resolve({ status: 'ok' }),
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
posthog.capture('test-event-1')
|
|
227
|
+
posthog.capture('cursed-event-2')
|
|
228
|
+
posthog.capture('test-event-3')
|
|
229
|
+
|
|
230
|
+
await expect(posthog.flush()).rejects.toHaveProperty('name', 'PostHogFetchHttpError')
|
|
231
|
+
expect(successfulMessages).toMatchObject([{ event: 'test-event-1' }])
|
|
232
|
+
expect(mocks.storage.getItem(PostHogPersistedProperty.Queue)).toMatchObject([
|
|
233
|
+
{ message: { event: 'test-event-3' } },
|
|
234
|
+
])
|
|
235
|
+
})
|
|
236
|
+
})
|
|
237
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { PostHogPersistedProperty } from '@/types'
|
|
2
|
+
import { createTestClient, PostHogCoreTestClient, PostHogCoreTestClientMocks } from '@/testing'
|
|
3
|
+
|
|
4
|
+
describe('PostHog Core', () => {
|
|
5
|
+
let posthog: PostHogCoreTestClient
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
|
+
let mocks: PostHogCoreTestClientMocks
|
|
8
|
+
|
|
9
|
+
jest.useFakeTimers()
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 5 })
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
describe('optOut', () => {
|
|
16
|
+
it('should be optedIn by default', async () => {
|
|
17
|
+
expect(posthog.optedOut).toEqual(false)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should be able to init disabled', async () => {
|
|
21
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { defaultOptIn: false })
|
|
22
|
+
expect(posthog.optedOut).toEqual(true)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('should opt in/out when called', async () => {
|
|
26
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { defaultOptIn: false })
|
|
27
|
+
posthog.optOut()
|
|
28
|
+
expect(posthog.optedOut).toEqual(true)
|
|
29
|
+
posthog.optIn()
|
|
30
|
+
expect(posthog.optedOut).toEqual(false)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should persist enabled state when called', async () => {
|
|
34
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { defaultOptIn: false })
|
|
35
|
+
expect(posthog.getPersistedProperty(PostHogPersistedProperty.OptedOut)).toEqual(undefined)
|
|
36
|
+
posthog.optOut()
|
|
37
|
+
expect(posthog.getPersistedProperty(PostHogPersistedProperty.OptedOut)).toEqual(true)
|
|
38
|
+
posthog.optIn()
|
|
39
|
+
expect(posthog.getPersistedProperty(PostHogPersistedProperty.OptedOut)).toEqual(false)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('should start in the correct state', async () => {
|
|
43
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { defaultOptIn: false }, (mocks) => {
|
|
44
|
+
mocks.storage.setItem(PostHogPersistedProperty.OptedOut, true)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
expect(posthog.optedOut).toEqual(true)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
})
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createTestClient,
|
|
3
|
+
PostHogCoreTestClient,
|
|
4
|
+
PostHogCoreTestClientMocks,
|
|
5
|
+
parseBody,
|
|
6
|
+
waitForPromises,
|
|
7
|
+
} from '@/testing'
|
|
8
|
+
|
|
9
|
+
describe('PostHog Core', () => {
|
|
10
|
+
let posthog: PostHogCoreTestClient
|
|
11
|
+
let mocks: PostHogCoreTestClientMocks
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.useFakeTimers()
|
|
15
|
+
jest.setSystemTime(new Date('2022-01-01'))
|
|
16
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 1 })
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
describe('groups', () => {
|
|
20
|
+
it('should store groups as persisted props', () => {
|
|
21
|
+
const groups = { posthog: 'team-1', other: 'key-2' }
|
|
22
|
+
posthog.groups(groups)
|
|
23
|
+
|
|
24
|
+
expect(mocks.storage.setItem).toHaveBeenCalledWith('props', {
|
|
25
|
+
$groups: groups,
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
describe('group', () => {
|
|
31
|
+
it('should store group as persisted props', () => {
|
|
32
|
+
const groups = { posthog: 'team-1' }
|
|
33
|
+
posthog.groups(groups)
|
|
34
|
+
posthog.group('other', 'foo')
|
|
35
|
+
posthog.group('posthog', 'team-2')
|
|
36
|
+
|
|
37
|
+
expect(mocks.storage.setItem).toHaveBeenCalledWith('props', {
|
|
38
|
+
$groups: {
|
|
39
|
+
posthog: 'team-2',
|
|
40
|
+
other: 'foo',
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('should call groupIdentify if including props', async () => {
|
|
46
|
+
posthog.group('other', 'team', { foo: 'bar' })
|
|
47
|
+
await waitForPromises()
|
|
48
|
+
|
|
49
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(2) // 1 for flags, 1 for groupIdentify
|
|
50
|
+
const batchCall = mocks.fetch.mock.calls[1]
|
|
51
|
+
expect(batchCall[0]).toEqual('https://us.i.posthog.com/batch/')
|
|
52
|
+
expect(parseBody(batchCall)).toMatchObject({
|
|
53
|
+
batch: [
|
|
54
|
+
{
|
|
55
|
+
event: '$groupidentify',
|
|
56
|
+
distinct_id: posthog.getDistinctId(),
|
|
57
|
+
properties: {
|
|
58
|
+
$group_type: 'other',
|
|
59
|
+
$group_key: 'team',
|
|
60
|
+
$group_set: { foo: 'bar' },
|
|
61
|
+
},
|
|
62
|
+
type: 'capture',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('groupIdentify', () => {
|
|
70
|
+
it('should identify group', async () => {
|
|
71
|
+
posthog.groupIdentify('posthog', 'team-1', { analytics: true })
|
|
72
|
+
await waitForPromises()
|
|
73
|
+
|
|
74
|
+
expect(parseBody(mocks.fetch.mock.calls[0])).toMatchObject({
|
|
75
|
+
api_key: 'TEST_API_KEY',
|
|
76
|
+
batch: [
|
|
77
|
+
{
|
|
78
|
+
event: '$groupidentify',
|
|
79
|
+
distinct_id: posthog.getDistinctId(),
|
|
80
|
+
library: 'posthog-core-tests',
|
|
81
|
+
library_version: '2.0.0-alpha',
|
|
82
|
+
properties: {
|
|
83
|
+
$lib: 'posthog-core-tests',
|
|
84
|
+
$lib_version: '2.0.0-alpha',
|
|
85
|
+
$group_type: 'posthog',
|
|
86
|
+
$group_key: 'team-1',
|
|
87
|
+
$group_set: { analytics: true },
|
|
88
|
+
},
|
|
89
|
+
timestamp: '2022-01-01T00:00:00.000Z',
|
|
90
|
+
type: 'capture',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
})
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseBody,
|
|
3
|
+
waitForPromises,
|
|
4
|
+
createTestClient,
|
|
5
|
+
PostHogCoreTestClient,
|
|
6
|
+
PostHogCoreTestClientMocks,
|
|
7
|
+
} from '@/testing'
|
|
8
|
+
import { PostHogPersistedProperty } from '@/types'
|
|
9
|
+
|
|
10
|
+
describe('PostHog Core', () => {
|
|
11
|
+
let posthog: PostHogCoreTestClient
|
|
12
|
+
let mocks: PostHogCoreTestClientMocks
|
|
13
|
+
|
|
14
|
+
jest.useFakeTimers()
|
|
15
|
+
jest.setSystemTime(new Date('2022-01-01'))
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 1 })
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
describe('identify', () => {
|
|
22
|
+
// Identify also triggers a subsequent flags call so we should expect 2 calls
|
|
23
|
+
it('should send an $identify event', async () => {
|
|
24
|
+
posthog.identify('id-1', { foo: 'bar' })
|
|
25
|
+
await waitForPromises()
|
|
26
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
27
|
+
const batchCall = mocks.fetch.mock.calls[1]
|
|
28
|
+
expect(batchCall[0]).toEqual('https://us.i.posthog.com/batch/')
|
|
29
|
+
expect(parseBody(batchCall)).toMatchObject({
|
|
30
|
+
api_key: 'TEST_API_KEY',
|
|
31
|
+
batch: [
|
|
32
|
+
{
|
|
33
|
+
event: '$identify',
|
|
34
|
+
distinct_id: posthog.getDistinctId(),
|
|
35
|
+
library: 'posthog-core-tests',
|
|
36
|
+
library_version: '2.0.0-alpha',
|
|
37
|
+
properties: {
|
|
38
|
+
$lib: 'posthog-core-tests',
|
|
39
|
+
$lib_version: '2.0.0-alpha',
|
|
40
|
+
$anon_distinct_id: expect.any(String),
|
|
41
|
+
$session_id: expect.any(String),
|
|
42
|
+
$set: {
|
|
43
|
+
foo: 'bar',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
timestamp: expect.any(String),
|
|
47
|
+
uuid: expect.any(String),
|
|
48
|
+
type: 'identify',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
sent_at: expect.any(String),
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('should send an $identify with $set and $set_once event', async () => {
|
|
56
|
+
posthog.identify('id-1', {
|
|
57
|
+
$set: {
|
|
58
|
+
foo: 'bar',
|
|
59
|
+
},
|
|
60
|
+
$set_once: {
|
|
61
|
+
vip: true,
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
await waitForPromises()
|
|
65
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
66
|
+
const batchCall = mocks.fetch.mock.calls[1]
|
|
67
|
+
expect(batchCall[0]).toEqual('https://us.i.posthog.com/batch/')
|
|
68
|
+
expect(parseBody(batchCall)).toMatchObject({
|
|
69
|
+
api_key: 'TEST_API_KEY',
|
|
70
|
+
batch: [
|
|
71
|
+
{
|
|
72
|
+
event: '$identify',
|
|
73
|
+
distinct_id: posthog.getDistinctId(),
|
|
74
|
+
library: 'posthog-core-tests',
|
|
75
|
+
library_version: '2.0.0-alpha',
|
|
76
|
+
properties: {
|
|
77
|
+
$lib: 'posthog-core-tests',
|
|
78
|
+
$lib_version: '2.0.0-alpha',
|
|
79
|
+
$anon_distinct_id: expect.any(String),
|
|
80
|
+
$session_id: expect.any(String),
|
|
81
|
+
$set: {
|
|
82
|
+
foo: 'bar',
|
|
83
|
+
},
|
|
84
|
+
$set_once: {
|
|
85
|
+
vip: true,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
timestamp: expect.any(String),
|
|
89
|
+
uuid: expect.any(String),
|
|
90
|
+
type: 'identify',
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
sent_at: expect.any(String),
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('should send an $identify with $set_once event', async () => {
|
|
98
|
+
posthog.identify('id-1', {
|
|
99
|
+
foo: 'bar',
|
|
100
|
+
$set_once: {
|
|
101
|
+
vip: true,
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
await waitForPromises()
|
|
105
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
106
|
+
const batchCall = mocks.fetch.mock.calls[1]
|
|
107
|
+
expect(batchCall[0]).toEqual('https://us.i.posthog.com/batch/')
|
|
108
|
+
expect(parseBody(batchCall)).toMatchObject({
|
|
109
|
+
api_key: 'TEST_API_KEY',
|
|
110
|
+
batch: [
|
|
111
|
+
{
|
|
112
|
+
event: '$identify',
|
|
113
|
+
distinct_id: posthog.getDistinctId(),
|
|
114
|
+
library: 'posthog-core-tests',
|
|
115
|
+
library_version: '2.0.0-alpha',
|
|
116
|
+
properties: {
|
|
117
|
+
$lib: 'posthog-core-tests',
|
|
118
|
+
$lib_version: '2.0.0-alpha',
|
|
119
|
+
$anon_distinct_id: expect.any(String),
|
|
120
|
+
$session_id: expect.any(String),
|
|
121
|
+
$set: {
|
|
122
|
+
foo: 'bar',
|
|
123
|
+
},
|
|
124
|
+
$set_once: {
|
|
125
|
+
vip: true,
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
timestamp: expect.any(String),
|
|
129
|
+
uuid: expect.any(String),
|
|
130
|
+
type: 'identify',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
sent_at: expect.any(String),
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('should include anonymous ID if set', async () => {
|
|
138
|
+
posthog.identify('id-1', { foo: 'bar' })
|
|
139
|
+
await waitForPromises()
|
|
140
|
+
|
|
141
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
142
|
+
const batchCall = mocks.fetch.mock.calls[1]
|
|
143
|
+
expect(batchCall[0]).toEqual('https://us.i.posthog.com/batch/')
|
|
144
|
+
expect(parseBody(batchCall)).toMatchObject({
|
|
145
|
+
batch: [
|
|
146
|
+
{
|
|
147
|
+
distinct_id: posthog.getDistinctId(),
|
|
148
|
+
properties: {
|
|
149
|
+
$anon_distinct_id: expect.any(String),
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('should update distinctId if different', () => {
|
|
157
|
+
const distinctId = posthog.getDistinctId()
|
|
158
|
+
posthog.identify('id-1', { foo: 'bar' })
|
|
159
|
+
|
|
160
|
+
expect(mocks.storage.setItem).toHaveBeenCalledWith('anonymous_id', distinctId)
|
|
161
|
+
expect(mocks.storage.setItem).toHaveBeenCalledWith('distinct_id', 'id-1')
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it('should use existing distinctId from storage', async () => {
|
|
165
|
+
mocks.storage.setItem(PostHogPersistedProperty.AnonymousId, 'my-old-value')
|
|
166
|
+
mocks.storage.setItem.mockClear()
|
|
167
|
+
posthog.identify('id-1', { foo: 'bar' })
|
|
168
|
+
await waitForPromises()
|
|
169
|
+
|
|
170
|
+
// One call exists for the queueing, one for persisting distinct id
|
|
171
|
+
expect(mocks.storage.setItem).toHaveBeenCalledWith('distinct_id', 'id-1')
|
|
172
|
+
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
173
|
+
const batchCall = mocks.fetch.mock.calls[1]
|
|
174
|
+
expect(batchCall[0]).toEqual('https://us.i.posthog.com/batch/')
|
|
175
|
+
expect(parseBody(batchCall)).toMatchObject({
|
|
176
|
+
batch: [
|
|
177
|
+
{
|
|
178
|
+
distinct_id: 'id-1',
|
|
179
|
+
properties: {
|
|
180
|
+
$anon_distinct_id: 'my-old-value',
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('should not update stored properties if distinct_id the same', () => {
|
|
188
|
+
mocks.storage.setItem(PostHogPersistedProperty.DistinctId, 'id-1')
|
|
189
|
+
mocks.storage.setItem.mockClear()
|
|
190
|
+
posthog.identify('id-1', { foo: 'bar' })
|
|
191
|
+
expect(mocks.storage.setItem).not.toHaveBeenCalledWith('distinct_id', 'id-1')
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
})
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createTestClient, waitForPromises, PostHogCoreTestClient, PostHogCoreTestClientMocks } from '@/testing'
|
|
2
|
+
|
|
3
|
+
describe('PostHog Core', () => {
|
|
4
|
+
let posthog: PostHogCoreTestClient
|
|
5
|
+
let mocks: PostHogCoreTestClientMocks
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', {})
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
describe('init', () => {
|
|
12
|
+
it('should initialise', () => {
|
|
13
|
+
expect(posthog.optedOut).toEqual(false)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('should throw if missing api key', () => {
|
|
17
|
+
expect(() => createTestClient(undefined as unknown as string)).toThrowError(
|
|
18
|
+
"You must pass your PostHog project's api key."
|
|
19
|
+
)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('should throw if empty api key', () => {
|
|
23
|
+
expect(() => createTestClient(' ')).toThrowError("You must pass your PostHog project's api key.")
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should throw if non string api key', () => {
|
|
27
|
+
expect(() => createTestClient({} as string)).toThrowError("You must pass your PostHog project's api key.")
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('should initialise default options', () => {
|
|
31
|
+
expect(posthog as any).toMatchObject({
|
|
32
|
+
apiKey: 'TEST_API_KEY',
|
|
33
|
+
host: 'https://us.i.posthog.com',
|
|
34
|
+
flushAt: 20,
|
|
35
|
+
flushInterval: 10000,
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('overwrites defaults with options', () => {
|
|
40
|
+
;[posthog, mocks] = createTestClient('key', {
|
|
41
|
+
host: 'https://a.com',
|
|
42
|
+
flushAt: 1,
|
|
43
|
+
flushInterval: 2,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
expect(posthog).toMatchObject({
|
|
47
|
+
apiKey: 'key',
|
|
48
|
+
host: 'https://a.com',
|
|
49
|
+
flushAt: 1,
|
|
50
|
+
flushInterval: 2,
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should keep the flushAt option above zero', () => {
|
|
55
|
+
;[posthog, mocks] = createTestClient('key', { flushAt: -2 }) as any
|
|
56
|
+
expect((posthog as any).flushAt).toEqual(1)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should remove trailing slashes from `host`', () => {
|
|
60
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { host: 'http://my-posthog.com///' })
|
|
61
|
+
|
|
62
|
+
expect((posthog as any).host).toEqual('http://my-posthog.com')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('should use bootstrapped distinct ID when present', async () => {
|
|
66
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', { bootstrap: { distinctId: 'new_anon_id' } })
|
|
67
|
+
|
|
68
|
+
expect((posthog as any).getDistinctId()).toEqual('new_anon_id')
|
|
69
|
+
expect((posthog as any).getAnonymousId()).toEqual('new_anon_id')
|
|
70
|
+
|
|
71
|
+
await posthog.identify('random_id')
|
|
72
|
+
|
|
73
|
+
expect((posthog as any).getDistinctId()).toEqual('random_id')
|
|
74
|
+
expect((posthog as any).getAnonymousId()).toEqual('new_anon_id')
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it('should use bootstrapped distinct ID as identified ID when present', async () => {
|
|
78
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', {
|
|
79
|
+
bootstrap: { distinctId: 'new_id', isIdentifiedId: true },
|
|
80
|
+
})
|
|
81
|
+
jest.runOnlyPendingTimers()
|
|
82
|
+
|
|
83
|
+
expect((posthog as any).getDistinctId()).toEqual('new_id')
|
|
84
|
+
expect((posthog as any).getAnonymousId()).not.toEqual('new_id')
|
|
85
|
+
|
|
86
|
+
await posthog.identify('random_id')
|
|
87
|
+
|
|
88
|
+
expect((posthog as any).getDistinctId()).toEqual('random_id')
|
|
89
|
+
expect((posthog as any).getAnonymousId()).toEqual('new_id')
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
describe('disabled', () => {
|
|
94
|
+
it('should not send events when disabled', async () => {
|
|
95
|
+
;[posthog, mocks] = createTestClient('TEST_API_KEY', {
|
|
96
|
+
disabled: true,
|
|
97
|
+
flushAt: 1,
|
|
98
|
+
})
|
|
99
|
+
jest.runOnlyPendingTimers()
|
|
100
|
+
|
|
101
|
+
expect(posthog.getFeatureFlags()).toEqual(undefined)
|
|
102
|
+
posthog.capture('test')
|
|
103
|
+
posthog.capture('identify')
|
|
104
|
+
|
|
105
|
+
await waitForPromises()
|
|
106
|
+
|
|
107
|
+
expect(mocks.fetch).not.toHaveBeenCalled()
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
})
|