Files
coinhunter-cli/tests/test_config_runtime.py
Tacit Lab d629c25232 fix: resolve merge conflicts and lint issues
- Merge origin/main changes (flattened buy/sell commands, --doc flag, aliases)
- Fix spinner placement for buy/sell commands
- Fix duplicate alias key 'p' in canonical subcommands
- Remove unused mypy ignore comments in spot_client.py
- Fix nested with statements in tests

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 16:59:53 +08:00

102 lines
3.5 KiB
Python

"""Config and runtime tests."""
from __future__ import annotations
import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
from coinhunter.config import (
ensure_init_files,
get_binance_credentials,
load_config,
load_env_file,
)
from coinhunter.runtime import get_runtime_paths
class ConfigRuntimeTestCase(unittest.TestCase):
def test_init_files_created_in_coinhunter_home(self):
with (
tempfile.TemporaryDirectory() as tmp_dir,
patch.dict(os.environ, {"COINHUNTER_HOME": str(Path(tmp_dir) / "home")}, clear=False),
):
paths = get_runtime_paths()
payload = ensure_init_files(paths)
self.assertTrue(paths.config_file.exists())
self.assertTrue(paths.env_file.exists())
self.assertTrue(paths.logs_dir.exists())
self.assertEqual(payload["root"], str(paths.root))
def test_load_config_and_env(self):
with (
tempfile.TemporaryDirectory() as tmp_dir,
patch.dict(
os.environ,
{"COINHUNTER_HOME": str(Path(tmp_dir) / "home")},
clear=False,
),
):
paths = get_runtime_paths()
ensure_init_files(paths)
paths.env_file.write_text("BINANCE_API_KEY=abc\nBINANCE_API_SECRET=def\n", encoding="utf-8")
config = load_config(paths)
loaded = load_env_file(paths)
self.assertEqual(config["market"]["default_quote"], "USDT")
self.assertEqual(loaded["BINANCE_API_KEY"], "abc")
self.assertEqual(os.environ["BINANCE_API_SECRET"], "def")
def test_env_file_overrides_existing_environment(self):
with (
tempfile.TemporaryDirectory() as tmp_dir,
patch.dict(
os.environ,
{"COINHUNTER_HOME": str(Path(tmp_dir) / "home"), "BINANCE_API_KEY": "old_key"},
clear=False,
),
):
paths = get_runtime_paths()
ensure_init_files(paths)
paths.env_file.write_text("BINANCE_API_KEY=new_key\nBINANCE_API_SECRET=new_secret\n", encoding="utf-8")
load_env_file(paths)
self.assertEqual(os.environ["BINANCE_API_KEY"], "new_key")
self.assertEqual(os.environ["BINANCE_API_SECRET"], "new_secret")
def test_missing_credentials_raise(self):
with (
tempfile.TemporaryDirectory() as tmp_dir,
patch.dict(
os.environ,
{"COINHUNTER_HOME": str(Path(tmp_dir) / "home")},
clear=False,
),
):
os.environ.pop("BINANCE_API_KEY", None)
os.environ.pop("BINANCE_API_SECRET", None)
paths = get_runtime_paths()
ensure_init_files(paths)
with self.assertRaisesRegex(RuntimeError, "Missing BINANCE_API_KEY"):
get_binance_credentials(paths)
def test_permission_error_is_explained(self):
with (
tempfile.TemporaryDirectory() as tmp_dir,
patch.dict(
os.environ,
{"COINHUNTER_HOME": str(Path(tmp_dir) / "home")},
clear=False,
),
):
paths = get_runtime_paths()
with (
patch("coinhunter.config.ensure_runtime_dirs", side_effect=PermissionError("no write access")),
self.assertRaisesRegex(RuntimeError, "Set COINHUNTER_HOME to a writable directory"),
):
ensure_init_files(paths)