impreza-cli 0.6.0__tar.gz → 0.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/PKG-INFO +21 -11
  2. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/README.md +19 -9
  3. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/context.py +18 -0
  4. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/config.py +6 -0
  5. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/main.py +10 -1
  6. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/sdk.py +6 -3
  7. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/state.py +5 -0
  8. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli.egg-info/PKG-INFO +21 -11
  9. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli.egg-info/requires.txt +1 -1
  10. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/pyproject.toml +1 -1
  11. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_context_commands.py +116 -0
  12. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/__init__.py +0 -0
  13. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/__init__.py +0 -0
  14. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/_helpers.py +0 -0
  15. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/account.py +0 -0
  16. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/catalog.py +0 -0
  17. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/config.py +0 -0
  18. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/dedicated.py +0 -0
  19. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/doctor.py +0 -0
  20. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/domain.py +0 -0
  21. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/invoice.py +0 -0
  22. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/key.py +0 -0
  23. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/orders.py +0 -0
  24. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/services.py +0 -0
  25. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/vps.py +0 -0
  26. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/vps_cloud.py +0 -0
  27. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/vps_proxmox.py +0 -0
  28. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/commands/webhooks.py +0 -0
  29. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli/output.py +0 -0
  30. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli.egg-info/SOURCES.txt +0 -0
  31. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli.egg-info/dependency_links.txt +0 -0
  32. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli.egg-info/entry_points.txt +0 -0
  33. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/impreza_cli.egg-info/top_level.txt +0 -0
  34. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/setup.cfg +0 -0
  35. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/.gitkeep +0 -0
  36. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/__init__.py +0 -0
  37. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/conftest.py +0 -0
  38. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_account_commands.py +0 -0
  39. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_account_topup_commands.py +0 -0
  40. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_catalog_commands.py +0 -0
  41. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_config.py +0 -0
  42. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_config_commands.py +0 -0
  43. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_dedicated_commands.py +0 -0
  44. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_doctor_commands.py +0 -0
  45. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_domain_commands.py +0 -0
  46. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_invoice_commands.py +0 -0
  47. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_key_commands.py +0 -0
  48. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_orders_commands.py +0 -0
  49. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_2_2_smoke.py +0 -0
  50. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_2_3_smoke.py +0 -0
  51. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_2_4_smoke.py +0 -0
  52. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_2_5_smoke.py +0 -0
  53. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_2_6_smoke.py +0 -0
  54. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_3_1_smoke.py +0 -0
  55. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_3_2_smoke.py +0 -0
  56. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_3_3_smoke.py +0 -0
  57. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_3_4_smoke.py +0 -0
  58. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_3_5_smoke.py +0 -0
  59. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_3_6_smoke.py +0 -0
  60. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_phase_3_7_smoke.py +0 -0
  61. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_services_commands.py +0 -0
  62. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_vps_cloud_commands.py +0 -0
  63. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_vps_commands.py +0 -0
  64. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_vps_proxmox_commands.py +0 -0
  65. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_webhooks_commands.py +0 -0
  66. {impreza_cli-0.6.0 → impreza_cli-0.7.0}/tests/test_yaml_output.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: impreza-cli
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Official command-line interface for the Impreza Host public REST API
5
5
  Author-email: Impreza Host <support@imprezahost.com>
6
6
  License: MIT
@@ -23,7 +23,7 @@ Classifier: Topic :: Internet :: WWW/HTTP
23
23
  Classifier: Topic :: Utilities
24
24
  Requires-Python: >=3.10
25
25
  Description-Content-Type: text/markdown
26
- Requires-Dist: impreza-sdk<0.7,>=0.6.0
26
+ Requires-Dist: impreza-sdk<0.8,>=0.7.0
27
27
  Requires-Dist: typer>=0.12
28
28
  Requires-Dist: rich>=13.7
29
29
  Requires-Dist: click>=8.0
@@ -227,23 +227,33 @@ equivalent) and `impreza <TAB>` should suggest resource groups,
227
227
 
228
228
  ## Tor
229
229
 
230
- Inherited from the SDK. Three knobs:
230
+ Four knobs, from the most persistent to the most one-off:
231
231
 
