@posthog/react 1.2.3 → 1.3.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.
@@ -0,0 +1,19 @@
1
+ import * as React from 'react'
2
+ import { renderHook } from '@testing-library/react-hooks'
3
+ import { PostHogProvider, PostHog } from '../../context'
4
+ import { usePostHog } from '..'
5
+
6
+ jest.useFakeTimers()
7
+
8
+ const posthog = { posthog_client: true } as unknown as PostHog
9
+
10
+ describe('usePostHog hook', () => {
11
+ it('should return the client', () => {
12
+ const { result } = renderHook(() => usePostHog(), {
13
+ wrapper: ({ children }: { children: React.ReactNode }) => (
14
+ <PostHogProvider client={posthog}>{children}</PostHogProvider>
15
+ ),
16
+ })
17
+ expect(result.current).toEqual(posthog)
18
+ })
19
+ })
@@ -1,298 +0,0 @@
1
- import * as React from 'react'
2
- import { useState } from 'react'
3
- import { render, screen, fireEvent } from '@testing-library/react'
4
- import { PostHogProvider } from '../../context'
5
- import { PostHogFeature } from '../'
6
- import '@testing-library/jest-dom'
7
-
8
- const FEATURE_FLAG_STATUS = {
9
- multivariate_feature: 'string-value',
10
- example_feature_payload: 'test',
11
- test: true,
12
- test_false: false,
13
- }
14
-
15
- const FEATURE_FLAG_PAYLOADS = {
16
- example_feature_payload: {
17
- id: 1,
18
- name: 'example_feature_1_payload',
19
- key: 'example_feature_1_payload',
20
- },
21
- }
22
-
23
- describe('PostHogFeature component', () => {
24
- given('featureFlag', () => 'test')
25
- given('matchValue', () => true)
26
- given(
27
- 'render',
28
- () => () =>
29
- render(
30
- <PostHogProvider client={given.posthog}>
31
- <PostHogFeature flag={given.featureFlag} match={given.matchValue}>
32
- <div data-testid="helloDiv">Hello</div>
33
- </PostHogFeature>
34
- </PostHogProvider>
35
- )
36
- )
37
- given('posthog', () => ({
38
- isFeatureEnabled: (flag) => !!FEATURE_FLAG_STATUS[flag],
39
- getFeatureFlag: (flag) => FEATURE_FLAG_STATUS[flag],
40
- getFeatureFlagPayload: (flag) => FEATURE_FLAG_PAYLOADS[flag],
41
- onFeatureFlags: (callback) => {
42
- const activeFlags = []
43
- for (const flag in FEATURE_FLAG_STATUS) {
44
- if (FEATURE_FLAG_STATUS[flag]) {
45
- activeFlags.push(flag)
46
- }
47
- }
48
- callback(activeFlags)
49
- return () => {}
50
- },
51
- capture: jest.fn(),
52
- }))
53
-
54
- beforeEach(() => {
55
- // IntersectionObserver isn't available in test environment
56
- const mockIntersectionObserver = jest.fn()
57
- mockIntersectionObserver.mockReturnValue({
58
- observe: () => null,
59
- unobserve: () => null,
60
- disconnect: () => null,
61
- })
62
-
63
- // eslint-disable-next-line compat/compat
64
- window.IntersectionObserver = mockIntersectionObserver
65
- })
66
-
67
- it('should track interactions with the feature component', () => {
68
- given.render()
69
-
70
- fireEvent.click(screen.getByTestId('helloDiv'))
71
- expect(given.posthog.capture).toHaveBeenCalledWith('$feature_interaction', {
72
- feature_flag: 'test',
73
- $set: { '$feature_interaction/test': true },
74
- })
75
- expect(given.posthog.capture).toHaveBeenCalledTimes(1)
76
- })
77
-
78
- it('should not fire for every interaction with the feature component', () => {
79
- given.render()
80
-
81
- fireEvent.click(screen.getByTestId('helloDiv'))
82
- expect(given.posthog.capture).toHaveBeenCalledWith('$feature_interaction', {
83
- feature_flag: 'test',
84
- $set: { '$feature_interaction/test': true },
85
- })
86
- expect(given.posthog.capture).toHaveBeenCalledTimes(1)
87
-
88
- fireEvent.click(screen.getByTestId('helloDiv'))
89
- fireEvent.click(screen.getByTestId('helloDiv'))
90
- fireEvent.click(screen.getByTestId('helloDiv'))
91
- expect(given.posthog.capture).toHaveBeenCalledTimes(1)
92
- })
93
-
94
- it('should track an interaction with each child node of the feature component', () => {
95
- given(
96
- 'render',
97
- () => () =>
98
- render(
99
- <PostHogProvider client={given.posthog}>
100
- <PostHogFeature flag={given.featureFlag} match={given.matchValue}>
101
- <div data-testid="helloDiv">Hello</div>
102
- <div data-testid="worldDiv">World!</div>
103
- </PostHogFeature>
104
- </PostHogProvider>
105
- )
106
- )
107
- given.render()
108
-
109
- fireEvent.click(screen.getByTestId('helloDiv'))
110
- fireEvent.click(screen.getByTestId('helloDiv'))
111
- fireEvent.click(screen.getByTestId('worldDiv'))
112
- fireEvent.click(screen.getByTestId('worldDiv'))
113
- fireEvent.click(screen.getByTestId('worldDiv'))
114
- expect(given.posthog.capture).toHaveBeenCalledWith('$feature_interaction', {
115
- feature_flag: 'test',
116
- $set: { '$feature_interaction/test': true },
117
- })
118
- expect(given.posthog.capture).toHaveBeenCalledTimes(1)
119
- })
120
-
121
- it('should not fire events when interaction is disabled', () => {
122
- given(
123
- 'render',
124
- () => () =>
125
- render(
126
- <PostHogProvider client={given.posthog}>
127
- <PostHogFeature flag={given.featureFlag} match={given.matchValue} trackInteraction={false}>
128
- <div data-testid="helloDiv">Hello</div>
129
- </PostHogFeature>
130
- </PostHogProvider>
131
- )
132
- )
133
- given.render()
134
-
135
- fireEvent.click(screen.getByTestId('helloDiv'))
136
- expect(given.posthog.capture).not.toHaveBeenCalled()
137
-
138
- fireEvent.click(screen.getByTestId('helloDiv'))
139
- fireEvent.click(screen.getByTestId('helloDiv'))
140
- fireEvent.click(screen.getByTestId('helloDiv'))
141
- expect(given.posthog.capture).not.toHaveBeenCalled()
142
- })
143
-
144
- it('should fire events when interaction is disabled but re-enabled after', () => {
145
- const DynamicUpdateComponent = () => {
146
- const [trackInteraction, setTrackInteraction] = useState(false)
147
-
148
- return (
149
- <>
150
- <div
151
- data-testid="clicker"
152
- onClick={() => {
153
- setTrackInteraction(true)
154
- }}
155
- >
156
- Click me
157
- </div>
158
- <PostHogFeature
159
- flag={given.featureFlag}
160
- match={given.matchValue}
161
- trackInteraction={trackInteraction}
162
- >
163
- <div data-testid="helloDiv">Hello</div>
164
- </PostHogFeature>
165
- </>
166
- )
167
- }
168
-
169
- given(
170
- 'render',
171
- () => () =>
172
- render(
173
- <PostHogProvider client={given.posthog}>
174
- <DynamicUpdateComponent />
175
- </PostHogProvider>
176
- )
177
- )
178
- given.render()
179
-
180
- fireEvent.click(screen.getByTestId('helloDiv'))
181
- expect(given.posthog.capture).not.toHaveBeenCalled()
182
-
183
- fireEvent.click(screen.getByTestId('clicker'))
184
- fireEvent.click(screen.getByTestId('helloDiv'))
185
- fireEvent.click(screen.getByTestId('helloDiv'))
186
- expect(given.posthog.capture).toHaveBeenCalledWith('$feature_interaction', {
187
- feature_flag: 'test',
188
- $set: { '$feature_interaction/test': true },
189
- })
190
- expect(given.posthog.capture).toHaveBeenCalledTimes(1)
191
- })
192
-
193
- it('should not show the feature component if the flag is not enabled', () => {
194
- given('featureFlag', () => 'test_false')
195
- given.render()
196
-
197
- expect(screen.queryByTestId('helloDiv')).not.toBeInTheDocument()
198
- expect(given.posthog.capture).not.toHaveBeenCalled()
199
-
200
- // check if any elements are found
201
- const allTags = screen.queryAllByText(/.*/)
202
-
203
- // Assert that no random elements are found
204
- expect(allTags.length).toEqual(2)
205
- expect(allTags[0].tagName).toEqual('BODY')
206
- expect(allTags[1].tagName).toEqual('DIV')
207
- })
208
-
209
- it('should fallback when provided', () => {
210
- given('featureFlag', () => 'test_false')
211
- given(
212
- 'render',
213
- () => () =>
214
- render(
215
- <PostHogProvider client={given.posthog}>
216
- <PostHogFeature
217
- flag={given.featureFlag}
218
- match={given.matchValue}
219
- fallback={<div data-testid="nope">Nope</div>}
220
- >
221
- <div data-testid="helloDiv">Hello</div>
222
- </PostHogFeature>
223
- </PostHogProvider>
224
- )
225
- )
226
- given.render()
227
-
228
- expect(screen.queryByTestId('helloDiv')).not.toBeInTheDocument()
229
- expect(given.posthog.capture).not.toHaveBeenCalled()
230
-
231
- fireEvent.click(screen.getByTestId('nope'))
232
- expect(given.posthog.capture).not.toHaveBeenCalled()
233
- })
234
-
235
- it('should handle showing multivariate flags with bool match', () => {
236
- given('featureFlag', () => 'multivariate_feature')
237
- given('matchValue', () => true)
238
-
239
- given.render()
240
-
241
- expect(screen.queryByTestId('helloDiv')).not.toBeInTheDocument()
242
- expect(given.posthog.capture).not.toHaveBeenCalled()
243
- })
244
-
245
- it('should handle showing multivariate flags with incorrect match', () => {
246
- given('featureFlag', () => 'multivariate_feature')
247
- given('matchValue', () => 'string-valueCXCC')
248
-
249
- given.render()
250
-
251
- expect(screen.queryByTestId('helloDiv')).not.toBeInTheDocument()
252
- expect(given.posthog.capture).not.toHaveBeenCalled()
253
- })
254
-
255
- it('should handle showing multivariate flags', () => {
256
- given('featureFlag', () => 'multivariate_feature')
257
- given('matchValue', () => 'string-value')
258
-
259
- given.render()
260
-
261
- expect(screen.queryByTestId('helloDiv')).toBeInTheDocument()
262
- expect(given.posthog.capture).not.toHaveBeenCalled()
263
-
264
- fireEvent.click(screen.getByTestId('helloDiv'))
265
- expect(given.posthog.capture).toHaveBeenCalledWith('$feature_interaction', {
266
- feature_flag: 'multivariate_feature',
267
- feature_flag_variant: 'string-value',
268
- $set: { '$feature_interaction/multivariate_feature': 'string-value' },
269
- })
270
- expect(given.posthog.capture).toHaveBeenCalledTimes(1)
271
- })
272
-
273
- it('should handle payload flags', () => {
274
- given('featureFlag', () => 'example_feature_payload')
275
- given('matchValue', () => 'test')
276
- given(
277
- 'render',
278
- () => () =>
279
- render(
280
- <PostHogProvider client={given.posthog}>
281
- <PostHogFeature flag={given.featureFlag} match={given.matchValue}>
282
- {(payload) => {
283
- return <div data-testid={`hi_${payload.name}`}>Hullo</div>
284
- }}
285
- </PostHogFeature>
286
- </PostHogProvider>
287
- )
288
- )
289
-
290
- given.render()
291
-
292
- expect(screen.queryByTestId('hi_example_feature_1_payload')).toBeInTheDocument()
293
- expect(given.posthog.capture).not.toHaveBeenCalled()
294
-
295
- fireEvent.click(screen.getByTestId('hi_example_feature_1_payload'))
296
- expect(given.posthog.capture).toHaveBeenCalledTimes(1)
297
- })
298
- })
@@ -1,23 +0,0 @@
1
- import * as React from 'react'
2
- import { renderHook } from '@testing-library/react-hooks'
3
- import { PostHogProvider } from '../../context'
4
- import { usePostHog } from '..'
5
-
6
- jest.useFakeTimers()
7
-
8
- const posthog = { posthog_client: true }
9
-
10
- describe('usePostHog hook', () => {
11
- given('renderProvider', () => ({ children }) => (
12
- <PostHogProvider client={given.posthog}>{children}</PostHogProvider>
13
- ))
14
-
15
- given('posthog', () => posthog)
16
-
17
- it('should return the client', () => {
18
- let { result } = renderHook(() => usePostHog(), {
19
- wrapper: given.renderProvider,
20
- })
21
- expect(result.current).toEqual(posthog)
22
- })
23
- })