posthog-node 3.4.0 → 3.6.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/CHANGELOG.md +9 -0
- package/lib/index.cjs.js +187 -75
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +19 -13
- package/lib/index.esm.js +187 -75
- package/lib/index.esm.js.map +1 -1
- package/lib/posthog-core/src/index.d.ts +13 -12
- package/lib/posthog-core/src/types.d.ts +4 -1
- package/lib/posthog-node/src/posthog-node.d.ts +4 -3
- package/lib/posthog-node/src/types.d.ts +5 -4
- package/package.json +1 -1
- package/src/feature-flags.ts +10 -6
- package/src/posthog-node.ts +113 -24
- package/src/types.ts +5 -4
- package/test/extensions/sentry-integration.spec.ts +3 -0
- package/test/feature-flags.spec.ts +17 -2
- package/test/posthog-node.spec.ts +427 -10
|
@@ -4,6 +4,7 @@ jest.mock('../src/fetch')
|
|
|
4
4
|
import fetch from '../src/fetch'
|
|
5
5
|
import { anyDecideCall, anyLocalEvalCall, apiImplementation } from './feature-flags.spec'
|
|
6
6
|
import { waitForPromises, wait } from '../../posthog-core/test/test-utils/test-utils'
|
|
7
|
+
import { generateUUID } from 'posthog-core/src/utils'
|
|
7
8
|
|
|
8
9
|
jest.mock('../package.json', () => ({ version: '1.2.3' }))
|
|
9
10
|
|
|
@@ -51,7 +52,9 @@ describe('PostHog Node.js', () => {
|
|
|
51
52
|
expect(mockedFetch).toHaveBeenCalledTimes(0)
|
|
52
53
|
posthog.capture({ distinctId: '123', event: 'test-event', properties: { foo: 'bar' }, groups: { org: 123 } })
|
|
53
54
|
|
|
55
|
+
await waitForPromises()
|
|
54
56
|
jest.runOnlyPendingTimers()
|
|
57
|
+
|
|
55
58
|
const batchEvents = getLastBatchEvents()
|
|
56
59
|
expect(batchEvents).toEqual([
|
|
57
60
|
{
|
|
@@ -64,6 +67,7 @@ describe('PostHog Node.js', () => {
|
|
|
64
67
|
$lib: 'posthog-node',
|
|
65
68
|
$lib_version: '1.2.3',
|
|
66
69
|
},
|
|
70
|
+
uuid: expect.any(String),
|
|
67
71
|
timestamp: expect.any(String),
|
|
68
72
|
type: 'capture',
|
|
69
73
|
library: 'posthog-node',
|
|
@@ -76,6 +80,7 @@ describe('PostHog Node.js', () => {
|
|
|
76
80
|
expect(mockedFetch).toHaveBeenCalledTimes(0)
|
|
77
81
|
posthog.capture({ distinctId: '123', event: 'test-event', properties: { foo: 'bar' }, groups: { org: 123 } })
|
|
78
82
|
|
|
83
|
+
await waitForPromises()
|
|
79
84
|
jest.runOnlyPendingTimers()
|
|
80
85
|
expect(getLastBatchEvents()?.[0]).toEqual(
|
|
81
86
|
expect.objectContaining({
|
|
@@ -98,6 +103,7 @@ describe('PostHog Node.js', () => {
|
|
|
98
103
|
groups: { other_group: 'x' },
|
|
99
104
|
})
|
|
100
105
|
|
|
106
|
+
await waitForPromises()
|
|
101
107
|
jest.runOnlyPendingTimers()
|
|
102
108
|
expect(getLastBatchEvents()?.[0]).toEqual(
|
|
103
109
|
expect.objectContaining({
|
|
@@ -173,6 +179,7 @@ describe('PostHog Node.js', () => {
|
|
|
173
179
|
it('should allow overriding timestamp', async () => {
|
|
174
180
|
expect(mockedFetch).toHaveBeenCalledTimes(0)
|
|
175
181
|
posthog.capture({ event: 'custom-time', distinctId: '123', timestamp: new Date('2021-02-03') })
|
|
182
|
+
await waitForPromises()
|
|
176
183
|
jest.runOnlyPendingTimers()
|
|
177
184
|
const batchEvents = getLastBatchEvents()
|
|
178
185
|
expect(batchEvents).toMatchObject([
|
|
@@ -180,6 +187,24 @@ describe('PostHog Node.js', () => {
|
|
|
180
187
|
distinct_id: '123',
|
|
181
188
|
timestamp: '2021-02-03T00:00:00.000Z',
|
|
182
189
|
event: 'custom-time',
|
|
190
|
+
uuid: expect.any(String),
|
|
191
|
+
},
|
|
192
|
+
])
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
it('should allow overriding uuid', async () => {
|
|
196
|
+
expect(mockedFetch).toHaveBeenCalledTimes(0)
|
|
197
|
+
const uuid = generateUUID()
|
|
198
|
+
posthog.capture({ event: 'custom-time', distinctId: '123', uuid })
|
|
199
|
+
await waitForPromises()
|
|
200
|
+
jest.runOnlyPendingTimers()
|
|
201
|
+
const batchEvents = getLastBatchEvents()
|
|
202
|
+
expect(batchEvents).toMatchObject([
|
|
203
|
+
{
|
|
204
|
+
distinct_id: '123',
|
|
205
|
+
timestamp: expect.any(String),
|
|
206
|
+
event: 'custom-time',
|
|
207
|
+
uuid: uuid,
|
|
183
208
|
},
|
|
184
209
|
])
|
|
185
210
|
})
|
|
@@ -194,6 +219,7 @@ describe('PostHog Node.js', () => {
|
|
|
194
219
|
disableGeoip: false,
|
|
195
220
|
})
|
|
196
221
|
|
|
222
|
+
await waitForPromises()
|
|
197
223
|
jest.runOnlyPendingTimers()
|
|
198
224
|
const batchEvents = getLastBatchEvents()
|
|
199
225
|
expect(batchEvents?.[0].properties).toEqual({
|
|
@@ -212,7 +238,9 @@ describe('PostHog Node.js', () => {
|
|
|
212
238
|
})
|
|
213
239
|
client.capture({ distinctId: '123', event: 'test-event', properties: { foo: 'bar' }, groups: { org: 123 } })
|
|
214
240
|
|
|
241
|
+
await waitForPromises()
|
|
215
242
|
jest.runOnlyPendingTimers()
|
|
243
|
+
|
|
216
244
|
let batchEvents = getLastBatchEvents()
|
|
217
245
|
expect(batchEvents?.[0].properties).toEqual({
|
|
218
246
|
$groups: { org: 123 },
|
|
@@ -229,6 +257,7 @@ describe('PostHog Node.js', () => {
|
|
|
229
257
|
disableGeoip: true,
|
|
230
258
|
})
|
|
231
259
|
|
|
260
|
+
await waitForPromises()
|
|
232
261
|
jest.runOnlyPendingTimers()
|
|
233
262
|
batchEvents = getLastBatchEvents()
|
|
234
263
|
console.warn(batchEvents)
|
|
@@ -248,6 +277,7 @@ describe('PostHog Node.js', () => {
|
|
|
248
277
|
disableGeoip: false,
|
|
249
278
|
})
|
|
250
279
|
|
|
280
|
+
await waitForPromises()
|
|
251
281
|
jest.runOnlyPendingTimers()
|
|
252
282
|
batchEvents = getLastBatchEvents()
|
|
253
283
|
expect(batchEvents?.[0].properties).toEqual({
|
|
@@ -286,6 +316,7 @@ describe('PostHog Node.js', () => {
|
|
|
286
316
|
|
|
287
317
|
afterEach(() => {
|
|
288
318
|
posthog.debug(false)
|
|
319
|
+
jest.useFakeTimers()
|
|
289
320
|
})
|
|
290
321
|
|
|
291
322
|
it('should shutdown cleanly', async () => {
|
|
@@ -321,6 +352,45 @@ describe('PostHog Node.js', () => {
|
|
|
321
352
|
jest.useFakeTimers()
|
|
322
353
|
logSpy.mockRestore()
|
|
323
354
|
})
|
|
355
|
+
|
|
356
|
+
it('should shutdown cleanly with pending capture flag promises', async () => {
|
|
357
|
+
posthog = new PostHog('TEST_API_KEY', {
|
|
358
|
+
host: 'http://example.com',
|
|
359
|
+
fetchRetryCount: 0,
|
|
360
|
+
flushAt: 4,
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
364
|
+
jest.useRealTimers()
|
|
365
|
+
posthog.debug(true)
|
|
366
|
+
|
|
367
|
+
for (let i = 0; i < 10; i++) {
|
|
368
|
+
posthog.capture({ event: 'test-event', distinctId: `${i}`, sendFeatureFlags: true })
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
await posthog.shutdownAsync()
|
|
372
|
+
// all capture calls happen during shutdown
|
|
373
|
+
const batchEvents = getLastBatchEvents()
|
|
374
|
+
expect(batchEvents?.length).toEqual(2)
|
|
375
|
+
expect(batchEvents?.[batchEvents?.length - 1]).toMatchObject({
|
|
376
|
+
// last event in batch
|
|
377
|
+
distinct_id: '9',
|
|
378
|
+
event: 'test-event',
|
|
379
|
+
library: 'posthog-node',
|
|
380
|
+
library_version: '1.2.3',
|
|
381
|
+
properties: {
|
|
382
|
+
$lib: 'posthog-node',
|
|
383
|
+
$lib_version: '1.2.3',
|
|
384
|
+
$geoip_disable: true,
|
|
385
|
+
},
|
|
386
|
+
timestamp: expect.any(String),
|
|
387
|
+
type: 'capture',
|
|
388
|
+
})
|
|
389
|
+
expect(10).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('capture')).length)
|
|
390
|
+
expect(3).toEqual(logSpy.mock.calls.filter((call) => call[1].includes('flush')).length)
|
|
391
|
+
jest.useFakeTimers()
|
|
392
|
+
logSpy.mockRestore()
|
|
393
|
+
})
|
|
324
394
|
})
|
|
325
395
|
|
|
326
396
|
describe('groupIdentify', () => {
|
|
@@ -384,8 +454,79 @@ describe('PostHog Node.js', () => {
|
|
|
384
454
|
'feature-variant': 2,
|
|
385
455
|
}
|
|
386
456
|
|
|
457
|
+
const multivariateFlag = {
|
|
458
|
+
id: 1,
|
|
459
|
+
name: 'Beta Feature',
|
|
460
|
+
key: 'beta-feature-local',
|
|
461
|
+
is_simple_flag: false,
|
|
462
|
+
active: true,
|
|
463
|
+
rollout_percentage: 100,
|
|
464
|
+
filters: {
|
|
465
|
+
groups: [
|
|
466
|
+
{
|
|
467
|
+
properties: [{ key: 'email', type: 'person', value: 'test@posthog.com', operator: 'exact' }],
|
|
468
|
+
rollout_percentage: 100,
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
rollout_percentage: 50,
|
|
472
|
+
},
|
|
473
|
+
],
|
|
474
|
+
multivariate: {
|
|
475
|
+
variants: [
|
|
476
|
+
{ key: 'first-variant', name: 'First Variant', rollout_percentage: 50 },
|
|
477
|
+
{ key: 'second-variant', name: 'Second Variant', rollout_percentage: 25 },
|
|
478
|
+
{ key: 'third-variant', name: 'Third Variant', rollout_percentage: 25 },
|
|
479
|
+
],
|
|
480
|
+
},
|
|
481
|
+
payloads: { 'first-variant': 'some-payload', 'third-variant': { a: 'json' } },
|
|
482
|
+
},
|
|
483
|
+
}
|
|
484
|
+
const basicFlag = {
|
|
485
|
+
id: 1,
|
|
486
|
+
name: 'Beta Feature',
|
|
487
|
+
key: 'person-flag',
|
|
488
|
+
is_simple_flag: true,
|
|
489
|
+
active: true,
|
|
490
|
+
filters: {
|
|
491
|
+
groups: [
|
|
492
|
+
{
|
|
493
|
+
properties: [
|
|
494
|
+
{
|
|
495
|
+
key: 'region',
|
|
496
|
+
operator: 'exact',
|
|
497
|
+
value: ['USA'],
|
|
498
|
+
type: 'person',
|
|
499
|
+
},
|
|
500
|
+
],
|
|
501
|
+
rollout_percentage: 100,
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
payloads: { true: 300 },
|
|
505
|
+
},
|
|
506
|
+
}
|
|
507
|
+
const falseFlag = {
|
|
508
|
+
id: 1,
|
|
509
|
+
name: 'Beta Feature',
|
|
510
|
+
key: 'false-flag',
|
|
511
|
+
is_simple_flag: true,
|
|
512
|
+
active: true,
|
|
513
|
+
filters: {
|
|
514
|
+
groups: [
|
|
515
|
+
{
|
|
516
|
+
properties: [],
|
|
517
|
+
rollout_percentage: 0,
|
|
518
|
+
},
|
|
519
|
+
],
|
|
520
|
+
payloads: { true: 300 },
|
|
521
|
+
},
|
|
522
|
+
}
|
|
523
|
+
|
|
387
524
|
mockedFetch.mockImplementation(
|
|
388
|
-
apiImplementation({
|
|
525
|
+
apiImplementation({
|
|
526
|
+
decideFlags: mockFeatureFlags,
|
|
527
|
+
decideFlagPayloads: mockFeatureFlagPayloads,
|
|
528
|
+
localFlags: { flags: [multivariateFlag, basicFlag, falseFlag] },
|
|
529
|
+
})
|
|
389
530
|
)
|
|
390
531
|
|
|
391
532
|
posthog = new PostHog('TEST_API_KEY', {
|
|
@@ -430,15 +571,14 @@ describe('PostHog Node.js', () => {
|
|
|
430
571
|
sendFeatureFlags: true,
|
|
431
572
|
})
|
|
432
573
|
|
|
574
|
+
jest.runOnlyPendingTimers()
|
|
575
|
+
await waitForPromises()
|
|
576
|
+
|
|
433
577
|
expect(mockedFetch).toHaveBeenCalledWith(
|
|
434
578
|
'http://example.com/decide/?v=3',
|
|
435
579
|
expect.objectContaining({ method: 'POST' })
|
|
436
580
|
)
|
|
437
581
|
|
|
438
|
-
jest.runOnlyPendingTimers()
|
|
439
|
-
|
|
440
|
-
await waitForPromises()
|
|
441
|
-
|
|
442
582
|
expect(getLastBatchEvents()?.[0]).toEqual(
|
|
443
583
|
expect.objectContaining({
|
|
444
584
|
distinct_id: 'distinct_id',
|
|
@@ -464,6 +604,113 @@ describe('PostHog Node.js', () => {
|
|
|
464
604
|
)
|
|
465
605
|
})
|
|
466
606
|
|
|
607
|
+
it('captures feature flags with locally evaluated flags', async () => {
|
|
608
|
+
mockedFetch.mockClear()
|
|
609
|
+
mockedFetch.mockClear()
|
|
610
|
+
expect(mockedFetch).toHaveBeenCalledTimes(0)
|
|
611
|
+
|
|
612
|
+
posthog = new PostHog('TEST_API_KEY', {
|
|
613
|
+
host: 'http://example.com',
|
|
614
|
+
flushAt: 1,
|
|
615
|
+
fetchRetryCount: 0,
|
|
616
|
+
personalApiKey: 'TEST_PERSONAL_API_KEY',
|
|
617
|
+
})
|
|
618
|
+
|
|
619
|
+
jest.runOnlyPendingTimers()
|
|
620
|
+
await waitForPromises()
|
|
621
|
+
|
|
622
|
+
posthog.capture({
|
|
623
|
+
distinctId: 'distinct_id',
|
|
624
|
+
event: 'node test event',
|
|
625
|
+
})
|
|
626
|
+
|
|
627
|
+
expect(mockedFetch).toHaveBeenCalledWith(...anyLocalEvalCall)
|
|
628
|
+
// no decide call
|
|
629
|
+
expect(mockedFetch).not.toHaveBeenCalledWith(
|
|
630
|
+
'http://example.com/decide/?v=3',
|
|
631
|
+
expect.objectContaining({ method: 'POST' })
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
jest.runOnlyPendingTimers()
|
|
635
|
+
|
|
636
|
+
await waitForPromises()
|
|
637
|
+
|
|
638
|
+
expect(getLastBatchEvents()?.[0]).toEqual(
|
|
639
|
+
expect.objectContaining({
|
|
640
|
+
distinct_id: 'distinct_id',
|
|
641
|
+
event: 'node test event',
|
|
642
|
+
properties: expect.objectContaining({
|
|
643
|
+
$active_feature_flags: ['beta-feature-local'],
|
|
644
|
+
'$feature/beta-feature-local': 'third-variant',
|
|
645
|
+
'$feature/false-flag': false,
|
|
646
|
+
$lib: 'posthog-node',
|
|
647
|
+
$lib_version: '1.2.3',
|
|
648
|
+
$geoip_disable: true,
|
|
649
|
+
}),
|
|
650
|
+
})
|
|
651
|
+
)
|
|
652
|
+
expect(
|
|
653
|
+
Object.prototype.hasOwnProperty.call(getLastBatchEvents()?.[0].properties, '$feature/beta-feature-local')
|
|
654
|
+
).toBe(true)
|
|
655
|
+
expect(Object.prototype.hasOwnProperty.call(getLastBatchEvents()?.[0].properties, '$feature/beta-feature')).toBe(
|
|
656
|
+
false
|
|
657
|
+
)
|
|
658
|
+
|
|
659
|
+
await posthog.shutdownAsync()
|
|
660
|
+
})
|
|
661
|
+
|
|
662
|
+
it('doesnt add flag properties when locally evaluated flags are empty', async () => {
|
|
663
|
+
mockedFetch.mockClear()
|
|
664
|
+
expect(mockedFetch).toHaveBeenCalledTimes(0)
|
|
665
|
+
mockedFetch.mockImplementation(
|
|
666
|
+
apiImplementation({ decideFlags: { a: false, b: 'true' }, decideFlagPayloads: {}, localFlags: { flags: [] } })
|
|
667
|
+
)
|
|
668
|
+
|
|
669
|
+
posthog = new PostHog('TEST_API_KEY', {
|
|
670
|
+
host: 'http://example.com',
|
|
671
|
+
flushAt: 1,
|
|
672
|
+
fetchRetryCount: 0,
|
|
673
|
+
personalApiKey: 'TEST_PERSONAL_API_KEY',
|
|
674
|
+
})
|
|
675
|
+
|
|
676
|
+
posthog.capture({
|
|
677
|
+
distinctId: 'distinct_id',
|
|
678
|
+
event: 'node test event',
|
|
679
|
+
})
|
|
680
|
+
|
|
681
|
+
jest.runOnlyPendingTimers()
|
|
682
|
+
await waitForPromises()
|
|
683
|
+
|
|
684
|
+
expect(mockedFetch).toHaveBeenCalledWith(...anyLocalEvalCall)
|
|
685
|
+
// no decide call
|
|
686
|
+
expect(mockedFetch).not.toHaveBeenCalledWith(
|
|
687
|
+
'http://example.com/decide/?v=3',
|
|
688
|
+
expect.objectContaining({ method: 'POST' })
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
jest.runOnlyPendingTimers()
|
|
692
|
+
|
|
693
|
+
await waitForPromises()
|
|
694
|
+
|
|
695
|
+
expect(getLastBatchEvents()?.[0]).toEqual(
|
|
696
|
+
expect.objectContaining({
|
|
697
|
+
distinct_id: 'distinct_id',
|
|
698
|
+
event: 'node test event',
|
|
699
|
+
properties: expect.objectContaining({
|
|
700
|
+
$lib: 'posthog-node',
|
|
701
|
+
$lib_version: '1.2.3',
|
|
702
|
+
$geoip_disable: true,
|
|
703
|
+
}),
|
|
704
|
+
})
|
|
705
|
+
)
|
|
706
|
+
expect(
|
|
707
|
+
Object.prototype.hasOwnProperty.call(getLastBatchEvents()?.[0].properties, '$feature/beta-feature-local')
|
|
708
|
+
).toBe(false)
|
|
709
|
+
expect(Object.prototype.hasOwnProperty.call(getLastBatchEvents()?.[0].properties, '$feature/beta-feature')).toBe(
|
|
710
|
+
false
|
|
711
|
+
)
|
|
712
|
+
})
|
|
713
|
+
|
|
467
714
|
it('captures feature flags with same geoip setting as capture', async () => {
|
|
468
715
|
mockedFetch.mockClear()
|
|
469
716
|
mockedFetch.mockClear()
|
|
@@ -482,19 +729,19 @@ describe('PostHog Node.js', () => {
|
|
|
482
729
|
disableGeoip: false,
|
|
483
730
|
})
|
|
484
731
|
|
|
732
|
+
await waitForPromises()
|
|
733
|
+
jest.runOnlyPendingTimers()
|
|
734
|
+
|
|
485
735
|
expect(mockedFetch).toHaveBeenCalledWith(
|
|
486
736
|
'http://example.com/decide/?v=3',
|
|
487
737
|
expect.objectContaining({ method: 'POST', body: expect.not.stringContaining('geoip_disable') })
|
|
488
738
|
)
|
|
489
739
|
|
|
490
|
-
jest.runOnlyPendingTimers()
|
|
491
|
-
|
|
492
|
-
await waitForPromises()
|
|
493
|
-
|
|
494
740
|
expect(getLastBatchEvents()?.[0].properties).toEqual({
|
|
495
741
|
$active_feature_flags: ['feature-1', 'feature-2', 'feature-variant'],
|
|
496
742
|
'$feature/feature-1': true,
|
|
497
743
|
'$feature/feature-2': true,
|
|
744
|
+
'$feature/disabled-flag': false,
|
|
498
745
|
'$feature/feature-variant': 'variant',
|
|
499
746
|
$lib: 'posthog-node',
|
|
500
747
|
$lib_version: '1.2.3',
|
|
@@ -534,14 +781,16 @@ describe('PostHog Node.js', () => {
|
|
|
534
781
|
personalApiKey: 'TEST_PERSONAL_API_KEY',
|
|
535
782
|
maxCacheSize: 10,
|
|
536
783
|
fetchRetryCount: 0,
|
|
784
|
+
flushAt: 1,
|
|
537
785
|
})
|
|
538
786
|
|
|
539
787
|
expect(Object.keys(posthog.distinctIdHasSentFlagCalls).length).toEqual(0)
|
|
540
788
|
|
|
541
|
-
for (let i = 0; i <
|
|
789
|
+
for (let i = 0; i < 100; i++) {
|
|
542
790
|
const distinctId = `some-distinct-id${i}`
|
|
543
791
|
await posthog.getFeatureFlag('beta-feature', distinctId)
|
|
544
792
|
|
|
793
|
+
await waitForPromises()
|
|
545
794
|
jest.runOnlyPendingTimers()
|
|
546
795
|
|
|
547
796
|
const batchEvents = getLastBatchEvents()
|
|
@@ -566,6 +815,8 @@ describe('PostHog Node.js', () => {
|
|
|
566
815
|
})
|
|
567
816
|
|
|
568
817
|
it('$feature_flag_called is called appropriately when querying flags', async () => {
|
|
818
|
+
mockedFetch.mockClear()
|
|
819
|
+
|
|
569
820
|
const flags = {
|
|
570
821
|
flags: [
|
|
571
822
|
{
|
|
@@ -596,12 +847,19 @@ describe('PostHog Node.js', () => {
|
|
|
596
847
|
fetchRetryCount: 0,
|
|
597
848
|
})
|
|
598
849
|
|
|
850
|
+
jest.runOnlyPendingTimers()
|
|
851
|
+
|
|
599
852
|
expect(
|
|
600
853
|
await posthog.getFeatureFlag('beta-feature', 'some-distinct-id', {
|
|
601
854
|
personProperties: { region: 'USA', name: 'Aloha' },
|
|
602
855
|
})
|
|
603
856
|
).toEqual(true)
|
|
857
|
+
|
|
858
|
+
// TRICKY: There's now an extra step before events are queued, so need to wait for that to resolve
|
|
604
859
|
jest.runOnlyPendingTimers()
|
|
860
|
+
await waitForPromises()
|
|
861
|
+
await posthog.flushAsync()
|
|
862
|
+
|
|
605
863
|
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))
|
|
606
864
|
|
|
607
865
|
expect(getLastBatchEvents()?.[0]).toEqual(
|
|
@@ -628,6 +886,8 @@ describe('PostHog Node.js', () => {
|
|
|
628
886
|
})
|
|
629
887
|
).toEqual(true)
|
|
630
888
|
jest.runOnlyPendingTimers()
|
|
889
|
+
await waitForPromises()
|
|
890
|
+
await posthog.flushAsync()
|
|
631
891
|
|
|
632
892
|
expect(mockedFetch).not.toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))
|
|
633
893
|
|
|
@@ -640,6 +900,8 @@ describe('PostHog Node.js', () => {
|
|
|
640
900
|
})
|
|
641
901
|
).toEqual(true)
|
|
642
902
|
jest.runOnlyPendingTimers()
|
|
903
|
+
await waitForPromises()
|
|
904
|
+
await posthog.flushAsync()
|
|
643
905
|
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))
|
|
644
906
|
|
|
645
907
|
expect(getLastBatchEvents()?.[0]).toEqual(
|
|
@@ -667,6 +929,8 @@ describe('PostHog Node.js', () => {
|
|
|
667
929
|
})
|
|
668
930
|
).toEqual(true)
|
|
669
931
|
jest.runOnlyPendingTimers()
|
|
932
|
+
await waitForPromises()
|
|
933
|
+
await posthog.flushAsync()
|
|
670
934
|
expect(mockedFetch).not.toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))
|
|
671
935
|
|
|
672
936
|
// # called for different flag, falls back to decide, should call capture again
|
|
@@ -677,6 +941,8 @@ describe('PostHog Node.js', () => {
|
|
|
677
941
|
})
|
|
678
942
|
).toEqual('decide-value')
|
|
679
943
|
jest.runOnlyPendingTimers()
|
|
944
|
+
await waitForPromises()
|
|
945
|
+
await posthog.flushAsync()
|
|
680
946
|
// one to decide, one to batch
|
|
681
947
|
expect(mockedFetch).toHaveBeenCalledWith(...anyDecideCall)
|
|
682
948
|
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))
|
|
@@ -705,6 +971,8 @@ describe('PostHog Node.js', () => {
|
|
|
705
971
|
})
|
|
706
972
|
).toEqual(true)
|
|
707
973
|
jest.runOnlyPendingTimers()
|
|
974
|
+
await waitForPromises()
|
|
975
|
+
await posthog.flushAsync()
|
|
708
976
|
// call decide, but not batch
|
|
709
977
|
expect(mockedFetch).toHaveBeenCalledWith(...anyDecideCall)
|
|
710
978
|
expect(mockedFetch).not.toHaveBeenCalledWith('http://example.com/batch/', expect.any(Object))
|
|
@@ -750,5 +1018,154 @@ describe('PostHog Node.js', () => {
|
|
|
750
1018
|
expect.objectContaining({ method: 'POST', body: expect.not.stringContaining('geoip_disable') })
|
|
751
1019
|
)
|
|
752
1020
|
})
|
|
1021
|
+
|
|
1022
|
+
it('should add default person & group properties for feature flags', async () => {
|
|
1023
|
+
await posthog.getFeatureFlag('random_key', 'some_id', {
|
|
1024
|
+
groups: { company: 'id:5', instance: 'app.posthog.com' },
|
|
1025
|
+
personProperties: { x1: 'y1' },
|
|
1026
|
+
groupProperties: { company: { x: 'y' } },
|
|
1027
|
+
})
|
|
1028
|
+
jest.runOnlyPendingTimers()
|
|
1029
|
+
|
|
1030
|
+
expect(mockedFetch).toHaveBeenCalledWith(
|
|
1031
|
+
'http://example.com/decide/?v=3',
|
|
1032
|
+
expect.objectContaining({
|
|
1033
|
+
body: JSON.stringify({
|
|
1034
|
+
token: 'TEST_API_KEY',
|
|
1035
|
+
distinct_id: 'some_id',
|
|
1036
|
+
groups: { company: 'id:5', instance: 'app.posthog.com' },
|
|
1037
|
+
person_properties: {
|
|
1038
|
+
$current_distinct_id: 'some_id',
|
|
1039
|
+
x1: 'y1',
|
|
1040
|
+
},
|
|
1041
|
+
group_properties: {
|
|
1042
|
+
company: { $group_key: 'id:5', x: 'y' },
|
|
1043
|
+
instance: { $group_key: 'app.posthog.com' },
|
|
1044
|
+
},
|
|
1045
|
+
geoip_disable: true,
|
|
1046
|
+
}),
|
|
1047
|
+
})
|
|
1048
|
+
)
|
|
1049
|
+
|
|
1050
|
+
mockedFetch.mockClear()
|
|
1051
|
+
|
|
1052
|
+
await posthog.getFeatureFlag('random_key', 'some_id', {
|
|
1053
|
+
groups: { company: 'id:5', instance: 'app.posthog.com' },
|
|
1054
|
+
personProperties: { $current_distinct_id: 'override' },
|
|
1055
|
+
groupProperties: { company: { $group_key: 'group_override' } },
|
|
1056
|
+
})
|
|
1057
|
+
jest.runOnlyPendingTimers()
|
|
1058
|
+
|
|
1059
|
+
expect(mockedFetch).toHaveBeenCalledWith(
|
|
1060
|
+
'http://example.com/decide/?v=3',
|
|
1061
|
+
expect.objectContaining({
|
|
1062
|
+
body: JSON.stringify({
|
|
1063
|
+
token: 'TEST_API_KEY',
|
|
1064
|
+
distinct_id: 'some_id',
|
|
1065
|
+
groups: { company: 'id:5', instance: 'app.posthog.com' },
|
|
1066
|
+
person_properties: {
|
|
1067
|
+
$current_distinct_id: 'override',
|
|
1068
|
+
},
|
|
1069
|
+
group_properties: {
|
|
1070
|
+
company: { $group_key: 'group_override' },
|
|
1071
|
+
instance: { $group_key: 'app.posthog.com' },
|
|
1072
|
+
},
|
|
1073
|
+
geoip_disable: true,
|
|
1074
|
+
}),
|
|
1075
|
+
})
|
|
1076
|
+
)
|
|
1077
|
+
|
|
1078
|
+
mockedFetch.mockClear()
|
|
1079
|
+
|
|
1080
|
+
// test nones
|
|
1081
|
+
await posthog.getAllFlagsAndPayloads('some_id', {
|
|
1082
|
+
groups: undefined,
|
|
1083
|
+
personProperties: undefined,
|
|
1084
|
+
groupProperties: undefined,
|
|
1085
|
+
})
|
|
1086
|
+
|
|
1087
|
+
jest.runOnlyPendingTimers()
|
|
1088
|
+
|
|
1089
|
+
expect(mockedFetch).toHaveBeenCalledWith(
|
|
1090
|
+
'http://example.com/decide/?v=3',
|
|
1091
|
+
expect.objectContaining({
|
|
1092
|
+
body: JSON.stringify({
|
|
1093
|
+
token: 'TEST_API_KEY',
|
|
1094
|
+
distinct_id: 'some_id',
|
|
1095
|
+
groups: {},
|
|
1096
|
+
person_properties: {
|
|
1097
|
+
$current_distinct_id: 'some_id',
|
|
1098
|
+
},
|
|
1099
|
+
group_properties: {},
|
|
1100
|
+
geoip_disable: true,
|
|
1101
|
+
}),
|
|
1102
|
+
})
|
|
1103
|
+
)
|
|
1104
|
+
|
|
1105
|
+
mockedFetch.mockClear()
|
|
1106
|
+
await posthog.getAllFlags('some_id', {
|
|
1107
|
+
groups: { company: 'id:5' },
|
|
1108
|
+
personProperties: undefined,
|
|
1109
|
+
groupProperties: undefined,
|
|
1110
|
+
})
|
|
1111
|
+
jest.runOnlyPendingTimers()
|
|
1112
|
+
|
|
1113
|
+
expect(mockedFetch).toHaveBeenCalledWith(
|
|
1114
|
+
'http://example.com/decide/?v=3',
|
|
1115
|
+
expect.objectContaining({
|
|
1116
|
+
body: JSON.stringify({
|
|
1117
|
+
token: 'TEST_API_KEY',
|
|
1118
|
+
distinct_id: 'some_id',
|
|
1119
|
+
groups: { company: 'id:5' },
|
|
1120
|
+
person_properties: {
|
|
1121
|
+
$current_distinct_id: 'some_id',
|
|
1122
|
+
},
|
|
1123
|
+
group_properties: { company: { $group_key: 'id:5' } },
|
|
1124
|
+
geoip_disable: true,
|
|
1125
|
+
}),
|
|
1126
|
+
})
|
|
1127
|
+
)
|
|
1128
|
+
|
|
1129
|
+
mockedFetch.mockClear()
|
|
1130
|
+
await posthog.getFeatureFlagPayload('random_key', 'some_id', undefined)
|
|
1131
|
+
jest.runOnlyPendingTimers()
|
|
1132
|
+
|
|
1133
|
+
expect(mockedFetch).toHaveBeenCalledWith(
|
|
1134
|
+
'http://example.com/decide/?v=3',
|
|
1135
|
+
expect.objectContaining({
|
|
1136
|
+
body: JSON.stringify({
|
|
1137
|
+
token: 'TEST_API_KEY',
|
|
1138
|
+
distinct_id: 'some_id',
|
|
1139
|
+
groups: {},
|
|
1140
|
+
person_properties: {
|
|
1141
|
+
$current_distinct_id: 'some_id',
|
|
1142
|
+
},
|
|
1143
|
+
group_properties: {},
|
|
1144
|
+
geoip_disable: true,
|
|
1145
|
+
}),
|
|
1146
|
+
})
|
|
1147
|
+
)
|
|
1148
|
+
|
|
1149
|
+
mockedFetch.mockClear()
|
|
1150
|
+
|
|
1151
|
+
await posthog.isFeatureEnabled('random_key', 'some_id')
|
|
1152
|
+
jest.runOnlyPendingTimers()
|
|
1153
|
+
|
|
1154
|
+
expect(mockedFetch).toHaveBeenCalledWith(
|
|
1155
|
+
'http://example.com/decide/?v=3',
|
|
1156
|
+
expect.objectContaining({
|
|
1157
|
+
body: JSON.stringify({
|
|
1158
|
+
token: 'TEST_API_KEY',
|
|
1159
|
+
distinct_id: 'some_id',
|
|
1160
|
+
groups: {},
|
|
1161
|
+
person_properties: {
|
|
1162
|
+
$current_distinct_id: 'some_id',
|
|
1163
|
+
},
|
|
1164
|
+
group_properties: {},
|
|
1165
|
+
geoip_disable: true,
|
|
1166
|
+
}),
|
|
1167
|
+
})
|
|
1168
|
+
)
|
|
1169
|
+
})
|
|
753
1170
|
})
|
|
754
1171
|
})
|