11import json
2+ import sys
23from datetime import datetime , timezone
34from types import SimpleNamespace
45from typing import Any
@@ -33,6 +34,17 @@ def test_format_tunnel_does_not_derive_created_from_expiration() -> None:
3334 assert tunnel_data ["expires_at" ] is not None
3435
3536
37+ def test_tunnel_start_import_failure_exits_cleanly (monkeypatch : pytest .MonkeyPatch ) -> None :
38+ monkeypatch .setenv ("PRIME_DISABLE_VERSION_CHECK" , "1" )
39+ monkeypatch .setitem (sys .modules , "prime_tunnel" , None )
40+
41+ result = runner .invoke (app , ["tunnel" , "start" ])
42+
43+ assert result .exit_code == 1
44+ assert "Error:" in result .output
45+ assert "Traceback" not in result .output
46+
47+
3648def test_tunnel_list_passes_label_filters (monkeypatch : pytest .MonkeyPatch ) -> None :
3749 monkeypatch .setenv ("PRIME_DISABLE_VERSION_CHECK" , "1" )
3850 captured : dict [str , Any ] = {}
@@ -65,7 +77,7 @@ async def list_tunnels_page(self, **kwargs: Any) -> Any:
6577 async def close (self ) -> None :
6678 return None
6779
68- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
80+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
6981
7082 result = runner .invoke (
7183 app ,
@@ -89,7 +101,7 @@ async def list_tunnels_page(self, **kwargs: Any) -> Any:
89101 async def close (self ) -> None :
90102 return None
91103
92- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
104+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
93105
94106 result = runner .invoke (app , ["tunnel" , "list" , "--output" , "json" ])
95107
@@ -117,7 +129,7 @@ async def bulk_delete_tunnels(self, **kwargs: Any) -> dict[str, Any]:
117129 async def close (self ) -> None :
118130 return None
119131
120- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
132+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
121133
122134 result = runner .invoke (app , ["tunnel" , "stop" , "--label" , "dev" , "--yes" ])
123135
@@ -141,7 +153,7 @@ async def bulk_delete_tunnels(self, **kwargs: Any) -> dict[str, Any]:
141153 async def close (self ) -> None :
142154 return None
143155
144- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
156+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
145157
146158 # No --yes: if the scope check ran after the prompt we'd see the confirmation
147159 # text; instead it must fail fast with a clean error and never prompt.
@@ -179,7 +191,7 @@ async def bulk_delete_tunnels(self, tunnel_ids: list[str]) -> dict[str, Any]:
179191 async def close (self ) -> None :
180192 return None
181193
182- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
194+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
183195
184196 result = runner .invoke (app , ["tunnel" , "stop" , "--all" , "--yes" ])
185197
@@ -216,7 +228,7 @@ async def bulk_delete_tunnels(self, tunnel_ids: list[str]) -> dict[str, Any]:
216228 async def close (self ) -> None :
217229 return None
218230
219- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
231+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
220232
221233 result = runner .invoke (app , ["tunnel" , "stop" , "--all" , "--all-users" , "--yes" ])
222234
@@ -252,7 +264,7 @@ async def bulk_delete_tunnels(self, tunnel_ids: list[str]) -> dict[str, Any]:
252264 async def close (self ) -> None :
253265 return None
254266
255- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
267+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
256268
257269 result = runner .invoke (app , ["tunnel" , "stop" , "--all" , "--yes" ])
258270
@@ -278,7 +290,7 @@ async def bulk_delete_tunnels(self, tunnel_ids: list[str]) -> dict[str, Any]:
278290 async def close (self ) -> None :
279291 return None
280292
281- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
293+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
282294
283295 result = runner .invoke (app , ["tunnel" , "stop" , "--all" , "--yes" ])
284296
@@ -301,7 +313,7 @@ async def bulk_delete_tunnels(self, **kwargs: Any) -> dict[str, Any]:
301313 async def close (self ) -> None :
302314 return None
303315
304- monkeypatch .setattr ("prime_cli.commands.tunnel.TunnelClient " , FakeTunnelClient )
316+ monkeypatch .setattr ("prime_cli.commands.tunnel._create_tunnel_client " , FakeTunnelClient )
305317
306318 result = runner .invoke (app , ["tunnel" , "stop" , "--all" , "--yes" ])
307319
0 commit comments