@@ -40,6 +40,7 @@ const createWrapper = (queryClient?: QueryClient) => {
4040 defaultOptions : {
4141 queries : {
4242 retry : false ,
43+ retryDelay : 0 ,
4344 gcTime : 0 ,
4445 } ,
4546 mutations : {
@@ -96,12 +97,14 @@ describe('queryHooks', () => {
9697 throw new Error ( 'Function not implemented.' ) ;
9798 } ,
9899 } ) ;
99- ( api . initializeList as jest . Mock ) . mockRejectedValue ( new Error ( 'API Error' ) ) ;
100+ const error : any = new Error ( 'API Error' ) ;
101+ error . response = { status : 403 } ;
102+ ( api . initializeList as jest . Mock ) . mockRejectedValue ( error ) ;
100103
101104 // Don't use gcTime: 0 here — we need the seeded cache entry to persist
102105 // for the fallback lookup via queryClient.getQueryData()
103106 const queryClient = new QueryClient ( {
104- defaultOptions : { queries : { retry : false } , mutations : { retry : false } } ,
107+ defaultOptions : { queries : { retry : false , retryDelay : 0 } , mutations : { retry : false } } ,
105108 } ) ;
106109 queryClient . setQueryData (
107110 learnerDashboardQueryKeys . initialize ( undefined ) ,
@@ -120,6 +123,48 @@ describe('queryHooks', () => {
120123 expect ( result . current . data ) . toEqual ( mockNormalUserData ) ;
121124 } ) ;
122125
126+ it ( 'should not retry on 4xx errors' , async ( ) => {
127+ mockUseMasquerade . mockReturnValue ( {
128+ masqueradeUser : null ,
129+ setMasqueradeUser ( ) : void { throw new Error ( 'Function not implemented.' ) ; } ,
130+ } ) ;
131+ const error : any = new Error ( 'Forbidden' ) ;
132+ error . response = { status : 403 } ;
133+ ( api . initializeList as jest . Mock ) . mockRejectedValue ( error ) ;
134+
135+ const { result } = renderHook ( ( ) => useInitializeLearnerHome ( ) , {
136+ wrapper : createWrapper ( ) ,
137+ } ) ;
138+
139+ await waitFor ( ( ) => {
140+ expect ( result . current . isError ) . toBe ( true ) ;
141+ } ) ;
142+
143+ // 4xx errors should not be retried — only 1 call
144+ expect ( api . initializeList ) . toHaveBeenCalledTimes ( 1 ) ;
145+ } ) ;
146+
147+ it ( 'should retry on 5xx errors up to 3 times' , async ( ) => {
148+ mockUseMasquerade . mockReturnValue ( {
149+ masqueradeUser : null ,
150+ setMasqueradeUser ( ) : void { throw new Error ( 'Function not implemented.' ) ; } ,
151+ } ) ;
152+ const error : any = new Error ( 'Server Error' ) ;
153+ error . response = { status : 500 } ;
154+ ( api . initializeList as jest . Mock ) . mockRejectedValue ( error ) ;
155+
156+ const { result } = renderHook ( ( ) => useInitializeLearnerHome ( ) , {
157+ wrapper : createWrapper ( ) ,
158+ } ) ;
159+
160+ await waitFor ( ( ) => {
161+ expect ( result . current . isError ) . toBe ( true ) ;
162+ } ) ;
163+
164+ // 1 initial + 3 retries = 4 total calls
165+ expect ( api . initializeList ) . toHaveBeenCalledTimes ( 4 ) ;
166+ } ) ;
167+
123168 it ( 'should have correct query configuration for masquerading' , async ( ) => {
124169 const masqueradeUser = 'test-user' ;
125170 mockUseMasquerade . mockReturnValue ( {
0 commit comments