@@ -141,17 +141,17 @@ describe("fetch utilities", () => {
141141
142142 describeNetwork ( "fetchWithTimeout" , ( ) => {
143143 it ( "successfully fetches when request completes before timeout" , async ( ) => {
144- // Use a real endpoint that responds quickly
145- const response = await fetchWithTimeout ( "https://httpbin.org/get " , {
144+ // Use jsonplaceholder - reliable and fast
145+ const response = await fetchWithTimeout ( "https://jsonplaceholder.typicode.com/posts/1 " , {
146146 timeoutMs : 10000 ,
147147 } ) ;
148148 expect ( response . ok ) . toBe ( true ) ;
149149 } ) ;
150150
151151 it ( "throws FetchTimeoutError when request exceeds timeout" , async ( ) => {
152- // Use a delay endpoint with very short timeout
152+ // Use an unreachable IP to trigger timeout (10.255.255.1 is non-routable)
153153 try {
154- await fetchWithTimeout ( "https ://httpbin.org/delay/5 " , {
154+ await fetchWithTimeout ( "http ://10.255.255.1:12345/ " , {
155155 timeoutMs : 100 ,
156156 } ) ;
157157 expect . unreachable ( "Should have thrown FetchTimeoutError" ) ;
@@ -170,21 +170,22 @@ describe("fetch utilities", () => {
170170
171171 describeNetwork ( "fetchWithRetry" , ( ) => {
172172 it ( "succeeds on first attempt for successful requests" , async ( ) => {
173- const response = await fetchWithRetry ( "https://httpbin.org/get " , {
173+ const response = await fetchWithRetry ( "https://jsonplaceholder.typicode.com/posts/1 " , {
174174 retry : { maxRetries : 3 } ,
175175 } ) ;
176176 expect ( response . ok ) . toBe ( true ) ;
177177 } ) ;
178178
179179 it ( "returns response for non-retryable 4xx errors without retrying" , async ( ) => {
180- const response = await fetchWithRetry ( "https://httpbin.org/status/404" , {
180+ // jsonplaceholder returns 404 for non-existent posts
181+ const response = await fetchWithRetry ( "https://jsonplaceholder.typicode.com/posts/99999999" , {
181182 retry : { maxRetries : 3 } ,
182183 } ) ;
183184 expect ( response . status ) . toBe ( 404 ) ;
184185 } ) ;
185186
186187 it ( "can disable retries with retry: false" , async ( ) => {
187- const response = await fetchWithRetry ( "https://httpbin.org/get " , {
188+ const response = await fetchWithRetry ( "https://jsonplaceholder.typicode.com/posts/1 " , {
188189 retry : false ,
189190 } ) ;
190191 expect ( response . ok ) . toBe ( true ) ;
@@ -202,41 +203,30 @@ describe("fetch utilities", () => {
202203
203204 describeNetwork ( "resilientFetch" , ( ) => {
204205 it ( "successfully fetches with both timeout and retry protection" , async ( ) => {
205- const response = await resilientFetch ( "https://httpbin.org/get " , {
206+ const response = await resilientFetch ( "https://jsonplaceholder.typicode.com/posts/1 " , {
206207 timeoutMs : 10000 ,
207208 retry : { maxRetries : 2 } ,
208209 } ) ;
209210 expect ( response . ok ) . toBe ( true ) ;
210211 } ) ;
211212
212- it ( "includes custom headers in request" , async ( ) => {
213- const response = await resilientFetch ( "https://httpbin.org/headers" , {
214- headers : {
215- "X-Custom-Header" : "test-value" ,
216- "User-Agent" : "test-agent/1.0" ,
217- } ,
218- } ) ;
219- expect ( response . ok ) . toBe ( true ) ;
220- const data = await response . json ( ) ;
221- expect ( data . headers [ "X-Custom-Header" ] ) . toBe ( "test-value" ) ;
222- } ) ;
223-
224213 it ( "handles 404 response (non-retryable)" , async ( ) => {
225- const response = await resilientFetch ( "https://httpbin.org/status/404 " ) ;
214+ const response = await resilientFetch ( "https://jsonplaceholder.typicode.com/posts/99999999 " ) ;
226215 expect ( response . status ) . toBe ( 404 ) ;
227216 expect ( response . ok ) . toBe ( false ) ;
228217 } ) ;
229218
230219 it ( "can disable retries with retry: false" , async ( ) => {
231- const response = await resilientFetch ( "https://httpbin.org/get " , {
220+ const response = await resilientFetch ( "https://jsonplaceholder.typicode.com/posts/1 " , {
232221 retry : false ,
233222 } ) ;
234223 expect ( response . ok ) . toBe ( true ) ;
235224 } ) ;
236225
237226 it ( "throws FetchTimeoutError on timeout" , async ( ) => {
238227 try {
239- await resilientFetch ( "https://httpbin.org/delay/5" , {
228+ // Use unreachable IP to trigger timeout
229+ await resilientFetch ( "http://10.255.255.1:12345/" , {
240230 timeoutMs : 100 ,
241231 retry : false , // Disable retries to speed up test
242232 } ) ;
@@ -248,7 +238,8 @@ describe("fetch utilities", () => {
248238
249239 it ( "throws FetchRetryError after exhausting retries on timeout" , async ( ) => {
250240 try {
251- await resilientFetch ( "https://httpbin.org/delay/5" , {
241+ // Use unreachable IP to trigger timeout
242+ await resilientFetch ( "http://10.255.255.1:12345/" , {
252243 timeoutMs : 100 ,
253244 retry : { maxRetries : 1 , initialDelayMs : 50 } ,
254245 } ) ;
@@ -280,14 +271,15 @@ describe("fetch utilities", () => {
280271 } ) ;
281272
282273 it ( "handles JSON response" , async ( ) => {
283- const response = await resilientFetch ( "https://httpbin.org/json " , {
274+ const response = await resilientFetch ( "https://jsonplaceholder.typicode.com/posts/1 " , {
284275 headers : {
285276 Accept : "application/json" ,
286277 } ,
287278 } ) ;
288279 expect ( response . ok ) . toBe ( true ) ;
289280 const data = await response . json ( ) ;
290281 expect ( data ) . toBeDefined ( ) ;
282+ expect ( data . id ) . toBe ( 1 ) ;
291283 } ) ;
292284 } ) ;
293285} ) ;
0 commit comments