@posthog/core 1.2.1 → 1.2.3
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/parsers/base.d.ts +0 -5
- package/dist/error-tracking/parsers/base.d.ts.map +1 -1
- package/dist/error-tracking/parsers/base.js +1 -21
- package/dist/error-tracking/parsers/base.mjs +1 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -20
- package/dist/index.mjs +1 -2
- package/dist/logger.d.ts +11 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +74 -0
- package/dist/logger.mjs +37 -0
- package/dist/posthog-core-stateless.d.ts +2 -1
- package/dist/posthog-core-stateless.d.ts.map +1 -1
- package/dist/posthog-core-stateless.js +31 -29
- package/dist/posthog-core-stateless.mjs +31 -29
- package/dist/posthog-core.d.ts.map +1 -1
- package/dist/posthog-core.js +9 -9
- package/dist/posthog-core.mjs +9 -9
- package/dist/testing/test-utils.d.ts.map +1 -1
- package/dist/testing/test-utils.js +4 -6
- package/dist/testing/test-utils.mjs +4 -6
- package/dist/types.d.ts +1 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/error-tracking/parsers/base.ts +0 -5
- package/src/index.ts +0 -1
- package/src/logger.ts +58 -0
- package/src/posthog-core-stateless.ts +35 -35
- package/src/posthog-core.ts +9 -17
- package/src/testing/test-utils.ts +4 -6
- package/src/types.ts +1 -3
- package/src/__tests__/featureFlagUtils.spec.ts +0 -427
- package/src/__tests__/gzip.spec.ts +0 -69
- package/src/__tests__/posthog.ai.spec.ts +0 -110
- package/src/__tests__/posthog.capture.spec.ts +0 -91
- package/src/__tests__/posthog.core.spec.ts +0 -135
- package/src/__tests__/posthog.debug.spec.ts +0 -36
- package/src/__tests__/posthog.enqueue.spec.ts +0 -93
- package/src/__tests__/posthog.featureflags.spec.ts +0 -1106
- package/src/__tests__/posthog.featureflags.v1.spec.ts +0 -922
- package/src/__tests__/posthog.flush.spec.ts +0 -237
- package/src/__tests__/posthog.gdpr.spec.ts +0 -50
- package/src/__tests__/posthog.groups.spec.ts +0 -96
- package/src/__tests__/posthog.identify.spec.ts +0 -194
- package/src/__tests__/posthog.init.spec.ts +0 -110
- package/src/__tests__/posthog.listeners.spec.ts +0 -51
- package/src/__tests__/posthog.register.spec.ts +0 -47
- package/src/__tests__/posthog.reset.spec.ts +0 -76
- package/src/__tests__/posthog.sessions.spec.ts +0 -63
- package/src/__tests__/posthog.setProperties.spec.ts +0 -102
- package/src/__tests__/posthog.shutdown.spec.ts +0 -88
- package/src/__tests__/utils.spec.ts +0 -36
|
@@ -1,237 +0,0 @@
|
|
|
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
|
-
})
|
|
@@ -1,50 +0,0 @@
|
|
|
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
|
-
})
|
|
@@ -1,96 +0,0 @@
|
|
|
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
|
-
})
|
|
@@ -1,194 +0,0 @@
|
|
|
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
|
-
})
|
|
@@ -1,110 +0,0 @@
|
|
|
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
|
-
})
|