@@ -17,8 +17,84 @@ describe("RequestManager", () => {
1717 baseRetryDelay : 50 ,
1818 maxConcurrent : 2
1919 } ) ;
20+ } ) ;
21+ describe ( "failure handling and cleanup" , ( ) => {
22+
23+ it ( "should reject the promise if request never responds" , async ( ) => {
24+ jest . useFakeTimers ( ) ;
25+
26+ const neverResolvingRequest = jest . fn ( ( ) => {
27+ // intentionally never calls callback
2028 } ) ;
2129
30+ const promise = requestManager . throttledRequest (
31+ { action : "hang-test" } ,
32+ neverResolvingRequest
33+ ) ;
34+
35+ // Fast-forward time beyond expected timeout (30s or configured)
36+ jest . advanceTimersByTime ( 60000 ) ;
37+ await Promise . resolve ( ) ;
38+
39+
40+ await expect ( promise ) . rejects . toBeDefined ( ) ;
41+
42+ jest . useRealTimers ( ) ;
43+ } ) ;
44+
45+ it ( "should clean up pendingRequests after timeout failure" , async ( ) => {
46+ jest . useFakeTimers ( ) ;
47+
48+ const neverResolvingRequest = jest . fn ( ( ) => { } ) ;
49+
50+ const promise = requestManager . throttledRequest (
51+ { action : "cleanup-test" } ,
52+ neverResolvingRequest
53+ ) ;
54+
55+ // Request should be pending initially
56+ expect ( requestManager . pendingRequests . size ) . toBe ( 1 ) ;
57+
58+ jest . advanceTimersByTime ( 60000 ) ;
59+ await Promise . resolve ( ) ;
60+
61+
62+ await promise . catch ( ( ) => { } ) ;
63+
64+ expect ( requestManager . pendingRequests . size ) . toBe ( 0 ) ;
65+
66+ jest . useRealTimers ( ) ;
67+ } ) ;
68+
69+ it ( "should allow new requests after a failed request" , async ( ) => {
70+ jest . useFakeTimers ( ) ;
71+
72+ const neverResolvingRequest = jest . fn ( ( ) => { } ) ;
73+ const successRequest = jest . fn ( cb => cb ( { success : true } ) ) ;
74+
75+ const failed = requestManager . throttledRequest (
76+ { action : "fail-first" } ,
77+ neverResolvingRequest
78+ ) ;
79+
80+ jest . advanceTimersByTime ( 60000 ) ;
81+ await Promise . resolve ( ) ;
82+
83+ await failed . catch ( ( ) => { } ) ;
84+
85+ const result = await requestManager . throttledRequest (
86+ { action : "next" } ,
87+ successRequest
88+ ) ;
89+
90+ expect ( result . success ) . toBe ( true ) ;
91+
92+ jest . useRealTimers ( ) ;
93+
94+ } ) ;
95+
96+ } ) ;
97+
2298 afterEach ( ( ) => {
2399 requestManager . clearPending ( ) ;
24100 } ) ;
0 commit comments