3030from runloop_api_client .lib .polling import PollingConfig
3131
3232
33- class TestAsyncDevboxClient :
34- """Tests for AsyncDevboxClient class."""
33+ class TestAsyncDevboxOps :
34+ """Tests for AsyncDevboxOps class."""
3535
3636 @pytest .mark .asyncio
3737 async def test_create (self , mock_async_client : AsyncMock , devbox_view : MockDevboxView ) -> None :
@@ -106,8 +106,20 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
106106 assert not mock_async_client .devboxes .await_running .called
107107
108108 @pytest .mark .asyncio
109- async def test_list (self , mock_async_client : AsyncMock , devbox_view : MockDevboxView ) -> None :
110- """Test list method."""
109+ async def test_list_empty (self , mock_async_client : AsyncMock ) -> None :
110+ """Test list method with empty results."""
111+ page = SimpleNamespace (devboxes = [])
112+ mock_async_client .devboxes .list = AsyncMock (return_value = page )
113+
114+ ops = AsyncDevboxOps (mock_async_client )
115+ devboxes = await ops .list (limit = 10 , status = "running" )
116+
117+ assert len (devboxes ) == 0
118+ mock_async_client .devboxes .list .assert_called_once ()
119+
120+ @pytest .mark .asyncio
121+ async def test_list_single (self , mock_async_client : AsyncMock , devbox_view : MockDevboxView ) -> None :
122+ """Test list method with single result."""
111123 page = SimpleNamespace (devboxes = [devbox_view ])
112124 mock_async_client .devboxes .list = AsyncMock (return_value = page )
113125
@@ -123,13 +135,43 @@ async def test_list(self, mock_async_client: AsyncMock, devbox_view: MockDevboxV
123135 assert devboxes [0 ].id == "dev_123"
124136 mock_async_client .devboxes .list .assert_called_once ()
125137
138+ @pytest .mark .asyncio
139+ async def test_list_multiple (self , mock_async_client : AsyncMock ) -> None :
140+ """Test list method with multiple results."""
141+ devbox_view1 = MockDevboxView (id = "dev_001" , name = "devbox-1" )
142+ devbox_view2 = MockDevboxView (id = "dev_002" , name = "devbox-2" )
143+ page = SimpleNamespace (devboxes = [devbox_view1 , devbox_view2 ])
144+ mock_async_client .devboxes .list = AsyncMock (return_value = page )
145+
146+ ops = AsyncDevboxOps (mock_async_client )
147+ devboxes = await ops .list (limit = 10 , status = "running" )
148+
149+ assert len (devboxes ) == 2
150+ assert isinstance (devboxes [0 ], AsyncDevbox )
151+ assert isinstance (devboxes [1 ], AsyncDevbox )
152+ assert devboxes [0 ].id == "dev_001"
153+ assert devboxes [1 ].id == "dev_002"
154+ mock_async_client .devboxes .list .assert_called_once ()
155+
156+
157+ class TestAsyncSnapshotOps :
158+ """Tests for AsyncSnapshotOps class."""
159+
160+ @pytest .mark .asyncio
161+ async def test_list_empty (self , mock_async_client : AsyncMock ) -> None :
162+ """Test list method with empty results."""
163+ page = SimpleNamespace (snapshots = [])
164+ mock_async_client .devboxes .disk_snapshots .list = AsyncMock (return_value = page )
165+
166+ ops = AsyncSnapshotOps (mock_async_client )
167+ snapshots = await ops .list (devbox_id = "dev_123" , limit = 10 )
126168
127- class TestAsyncSnapshotClient :
128- """Tests for AsyncSnapshotClient class."""
169+ assert len ( snapshots ) == 0
170+ mock_async_client . devboxes . disk_snapshots . list . assert_called_once ()
129171
130172 @pytest .mark .asyncio
131- async def test_list (self , mock_async_client : AsyncMock , snapshot_view : MockSnapshotView ) -> None :
132- """Test list method."""
173+ async def test_list_single (self , mock_async_client : AsyncMock , snapshot_view : MockSnapshotView ) -> None :
174+ """Test list method with single result ."""
133175 page = SimpleNamespace (snapshots = [snapshot_view ])
134176 mock_async_client .devboxes .disk_snapshots .list = AsyncMock (return_value = page )
135177
@@ -145,6 +187,24 @@ async def test_list(self, mock_async_client: AsyncMock, snapshot_view: MockSnaps
145187 assert snapshots [0 ].id == "snap_123"
146188 mock_async_client .devboxes .disk_snapshots .list .assert_called_once ()
147189
190+ @pytest .mark .asyncio
191+ async def test_list_multiple (self , mock_async_client : AsyncMock ) -> None :
192+ """Test list method with multiple results."""
193+ snapshot_view1 = MockSnapshotView (id = "snap_001" , name = "snapshot-1" )
194+ snapshot_view2 = MockSnapshotView (id = "snap_002" , name = "snapshot-2" )
195+ page = SimpleNamespace (snapshots = [snapshot_view1 , snapshot_view2 ])
196+ mock_async_client .devboxes .disk_snapshots .list = AsyncMock (return_value = page )
197+
198+ ops = AsyncSnapshotOps (mock_async_client )
199+ snapshots = await ops .list (devbox_id = "dev_123" , limit = 10 )
200+
201+ assert len (snapshots ) == 2
202+ assert isinstance (snapshots [0 ], AsyncSnapshot )
203+ assert isinstance (snapshots [1 ], AsyncSnapshot )
204+ assert snapshots [0 ].id == "snap_001"
205+ assert snapshots [1 ].id == "snap_002"
206+ mock_async_client .devboxes .disk_snapshots .list .assert_called_once ()
207+
148208 def test_from_id (self , mock_async_client : AsyncMock ) -> None :
149209 """Test from_id method."""
150210 ops = AsyncSnapshotOps (mock_async_client )
@@ -154,8 +214,8 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
154214 assert snapshot .id == "snap_123"
155215
156216
157- class TestAsyncBlueprintClient :
158- """Tests for AsyncBlueprintClient class."""
217+ class TestAsyncBlueprintOps :
218+ """Tests for AsyncBlueprintOps class."""
159219
160220 @pytest .mark .asyncio
161221 async def test_create (self , mock_async_client : AsyncMock , blueprint_view : MockBlueprintView ) -> None :
@@ -181,8 +241,20 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
181241 assert blueprint .id == "bp_123"
182242
183243 @pytest .mark .asyncio
184- async def test_list (self , mock_async_client : AsyncMock , blueprint_view : MockBlueprintView ) -> None :
185- """Test list method."""
244+ async def test_list_empty (self , mock_async_client : AsyncMock ) -> None :
245+ """Test list method with empty results."""
246+ page = SimpleNamespace (blueprints = [])
247+ mock_async_client .blueprints .list = AsyncMock (return_value = page )
248+
249+ ops = AsyncBlueprintOps (mock_async_client )
250+ blueprints = await ops .list (limit = 10 )
251+
252+ assert len (blueprints ) == 0
253+ mock_async_client .blueprints .list .assert_called_once ()
254+
255+ @pytest .mark .asyncio
256+ async def test_list_single (self , mock_async_client : AsyncMock , blueprint_view : MockBlueprintView ) -> None :
257+ """Test list method with single result."""
186258 page = SimpleNamespace (blueprints = [blueprint_view ])
187259 mock_async_client .blueprints .list = AsyncMock (return_value = page )
188260
@@ -198,9 +270,27 @@ async def test_list(self, mock_async_client: AsyncMock, blueprint_view: MockBlue
198270 assert blueprints [0 ].id == "bp_123"
199271 mock_async_client .blueprints .list .assert_called_once ()
200272
273+ @pytest .mark .asyncio
274+ async def test_list_multiple (self , mock_async_client : AsyncMock ) -> None :
275+ """Test list method with multiple results."""
276+ blueprint_view1 = MockBlueprintView (id = "bp_001" , name = "blueprint-1" )
277+ blueprint_view2 = MockBlueprintView (id = "bp_002" , name = "blueprint-2" )
278+ page = SimpleNamespace (blueprints = [blueprint_view1 , blueprint_view2 ])
279+ mock_async_client .blueprints .list = AsyncMock (return_value = page )
201280
202- class TestAsyncStorageObjectClient :
203- """Tests for AsyncStorageObjectClient class."""
281+ ops = AsyncBlueprintOps (mock_async_client )
282+ blueprints = await ops .list (limit = 10 )
283+
284+ assert len (blueprints ) == 2
285+ assert isinstance (blueprints [0 ], AsyncBlueprint )
286+ assert isinstance (blueprints [1 ], AsyncBlueprint )
287+ assert blueprints [0 ].id == "bp_001"
288+ assert blueprints [1 ].id == "bp_002"
289+ mock_async_client .blueprints .list .assert_called_once ()
290+
291+
292+ class TestAsyncStorageObjectOps :
293+ """Tests for AsyncStorageObjectOps class."""
204294
205295 @pytest .mark .asyncio
206296 async def test_create (self , mock_async_client : AsyncMock , object_view : MockObjectView ) -> None :
@@ -229,8 +319,20 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
229319 assert obj .upload_url is None
230320
231321 @pytest .mark .asyncio
232- async def test_list (self , mock_async_client : AsyncMock , object_view : MockObjectView ) -> None :
233- """Test list method."""
322+ async def test_list_empty (self , mock_async_client : AsyncMock ) -> None :
323+ """Test list method with empty results."""
324+ page = SimpleNamespace (objects = [])
325+ mock_async_client .objects .list = AsyncMock (return_value = page )
326+
327+ ops = AsyncStorageObjectOps (mock_async_client )
328+ objects = await ops .list (limit = 10 )
329+
330+ assert len (objects ) == 0
331+ mock_async_client .objects .list .assert_called_once ()
332+
333+ @pytest .mark .asyncio
334+ async def test_list_single (self , mock_async_client : AsyncMock , object_view : MockObjectView ) -> None :
335+ """Test list method with single result."""
234336 page = SimpleNamespace (objects = [object_view ])
235337 mock_async_client .objects .list = AsyncMock (return_value = page )
236338
@@ -256,6 +358,24 @@ async def test_list(self, mock_async_client: AsyncMock, object_view: MockObjectV
256358 state = "READ_ONLY" ,
257359 )
258360
361+ @pytest .mark .asyncio
362+ async def test_list_multiple (self , mock_async_client : AsyncMock ) -> None :
363+ """Test list method with multiple results."""
364+ object_view1 = MockObjectView (id = "obj_001" , name = "object-1" )
365+ object_view2 = MockObjectView (id = "obj_002" , name = "object-2" )
366+ page = SimpleNamespace (objects = [object_view1 , object_view2 ])
367+ mock_async_client .objects .list = AsyncMock (return_value = page )
368+
369+ ops = AsyncStorageObjectOps (mock_async_client )
370+ objects = await ops .list (limit = 10 )
371+
372+ assert len (objects ) == 2
373+ assert isinstance (objects [0 ], AsyncStorageObject )
374+ assert isinstance (objects [1 ], AsyncStorageObject )
375+ assert objects [0 ].id == "obj_001"
376+ assert objects [1 ].id == "obj_002"
377+ mock_async_client .objects .list .assert_called_once ()
378+
259379 @pytest .mark .asyncio
260380 async def test_upload_from_file (
261381 self , mock_async_client : AsyncMock , object_view : MockObjectView , tmp_path : Path
@@ -517,8 +637,8 @@ async def test_upload_from_dir_with_string_path(
517637 mock_async_client .objects .complete .assert_awaited_once ()
518638
519639
520- class TestAsyncScorerClient :
521- """Tests for AsyncScorerClient class."""
640+ class TestAsyncScorerOps :
641+ """Tests for AsyncScorerOps class."""
522642
523643 @pytest .mark .asyncio
524644 async def test_create (self , mock_async_client : AsyncMock , scorer_view : MockScorerView ) -> None :
@@ -544,8 +664,24 @@ def test_from_id(self, mock_async_client: AsyncMock) -> None:
544664 assert scorer .id == "scorer_123"
545665
546666 @pytest .mark .asyncio
547- async def test_list (self , mock_async_client : AsyncMock , scorer_view : MockScorerView ) -> None :
548- """Test list method."""
667+ async def test_list_empty (self , mock_async_client : AsyncMock ) -> None :
668+ """Test list method with empty results."""
669+
670+ async def async_iter ():
671+ return
672+ yield # Make this a generator
673+
674+ mock_async_client .scenarios .scorers .list = AsyncMock (return_value = async_iter ())
675+
676+ ops = AsyncScorerOps (mock_async_client )
677+ scorers = await ops .list (limit = 10 )
678+
679+ assert len (scorers ) == 0
680+ mock_async_client .scenarios .scorers .list .assert_called_once ()
681+
682+ @pytest .mark .asyncio
683+ async def test_list_single (self , mock_async_client : AsyncMock , scorer_view : MockScorerView ) -> None :
684+ """Test list method with single result."""
549685
550686 async def async_iter ():
551687 yield scorer_view
@@ -563,6 +699,28 @@ async def async_iter():
563699 assert scorers [0 ].id == "scorer_123"
564700 mock_async_client .scenarios .scorers .list .assert_called_once ()
565701
702+ @pytest .mark .asyncio
703+ async def test_list_multiple (self , mock_async_client : AsyncMock ) -> None :
704+ """Test list method with multiple results."""
705+ scorer_view1 = MockScorerView (id = "scorer_001" , type = "scorer-1" )
706+ scorer_view2 = MockScorerView (id = "scorer_002" , type = "scorer-2" )
707+
708+ async def async_iter ():
709+ yield scorer_view1
710+ yield scorer_view2
711+
712+ mock_async_client .scenarios .scorers .list = AsyncMock (return_value = async_iter ())
713+
714+ ops = AsyncScorerOps (mock_async_client )
715+ scorers = await ops .list (limit = 10 )
716+
717+ assert len (scorers ) == 2
718+ assert isinstance (scorers [0 ], AsyncScorer )
719+ assert isinstance (scorers [1 ], AsyncScorer )
720+ assert scorers [0 ].id == "scorer_001"
721+ assert scorers [1 ].id == "scorer_002"
722+ mock_async_client .scenarios .scorers .list .assert_called_once ()
723+
566724
567725class TestAsyncRunloopSDK :
568726 """Tests for AsyncRunloopSDK class."""
0 commit comments