Files
zyt/app/tests/test_config.py
2026-08-28 18:24:37 +08:00

136 lines
4.3 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
import pytest
from doctor_workstation import config as config_module
from doctor_workstation.config import AppConfig, normalize_api_base_url
@pytest.mark.parametrize(
("raw", "expected"),
[
("https://api.example.com", "https://api.example.com/adminapi"),
("https://api.example.com/", "https://api.example.com/adminapi"),
("https://api.example.com/adminapi", "https://api.example.com/adminapi"),
("http://127.0.0.1:8080/gateway", "http://127.0.0.1:8080/gateway/adminapi"),
("", ""),
],
)
def test_normalize_api_base_url(raw: str, expected: str) -> None:
assert normalize_api_base_url(raw) == expected
@pytest.mark.parametrize(
"raw",
["api.example.com", "ftp://api.example.com", "https://u:p@example.com", "https://x.test?a=1"],
)
def test_normalize_api_base_url_rejects_unsafe_values(raw: str) -> None:
with pytest.raises(ValueError):
normalize_api_base_url(raw)
def test_config_update_validates_video_mode() -> None:
with pytest.raises(ValueError):
AppConfig().with_updates(video_mode="unknown")
def test_config_update_normalizes_ssl_boolean_strings() -> None:
assert AppConfig(debug_mode=True).with_updates(verify_ssl="false").verify_ssl is False
assert (
AppConfig(debug_mode=True, verify_ssl=False)
.with_updates(verify_ssl="true")
.verify_ssl
is True
)
def test_production_config_locks_online_server_and_disables_demo(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
config_dir = tmp_path / "config"
config_dir.mkdir()
(config_dir / "preferences.json").write_text(
json.dumps(
{
"api_base_url": "https://stale.example.test/adminapi",
"demo_mode": True,
"verify_ssl": False,
}
),
encoding="utf-8",
)
monkeypatch.setattr(config_module, "DEBUG_MODE", False)
monkeypatch.setattr(
config_module,
"ONLINE_API_BASE_URL",
"https://prod.example.test",
)
monkeypatch.setenv("DOCTOR_CONFIG_DIR", str(config_dir))
monkeypatch.setenv("DOCTOR_API_BASE_URL", "https://env.example.test")
monkeypatch.setenv("DOCTOR_DEMO_MODE", "true")
monkeypatch.setenv("DOCTOR_VERIFY_SSL", "false")
config = AppConfig.load()
assert config.debug_mode is False
assert config.api_base_url == "https://prod.example.test/adminapi"
assert config.demo_mode is False
assert config.verify_ssl is True
updated = config.with_updates(
api_base_url="https://changed.example.test",
demo_mode=True,
verify_ssl=False,
)
assert updated.api_base_url == config.api_base_url
assert updated.demo_mode is False
assert updated.verify_ssl is True
def test_debug_config_keeps_environment_server_controls(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
monkeypatch.setattr(config_module, "DEBUG_MODE", True)
monkeypatch.setenv("DOCTOR_CONFIG_DIR", str(tmp_path / "config"))
monkeypatch.setenv("DOCTOR_API_BASE_URL", "http://127.0.0.1:8080")
monkeypatch.setenv("DOCTOR_DEMO_MODE", "true")
monkeypatch.setenv("DOCTOR_VERIFY_SSL", "false")
config = AppConfig.load()
assert config.debug_mode is True
assert config.api_base_url == "http://127.0.0.1:8080/adminapi"
assert config.demo_mode is True
assert config.verify_ssl is False
def test_production_config_rejects_empty_online_domain(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
monkeypatch.setattr(config_module, "DEBUG_MODE", False)
monkeypatch.setattr(config_module, "ONLINE_API_BASE_URL", "")
monkeypatch.setenv("DOCTOR_CONFIG_DIR", str(tmp_path / "config"))
with pytest.raises(ValueError, match="ONLINE_API_BASE_URL 不能为空"):
AppConfig.load()
def test_runtime_directories_can_be_isolated_without_replacing_user_home(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
config_dir = tmp_path / "config"
log_dir = tmp_path / "logs"
monkeypatch.setenv("DOCTOR_CONFIG_DIR", str(config_dir))
monkeypatch.setenv("DOCTOR_LOG_DIR", str(log_dir))
config = AppConfig()
assert config.config_dir == config_dir
assert config.log_dir == log_dir