@@ -81,3 +81,50 @@ async def test_get_default_user_id(self) -> None:
8181
8282 # Verify API call
8383 client .get .assert_called_once_with ("users/mine" )
84+
85+ @pytest .mark .asyncio
86+ async def test_process_bulk_async_preserves_input_order (self ) -> None :
87+ """Gather results stay in input order even when later items finish first."""
88+ import asyncio
89+
90+ client = MockAsyncHTTPClient ()
91+ ops = AsyncBaseOperations (client )
92+
93+ # Delays inverted so item 0 finishes last, item 2 finishes first.
94+ delays = {0 : 0.05 , 1 : 0.02 , 2 : 0.01 }
95+
96+ async def create_func (item_data : dict ) -> str :
97+ await asyncio .sleep (delays [item_data ["index" ]])
98+ return f"created-{ item_data ['index' ]} "
99+
100+ items = [{"index" : i , "title" : f"item-{ i } " } for i in range (3 )]
101+ result = await ops ._process_bulk_async (
102+ items , create_func , required_fields = ["title" ], max_concurrent = 3
103+ )
104+
105+ assert result .failed == []
106+ assert result .successful == ["created-0" , "created-1" , "created-2" ]
107+
108+ @pytest .mark .asyncio
109+ async def test_process_bulk_async_failure_index_matches_input (self ) -> None :
110+ """Failed items keep the original input index without post-sort."""
111+ import asyncio
112+
113+ client = MockAsyncHTTPClient ()
114+ ops = AsyncBaseOperations (client )
115+
116+ async def create_func (item_data : dict ) -> str :
117+ await asyncio .sleep (0.01 if item_data ["index" ] != 0 else 0.03 )
118+ if item_data ["index" ] == 1 :
119+ raise ValueError ("boom" )
120+ return f"created-{ item_data ['index' ]} "
121+
122+ items = [{"index" : i , "title" : f"item-{ i } " } for i in range (3 )]
123+ result = await ops ._process_bulk_async (
124+ items , create_func , required_fields = ["title" ], max_concurrent = 3
125+ )
126+
127+ assert result .successful == ["created-0" , "created-2" ]
128+ assert len (result .failed ) == 1
129+ assert result .failed [0 ].index == 1
130+ assert "boom" in result .failed [0 ].error
0 commit comments