232
232
  ```bash
233
- # Per-context override at create time
234
- impreza context create offshore \
235
- --key imp_... --secret ... \
236
- # No --proxy flag yet; for now, set IMPREZA_USE_TOR before invoking
233
+ # Persisted at context creation (writes [settings] use_tor=true)
234
+ impreza context create offshore --key imp_... --secret ... --via-tor
235
+
236
+ # Explicit SOCKS5 proxy instead (wins over use_tor; works for any
237
+ # SOCKS5, not just Tor)
238
+ impreza context create offshore --key imp_... --secret ... --proxy socks5://127.0.0.1:9050
239
+
240
+ # One-shot global flag on any command
241
+ impreza --via-tor account info
237
242
 
238
243
  # Env var, picked up by the SDK transparently
239
244
  IMPREZA_USE_TOR=1 impreza account info
240
-
241
- # Programmatic via the SDK (Python users skip the CLI for this)
242
245
  ```
243
246
 
247
+ All four route through the local Tor daemon's SOCKS5 port with remote
248
+ DNS (no local lookup of the API hostname). Because exit nodes rotate,
249
+ set the API key's IP factor to `tofu` or `keyonly` in the client area —
250
+ `whitelist` cannot work without a stable egress IP. When the account
251
+ uses the API's `.onion` mirror, the IP factor sees a stable loopback
252
+ instead.
253
+
244
254
  The SDK's `auto_tor=True` path (probe Tor, fall back to clearnet)
245
- isn't surfaced through the CLI yet — coming in a future release
246
- alongside the `--via-tor` shortcut.
255
+ isn't surfaced through the CLI yet — it is a fail-open convenience,
256
+ which is the wrong default here.
247
257
 
248
258
  ## Error handling
249
259
 
@@ -185,23 +185,33 @@ equivalent) and `impreza <TAB>` should suggest resource groups,
185
185
 
186
186
  ## Tor
187
187
 
188
- Inherited from the SDK. Three knobs:
188
+ Four knobs, from the most persistent to the most one-off:
189
189
 
190
190
  ```bash
191
- # Per-context override at create time
192
- impreza context create offshore \
193
- --key imp_... --secret ... \
194
- # No --proxy flag yet; for now, set IMPREZA_USE_TOR before invoking
191
+ # Persisted at context creation (writes [settings] use_tor=true)
192
+ impreza context create offshore --key imp_... --secret ... --via-tor
193
+
194
+ # Explicit SOCKS5 proxy instead (wins over use_tor; works for any
195
+ # SOCKS5, not just Tor)
196
+ impreza context create offshore --key imp_... --secret ... --proxy socks5://127.0.0.1:9050
197
+
198
+ # One-shot global flag on any command
199
+ impreza --via-tor account info
195
200
 
196
201
  # Env var, picked up by the SDK transparently
197
202
  IMPREZA_USE_TOR=1 impreza account info
198
-
199
- # Programmatic via the SDK (Python users skip the CLI for this)
200
203
  ```
201
204
 
205
+ All four route through the local Tor daemon's SOCKS5 port with remote
206
+ DNS (no local lookup of the API hostname). Because exit nodes rotate,
207
+ set the API key's IP factor to `tofu` or `keyonly` in the client area —
208
+ `whitelist` cannot work without a stable egress IP. When the account
209
+ uses the API's `.onion` mirror, the IP factor sees a stable loopback
210
+ instead.
211
+
202
212
  The SDK's `auto_tor=True` path (probe Tor, fall back to clearnet)
203
- isn't surfaced through the CLI yet — coming in a future release
204
- alongside the `--via-tor` shortcut.
213
+ isn't surfaced through the CLI yet — it is a fail-open convenience,
214
+ which is the wrong default here.
205
215
 
206
216
  ## Error handling
207
217
 
@@ -88,6 +88,18 @@ def create(
88
88
  help="Optional default output format for this context.",
89
89
  case_sensitive=False,
90
90
  ),
