-
Notifications
You must be signed in to change notification settings - Fork 237
Expand file tree
/
Copy pathPostHogErrorBoundary.test.tsx
More file actions
127 lines (105 loc) · 4.6 KB
/
PostHogErrorBoundary.test.tsx
File metadata and controls
127 lines (105 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* eslint-disable no-console */
import * as React from 'react'
import { render } from '@testing-library/react'
import { __POSTHOG_ERROR_MESSAGES, PostHogErrorBoundary } from '../PostHogErrorBoundary'
import posthog from 'posthog-js'
import { setDefaultPostHogInstance } from '../../context/posthog-default'
describe('PostHogErrorBoundary component', () => {
beforeEach(() => {
setDefaultPostHogInstance(posthog)
})
afterEach(() => {
setDefaultPostHogInstance(undefined)
})
mockFunction(console, 'error')
mockFunction(console, 'warn')
mockFunction(posthog, 'captureException')
const renderWithError = (props: any) => render(<RenderWithError {...props} />)
const renderWithoutError = (props?: any) => render(<RenderWithoutError {...props} />)
it('should call captureException with error message', () => {
const { container } = renderWithError({ message: 'Test error', fallback: <div></div> })
expect(posthog.captureException).toHaveBeenCalledWith(new Error('Test error'), undefined)
expect(container.innerHTML).toBe('<div></div>')
expect(console.error).toHaveBeenCalledTimes(1)
expect((console.error as any).mock.calls[0][1].message).toEqual('Test error')
})
it('should warn user when fallback is null', () => {
const { container } = renderWithError({ fallback: null })
expect(posthog.captureException).toHaveBeenCalledWith(new Error('Error'), undefined)
expect(container.innerHTML).toBe('')
expect(console.warn).toHaveBeenCalledWith(__POSTHOG_ERROR_MESSAGES.INVALID_FALLBACK)
})
it('should warn user when fallback is a string', () => {
const { container } = renderWithError({ fallback: 'hello' })
expect(posthog.captureException).toHaveBeenCalledWith(new Error('Error'), undefined)
expect(container.innerHTML).toBe('')
expect(console.warn).toHaveBeenCalledWith(__POSTHOG_ERROR_MESSAGES.INVALID_FALLBACK)
})
it('should add additional properties before sending event (as object)', () => {
const props = { team_id: '1234' }
renderWithError({ message: 'Kaboom', additionalProperties: props })
expect(posthog.captureException).toHaveBeenCalledWith(new Error('Kaboom'), props)
})
it('should add additional properties before sending event (as function)', () => {
const props = { team_id: '1234' }
renderWithError({
message: 'Kaboom',
additionalProperties: (err: Error) => {
expect(err.message).toBe('Kaboom')
return props
},
})
expect(posthog.captureException).toHaveBeenCalledWith(new Error('Kaboom'), props)
})
it('should render children without errors', () => {
const { container } = renderWithoutError()
expect(container.innerHTML).toBe('<div>Amazing content</div>')
})
})
describe('captureException processing', () => {
beforeEach(() => {
setDefaultPostHogInstance(posthog)
})
afterEach(() => {
setDefaultPostHogInstance(undefined)
})
mockFunction(console, 'error')
mockFunction(console, 'warn')
mockFunction(posthog, 'capture')
const renderWithError = (props: any) => render(<RenderWithError {...props} />)
it('should call capture with a stacktrace', () => {
renderWithError({ message: 'Kaboom', fallback: <div></div>, additionalProperties: {} })
const captureCalls = (posthog.capture as jest.Mock).mock.calls
expect(captureCalls.length).toBe(1)
const exceptionList = captureCalls[0][1].$exception_list
expect(exceptionList.length).toBe(1)
const stacktrace = exceptionList[0].stacktrace
expect(stacktrace.frames.length).toBeGreaterThan(20)
})
})
function mockFunction(object: any, funcName: string) {
const originalFunc = object[funcName]
beforeEach(() => {
object[funcName] = jest.fn()
})
afterEach(() => {
object[funcName] = originalFunc
})
}
function ComponentWithError({ message }: { message: string }): React.ReactElement {
throw new Error(message)
}
function RenderWithError({ message = 'Error', fallback, additionalProperties }: any) {
return (
<PostHogErrorBoundary fallback={fallback} additionalProperties={additionalProperties}>
<ComponentWithError message={message} />
</PostHogErrorBoundary>
)
}
function RenderWithoutError({ additionalProperties }: any) {
return (
<PostHogErrorBoundary fallback={<div></div>} additionalProperties={additionalProperties}>
<div>Amazing content</div>
</PostHogErrorBoundary>
)
}