1
1
import { fireEvent , render , screen } from '@testing-library/react' ;
2
2
import * as React from 'react' ;
3
3
4
- import { ErrorBoundary , ErrorBoundaryProps } from '../src/errorboundary' ;
4
+ import { ErrorBoundary , ErrorBoundaryProps , UNKNOWN_COMPONENT , withErrorBoundary } from '../src/errorboundary' ;
5
5
6
6
const mockCaptureException = jest . fn ( ) ;
7
7
const mockShowReportDialog = jest . fn ( ) ;
8
+ const EVENT_ID = 'test-id-123' ;
8
9
9
10
jest . mock ( '@sentry/browser' , ( ) => ( {
10
11
captureException : ( err : any , ctx : any ) => {
11
12
mockCaptureException ( err , ctx ) ;
13
+ return EVENT_ID ;
12
14
} ,
13
15
showReportDialog : ( options : any ) => {
14
16
mockShowReportDialog ( options ) ;
@@ -18,7 +20,15 @@ jest.mock('@sentry/browser', () => ({
18
20
const TestApp : React . FC < ErrorBoundaryProps > = ( { children, ...props } ) => {
19
21
const [ isError , setError ] = React . useState ( false ) ;
20
22
return (
21
- < ErrorBoundary { ...props } >
23
+ < ErrorBoundary
24
+ { ...props }
25
+ onReset = { ( err : Error , stack : string ) => {
26
+ setError ( false ) ;
27
+ if ( props . onReset ) {
28
+ props . onReset ( err , stack ) ;
29
+ }
30
+ } }
31
+ >
22
32
{ isError ? < Bam /> : children }
23
33
< button
24
34
data-testid = "errorBtn"
@@ -34,6 +44,20 @@ function Bam(): JSX.Element {
34
44
throw new Error ( 'boom' ) ;
35
45
}
36
46
47
+ describe ( 'withErrorBoundary' , ( ) => {
48
+ it ( 'sets displayName properly' , ( ) => {
49
+ const TestComponent = ( ) => < h1 > Hello World</ h1 > ;
50
+
51
+ const Component = withErrorBoundary ( TestComponent , { fallback : < h1 > fallback</ h1 > } ) ;
52
+ expect ( Component . displayName ) . toBe ( 'errorBoundary(TestComponent)' ) ;
53
+ } ) ;
54
+
55
+ it ( 'defaults to an unknown displayName' , ( ) => {
56
+ const Component = withErrorBoundary ( ( ) => < h1 > Hello World</ h1 > , { fallback : < h1 > fallback</ h1 > } ) ;
57
+ expect ( Component . displayName ) . toBe ( `errorBoundary(${ UNKNOWN_COMPONENT } )` ) ;
58
+ } ) ;
59
+ } ) ;
60
+
37
61
describe ( 'ErrorBoundary' , ( ) => {
38
62
jest . spyOn ( console , 'error' ) . mockImplementation ( ) ;
39
63
@@ -44,7 +68,6 @@ describe('ErrorBoundary', () => {
44
68
45
69
it ( 'renders null if not given a valid `fallback` prop' , ( ) => {
46
70
const { container } = render (
47
- // @ts -ignore
48
71
< ErrorBoundary fallback = { new Error ( 'true' ) } >
49
72
< Bam />
50
73
</ ErrorBoundary > ,
@@ -55,7 +78,6 @@ describe('ErrorBoundary', () => {
55
78
56
79
it ( 'renders a fallback on error' , ( ) => {
57
80
const { container } = render (
58
- // @ts -ignore
59
81
< ErrorBoundary fallback = { < h1 > Error Component</ h1 > } >
60
82
< Bam />
61
83
</ ErrorBoundary > ,
@@ -186,12 +208,30 @@ describe('ErrorBoundary', () => {
186
208
fireEvent . click ( btn ) ;
187
209
188
210
expect ( mockShowReportDialog ) . toHaveBeenCalledTimes ( 1 ) ;
189
- expect ( mockShowReportDialog ) . toHaveBeenCalledWith ( options ) ;
211
+ expect ( mockShowReportDialog ) . toHaveBeenCalledWith ( { ... options , eventId : EVENT_ID } ) ;
190
212
} ) ;
191
213
192
- it ( 'resets to initial state when reset' , ( ) => {
193
- const mockOnReset = jest . fn ( ) ;
214
+ it ( 'resets to initial state when reset' , async ( ) => {
194
215
const { container } = render (
216
+ < TestApp fallback = { ( { resetError } ) => < button data-testid = "reset" onClick = { resetError } /> } >
217
+ < h1 > children</ h1 >
218
+ </ TestApp > ,
219
+ ) ;
220
+
221
+ expect ( container . innerHTML ) . toContain ( '<h1>children</h1>' ) ;
222
+ const btn = screen . getByTestId ( 'errorBtn' ) ;
223
+ fireEvent . click ( btn ) ;
224
+ expect ( container . innerHTML ) . toContain ( '<button data-testid="reset">' ) ;
225
+
226
+ const reset = screen . getByTestId ( 'reset' ) ;
227
+ fireEvent . click ( reset ) ;
228
+
229
+ expect ( container . innerHTML ) . toContain ( '<h1>children</h1>' ) ;
230
+ } ) ;
231
+
232
+ it ( 'calls `onReset()` when reset' , ( ) => {
233
+ const mockOnReset = jest . fn ( ) ;
234
+ render (
195
235
< TestApp
196
236
onReset = { mockOnReset }
197
237
fallback = { ( { resetError } ) => < button data-testid = "reset" onClick = { resetError } /> }
@@ -200,17 +240,14 @@ describe('ErrorBoundary', () => {
200
240
</ TestApp > ,
201
241
) ;
202
242
203
- expect ( container . innerHTML ) . toContain ( '<h1>children</h1>' ) ;
204
243
expect ( mockOnReset ) . toHaveBeenCalledTimes ( 0 ) ;
205
-
206
244
const btn = screen . getByTestId ( 'errorBtn' ) ;
207
245
fireEvent . click ( btn ) ;
208
-
209
- expect ( container . innerHTML ) . toContain ( '<button data-testid="reset">' ) ;
210
246
expect ( mockOnReset ) . toHaveBeenCalledTimes ( 0 ) ;
211
247
212
248
const reset = screen . getByTestId ( 'reset' ) ;
213
249
fireEvent . click ( reset ) ;
250
+
214
251
expect ( mockOnReset ) . toHaveBeenCalledTimes ( 1 ) ;
215
252
expect ( mockOnReset ) . toHaveBeenCalledWith ( expect . any ( Error ) , expect . any ( String ) ) ;
216
253
} ) ;
0 commit comments