91
+ via_tor: bool = typer.Option(
92
+ False,
93
+ "--via-tor",
94
+ help="Route API calls through the local Tor daemon "
95
+ "(sets [settings] use_tor=true, CLI-wide).",
96
+ ),
97
+ proxy: str | None = typer.Option(
98
+ None,
99
+ "--proxy",
100
+ help="Explicit SOCKS5 proxy, e.g. socks5://127.0.0.1:9050 "
101
+ "(sets [settings] proxy, CLI-wide; wins over use_tor).",
102
+ ),
91
103
  overwrite: bool = typer.Option(
92
104
  False,
93
105
  "--overwrite",
@@ -108,6 +120,12 @@ def create(
108
120
  )
109
121
  except (ContextAlreadyExists, InvalidContextName) as exc:
110
122
  _exit_on_config_error(exc)
123
+
124
+ if via_tor or proxy:
125
+ if via_tor:
126
+ cfg.settings.use_tor = True
127
+ if proxy:
128
+ cfg.settings.proxy = proxy
111
129
  cfg.save()
112
130
 
113
131
  is_default = cfg.default_context == name
@@ -167,6 +167,7 @@ class _Settings:
167
167
 
168
168
  poll_interval: float | None = None
169
169
  use_tor: bool | None = None
170
+ proxy: str | None = None
170
171
 
171
172
  def to_toml_dict(self) -> dict[str, Any]:
172
173
  body: dict[str, Any] = {}
@@ -174,6 +175,8 @@ class _Settings:
174
175
  body["poll_interval"] = self.poll_interval
175
176
  if self.use_tor is not None:
176
177
  body["use_tor"] = self.use_tor
178
+ if self.proxy is not None:
179
+ body["proxy"] = self.proxy
177
180
  return body
178
181
 
179
182
 
@@ -267,6 +270,9 @@ class Config:
267
270
  tor = settings_raw.get("use_tor")
268
271
  if isinstance(tor, bool):
269
272
  settings.use_tor = tor
273
+ proxy = settings_raw.get("proxy")
274
+ if isinstance(proxy, str) and proxy:
275
+ settings.proxy = proxy
270
276
 
271
277
  default_context = raw.get("default_context")
272
278
  if not isinstance(default_context, str):
@@ -62,6 +62,15 @@ def _root(
62
62
  "-c",
63
63
  help="Override the default context for this invocation.",
64
64
  ),
65
+ via_tor: bool = typer.Option(
66
+ False,
67
+ "--via-tor",
68
+ help=(
69
+ "Route this invocation through the local Tor daemon "
70
+ "(SOCKS5 127.0.0.1:9050). Overrides [settings] use_tor once; "
71
+ "persist it with `impreza context create --via-tor`."
72
+ ),
73
+ ),
65
74
  output: OutputFormat | None = typer.Option(
66
75
  None,
67
76
  "--output",
@@ -78,7 +87,7 @@ def _root(
78
87
  Global flags ``--context`` and ``--output`` apply to every
79
88
  subcommand and are inherited via Typer's context object.
80
89
  """
81
- ctx.obj = GlobalState(context_override=context, output=output)
90
+ ctx.obj = GlobalState(context_override=context, output=output, via_tor=via_tor)
82
91
 
83
92
 
84
93
  # ── Subcommand mounts ────────────────────────────────────────────────
@@ -69,10 +69,13 @@ def make_client(
69
69
  if ctx.base_url:
70
70
  kwargs["base_url"] = ctx.base_url
71
71
 
72
- # Tor preference comes from the [settings] block (CLI-wide). A
73
- # future per-context override (one VPN context, one clearnet, etc.)
72
+ # Tor/proxy preference: an explicit [settings] proxy wins; then the
73
+ # one-shot global --via-tor flag; then the CLI-wide use_tor setting.
74
+ # A future per-context override (one VPN context, one clearnet, etc.)
74
75
  # would slot in here without touching callers.
75
- if cfg.settings.use_tor:
76
+ if cfg.settings.proxy:
77
+ kwargs["proxy"] = cfg.settings.proxy
78
+ elif state.via_tor or cfg.settings.use_tor:
76
79
  kwargs["use_tor"] = True
77
80
 
78
81
  return Client(**kwargs)
@@ -31,6 +31,11 @@ class GlobalState:
31
31
  #: ``None`` means "use the config file's ``default_context``".
32
32
  context_override: str | None = None
33
33
 
34
+ #: One-shot Tor routing selected via the global ``--via-tor`` flag.
35
+ #: Overrides the config file's ``[settings] use_tor`` for this
36
+ #: invocation only; ``None``/False means "follow the config".
37
+ via_tor: bool = False
38
+
34
39
  #: Default output format selected via the global ``--output`` flag.
35
40
  #: Per-command ``--output`` flags can override this on a single
36
41
  #: invocation; ``None`` here means "no preference, fall back to
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: impreza-cli
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Official command-line interface for the Impreza Host public REST API
5
5
  Author-email: Impreza Host <support@imprezahost.com>
6
6
  License: MIT
@@ -23,7 +23,7 @@ Classifier: Topic :: Internet :: WWW/HTTP
23
23
  Classifier: Topic :: Utilities
24
24
  Requires-Python: >=3.10
25
25
  Description-Content-Type: text/markdown
26
- Requires-Dist: impreza-sdk<0.7,>=0.6.0
26
+ Requires-Dist: impreza-sdk<0.8,>=0.7.0
27
27
  Requires-Dist: typer>=0.12
28
28
  Requires-Dist: rich>=13.7
29
29
  Requires-Dist: click>=8.0
@@ -227,23 +227,33 @@ equivalent) and `impreza <TAB>` should suggest resource groups,
227
227
 
228
228
  ## Tor
229
229
 
230
- Inherited from the SDK. Three knobs:
230
+ Four knobs, from the most persistent to the most one-off:
231
231
 
232
232
  ```bash
233
- # Per-context override at create time
234
- impreza context create offshore \
235
- --key imp_... --secret ... \
236
- # No --proxy flag yet; for now, set IMPREZA_USE_TOR before invoking
233
+ # Persisted at context creation (writes [settings] use_tor=true)
234
+ impreza context create offshore --key imp_... --secret ... --via-tor
235
+
236
+ # Explicit SOCKS5 proxy instead (wins over use_tor; works for any
237
+ # SOCKS5, not just Tor)
238
+ impreza context create offshore --key imp_... --secret ... --proxy socks5://127.0.0.1:9050
239
+
240
+ # One-shot global flag on any command
241
+ impreza --via-tor account info
237
242
 
238
243
  # Env var, picked up by the SDK transparently
239
244
  IMPREZA_USE_TOR=1 impreza account info
240
-
241
- # Programmatic via the SDK (Python users skip the CLI for this)
242
245
  ```
243
246
 
247
+ All four route through the local Tor daemon's SOCKS5 port with remote
248
+ DNS (no local lookup of the API hostname). Because exit nodes rotate,
249
+ set the API key's IP factor to `tofu` or `keyonly` in the client area —
250
+ `whitelist` cannot work without a stable egress IP. When the account
251
+ uses the API's `.onion` mirror, the IP factor sees a stable loopback
252
+ instead.
253
+
244
254
  The SDK's `auto_tor=True` path (probe Tor, fall back to clearnet)
245
- isn't surfaced through the CLI yet — coming in a future release
246
- alongside the `--via-tor` shortcut.
255
+ isn't surfaced through the CLI yet — it is a fail-open convenience,
256
+ which is the wrong default here.
247
257
 
248
258
  ## Error handling
249
259
 
@@ -1,4 +1,4 @@
1
- impreza-sdk<0.7,>=0.6.0
1
+ impreza-sdk<0.8,>=0.7.0
2
2
  typer>=0.12
3
3
  rich>=13.7
4
4
  click>=8.0
@@ -41,7 +41,7 @@ dependencies = [
41
41
  # breaking (see CHANGELOG). Raise BOTH bounds in the same commit that
42
42
  # makes the CLI depend on a newer SDK feature, or this stops
43
43
  # protecting anything.
44
- "impreza-sdk>=0.6.0,<0.7",
44
+ "impreza-sdk>=0.7.0,<0.8",
45
45
  "typer>=0.12",
46
46
  "rich>=13.7",
47
47
  # Declared explicitly because `config.py` imports click directly, for
@@ -16,6 +16,8 @@ from typer.testing import CliRunner
16
16
 
17
17
  from impreza_cli.config import Config
18
18
  from impreza_cli.main import app
19
+ from impreza_cli.sdk import make_client
20
+ from impreza_cli.state import GlobalState
19
21
 
20
22
  # Click 8.2+ removed `mix_stderr` from CliRunner — stderr is always
21
23
  # captured separately now via result.stderr.
@@ -322,3 +324,117 @@ def test_full_lifecycle(isolated_config: Path, output_fmt: str) -> None:
322
324
  assert result.exit_code == 0
323
325
  assert "work" in result.stdout
324
326
  assert "personal" not in result.stdout
327
+
328
+
329
+ # ── Tor / proxy flags ─────────────────────────────────
330
+
331
+
332
+ def test_create_via_tor_sets_use_tor_setting(isolated_config: Path) -> None:
333
+ result = runner.invoke(
334
+ app,
335
+ [
336
+ "context", "create", "tor",
337
+ "--key", _FAKE_KEY, "--secret", _FAKE_SECRET, "--via-tor",
338
+ ],
339
+ )
340
+ assert result.exit_code == 0
341
+ cfg = Config.load(isolated_config)
342
+ assert cfg.settings.use_tor is True
343
+ assert cfg.settings.proxy is None
344
+
345
+
346
+ def test_create_with_proxy_sets_proxy_setting(isolated_config: Path) -> None:
347
+ result = runner.invoke(
348
+ app,
349
+ [
350
+ "context", "create", "tor",
351
+ "--key", _FAKE_KEY, "--secret", _FAKE_SECRET,
352
+ "--proxy", "socks5://127.0.0.1:9050",
353
+ ],
354
+ )
355
+ assert result.exit_code == 0
356
+ cfg = Config.load(isolated_config)
357
+ assert cfg.settings.proxy == "socks5://127.0.0.1:9050"
358
+ assert cfg.settings.use_tor is None # proxy wins; use_tor untouched
359
+
360
+
361
+ def test_create_without_tor_flags_leaves_settings_empty(
362
+ isolated_config: Path,
363
+ ) -> None:
364
+ result = runner.invoke(
365
+ app,
366
+ ["context", "create", "plain", "--key", _FAKE_KEY, "--secret", _FAKE_SECRET],
367
+ )
368
+ assert result.exit_code == 0
369
+ cfg = Config.load(isolated_config)
370
+ assert cfg.settings.use_tor is None
371
+ assert cfg.settings.proxy is None
372
+
373
+
374
+ def _capture_client_kwargs(monkeypatch: pytest.MonkeyPatch) -> dict[str, object]:
375
+ captured: dict[str, object] = {}
376
+
377
+ class _FakeClient:
378
+ def __init__(self, **kwargs: object) -> None:
379
+ captured.update(kwargs)
380
+
381
+ monkeypatch.setattr("impreza_cli.sdk.Client", _FakeClient)
382
+ return captured
383
+
384
+
385
+ def test_make_client_proxy_setting_wins(
386
+ isolated_config: Path, monkeypatch: pytest.MonkeyPatch
387
+ ) -> None:
388
+ runner.invoke(
389
+ app,
390
+ [
391
+ "context", "create", "tor",
392
+ "--key", _FAKE_KEY, "--secret", _FAKE_SECRET,
393
+ "--via-tor", "--proxy", "socks5://127.0.0.1:9150",
394
+ ],
395
+ )
396
+ captured = _capture_client_kwargs(monkeypatch)
397
+ make_client(GlobalState())
398
+ assert captured.get("proxy") == "socks5://127.0.0.1:9150"
399
+ assert "use_tor" not in captured
400
+
401
+
402
+ def test_make_client_use_tor_from_settings(
403
+ isolated_config: Path, monkeypatch: pytest.MonkeyPatch
404
+ ) -> None:
405
+ runner.invoke(
406
+ app,
407
+ [
408
+ "context", "create", "tor",
409
+ "--key", _FAKE_KEY, "--secret", _FAKE_SECRET, "--via-tor",
410
+ ],
411
+ )
412
+ captured = _capture_client_kwargs(monkeypatch)
413
+ make_client(GlobalState())
414
+ assert captured.get("use_tor") is True
415
+ assert "proxy" not in captured
416
+
417
+
418
+ def test_make_client_global_via_tor_flag(
419
+ isolated_config: Path, monkeypatch: pytest.MonkeyPatch
420
+ ) -> None:
421
+ runner.invoke(
422
+ app,
423
+ ["context", "create", "plain", "--key", _FAKE_KEY, "--secret", _FAKE_SECRET],
424
+ )
425
+ captured = _capture_client_kwargs(monkeypatch)
426
+ make_client(GlobalState(via_tor=True))
427
+ assert captured.get("use_tor") is True
428
+
429
+
430
+ def test_make_client_clearnet_default(
431
+ isolated_config: Path, monkeypatch: pytest.MonkeyPatch
432
+ ) -> None:
433
+ runner.invoke(
434
+ app,
435
+ ["context", "create", "plain", "--key", _FAKE_KEY, "--secret", _FAKE_SECRET],
436
+ )
437
+ captured = _capture_client_kwargs(monkeypatch)
438
+ make_client(GlobalState())
439
+ assert "use_tor" not in captured
440
+ assert "proxy" not in captured
File without changes
File without changes