1- import React from 'react' ;
2- import { vi } from 'vitest' ;
31import { render , screen } from '@testing-library/react' ;
42import '@testing-library/jest-dom/vitest' ;
3+ import { vi } from 'vitest' ;
54
65import ErrorBoundary from './ErrorBoundary' ;
7- import { ApiError , Problem } from '@pxweb2/pxweb2-api-client' ;
8- import { ApiProblemError } from '../../util/ApiProblemError' ;
96
10- // Mock only the UI components, not the business logic
7+ // Mock the error components
118vi . mock ( '../Errors/GenericError/GenericError' , ( ) => ( {
129 GenericError : ( ) => (
1310 < div data-testid = "generic-error" > Generic Error Component</ div >
1411 ) ,
1512} ) ) ;
1613
1714vi . mock ( '../Errors/NotFound/NotFound' , ( ) => ( {
18- NotFound : ( ) => < div data-testid = "not-found-error " > Not Found Component</ div > ,
15+ NotFound : ( ) => < div data-testid = "not-found" > Not Found Component</ div > ,
1916} ) ) ;
2017
2118describe ( 'ErrorBoundary' , ( ) => {
22- // Helper to create a real ApiError instance
23- const createMockApiError = (
24- status : number ,
25- problem ?: Partial < Problem > ,
26- ) : ApiError => {
27- const apiError = Object . create ( ApiError . prototype ) ;
28- apiError . status = status ;
29- apiError . url = 'http://test.com' ;
30- apiError . statusText = 'Error' ;
31- apiError . body = {
32- status : problem ?. status ?? status ,
33- title : problem ?. title ?? 'Test Error' ,
34- type : problem ?. type ?? 'test-error-type' ,
35- ...problem ,
36- } as Problem ;
37- apiError . request = { method : 'GET' , url : 'http://test.com' } ;
38- apiError . name = 'ApiError' ;
39- apiError . message = 'Test error' ;
40-
41- return apiError ;
42- } ;
43-
4419 // Setup console mocks before all tests
4520 let consoleErrorSpy : ReturnType < typeof vi . spyOn > ;
4621 let consoleLogSpy : ReturnType < typeof vi . spyOn > ;
@@ -73,9 +48,9 @@ describe('ErrorBoundary', () => {
7348 expect ( screen . getByText ( 'Child Component' ) ) . toBeInTheDocument ( ) ;
7449 } ) ;
7550
76- it ( 'renders GenericError when an error occurs' , ( ) => {
51+ it ( 'renders NotFound when a 404 error occurs' , ( ) => {
7752 const ErrorComponent = ( ) => {
78- throw new Error ( 'Test error ' ) ;
53+ throw new Error ( '404 Not Found ' ) ;
7954 } ;
8055
8156 render (
@@ -84,38 +59,17 @@ describe('ErrorBoundary', () => {
8459 </ ErrorBoundary > ,
8560 ) ;
8661
87- expect ( screen . getByTestId ( 'generic-error' ) ) . toBeInTheDocument ( ) ;
88- expect ( screen . getByText ( 'Generic Error Component' ) ) . toBeInTheDocument ( ) ;
89- } ) ;
90-
91- it ( 'renders NotFound component when ApiProblemError with 404 status occurs' , ( ) => {
92- const mockApiError = createMockApiError ( 404 , {
93- title : 'Not Found' ,
94- type : 'about:blank' ,
95- } ) ;
96- const ErrorComponent = ( ) => {
97- throw new ApiProblemError ( mockApiError , 'test-table-id' ) ;
98- } ;
99-
100- render (
101- < ErrorBoundary >
102- < ErrorComponent />
103- </ ErrorBoundary > ,
104- ) ;
105-
106- // Assert that the NotFound component is rendered instead of GenericError
107- expect ( screen . getByTestId ( 'not-found-error' ) ) . toBeInTheDocument ( ) ;
62+ expect ( screen . getByTestId ( 'not-found' ) ) . toBeInTheDocument ( ) ;
10863 expect ( screen . getByText ( 'Not Found Component' ) ) . toBeInTheDocument ( ) ;
10964 expect ( screen . queryByTestId ( 'generic-error' ) ) . not . toBeInTheDocument ( ) ;
65+ expect (
66+ screen . queryByText ( 'Generic Error Component' ) ,
67+ ) . not . toBeInTheDocument ( ) ;
11068 } ) ;
11169
112- it ( 'renders GenericError when ApiProblemError with non-404 status occurs' , ( ) => {
113- const mockApiError = createMockApiError ( 500 , {
114- title : 'Internal Server Error' ,
115- type : 'about:blank' ,
116- } ) ;
70+ it ( 'renders GenericError when a non-404 error occurs' , ( ) => {
11771 const ErrorComponent = ( ) => {
118- throw new ApiProblemError ( mockApiError , 'test-table-id ') ;
72+ throw new Error ( 'Test error ') ;
11973 } ;
12074
12175 render (
@@ -124,135 +78,9 @@ describe('ErrorBoundary', () => {
12478 </ ErrorBoundary > ,
12579 ) ;
12680
127- // Assert that the GenericError component is rendered, not NotFound
12881 expect ( screen . getByTestId ( 'generic-error' ) ) . toBeInTheDocument ( ) ;
12982 expect ( screen . getByText ( 'Generic Error Component' ) ) . toBeInTheDocument ( ) ;
130- expect ( screen . queryByTestId ( 'not-found-error' ) ) . not . toBeInTheDocument ( ) ;
131- } ) ;
132-
133- it ( 'renders NotFound when error message starts with 404 status code' , ( ) => {
134- const ErrorComponent = ( ) => {
135- throw new Error (
136- '404\n TableId: TAB60065 \n Not Found\n - https://...' ,
137- ) ;
138- } ;
139-
140- render (
141- < ErrorBoundary >
142- < ErrorComponent />
143- </ ErrorBoundary > ,
144- ) ;
145-
146- expect ( screen . getByTestId ( 'not-found-error' ) ) . toBeInTheDocument ( ) ;
147- } ) ;
148-
149- it ( 'renders NotFound when error message contains 404 pattern' , ( ) => {
150- const ErrorComponent = ( ) => {
151- throw new Error ( 'Request failed with status code 404' ) ;
152- } ;
153-
154- render (
155- < ErrorBoundary >
156- < ErrorComponent />
157- </ ErrorBoundary > ,
158- ) ;
159-
160- expect ( screen . getByTestId ( 'not-found-error' ) ) . toBeInTheDocument ( ) ;
161- } ) ;
162-
163- it ( 'renders NotFound when error message contains "not found" keyword' , ( ) => {
164- const ErrorComponent = ( ) => {
165- throw new Error ( 'Table not found in the database' ) ;
166- } ;
167-
168- render (
169- < ErrorBoundary >
170- < ErrorComponent />
171- </ ErrorBoundary > ,
172- ) ;
173-
174- expect ( screen . getByTestId ( 'not-found-error' ) ) . toBeInTheDocument ( ) ;
175- } ) ;
176-
177- it ( 'renders GenericError when error message contains 500 keyword' , ( ) => {
178- const ErrorComponent = ( ) => {
179- throw new Error ( 'Server error occurred: 500' ) ;
180- } ;
181-
182- render (
183- < ErrorBoundary >
184- < ErrorComponent />
185- </ ErrorBoundary > ,
186- ) ;
187-
188- expect ( screen . getByTestId ( 'generic-error' ) ) . toBeInTheDocument ( ) ;
189- } ) ;
190-
191- it ( 'renders GenericError when error message contains "server error" keyword' , ( ) => {
192- const ErrorComponent = ( ) => {
193- throw new Error ( 'Internal server error occurred' ) ;
194- } ;
195-
196- render (
197- < ErrorBoundary >
198- < ErrorComponent />
199- </ ErrorBoundary > ,
200- ) ;
201-
202- expect ( screen . getByTestId ( 'generic-error' ) ) . toBeInTheDocument ( ) ;
203- } ) ;
204-
205- it ( 'renders GenericError when status code in message is out of valid HTTP range' , ( ) => {
206- const ErrorComponent = ( ) => {
207- throw new Error ( 'Invalid status code 999 occurred' ) ;
208- } ;
209-
210- render (
211- < ErrorBoundary >
212- < ErrorComponent />
213- </ ErrorBoundary > ,
214- ) ;
215-
216- expect ( screen . getByTestId ( 'generic-error' ) ) . toBeInTheDocument ( ) ;
217- } ) ;
218-
219- it ( 'renders GenericError when error has null state' , ( ) => {
220- const ErrorComponent = ( ) => {
221- throw new Error ( 'Generic error without status' ) ;
222- } ;
223-
224- render (
225- < ErrorBoundary >
226- < ErrorComponent />
227- </ ErrorBoundary > ,
228- ) ;
229-
230- expect ( screen . getByTestId ( 'generic-error' ) ) . toBeInTheDocument ( ) ;
231- } ) ;
232-
233- it ( 'renders GenericError when error state is null' , ( ) => {
234- // This tests the edge case where state.error is null but hasError is true
235- // We can simulate this by manually setting the state after component mounts
236- const TestWrapper = ( ) => {
237- const boundaryRef = React . useRef < ErrorBoundary > ( null ) ;
238-
239- React . useEffect ( ( ) => {
240- if ( boundaryRef . current ) {
241- // Force the component into an error state with null error
242- boundaryRef . current . setState ( { hasError : true , error : null } ) ;
243- }
244- } , [ ] ) ;
245-
246- return (
247- < ErrorBoundary ref = { boundaryRef } >
248- < div > Child Component</ div >
249- </ ErrorBoundary >
250- ) ;
251- } ;
252-
253- render ( < TestWrapper /> ) ;
254-
255- // After the effect runs, it should show the generic error
256- expect ( screen . getByTestId ( 'generic-error' ) ) . toBeInTheDocument ( ) ;
83+ expect ( screen . queryByTestId ( 'not-found' ) ) . not . toBeInTheDocument ( ) ;
84+ expect ( screen . queryByText ( 'Not Found Component' ) ) . not . toBeInTheDocument ( ) ;
25785 } ) ;
25886} ) ;
0 commit comments