posthog-node 4.17.0 → 4.17.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/CHANGELOG.md +11 -0
- package/lib/edge/{index.cjs.js → index.cjs} +43 -11
- package/lib/edge/index.cjs.map +1 -0
- package/lib/edge/{index.esm.js → index.mjs} +43 -11
- package/lib/edge/index.mjs.map +1 -0
- package/lib/index.d.ts +69 -57
- package/lib/node/{index.cjs.js → index.cjs} +43 -11
- package/lib/node/index.cjs.map +1 -0
- package/lib/node/{index.esm.js → index.mjs} +43 -11
- package/lib/node/index.mjs.map +1 -0
- package/package.json +17 -17
- package/lib/edge/index.cjs.js.map +0 -1
- package/lib/edge/index.esm.js.map +0 -1
- package/lib/node/index.cjs.js.map +0 -1
- package/lib/node/index.esm.js.map +0 -1
- package/src/client.ts +0 -650
- package/src/entrypoints/index.edge.ts +0 -15
- package/src/entrypoints/index.node.ts +0 -17
- package/src/exports.ts +0 -3
- package/src/extensions/error-tracking/autocapture.ts +0 -65
- package/src/extensions/error-tracking/context-lines.node.ts +0 -392
- package/src/extensions/error-tracking/error-conversion.ts +0 -279
- package/src/extensions/error-tracking/get-module.node.ts +0 -57
- package/src/extensions/error-tracking/index.ts +0 -69
- package/src/extensions/error-tracking/reduceable-cache.ts +0 -39
- package/src/extensions/error-tracking/stack-parser.ts +0 -212
- package/src/extensions/error-tracking/type-checking.ts +0 -40
- package/src/extensions/error-tracking/types.ts +0 -69
- package/src/extensions/express.ts +0 -37
- package/src/extensions/feature-flags/crypto-helpers.ts +0 -36
- package/src/extensions/feature-flags/crypto.ts +0 -22
- package/src/extensions/feature-flags/feature-flags.ts +0 -865
- package/src/extensions/feature-flags/lazy.ts +0 -55
- package/src/extensions/sentry-integration.ts +0 -204
- package/src/fetch.ts +0 -39
- package/src/storage-memory.ts +0 -13
- package/src/types.ts +0 -275
- package/test/crypto.spec.ts +0 -36
- package/test/extensions/error-conversion.spec.ts +0 -44
- package/test/extensions/sentry-integration.spec.ts +0 -163
- package/test/feature-flags.decide.spec.ts +0 -381
- package/test/feature-flags.spec.ts +0 -4686
- package/test/lazy.spec.ts +0 -71
- package/test/posthog-node.spec.ts +0 -1341
- package/test/test-utils.ts +0 -111
- package/tsconfig.json +0 -8
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { PostHog } from '../../src/entrypoints/index.node'
|
|
2
|
-
import { PostHogSentryIntegration } from '../../src/extensions/sentry-integration'
|
|
3
|
-
jest.mock('../../src/fetch')
|
|
4
|
-
import fetch from '../../src/fetch'
|
|
5
|
-
import { waitForPromises } from 'posthog-core/test/test-utils/test-utils'
|
|
6
|
-
|
|
7
|
-
jest.mock('../../package.json', () => ({ version: '1.2.3' }))
|
|
8
|
-
|
|
9
|
-
const mockedFetch = jest.mocked(fetch, true)
|
|
10
|
-
|
|
11
|
-
const getLastBatchEvents = (): any[] | undefined => {
|
|
12
|
-
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/batch/', expect.objectContaining({ method: 'POST' }))
|
|
13
|
-
|
|
14
|
-
// reverse mock calls array to get the last call
|
|
15
|
-
const call = mockedFetch.mock.calls.reverse().find((x) => (x[0] as string).includes('/batch/'))
|
|
16
|
-
if (!call) {
|
|
17
|
-
return undefined
|
|
18
|
-
}
|
|
19
|
-
return JSON.parse((call[1] as any).body as any).batch
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const createMockSentryException = (): any => ({
|
|
23
|
-
exception: {
|
|
24
|
-
values: [
|
|
25
|
-
{
|
|
26
|
-
type: 'Error',
|
|
27
|
-
value: 'example error',
|
|
28
|
-
stacktrace: {
|
|
29
|
-
frames: [],
|
|
30
|
-
},
|
|
31
|
-
mechanism: { type: 'generic', handled: true },
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
event_id: '80a7023ac32c47f7acb0adaed600d149',
|
|
36
|
-
platform: 'node',
|
|
37
|
-
contexts: {},
|
|
38
|
-
server_name: 'localhost',
|
|
39
|
-
timestamp: 1704203482.356,
|
|
40
|
-
environment: 'production',
|
|
41
|
-
level: 'error',
|
|
42
|
-
tags: { posthog_distinct_id: 'EXAMPLE_APP_GLOBAL' },
|
|
43
|
-
breadcrumbs: [
|
|
44
|
-
{
|
|
45
|
-
timestamp: 1704203481.422,
|
|
46
|
-
category: 'console',
|
|
47
|
-
level: 'log',
|
|
48
|
-
message: '⚡: Server is running at http://localhost:8010',
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
timestamp: 1704203481.658,
|
|
52
|
-
category: 'console',
|
|
53
|
-
level: 'log',
|
|
54
|
-
message:
|
|
55
|
-
"PostHog Debug error [ClientError: Your personalApiKey is invalid. Are you sure you're not using your Project API key? More information: https://posthog.com/docs/api/overview]",
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
sdkProcessingMetadata: {
|
|
59
|
-
propagationContext: { traceId: 'ea26146e5a354cb0b3b1daebb3f90e33', spanId: '8d642089c3daa272' },
|
|
60
|
-
},
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
describe('PostHogSentryIntegration', () => {
|
|
64
|
-
let posthog: PostHog
|
|
65
|
-
let posthogSentry: PostHogSentryIntegration
|
|
66
|
-
|
|
67
|
-
jest.useFakeTimers()
|
|
68
|
-
|
|
69
|
-
beforeEach(() => {
|
|
70
|
-
posthog = new PostHog('TEST_API_KEY', {
|
|
71
|
-
host: 'http://example.com',
|
|
72
|
-
fetchRetryCount: 0,
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
posthogSentry = new PostHogSentryIntegration(posthog)
|
|
76
|
-
|
|
77
|
-
mockedFetch.mockResolvedValue({
|
|
78
|
-
status: 200,
|
|
79
|
-
text: () => Promise.resolve('ok'),
|
|
80
|
-
json: () =>
|
|
81
|
-
Promise.resolve({
|
|
82
|
-
status: 'ok',
|
|
83
|
-
}),
|
|
84
|
-
} as any)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
afterEach(async () => {
|
|
88
|
-
// ensure clean shutdown & no test interdependencies
|
|
89
|
-
await posthog.shutdown()
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('should forward sentry exceptions to posthog', async () => {
|
|
93
|
-
expect(mockedFetch).toHaveBeenCalledTimes(0)
|
|
94
|
-
|
|
95
|
-
const mockSentry = {
|
|
96
|
-
getClient: () => ({
|
|
97
|
-
getDsn: () => ({
|
|
98
|
-
projectId: 123,
|
|
99
|
-
}),
|
|
100
|
-
}),
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let processorFunction: any
|
|
104
|
-
|
|
105
|
-
posthogSentry.setupOnce(
|
|
106
|
-
(fn) => (processorFunction = fn),
|
|
107
|
-
() => mockSentry
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
processorFunction(createMockSentryException())
|
|
111
|
-
|
|
112
|
-
await waitForPromises() // First flush
|
|
113
|
-
jest.runOnlyPendingTimers() // Flush timer
|
|
114
|
-
await waitForPromises() // Second flush
|
|
115
|
-
const batchEvents = getLastBatchEvents()
|
|
116
|
-
|
|
117
|
-
expect(batchEvents).toEqual([
|
|
118
|
-
{
|
|
119
|
-
distinct_id: 'EXAMPLE_APP_GLOBAL',
|
|
120
|
-
event: '$exception',
|
|
121
|
-
properties: {
|
|
122
|
-
$exception_level: 'error',
|
|
123
|
-
$exception_list: [
|
|
124
|
-
{
|
|
125
|
-
mechanism: { handled: true, type: 'generic' },
|
|
126
|
-
stacktrace: { frames: [], type: 'raw' },
|
|
127
|
-
type: 'Error',
|
|
128
|
-
value: 'example error',
|
|
129
|
-
},
|
|
130
|
-
],
|
|
131
|
-
$exception_message: 'example error',
|
|
132
|
-
$exception_type: 'Error',
|
|
133
|
-
$exception_personURL: 'http://example.com/project/TEST_API_KEY/person/EXAMPLE_APP_GLOBAL',
|
|
134
|
-
$sentry_event_id: '80a7023ac32c47f7acb0adaed600d149',
|
|
135
|
-
$sentry_exception: {
|
|
136
|
-
values: [
|
|
137
|
-
{
|
|
138
|
-
type: 'Error',
|
|
139
|
-
value: 'example error',
|
|
140
|
-
stacktrace: { frames: [] },
|
|
141
|
-
mechanism: { type: 'generic', handled: true },
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
},
|
|
145
|
-
$sentry_exception_message: 'example error',
|
|
146
|
-
$sentry_exception_type: 'Error',
|
|
147
|
-
$sentry_tags: {
|
|
148
|
-
posthog_distinct_id: 'EXAMPLE_APP_GLOBAL',
|
|
149
|
-
'PostHog Person URL': 'http://example.com/project/TEST_API_KEY/person/EXAMPLE_APP_GLOBAL',
|
|
150
|
-
},
|
|
151
|
-
$lib: 'posthog-node',
|
|
152
|
-
$lib_version: '1.2.3',
|
|
153
|
-
$geoip_disable: true,
|
|
154
|
-
},
|
|
155
|
-
type: 'capture',
|
|
156
|
-
library: 'posthog-node',
|
|
157
|
-
library_version: '1.2.3',
|
|
158
|
-
timestamp: expect.any(String),
|
|
159
|
-
uuid: expect.any(String),
|
|
160
|
-
},
|
|
161
|
-
])
|
|
162
|
-
})
|
|
163
|
-
})
|
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
import { PostHog } from '../src/entrypoints/index.node'
|
|
2
|
-
import { PostHogOptions } from '../src/types'
|
|
3
|
-
import fetch from '../src/fetch'
|
|
4
|
-
import { apiImplementation, apiImplementationV4 } from './test-utils'
|
|
5
|
-
import { waitForPromises } from 'posthog-core/test/test-utils/test-utils'
|
|
6
|
-
import { PostHogV4DecideResponse } from 'posthog-core/src/types'
|
|
7
|
-
jest.mock('../src/fetch')
|
|
8
|
-
|
|
9
|
-
jest.spyOn(console, 'debug').mockImplementation()
|
|
10
|
-
|
|
11
|
-
const mockedFetch = jest.mocked(fetch, true)
|
|
12
|
-
|
|
13
|
-
const posthogImmediateResolveOptions: PostHogOptions = {
|
|
14
|
-
fetchRetryCount: 0,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
describe('decide v4', () => {
|
|
18
|
-
describe('getFeatureFlag v4', () => {
|
|
19
|
-
it('returns undefined if the flag is not found', async () => {
|
|
20
|
-
const decideResponse: PostHogV4DecideResponse = {
|
|
21
|
-
flags: {},
|
|
22
|
-
errorsWhileComputingFlags: false,
|
|
23
|
-
requestId: '0152a345-295f-4fba-adac-2e6ea9c91082',
|
|
24
|
-
}
|
|
25
|
-
mockedFetch.mockImplementation(apiImplementationV4(decideResponse))
|
|
26
|
-
|
|
27
|
-
const posthog = new PostHog('TEST_API_KEY', {
|
|
28
|
-
host: 'http://example.com',
|
|
29
|
-
...posthogImmediateResolveOptions,
|
|
30
|
-
})
|
|
31
|
-
let capturedMessage: any
|
|
32
|
-
posthog.on('capture', (message) => {
|
|
33
|
-
capturedMessage = message
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const result = await posthog.getFeatureFlag('non-existent-flag', 'some-distinct-id')
|
|
37
|
-
|
|
38
|
-
expect(result).toBe(undefined)
|
|
39
|
-
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/flags/?v=2', expect.any(Object))
|
|
40
|
-
|
|
41
|
-
await waitForPromises()
|
|
42
|
-
expect(capturedMessage).toMatchObject({
|
|
43
|
-
distinct_id: 'some-distinct-id',
|
|
44
|
-
event: '$feature_flag_called',
|
|
45
|
-
library: posthog.getLibraryId(),
|
|
46
|
-
library_version: posthog.getLibraryVersion(),
|
|
47
|
-
properties: {
|
|
48
|
-
'$feature/non-existent-flag': undefined,
|
|
49
|
-
$feature_flag: 'non-existent-flag',
|
|
50
|
-
$feature_flag_response: undefined,
|
|
51
|
-
$feature_flag_request_id: '0152a345-295f-4fba-adac-2e6ea9c91082',
|
|
52
|
-
$groups: undefined,
|
|
53
|
-
$lib: posthog.getLibraryId(),
|
|
54
|
-
$lib_version: posthog.getLibraryVersion(),
|
|
55
|
-
locally_evaluated: false,
|
|
56
|
-
},
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it.each([
|
|
61
|
-
{
|
|
62
|
-
key: 'variant-flag',
|
|
63
|
-
expectedResponse: 'variant-value',
|
|
64
|
-
expectedReason: 'Matched condition set 3',
|
|
65
|
-
expectedId: 2,
|
|
66
|
-
expectedVersion: 23,
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
key: 'boolean-flag',
|
|
70
|
-
expectedResponse: true,
|
|
71
|
-
expectedReason: 'Matched condition set 1',
|
|
72
|
-
expectedId: 1,
|
|
73
|
-
expectedVersion: 12,
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
key: 'non-matching-flag',
|
|
77
|
-
expectedResponse: false,
|
|
78
|
-
expectedReason: 'Did not match any condition',
|
|
79
|
-
expectedId: 3,
|
|
80
|
-
expectedVersion: 2,
|
|
81
|
-
},
|
|
82
|
-
])(
|
|
83
|
-
'captures a feature flag called event with extra metadata when the flag is found',
|
|
84
|
-
async ({ key, expectedResponse, expectedReason, expectedId, expectedVersion }) => {
|
|
85
|
-
const decideResponse: PostHogV4DecideResponse = {
|
|
86
|
-
flags: {
|
|
87
|
-
'variant-flag': {
|
|
88
|
-
key: 'variant-flag',
|
|
89
|
-
enabled: true,
|
|
90
|
-
variant: 'variant-value',
|
|
91
|
-
reason: {
|
|
92
|
-
code: 'variant',
|
|
93
|
-
condition_index: 2,
|
|
94
|
-
description: 'Matched condition set 3',
|
|
95
|
-
},
|
|
96
|
-
metadata: {
|
|
97
|
-
id: 2,
|
|
98
|
-
version: 23,
|
|
99
|
-
payload: '{"key": "value"}',
|
|
100
|
-
description: 'description',
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
'boolean-flag': {
|
|
104
|
-
key: 'boolean-flag',
|
|
105
|
-
enabled: true,
|
|
106
|
-
variant: undefined,
|
|
107
|
-
reason: {
|
|
108
|
-
code: 'boolean',
|
|
109
|
-
condition_index: 1,
|
|
110
|
-
description: 'Matched condition set 1',
|
|
111
|
-
},
|
|
112
|
-
metadata: {
|
|
113
|
-
id: 1,
|
|
114
|
-
version: 12,
|
|
115
|
-
payload: undefined,
|
|
116
|
-
description: 'description',
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
'non-matching-flag': {
|
|
120
|
-
key: 'non-matching-flag',
|
|
121
|
-
enabled: false,
|
|
122
|
-
variant: undefined,
|
|
123
|
-
reason: {
|
|
124
|
-
code: 'boolean',
|
|
125
|
-
condition_index: 1,
|
|
126
|
-
description: 'Did not match any condition',
|
|
127
|
-
},
|
|
128
|
-
metadata: {
|
|
129
|
-
id: 3,
|
|
130
|
-
version: 2,
|
|
131
|
-
payload: undefined,
|
|
132
|
-
description: 'description',
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
errorsWhileComputingFlags: false,
|
|
137
|
-
requestId: '0152a345-295f-4fba-adac-2e6ea9c91082',
|
|
138
|
-
}
|
|
139
|
-
mockedFetch.mockImplementation(apiImplementationV4(decideResponse))
|
|
140
|
-
|
|
141
|
-
const posthog = new PostHog('TEST_API_KEY', {
|
|
142
|
-
host: 'http://example.com',
|
|
143
|
-
...posthogImmediateResolveOptions,
|
|
144
|
-
})
|
|
145
|
-
let capturedMessage: any
|
|
146
|
-
posthog.on('capture', (message) => {
|
|
147
|
-
capturedMessage = message
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
const result = await posthog.getFeatureFlag(key, 'some-distinct-id')
|
|
151
|
-
|
|
152
|
-
expect(result).toBe(expectedResponse)
|
|
153
|
-
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/flags/?v=2', expect.any(Object))
|
|
154
|
-
|
|
155
|
-
await waitForPromises()
|
|
156
|
-
expect(capturedMessage).toMatchObject({
|
|
157
|
-
distinct_id: 'some-distinct-id',
|
|
158
|
-
event: '$feature_flag_called',
|
|
159
|
-
library: posthog.getLibraryId(),
|
|
160
|
-
library_version: posthog.getLibraryVersion(),
|
|
161
|
-
properties: {
|
|
162
|
-
[`$feature/${key}`]: expectedResponse,
|
|
163
|
-
$feature_flag: key,
|
|
164
|
-
$feature_flag_response: expectedResponse,
|
|
165
|
-
$feature_flag_id: expectedId,
|
|
166
|
-
$feature_flag_version: expectedVersion,
|
|
167
|
-
$feature_flag_reason: expectedReason,
|
|
168
|
-
$feature_flag_request_id: '0152a345-295f-4fba-adac-2e6ea9c91082',
|
|
169
|
-
$groups: undefined,
|
|
170
|
-
$lib: posthog.getLibraryId(),
|
|
171
|
-
$lib_version: posthog.getLibraryVersion(),
|
|
172
|
-
locally_evaluated: false,
|
|
173
|
-
},
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
describe('getFeatureFlagPayload v4', () => {
|
|
179
|
-
it('returns payload', async () => {
|
|
180
|
-
mockedFetch.mockImplementation(
|
|
181
|
-
apiImplementationV4({
|
|
182
|
-
flags: {
|
|
183
|
-
'flag-with-payload': {
|
|
184
|
-
key: 'flag-with-payload',
|
|
185
|
-
enabled: true,
|
|
186
|
-
variant: undefined,
|
|
187
|
-
reason: {
|
|
188
|
-
code: 'boolean',
|
|
189
|
-
condition_index: 1,
|
|
190
|
-
description: 'Matched condition set 2',
|
|
191
|
-
},
|
|
192
|
-
metadata: {
|
|
193
|
-
id: 1,
|
|
194
|
-
version: 12,
|
|
195
|
-
payload: '[0, 1, 2]',
|
|
196
|
-
description: 'description',
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
},
|
|
200
|
-
errorsWhileComputingFlags: false,
|
|
201
|
-
})
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
const posthog = new PostHog('TEST_API_KEY', {
|
|
205
|
-
host: 'http://example.com',
|
|
206
|
-
...posthogImmediateResolveOptions,
|
|
207
|
-
})
|
|
208
|
-
let capturedMessage: any
|
|
209
|
-
posthog.on('capture', (message) => {
|
|
210
|
-
capturedMessage = message
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
const result = await posthog.getFeatureFlagPayload('flag-with-payload', 'some-distinct-id')
|
|
214
|
-
|
|
215
|
-
expect(result).toEqual([0, 1, 2])
|
|
216
|
-
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/flags/?v=2', expect.any(Object))
|
|
217
|
-
|
|
218
|
-
await waitForPromises()
|
|
219
|
-
expect(capturedMessage).toBeUndefined()
|
|
220
|
-
})
|
|
221
|
-
})
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
describe('error handling', () => {
|
|
225
|
-
let posthog: PostHog
|
|
226
|
-
describe.each([
|
|
227
|
-
{
|
|
228
|
-
case: 'JSON error response',
|
|
229
|
-
mock: apiImplementationV4({
|
|
230
|
-
status: 400,
|
|
231
|
-
json: () => Promise.resolve({ error: 'error response' }),
|
|
232
|
-
}),
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
case: 'undefined response',
|
|
236
|
-
mock: apiImplementationV4({
|
|
237
|
-
status: 400,
|
|
238
|
-
json: () => Promise.resolve(undefined),
|
|
239
|
-
}),
|
|
240
|
-
},
|
|
241
|
-
{
|
|
242
|
-
case: 'null response',
|
|
243
|
-
mock: apiImplementationV4({
|
|
244
|
-
status: 400,
|
|
245
|
-
json: () => Promise.resolve(null),
|
|
246
|
-
}),
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
case: 'empty response',
|
|
250
|
-
mock: apiImplementationV4({
|
|
251
|
-
status: 400,
|
|
252
|
-
json: () => Promise.resolve({}),
|
|
253
|
-
}),
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
case: 'network error',
|
|
257
|
-
mock: () => Promise.reject(new Error('Network error')),
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
case: 'invalid JSON',
|
|
261
|
-
mock: apiImplementationV4({
|
|
262
|
-
status: 500,
|
|
263
|
-
json: () => Promise.reject(new Error('Invalid JSON')),
|
|
264
|
-
}),
|
|
265
|
-
},
|
|
266
|
-
])('when $case', ({ mock }) => {
|
|
267
|
-
beforeEach(() => {
|
|
268
|
-
posthog = new PostHog('TEST_API_KEY', {
|
|
269
|
-
host: 'http://example.com',
|
|
270
|
-
...posthogImmediateResolveOptions,
|
|
271
|
-
})
|
|
272
|
-
mockedFetch.mockImplementation(mock)
|
|
273
|
-
})
|
|
274
|
-
|
|
275
|
-
it('getFeatureFlag returns undefined', async () => {
|
|
276
|
-
expect(await posthog.getFeatureFlag('error-flag', 'some-distinct-id')).toBe(undefined)
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
it('isFeatureEnabled returns undefined', async () => {
|
|
280
|
-
expect(await posthog.isFeatureEnabled('error-flag', 'some-distinct-id')).toBe(undefined)
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
it('getFeatureFlagPayload returns undefined', async () => {
|
|
284
|
-
expect(await posthog.getFeatureFlagPayload('error-flag', 'some-distinct-id')).toBe(undefined)
|
|
285
|
-
})
|
|
286
|
-
|
|
287
|
-
it('getAllFlags returns empty object', async () => {
|
|
288
|
-
expect(await posthog.getAllFlags('some-distinct-id')).toEqual({})
|
|
289
|
-
})
|
|
290
|
-
|
|
291
|
-
it('getAllFlagsAndPayloads returns object with empty flags and payloads', async () => {
|
|
292
|
-
expect(await posthog.getAllFlagsAndPayloads('some-distinct-id')).toEqual({
|
|
293
|
-
featureFlags: {},
|
|
294
|
-
featureFlagPayloads: {},
|
|
295
|
-
})
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
it('captures no events', async () => {
|
|
299
|
-
let capturedMessage: any
|
|
300
|
-
posthog.on('capture', (message) => {
|
|
301
|
-
capturedMessage = message
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
await posthog.getFeatureFlag('error-flag', 'some-distinct-id')
|
|
305
|
-
await waitForPromises()
|
|
306
|
-
expect(capturedMessage).toBeUndefined()
|
|
307
|
-
})
|
|
308
|
-
})
|
|
309
|
-
})
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
describe('decide v3', () => {
|
|
313
|
-
describe('getFeatureFlag v3', () => {
|
|
314
|
-
it('returns undefined if the flag is not found', async () => {
|
|
315
|
-
mockedFetch.mockImplementation(apiImplementation({ decideFlags: {} }))
|
|
316
|
-
|
|
317
|
-
const posthog = new PostHog('TEST_API_KEY', {
|
|
318
|
-
host: 'http://example.com',
|
|
319
|
-
...posthogImmediateResolveOptions,
|
|
320
|
-
})
|
|
321
|
-
let capturedMessage: any
|
|
322
|
-
posthog.on('capture', (message) => {
|
|
323
|
-
capturedMessage = message
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
const result = await posthog.getFeatureFlag('non-existent-flag', 'some-distinct-id')
|
|
327
|
-
|
|
328
|
-
expect(result).toBe(undefined)
|
|
329
|
-
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/flags/?v=2', expect.any(Object))
|
|
330
|
-
|
|
331
|
-
await waitForPromises()
|
|
332
|
-
expect(capturedMessage).toMatchObject({
|
|
333
|
-
distinct_id: 'some-distinct-id',
|
|
334
|
-
event: '$feature_flag_called',
|
|
335
|
-
library: posthog.getLibraryId(),
|
|
336
|
-
library_version: posthog.getLibraryVersion(),
|
|
337
|
-
properties: {
|
|
338
|
-
'$feature/non-existent-flag': undefined,
|
|
339
|
-
$feature_flag: 'non-existent-flag',
|
|
340
|
-
$feature_flag_response: undefined,
|
|
341
|
-
$groups: undefined,
|
|
342
|
-
$lib: posthog.getLibraryId(),
|
|
343
|
-
$lib_version: posthog.getLibraryVersion(),
|
|
344
|
-
locally_evaluated: false,
|
|
345
|
-
},
|
|
346
|
-
})
|
|
347
|
-
})
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
describe('getFeatureFlagPayload v3', () => {
|
|
351
|
-
it('returns payload', async () => {
|
|
352
|
-
mockedFetch.mockImplementation(
|
|
353
|
-
apiImplementation({
|
|
354
|
-
decideFlags: {
|
|
355
|
-
'flag-with-payload': true,
|
|
356
|
-
},
|
|
357
|
-
decideFlagPayloads: {
|
|
358
|
-
'flag-with-payload': [0, 1, 2],
|
|
359
|
-
},
|
|
360
|
-
})
|
|
361
|
-
)
|
|
362
|
-
|
|
363
|
-
const posthog = new PostHog('TEST_API_KEY', {
|
|
364
|
-
host: 'http://example.com',
|
|
365
|
-
...posthogImmediateResolveOptions,
|
|
366
|
-
})
|
|
367
|
-
let capturedMessage: any = undefined
|
|
368
|
-
posthog.on('capture', (message) => {
|
|
369
|
-
capturedMessage = message
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
const result = await posthog.getFeatureFlagPayload('flag-with-payload', 'some-distinct-id')
|
|
373
|
-
|
|
374
|
-
expect(result).toEqual([0, 1, 2])
|
|
375
|
-
expect(mockedFetch).toHaveBeenCalledWith('http://example.com/flags/?v=2', expect.any(Object))
|
|
376
|
-
|
|
377
|
-
await waitForPromises()
|
|
378
|
-
expect(capturedMessage).toBeUndefined()
|
|
379
|
-
})
|
|
380
|
-
})
|
|
381
|
-
})
|