@posthog/core 1.2.0 → 1.2.2
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/error-properties-builder.d.ts +6 -6
- package/dist/error-tracking/error-properties-builder.d.ts.map +1 -1
- package/dist/error-tracking/error-properties-builder.js +7 -13
- package/dist/error-tracking/error-properties-builder.mjs +5 -11
- 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/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/error-tracking/error-properties-builder.ts +14 -16
- package/src/index.ts +0 -1
- package/src/types.ts +1 -1
- 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,922 +0,0 @@
|
|
|
1
|
-
import { PostHogPersistedProperty, PostHogV1FlagsResponse } from '@/types'
|
|
2
|
-
import { normalizeFlagsResponse } from '@/featureFlagUtils'
|
|
3
|
-
import {
|
|
4
|
-
parseBody,
|
|
5
|
-
waitForPromises,
|
|
6
|
-
createTestClient,
|
|
7
|
-
PostHogCoreTestClient,
|
|
8
|
-
PostHogCoreTestClientMocks,
|
|
9
|
-
} from '@/testing'
|
|
10
|
-
|
|
11
|
-
describe('PostHog Feature Flags v1', () => {
|
|
12
|
-
let posthog: PostHogCoreTestClient
|
|
13
|
-
let mocks: PostHogCoreTestClientMocks
|
|
14
|
-
|
|
15
|
-
jest.useFakeTimers()
|
|
16
|
-
jest.setSystemTime(new Date('2022-01-01'))
|
|
17
|
-
|
|
18
|
-
const createMockFeatureFlags = (): any => ({
|
|
19
|
-
'feature-1': true,
|
|
20
|
-
'feature-2': true,
|
|
21
|
-
'feature-variant': 'variant',
|
|
22
|
-
'json-payload': true,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
const createMockFeatureFlagPayloads = (): any => ({
|
|
26
|
-
'feature-1': JSON.stringify({
|
|
27
|
-
color: 'blue',
|
|
28
|
-
}),
|
|
29
|
-
'feature-variant': JSON.stringify([5]),
|
|
30
|
-
'json-payload': '{"a":"payload"}',
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const errorAPIResponse = Promise.resolve({
|
|
34
|
-
status: 400,
|
|
35
|
-
text: () => Promise.resolve('error'),
|
|
36
|
-
json: () =>
|
|
37
|
-
Promise.resolve({
|
|
38
|
-
status: 'error',
|
|
39
|
-
}),
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
beforeEach(() => {
|
|
43
|
-
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 1 }, (_mocks) => {
|
|
44
|
-
_mocks.fetch.mockImplementation((url) => {
|
|
45
|
-
if (url.includes('/flags/?v=2&config=true')) {
|
|
46
|
-
return Promise.resolve({
|
|
47
|
-
status: 200,
|
|
48
|
-
text: () => Promise.resolve('ok'),
|
|
49
|
-
json: () =>
|
|
50
|
-
Promise.resolve({
|
|
51
|
-
featureFlags: createMockFeatureFlags(),
|
|
52
|
-
featureFlagPayloads: createMockFeatureFlagPayloads(),
|
|
53
|
-
}),
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return Promise.resolve({
|
|
58
|
-
status: 200,
|
|
59
|
-
text: () => Promise.resolve('ok'),
|
|
60
|
-
json: () =>
|
|
61
|
-
Promise.resolve({
|
|
62
|
-
status: 'ok',
|
|
63
|
-
}),
|
|
64
|
-
})
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe('featureflags', () => {
|
|
70
|
-
it('getFeatureFlags should return undefined if not loaded', () => {
|
|
71
|
-
expect(posthog.getFeatureFlags()).toEqual(undefined)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
it('getFeatureFlagPayloads should return undefined if not loaded', () => {
|
|
75
|
-
expect(posthog.getFeatureFlagPayloads()).toEqual(undefined)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('getFeatureFlag should return undefined if not loaded', () => {
|
|
79
|
-
expect(posthog.getFeatureFlag('my-flag')).toEqual(undefined)
|
|
80
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(undefined)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('getFeatureFlagPayload should return undefined if not loaded', () => {
|
|
84
|
-
expect(posthog.getFeatureFlagPayload('my-flag')).toEqual(undefined)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('isFeatureEnabled should return undefined if not loaded', () => {
|
|
88
|
-
expect(posthog.isFeatureEnabled('my-flag')).toEqual(undefined)
|
|
89
|
-
expect(posthog.isFeatureEnabled('feature-1')).toEqual(undefined)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('should load legacy persisted feature flags', () => {
|
|
93
|
-
posthog.setPersistedProperty(PostHogPersistedProperty.FeatureFlags, createMockFeatureFlags())
|
|
94
|
-
expect(posthog.getFeatureFlags()).toEqual(createMockFeatureFlags())
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('should only call fetch once if already calling', async () => {
|
|
98
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(0)
|
|
99
|
-
posthog.reloadFeatureFlagsAsync()
|
|
100
|
-
posthog.reloadFeatureFlagsAsync()
|
|
101
|
-
const flags = await posthog.reloadFeatureFlagsAsync()
|
|
102
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(1)
|
|
103
|
-
expect(flags).toEqual(createMockFeatureFlags())
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('should emit featureflags event when flags are loaded', async () => {
|
|
107
|
-
const receivedFlags: any[] = []
|
|
108
|
-
const unsubscribe = posthog.onFeatureFlags((flags) => {
|
|
109
|
-
receivedFlags.push(flags)
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
await posthog.reloadFeatureFlagsAsync()
|
|
113
|
-
unsubscribe()
|
|
114
|
-
|
|
115
|
-
expect(receivedFlags).toEqual([createMockFeatureFlags()])
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
describe('when loaded', () => {
|
|
119
|
-
beforeEach(() => {
|
|
120
|
-
// The core doesn't reload flags by default (this is handled differently by web and RN)
|
|
121
|
-
posthog.reloadFeatureFlags()
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it('should return the value of a flag', async () => {
|
|
125
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(true)
|
|
126
|
-
expect(posthog.getFeatureFlag('feature-variant')).toEqual('variant')
|
|
127
|
-
expect(posthog.getFeatureFlag('feature-missing')).toEqual(false)
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('should return payload of matched flags only', async () => {
|
|
131
|
-
expect(posthog.getFeatureFlagPayload('feature-variant')).toEqual([5])
|
|
132
|
-
expect(posthog.getFeatureFlagPayload('feature-1')).toEqual({
|
|
133
|
-
color: 'blue',
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
expect(posthog.getFeatureFlagPayload('feature-2')).toEqual(null)
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
describe('when errored out', () => {
|
|
140
|
-
beforeEach(() => {
|
|
141
|
-
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 1 }, (_mocks) => {
|
|
142
|
-
_mocks.fetch.mockImplementation((url) => {
|
|
143
|
-
if (url.includes('/flags/')) {
|
|
144
|
-
return Promise.resolve({
|
|
145
|
-
status: 400,
|
|
146
|
-
text: () => Promise.resolve('ok'),
|
|
147
|
-
json: () =>
|
|
148
|
-
Promise.resolve({
|
|
149
|
-
error: 'went wrong',
|
|
150
|
-
}),
|
|
151
|
-
})
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return errorAPIResponse
|
|
155
|
-
})
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
posthog.reloadFeatureFlags()
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
it('should return undefined', async () => {
|
|
162
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
163
|
-
body: JSON.stringify({
|
|
164
|
-
token: 'TEST_API_KEY',
|
|
165
|
-
distinct_id: posthog.getDistinctId(),
|
|
166
|
-
groups: {},
|
|
167
|
-
person_properties: {},
|
|
168
|
-
group_properties: {},
|
|
169
|
-
$anon_distinct_id: posthog.getAnonymousId(),
|
|
170
|
-
}),
|
|
171
|
-
method: 'POST',
|
|
172
|
-
headers: {
|
|
173
|
-
'Content-Type': 'application/json',
|
|
174
|
-
'User-Agent': 'posthog-core-tests',
|
|
175
|
-
},
|
|
176
|
-
signal: expect.anything(),
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(undefined)
|
|
180
|
-
expect(posthog.getFeatureFlag('feature-variant')).toEqual(undefined)
|
|
181
|
-
expect(posthog.getFeatureFlag('feature-missing')).toEqual(undefined)
|
|
182
|
-
|
|
183
|
-
expect(posthog.isFeatureEnabled('feature-1')).toEqual(undefined)
|
|
184
|
-
expect(posthog.isFeatureEnabled('feature-variant')).toEqual(undefined)
|
|
185
|
-
expect(posthog.isFeatureEnabled('feature-missing')).toEqual(undefined)
|
|
186
|
-
|
|
187
|
-
expect(posthog.getFeatureFlagPayloads()).toEqual(undefined)
|
|
188
|
-
expect(posthog.getFeatureFlagPayload('feature-1')).toEqual(undefined)
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
describe('when subsequent flags calls return partial results', () => {
|
|
193
|
-
beforeEach(() => {
|
|
194
|
-
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 1 }, (_mocks) => {
|
|
195
|
-
_mocks.fetch
|
|
196
|
-
.mockImplementationOnce((url) => {
|
|
197
|
-
if (url.includes('/flags/?v=2&config=true')) {
|
|
198
|
-
return Promise.resolve({
|
|
199
|
-
status: 200,
|
|
200
|
-
text: () => Promise.resolve('ok'),
|
|
201
|
-
json: () =>
|
|
202
|
-
Promise.resolve({
|
|
203
|
-
featureFlags: createMockFeatureFlags(),
|
|
204
|
-
}),
|
|
205
|
-
})
|
|
206
|
-
}
|
|
207
|
-
return errorAPIResponse
|
|
208
|
-
})
|
|
209
|
-
.mockImplementationOnce((url) => {
|
|
210
|
-
if (url.includes('/flags/?v=2&config=true')) {
|
|
211
|
-
return Promise.resolve({
|
|
212
|
-
status: 200,
|
|
213
|
-
text: () => Promise.resolve('ok'),
|
|
214
|
-
json: () =>
|
|
215
|
-
Promise.resolve({
|
|
216
|
-
featureFlags: { 'x-flag': 'x-value', 'feature-1': false },
|
|
217
|
-
errorsWhileComputingFlags: true,
|
|
218
|
-
}),
|
|
219
|
-
})
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return errorAPIResponse
|
|
223
|
-
})
|
|
224
|
-
.mockImplementation(() => {
|
|
225
|
-
return errorAPIResponse
|
|
226
|
-
})
|
|
227
|
-
})
|
|
228
|
-
|
|
229
|
-
posthog.reloadFeatureFlags()
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
it('should return combined results', async () => {
|
|
233
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
234
|
-
body: JSON.stringify({
|
|
235
|
-
token: 'TEST_API_KEY',
|
|
236
|
-
distinct_id: posthog.getDistinctId(),
|
|
237
|
-
groups: {},
|
|
238
|
-
person_properties: {},
|
|
239
|
-
group_properties: {},
|
|
240
|
-
$anon_distinct_id: posthog.getAnonymousId(),
|
|
241
|
-
}),
|
|
242
|
-
method: 'POST',
|
|
243
|
-
headers: {
|
|
244
|
-
'Content-Type': 'application/json',
|
|
245
|
-
'User-Agent': 'posthog-core-tests',
|
|
246
|
-
},
|
|
247
|
-
signal: expect.anything(),
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
expect(posthog.getFeatureFlags()).toEqual({
|
|
251
|
-
'feature-1': true,
|
|
252
|
-
'feature-2': true,
|
|
253
|
-
'json-payload': true,
|
|
254
|
-
'feature-variant': 'variant',
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
// now second call to feature flags
|
|
258
|
-
await posthog.reloadFeatureFlagsAsync()
|
|
259
|
-
|
|
260
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
261
|
-
body: JSON.stringify({
|
|
262
|
-
token: 'TEST_API_KEY',
|
|
263
|
-
distinct_id: posthog.getDistinctId(),
|
|
264
|
-
groups: {},
|
|
265
|
-
person_properties: {},
|
|
266
|
-
group_properties: {},
|
|
267
|
-
$anon_distinct_id: posthog.getAnonymousId(),
|
|
268
|
-
}),
|
|
269
|
-
method: 'POST',
|
|
270
|
-
headers: {
|
|
271
|
-
'Content-Type': 'application/json',
|
|
272
|
-
'User-Agent': 'posthog-core-tests',
|
|
273
|
-
},
|
|
274
|
-
signal: expect.anything(),
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
expect(posthog.getFeatureFlags()).toEqual({
|
|
278
|
-
'feature-1': false,
|
|
279
|
-
'feature-2': true,
|
|
280
|
-
'json-payload': true,
|
|
281
|
-
'feature-variant': 'variant',
|
|
282
|
-
'x-flag': 'x-value',
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(false)
|
|
286
|
-
expect(posthog.getFeatureFlag('feature-variant')).toEqual('variant')
|
|
287
|
-
expect(posthog.getFeatureFlag('feature-missing')).toEqual(false)
|
|
288
|
-
expect(posthog.getFeatureFlag('x-flag')).toEqual('x-value')
|
|
289
|
-
|
|
290
|
-
expect(posthog.isFeatureEnabled('feature-1')).toEqual(false)
|
|
291
|
-
expect(posthog.isFeatureEnabled('feature-variant')).toEqual(true)
|
|
292
|
-
expect(posthog.isFeatureEnabled('feature-missing')).toEqual(false)
|
|
293
|
-
expect(posthog.isFeatureEnabled('x-flag')).toEqual(true)
|
|
294
|
-
})
|
|
295
|
-
})
|
|
296
|
-
|
|
297
|
-
describe('when subsequent flags calls return results without errors', () => {
|
|
298
|
-
beforeEach(() => {
|
|
299
|
-
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 1 }, (_mocks) => {
|
|
300
|
-
_mocks.fetch
|
|
301
|
-
.mockImplementationOnce((url) => {
|
|
302
|
-
if (url.includes('/flags/?v=2&config=true')) {
|
|
303
|
-
return Promise.resolve({
|
|
304
|
-
status: 200,
|
|
305
|
-
text: () => Promise.resolve('ok'),
|
|
306
|
-
json: () =>
|
|
307
|
-
Promise.resolve({
|
|
308
|
-
featureFlags: createMockFeatureFlags(),
|
|
309
|
-
}),
|
|
310
|
-
})
|
|
311
|
-
}
|
|
312
|
-
return errorAPIResponse
|
|
313
|
-
})
|
|
314
|
-
.mockImplementationOnce((url) => {
|
|
315
|
-
if (url.includes('/flags/?v=2&config=true')) {
|
|
316
|
-
return Promise.resolve({
|
|
317
|
-
status: 200,
|
|
318
|
-
text: () => Promise.resolve('ok'),
|
|
319
|
-
json: () =>
|
|
320
|
-
Promise.resolve({
|
|
321
|
-
featureFlags: { 'x-flag': 'x-value', 'feature-1': false },
|
|
322
|
-
errorsWhileComputingFlags: false,
|
|
323
|
-
}),
|
|
324
|
-
})
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return errorAPIResponse
|
|
328
|
-
})
|
|
329
|
-
.mockImplementation(() => {
|
|
330
|
-
return errorAPIResponse
|
|
331
|
-
})
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
posthog.reloadFeatureFlags()
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
it('should return only latest results', async () => {
|
|
338
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
339
|
-
body: JSON.stringify({
|
|
340
|
-
token: 'TEST_API_KEY',
|
|
341
|
-
distinct_id: posthog.getDistinctId(),
|
|
342
|
-
groups: {},
|
|
343
|
-
person_properties: {},
|
|
344
|
-
group_properties: {},
|
|
345
|
-
$anon_distinct_id: posthog.getAnonymousId(),
|
|
346
|
-
}),
|
|
347
|
-
method: 'POST',
|
|
348
|
-
headers: {
|
|
349
|
-
'Content-Type': 'application/json',
|
|
350
|
-
'User-Agent': 'posthog-core-tests',
|
|
351
|
-
},
|
|
352
|
-
signal: expect.anything(),
|
|
353
|
-
})
|
|
354
|
-
|
|
355
|
-
expect(posthog.getFeatureFlags()).toEqual({
|
|
356
|
-
'feature-1': true,
|
|
357
|
-
'feature-2': true,
|
|
358
|
-
'json-payload': true,
|
|
359
|
-
'feature-variant': 'variant',
|
|
360
|
-
})
|
|
361
|
-
|
|
362
|
-
// now second call to feature flags
|
|
363
|
-
await posthog.reloadFeatureFlagsAsync()
|
|
364
|
-
|
|
365
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
366
|
-
body: JSON.stringify({
|
|
367
|
-
token: 'TEST_API_KEY',
|
|
368
|
-
distinct_id: posthog.getDistinctId(),
|
|
369
|
-
groups: {},
|
|
370
|
-
person_properties: {},
|
|
371
|
-
group_properties: {},
|
|
372
|
-
$anon_distinct_id: posthog.getAnonymousId(),
|
|
373
|
-
}),
|
|
374
|
-
method: 'POST',
|
|
375
|
-
headers: {
|
|
376
|
-
'Content-Type': 'application/json',
|
|
377
|
-
'User-Agent': 'posthog-core-tests',
|
|
378
|
-
},
|
|
379
|
-
signal: expect.anything(),
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
expect(posthog.getFeatureFlags()).toEqual({
|
|
383
|
-
'feature-1': false,
|
|
384
|
-
'x-flag': 'x-value',
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(false)
|
|
388
|
-
expect(posthog.getFeatureFlag('feature-variant')).toEqual(false)
|
|
389
|
-
expect(posthog.getFeatureFlag('feature-missing')).toEqual(false)
|
|
390
|
-
expect(posthog.getFeatureFlag('x-flag')).toEqual('x-value')
|
|
391
|
-
|
|
392
|
-
expect(posthog.isFeatureEnabled('feature-1')).toEqual(false)
|
|
393
|
-
expect(posthog.isFeatureEnabled('feature-variant')).toEqual(false)
|
|
394
|
-
expect(posthog.isFeatureEnabled('feature-missing')).toEqual(false)
|
|
395
|
-
expect(posthog.isFeatureEnabled('x-flag')).toEqual(true)
|
|
396
|
-
})
|
|
397
|
-
})
|
|
398
|
-
|
|
399
|
-
it('should return the boolean value of a flag', async () => {
|
|
400
|
-
expect(posthog.isFeatureEnabled('feature-1')).toEqual(true)
|
|
401
|
-
expect(posthog.isFeatureEnabled('feature-variant')).toEqual(true)
|
|
402
|
-
expect(posthog.isFeatureEnabled('feature-missing')).toEqual(false)
|
|
403
|
-
})
|
|
404
|
-
|
|
405
|
-
it('should reload if groups are set', async () => {
|
|
406
|
-
posthog.group('my-group', 'is-great')
|
|
407
|
-
await waitForPromises()
|
|
408
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
409
|
-
expect(JSON.parse((mocks.fetch.mock.calls[1][1].body as string) || '')).toMatchObject({
|
|
410
|
-
groups: { 'my-group': 'is-great' },
|
|
411
|
-
})
|
|
412
|
-
})
|
|
413
|
-
|
|
414
|
-
it('should capture $feature_flag_called when called', async () => {
|
|
415
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(true)
|
|
416
|
-
await waitForPromises()
|
|
417
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
418
|
-
|
|
419
|
-
expect(parseBody(mocks.fetch.mock.calls[1])).toMatchObject({
|
|
420
|
-
batch: [
|
|
421
|
-
{
|
|
422
|
-
event: '$feature_flag_called',
|
|
423
|
-
distinct_id: posthog.getDistinctId(),
|
|
424
|
-
properties: {
|
|
425
|
-
$feature_flag: 'feature-1',
|
|
426
|
-
$feature_flag_response: true,
|
|
427
|
-
'$feature/feature-1': true,
|
|
428
|
-
$used_bootstrap_value: false,
|
|
429
|
-
},
|
|
430
|
-
type: 'capture',
|
|
431
|
-
},
|
|
432
|
-
],
|
|
433
|
-
})
|
|
434
|
-
|
|
435
|
-
// Only tracked once
|
|
436
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(true)
|
|
437
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
438
|
-
})
|
|
439
|
-
|
|
440
|
-
it('should capture $feature_flag_called again if new flags', async () => {
|
|
441
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(true)
|
|
442
|
-
await waitForPromises()
|
|
443
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
444
|
-
|
|
445
|
-
expect(parseBody(mocks.fetch.mock.calls[1])).toMatchObject({
|
|
446
|
-
batch: [
|
|
447
|
-
{
|
|
448
|
-
event: '$feature_flag_called',
|
|
449
|
-
distinct_id: posthog.getDistinctId(),
|
|
450
|
-
properties: {
|
|
451
|
-
$feature_flag: 'feature-1',
|
|
452
|
-
$feature_flag_response: true,
|
|
453
|
-
'$feature/feature-1': true,
|
|
454
|
-
$used_bootstrap_value: false,
|
|
455
|
-
},
|
|
456
|
-
type: 'capture',
|
|
457
|
-
},
|
|
458
|
-
],
|
|
459
|
-
})
|
|
460
|
-
|
|
461
|
-
await posthog.reloadFeatureFlagsAsync()
|
|
462
|
-
posthog.getFeatureFlag('feature-1')
|
|
463
|
-
|
|
464
|
-
await waitForPromises()
|
|
465
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(4)
|
|
466
|
-
|
|
467
|
-
expect(parseBody(mocks.fetch.mock.calls[3])).toMatchObject({
|
|
468
|
-
batch: [
|
|
469
|
-
{
|
|
470
|
-
event: '$feature_flag_called',
|
|
471
|
-
distinct_id: posthog.getDistinctId(),
|
|
472
|
-
properties: {
|
|
473
|
-
$feature_flag: 'feature-1',
|
|
474
|
-
$feature_flag_response: true,
|
|
475
|
-
'$feature/feature-1': true,
|
|
476
|
-
$used_bootstrap_value: false,
|
|
477
|
-
},
|
|
478
|
-
type: 'capture',
|
|
479
|
-
},
|
|
480
|
-
],
|
|
481
|
-
})
|
|
482
|
-
})
|
|
483
|
-
|
|
484
|
-
it('should capture $feature_flag_called when called, but not add all cached flags', async () => {
|
|
485
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(true)
|
|
486
|
-
await waitForPromises()
|
|
487
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
488
|
-
|
|
489
|
-
expect(parseBody(mocks.fetch.mock.calls[1])).toMatchObject({
|
|
490
|
-
batch: [
|
|
491
|
-
{
|
|
492
|
-
event: '$feature_flag_called',
|
|
493
|
-
distinct_id: posthog.getDistinctId(),
|
|
494
|
-
properties: {
|
|
495
|
-
$feature_flag: 'feature-1',
|
|
496
|
-
$feature_flag_response: true,
|
|
497
|
-
'$feature/feature-1': true,
|
|
498
|
-
$used_bootstrap_value: false,
|
|
499
|
-
},
|
|
500
|
-
type: 'capture',
|
|
501
|
-
},
|
|
502
|
-
],
|
|
503
|
-
})
|
|
504
|
-
|
|
505
|
-
// Only tracked once
|
|
506
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(true)
|
|
507
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
508
|
-
})
|
|
509
|
-
|
|
510
|
-
it('should persist feature flags', () => {
|
|
511
|
-
const expectedFeatureFlags = {
|
|
512
|
-
featureFlags: createMockFeatureFlags(),
|
|
513
|
-
featureFlagPayloads: createMockFeatureFlagPayloads(),
|
|
514
|
-
}
|
|
515
|
-
const normalizedFeatureFlags = normalizeFlagsResponse(expectedFeatureFlags as PostHogV1FlagsResponse)
|
|
516
|
-
expect(posthog.getPersistedProperty(PostHogPersistedProperty.FeatureFlagDetails)).toEqual(
|
|
517
|
-
normalizedFeatureFlags
|
|
518
|
-
)
|
|
519
|
-
})
|
|
520
|
-
|
|
521
|
-
it('should include feature flags in subsequent captures', async () => {
|
|
522
|
-
posthog.capture('test-event', { foo: 'bar' })
|
|
523
|
-
|
|
524
|
-
await waitForPromises()
|
|
525
|
-
|
|
526
|
-
expect(parseBody(mocks.fetch.mock.calls[1])).toMatchObject({
|
|
527
|
-
batch: [
|
|
528
|
-
{
|
|
529
|
-
event: 'test-event',
|
|
530
|
-
distinct_id: posthog.getDistinctId(),
|
|
531
|
-
properties: {
|
|
532
|
-
$active_feature_flags: ['feature-1', 'feature-2', 'feature-variant', 'json-payload'],
|
|
533
|
-
'$feature/feature-1': true,
|
|
534
|
-
'$feature/feature-2': true,
|
|
535
|
-
'$feature/json-payload': true,
|
|
536
|
-
'$feature/feature-variant': 'variant',
|
|
537
|
-
},
|
|
538
|
-
type: 'capture',
|
|
539
|
-
},
|
|
540
|
-
],
|
|
541
|
-
})
|
|
542
|
-
})
|
|
543
|
-
|
|
544
|
-
it('should override flags', () => {
|
|
545
|
-
posthog.overrideFeatureFlag({
|
|
546
|
-
'feature-2': false,
|
|
547
|
-
'feature-variant': 'control',
|
|
548
|
-
})
|
|
549
|
-
expect(posthog.getFeatureFlags()).toEqual({
|
|
550
|
-
'json-payload': true,
|
|
551
|
-
'feature-1': true,
|
|
552
|
-
'feature-variant': 'control',
|
|
553
|
-
})
|
|
554
|
-
})
|
|
555
|
-
})
|
|
556
|
-
|
|
557
|
-
describe('when quota limited', () => {
|
|
558
|
-
beforeEach(() => {
|
|
559
|
-
;[posthog, mocks] = createTestClient('TEST_API_KEY', { flushAt: 1 }, (_mocks) => {
|
|
560
|
-
_mocks.fetch.mockImplementation((url) => {
|
|
561
|
-
if (url.includes('/flags/')) {
|
|
562
|
-
return Promise.resolve({
|
|
563
|
-
status: 200,
|
|
564
|
-
text: () => Promise.resolve('ok'),
|
|
565
|
-
json: () =>
|
|
566
|
-
Promise.resolve({
|
|
567
|
-
quotaLimited: ['feature_flags'],
|
|
568
|
-
featureFlags: {},
|
|
569
|
-
featureFlagPayloads: {},
|
|
570
|
-
}),
|
|
571
|
-
})
|
|
572
|
-
}
|
|
573
|
-
return errorAPIResponse
|
|
574
|
-
})
|
|
575
|
-
})
|
|
576
|
-
|
|
577
|
-
posthog.reloadFeatureFlags()
|
|
578
|
-
})
|
|
579
|
-
|
|
580
|
-
it('should unset all flags when feature_flags is quota limited', async () => {
|
|
581
|
-
// First verify the fetch was called correctly
|
|
582
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
583
|
-
body: JSON.stringify({
|
|
584
|
-
token: 'TEST_API_KEY',
|
|
585
|
-
distinct_id: posthog.getDistinctId(),
|
|
586
|
-
groups: {},
|
|
587
|
-
person_properties: {},
|
|
588
|
-
group_properties: {},
|
|
589
|
-
$anon_distinct_id: posthog.getAnonymousId(),
|
|
590
|
-
}),
|
|
591
|
-
method: 'POST',
|
|
592
|
-
headers: {
|
|
593
|
-
'Content-Type': 'application/json',
|
|
594
|
-
'User-Agent': 'posthog-core-tests',
|
|
595
|
-
},
|
|
596
|
-
signal: expect.anything(),
|
|
597
|
-
})
|
|
598
|
-
|
|
599
|
-
// Verify all flag methods return undefined when quota limited
|
|
600
|
-
expect(posthog.getFeatureFlags()).toEqual(undefined)
|
|
601
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(undefined)
|
|
602
|
-
expect(posthog.getFeatureFlagPayloads()).toEqual(undefined)
|
|
603
|
-
expect(posthog.getFeatureFlagPayload('feature-1')).toEqual(undefined)
|
|
604
|
-
})
|
|
605
|
-
|
|
606
|
-
it('should emit debug message when quota limited', async () => {
|
|
607
|
-
const warnSpy = jest.spyOn(console, 'warn')
|
|
608
|
-
posthog.debug(true)
|
|
609
|
-
await posthog.reloadFeatureFlagsAsync()
|
|
610
|
-
|
|
611
|
-
expect(warnSpy).toHaveBeenCalledWith(
|
|
612
|
-
'[FEATURE FLAGS] Feature flags quota limit exceeded - unsetting all flags. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts'
|
|
613
|
-
)
|
|
614
|
-
})
|
|
615
|
-
})
|
|
616
|
-
})
|
|
617
|
-
|
|
618
|
-
describe('bootstrapped feature flags', () => {
|
|
619
|
-
beforeEach(() => {
|
|
620
|
-
;[posthog, mocks] = createTestClient(
|
|
621
|
-
'TEST_API_KEY',
|
|
622
|
-
{
|
|
623
|
-
flushAt: 1,
|
|
624
|
-
bootstrap: {
|
|
625
|
-
distinctId: 'tomato',
|
|
626
|
-
featureFlags: {
|
|
627
|
-
'bootstrap-1': 'variant-1',
|
|
628
|
-
'feature-1': 'feature-1-bootstrap-value',
|
|
629
|
-
enabled: true,
|
|
630
|
-
disabled: false,
|
|
631
|
-
},
|
|
632
|
-
featureFlagPayloads: {
|
|
633
|
-
'bootstrap-1': {
|
|
634
|
-
some: 'key',
|
|
635
|
-
},
|
|
636
|
-
'feature-1': {
|
|
637
|
-
color: 'feature-1-bootstrap-color',
|
|
638
|
-
},
|
|
639
|
-
'not-in-featureFlags': {
|
|
640
|
-
color: { foo: 'bar' },
|
|
641
|
-
},
|
|
642
|
-
enabled: 200,
|
|
643
|
-
},
|
|
644
|
-
},
|
|
645
|
-
},
|
|
646
|
-
(_mocks) => {
|
|
647
|
-
_mocks.fetch.mockImplementation((url) => {
|
|
648
|
-
if (url.includes('/flags/')) {
|
|
649
|
-
return Promise.reject(new Error('Not responding to emulate use of bootstrapped values'))
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
return Promise.resolve({
|
|
653
|
-
status: 200,
|
|
654
|
-
text: () => Promise.resolve('ok'),
|
|
655
|
-
json: () =>
|
|
656
|
-
Promise.resolve({
|
|
657
|
-
status: 'ok',
|
|
658
|
-
}),
|
|
659
|
-
})
|
|
660
|
-
})
|
|
661
|
-
}
|
|
662
|
-
)
|
|
663
|
-
})
|
|
664
|
-
|
|
665
|
-
it('getFeatureFlags should return bootstrapped flags', async () => {
|
|
666
|
-
expect(posthog.getFeatureFlags()).toEqual({
|
|
667
|
-
'bootstrap-1': 'variant-1',
|
|
668
|
-
enabled: true,
|
|
669
|
-
'feature-1': 'feature-1-bootstrap-value',
|
|
670
|
-
'not-in-featureFlags': true,
|
|
671
|
-
})
|
|
672
|
-
expect(posthog.getDistinctId()).toEqual('tomato')
|
|
673
|
-
expect(posthog.getAnonymousId()).toEqual('tomato')
|
|
674
|
-
})
|
|
675
|
-
|
|
676
|
-
it('getFeatureFlag should return bootstrapped flags', async () => {
|
|
677
|
-
expect(posthog.getFeatureFlag('my-flag')).toEqual(false)
|
|
678
|
-
expect(posthog.getFeatureFlag('bootstrap-1')).toEqual('variant-1')
|
|
679
|
-
expect(posthog.getFeatureFlag('enabled')).toEqual(true)
|
|
680
|
-
expect(posthog.getFeatureFlag('disabled')).toEqual(false)
|
|
681
|
-
// If a bootstrapped payload is not in the feature flags, we treat it as true
|
|
682
|
-
expect(posthog.getFeatureFlag('not-in-featureFlags')).toEqual(true)
|
|
683
|
-
})
|
|
684
|
-
|
|
685
|
-
it('getFeatureFlag should capture $feature_flag_called with bootstrapped values', async () => {
|
|
686
|
-
expect(posthog.getFeatureFlag('bootstrap-1')).toEqual('variant-1')
|
|
687
|
-
|
|
688
|
-
await waitForPromises()
|
|
689
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(1)
|
|
690
|
-
|
|
691
|
-
expect(parseBody(mocks.fetch.mock.calls[0])).toMatchObject({
|
|
692
|
-
batch: [
|
|
693
|
-
{
|
|
694
|
-
event: '$feature_flag_called',
|
|
695
|
-
distinct_id: posthog.getDistinctId(),
|
|
696
|
-
properties: {
|
|
697
|
-
$feature_flag: 'bootstrap-1',
|
|
698
|
-
$feature_flag_response: 'variant-1',
|
|
699
|
-
'$feature/bootstrap-1': 'variant-1',
|
|
700
|
-
$feature_flag_bootstrapped_response: 'variant-1',
|
|
701
|
-
$feature_flag_bootstrapped_payload: { some: 'key' },
|
|
702
|
-
$used_bootstrap_value: true,
|
|
703
|
-
},
|
|
704
|
-
type: 'capture',
|
|
705
|
-
},
|
|
706
|
-
],
|
|
707
|
-
})
|
|
708
|
-
})
|
|
709
|
-
|
|
710
|
-
it('isFeatureEnabled should return true/false for bootstrapped flags', () => {
|
|
711
|
-
expect(posthog.isFeatureEnabled('my-flag')).toEqual(false)
|
|
712
|
-
expect(posthog.isFeatureEnabled('bootstrap-1')).toEqual(true)
|
|
713
|
-
expect(posthog.isFeatureEnabled('enabled')).toEqual(true)
|
|
714
|
-
expect(posthog.isFeatureEnabled('disabled')).toEqual(false)
|
|
715
|
-
expect(posthog.isFeatureEnabled('not-in-featureFlags')).toEqual(true)
|
|
716
|
-
})
|
|
717
|
-
|
|
718
|
-
it('getFeatureFlagPayload should return bootstrapped payloads', () => {
|
|
719
|
-
expect(posthog.getFeatureFlagPayload('my-flag')).toEqual(null)
|
|
720
|
-
expect(posthog.getFeatureFlagPayload('bootstrap-1')).toEqual({
|
|
721
|
-
some: 'key',
|
|
722
|
-
})
|
|
723
|
-
expect(posthog.getFeatureFlagPayload('enabled')).toEqual(200)
|
|
724
|
-
expect(posthog.getFeatureFlagPayload('not-in-featureFlags')).toEqual({
|
|
725
|
-
color: { foo: 'bar' },
|
|
726
|
-
})
|
|
727
|
-
})
|
|
728
|
-
|
|
729
|
-
describe('when loaded', () => {
|
|
730
|
-
beforeEach(() => {
|
|
731
|
-
;[posthog, mocks] = createTestClient(
|
|
732
|
-
'TEST_API_KEY',
|
|
733
|
-
{
|
|
734
|
-
flushAt: 1,
|
|
735
|
-
bootstrap: {
|
|
736
|
-
distinctId: 'tomato',
|
|
737
|
-
featureFlags: {
|
|
738
|
-
'bootstrap-1': 'variant-1',
|
|
739
|
-
'feature-1': 'feature-1-bootstrap-value',
|
|
740
|
-
enabled: true,
|
|
741
|
-
disabled: false,
|
|
742
|
-
},
|
|
743
|
-
featureFlagPayloads: {
|
|
744
|
-
'bootstrap-1': {
|
|
745
|
-
some: 'key',
|
|
746
|
-
},
|
|
747
|
-
'feature-1': {
|
|
748
|
-
color: 'feature-1-bootstrap-color',
|
|
749
|
-
},
|
|
750
|
-
enabled: 200,
|
|
751
|
-
},
|
|
752
|
-
},
|
|
753
|
-
},
|
|
754
|
-
(_mocks) => {
|
|
755
|
-
_mocks.fetch.mockImplementation((url) => {
|
|
756
|
-
if (url.includes('/flags/')) {
|
|
757
|
-
return Promise.resolve({
|
|
758
|
-
status: 200,
|
|
759
|
-
text: () => Promise.resolve('ok'),
|
|
760
|
-
json: () =>
|
|
761
|
-
Promise.resolve({
|
|
762
|
-
featureFlags: createMockFeatureFlags(),
|
|
763
|
-
featureFlagPayloads: createMockFeatureFlagPayloads(),
|
|
764
|
-
}),
|
|
765
|
-
})
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
return Promise.resolve({
|
|
769
|
-
status: 200,
|
|
770
|
-
text: () => Promise.resolve('ok'),
|
|
771
|
-
json: () =>
|
|
772
|
-
Promise.resolve({
|
|
773
|
-
status: 'ok',
|
|
774
|
-
}),
|
|
775
|
-
})
|
|
776
|
-
})
|
|
777
|
-
}
|
|
778
|
-
)
|
|
779
|
-
|
|
780
|
-
posthog.reloadFeatureFlags()
|
|
781
|
-
})
|
|
782
|
-
|
|
783
|
-
it('should load new feature flags', async () => {
|
|
784
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
785
|
-
body: JSON.stringify({
|
|
786
|
-
token: 'TEST_API_KEY',
|
|
787
|
-
distinct_id: posthog.getDistinctId(),
|
|
788
|
-
groups: {},
|
|
789
|
-
person_properties: {},
|
|
790
|
-
group_properties: {},
|
|
791
|
-
$anon_distinct_id: 'tomato',
|
|
792
|
-
}),
|
|
793
|
-
method: 'POST',
|
|
794
|
-
headers: {
|
|
795
|
-
'Content-Type': 'application/json',
|
|
796
|
-
'User-Agent': 'posthog-core-tests',
|
|
797
|
-
},
|
|
798
|
-
signal: expect.anything(),
|
|
799
|
-
})
|
|
800
|
-
|
|
801
|
-
expect(posthog.getFeatureFlags()).toEqual({
|
|
802
|
-
'feature-1': true,
|
|
803
|
-
'feature-2': true,
|
|
804
|
-
'json-payload': true,
|
|
805
|
-
'feature-variant': 'variant',
|
|
806
|
-
})
|
|
807
|
-
})
|
|
808
|
-
|
|
809
|
-
it('should load new feature flag payloads', async () => {
|
|
810
|
-
expect(mocks.fetch).toHaveBeenCalledWith('https://us.i.posthog.com/flags/?v=2&config=true', {
|
|
811
|
-
body: JSON.stringify({
|
|
812
|
-
token: 'TEST_API_KEY',
|
|
813
|
-
distinct_id: posthog.getDistinctId(),
|
|
814
|
-
groups: {},
|
|
815
|
-
person_properties: {},
|
|
816
|
-
group_properties: {},
|
|
817
|
-
$anon_distinct_id: 'tomato',
|
|
818
|
-
}),
|
|
819
|
-
method: 'POST',
|
|
820
|
-
headers: {
|
|
821
|
-
'Content-Type': 'application/json',
|
|
822
|
-
'User-Agent': 'posthog-core-tests',
|
|
823
|
-
},
|
|
824
|
-
signal: expect.anything(),
|
|
825
|
-
})
|
|
826
|
-
expect(posthog.getFeatureFlagPayload('feature-1')).toEqual({
|
|
827
|
-
color: 'blue',
|
|
828
|
-
})
|
|
829
|
-
expect(posthog.getFeatureFlagPayload('feature-variant')).toEqual([5])
|
|
830
|
-
})
|
|
831
|
-
|
|
832
|
-
it('should capture $feature_flag_called with bootstrapped values', async () => {
|
|
833
|
-
expect(posthog.getFeatureFlag('feature-1')).toEqual(true)
|
|
834
|
-
|
|
835
|
-
await waitForPromises()
|
|
836
|
-
expect(mocks.fetch).toHaveBeenCalledTimes(2)
|
|
837
|
-
|
|
838
|
-
expect(parseBody(mocks.fetch.mock.calls[1])).toMatchObject({
|
|
839
|
-
batch: [
|
|
840
|
-
{
|
|
841
|
-
event: '$feature_flag_called',
|
|
842
|
-
distinct_id: posthog.getDistinctId(),
|
|
843
|
-
properties: {
|
|
844
|
-
$feature_flag: 'feature-1',
|
|
845
|
-
$feature_flag_response: true,
|
|
846
|
-
'$feature/feature-1': true,
|
|
847
|
-
$feature_flag_bootstrapped_response: 'feature-1-bootstrap-value',
|
|
848
|
-
$feature_flag_bootstrapped_payload: { color: 'feature-1-bootstrap-color' },
|
|
849
|
-
$used_bootstrap_value: false,
|
|
850
|
-
},
|
|
851
|
-
type: 'capture',
|
|
852
|
-
},
|
|
853
|
-
],
|
|
854
|
-
})
|
|
855
|
-
})
|
|
856
|
-
})
|
|
857
|
-
})
|
|
858
|
-
|
|
859
|
-
describe('bootstapped do not overwrite values', () => {
|
|
860
|
-
beforeEach(() => {
|
|
861
|
-
;[posthog, mocks] = createTestClient(
|
|
862
|
-
'TEST_API_KEY',
|
|
863
|
-
{
|
|
864
|
-
flushAt: 1,
|
|
865
|
-
bootstrap: {
|
|
866
|
-
distinctId: 'tomato',
|
|
867
|
-
featureFlags: { 'bootstrap-1': 'variant-1', enabled: true, disabled: false },
|
|
868
|
-
featureFlagPayloads: {
|
|
869
|
-
'bootstrap-1': {
|
|
870
|
-
some: 'key',
|
|
871
|
-
},
|
|
872
|
-
enabled: 200,
|
|
873
|
-
},
|
|
874
|
-
},
|
|
875
|
-
},
|
|
876
|
-
(_mocks) => {
|
|
877
|
-
_mocks.fetch.mockImplementation((url) => {
|
|
878
|
-
if (url.includes('/flags/')) {
|
|
879
|
-
return Promise.resolve({
|
|
880
|
-
status: 200,
|
|
881
|
-
text: () => Promise.resolve('ok'),
|
|
882
|
-
json: () =>
|
|
883
|
-
Promise.resolve({
|
|
884
|
-
featureFlags: createMockFeatureFlags(),
|
|
885
|
-
featureFlagPayloads: createMockFeatureFlagPayloads(),
|
|
886
|
-
}),
|
|
887
|
-
})
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
return Promise.resolve({
|
|
891
|
-
status: 200,
|
|
892
|
-
text: () => Promise.resolve('ok'),
|
|
893
|
-
json: () =>
|
|
894
|
-
Promise.resolve({
|
|
895
|
-
status: 'ok',
|
|
896
|
-
}),
|
|
897
|
-
})
|
|
898
|
-
})
|
|
899
|
-
},
|
|
900
|
-
{
|
|
901
|
-
distinct_id: '123',
|
|
902
|
-
feature_flags: { 'bootstrap-1': 'variant-2' },
|
|
903
|
-
feature_flag_payloads: { 'bootstrap-1': { some: 'other-key' } },
|
|
904
|
-
}
|
|
905
|
-
)
|
|
906
|
-
})
|
|
907
|
-
|
|
908
|
-
it('distinct id should not be overwritten if already there', () => {
|
|
909
|
-
expect(posthog.getDistinctId()).toEqual('123')
|
|
910
|
-
})
|
|
911
|
-
|
|
912
|
-
it('flags should not be overwritten if already there', () => {
|
|
913
|
-
expect(posthog.getFeatureFlag('bootstrap-1')).toEqual('variant-2')
|
|
914
|
-
})
|
|
915
|
-
|
|
916
|
-
it('flag payloads should not be overwritten if already there', () => {
|
|
917
|
-
expect(posthog.getFeatureFlagPayload('bootstrap-1')).toEqual({
|
|
918
|
-
some: 'other-key',
|
|
919
|
-
})
|
|
920
|
-
})
|
|
921
|
-
})
|
|
922
|
-
})
|