@@ -4,15 +4,47 @@ import { MetaProvider } from '@solidjs/meta';
44import { Route , Router } from '@solidjs/router' ;
55import { render , renderHook , screen , waitFor } from '@solidjs/testing-library' ;
66import { QueryClient , QueryClientProvider } from '@tanstack/solid-query' ;
7- import { describe , test , beforeEach } from 'vitest' ;
7+ import { HttpResponse , http } from 'msw' ;
8+ import toast from 'solid-toast' ;
9+ import { describe , expect , test , vi } from 'vitest' ;
810
911import PostList from '@/components/modules/PostList/PostList' ;
1012import useFetchPostList from '@/hooks/useFetchPostList' ;
13+ import { server } from '@/mocks/server' ;
14+
15+ const apiEndpointUrl = import . meta. env . VITE_PUBLIC_API_URL ;
16+
17+ vi . mock ( 'solid-toast' , ( ) => ( {
18+ default : {
19+ error : vi . fn ( ) ,
20+ } ,
21+ } ) ) ;
1122
1223describe ( 'PostList component' , ( ) => {
13- const queryClient = new QueryClient ( ) ;
24+ // const queryClient = new QueryClient({
25+ // defaultOptions: { queries: { retry: false } },
26+ // });
27+
28+ // beforeEach(() => {
29+ // render(() => <PostList />, {
30+ // wrapper: props => (
31+ // <MetaProvider>
32+ // <QueryClientProvider client={queryClient}>
33+ // <Router
34+ // // eslint-disable-next-line @typescript-eslint/no-shadow
35+ // root={props => <>{props.children}</>}
36+ // >
37+ // <Route path="/" component={() => <>{props.children}</>} />
38+ // </Router>
39+ // </QueryClientProvider>
40+ // </MetaProvider>
41+ // ),
42+ // });
43+ // });
44+
45+ test ( 'should render "Loading..." element before Data Fetching' , async ( ) => {
46+ const queryClient = new QueryClient ( ) ;
1447
15- beforeEach ( ( ) => {
1648 render ( ( ) => < PostList /> , {
1749 wrapper : props => (
1850 < MetaProvider >
@@ -27,9 +59,7 @@ describe('PostList component', () => {
2759 </ MetaProvider >
2860 ) ,
2961 } ) ;
30- } ) ;
3162
32- test ( 'should render "Loading..." element before Data Fetching' , async ( ) => {
3363 // screen.getByRole('button', { name: '' });
3464 const loadingEle = screen . getByText ( 'Loading...' ) ; // substring match
3565 expect ( loadingEle ) . toBeInTheDocument ( ) ;
@@ -40,6 +70,23 @@ describe('PostList component', () => {
4070 // });
4171
4272 test ( 'should success to fetch data' , async ( ) => {
73+ const queryClient = new QueryClient ( ) ;
74+
75+ render ( ( ) => < PostList /> , {
76+ wrapper : props => (
77+ < MetaProvider >
78+ < QueryClientProvider client = { queryClient } >
79+ < Router
80+ // eslint-disable-next-line @typescript-eslint/no-shadow
81+ root = { props => < > { props . children } </ > }
82+ >
83+ < Route path = "/" component = { ( ) => < > { props . children } </ > } />
84+ </ Router >
85+ </ QueryClientProvider >
86+ </ MetaProvider >
87+ ) ,
88+ } ) ;
89+
4390 // expect(await screen.findByText(/qui est esse/)).toBeInTheDocument();
4491
4592 // @ https://github.com/testing-library/react-hooks-testing-library/issues/23#issuecomment-477542354
@@ -63,14 +110,77 @@ describe('PostList component', () => {
63110 await waitFor ( ( ) => {
64111 expect ( result . data ?. length ) . toBe ( 100 ) ;
65112 } ) ;
113+ } ) ;
114+
115+ test ( 'should handle API call failure' , async ( ) => {
116+ const errorMessage = 'Failed to fetch data.' ;
117+ const toastErrorSpy = vi . spyOn ( toast , 'error' ) ;
118+
119+ server . use (
120+ http . get (
121+ `${ apiEndpointUrl } /posts` ,
122+ ( ) =>
123+ new HttpResponse ( null , {
124+ status : 500 ,
125+ } ) ,
126+ ) ,
127+ ) ;
128+
129+ const queryClient = new QueryClient ( {
130+ defaultOptions : { queries : { retry : false } } , // @ https://github.com/TanStack/query/discussions/2300#discussioncomment-811768
131+ } ) ;
66132
67- // await waitFor(async () => {
68- // if (!result.isSuccess) {
69- // throw Error('wait');
70- // }
133+ render ( ( ) => < PostList /> , {
134+ wrapper : props => (
135+ < MetaProvider >
136+ < QueryClientProvider client = { queryClient } >
137+ < Router
138+ // eslint-disable-next-line @typescript-eslint/no-shadow
139+ root = { props => < > { props . children } </ > }
140+ >
141+ < Route path = "/" component = { ( ) => < > { props . children } </ > } />
142+ </ Router >
143+ </ QueryClientProvider >
144+ </ MetaProvider >
145+ ) ,
146+ } ) ;
147+
148+ const wrapper = ( props : { children : JSX . Element } ) => (
149+ < QueryClientProvider client = { queryClient } >
150+ < Router
151+ // eslint-disable-next-line @typescript-eslint/no-shadow
152+ root = { props => < > { props . children } </ > }
153+ >
154+ < Route
155+ path = "/"
156+ component = { ( ) => (
157+ < >
158+ { props . children }
159+ { /* <Toaster position="bottom-center" /> */ }
160+ </ >
161+ ) }
162+ />
163+ </ Router >
164+ </ QueryClientProvider >
165+ ) ;
166+
167+ // screen.getByRole('');
168+ const { result } = renderHook ( ( ) => useFetchPostList ( ) , {
169+ wrapper,
170+ } ) ;
171+
172+ await waitFor ( ( ) => expect ( result . isError ) . toBe ( true ) ) ;
173+
174+ await waitFor ( ( ) => {
175+ expect ( result . error ) . toEqual ( Error ( 'Failed to fetch data' ) ) ;
176+ } ) ;
177+
178+ await waitFor ( ( ) => {
179+ expect ( toastErrorSpy ) . toHaveBeenCalledWith ( errorMessage ) ;
180+ } ) ;
71181
72- // // expect(await screen.findByText(/qui est esse/)).toBeInTheDocument();
73- // expect( screen.getByText(/qui est esse/)).toBeInTheDocument();
74- // } );
182+ // expect(
183+ // await screen.findByText('Failed to fetch data.'),
184+ // ).toBeInTheDocument( );
75185 } ) ;
76186} ) ;
0 commit comments