"""Tests for Config — loading, merging, defaults, overrides.""" from __future__ import annotations from pathlib import Path from volumen.config import Config MISSING = "/nonexistent/volumen.toml" class TestDefaults: def test_defaults_when_file_missing(self) -> None: config = Config.load(path=MISSING) assert config.port == 9090 assert config.language == "en" assert config.host == "::" def test_default_content_dir(self) -> None: config = Config.load(path=MISSING) assert config.content_dir == "/var/lib/volumen/posts" def test_default_site_title(self) -> None: config = Config.load(path=MISSING) assert config.site["title"] == "My Blog" class TestOverrides: def test_overrides_apply(self) -> None: config = Config.load( path=MISSING, overrides={"host": "127.0.0.1", "port": 9000, "content": "/srv/posts"}, ) assert config.host == "127.0.0.1" assert config.port == 9000 assert config.content_dir == "/srv/posts" def test_does_not_mutate_defaults(self) -> None: Config.load(path=MISSING, overrides={"host": "10.0.0.1"}) fresh = Config.load(path=MISSING) assert fresh.host == "::" def test_does_not_mutate_default_inner_hashes(self) -> None: config = Config.load(path=MISSING) config.site["title"] = "MUTATED" fresh = Config.load(path=MISSING) assert fresh.site["title"] == "My Blog" class TestLoadFromFile: def test_loads_and_merges_file(self, tmp_path: Path) -> None: config_path = tmp_path / "config.toml" config_path.write_text('[site]\ntitle = "Custom"\n') config = Config.load(path=str(config_path)) assert config.site["title"] == "Custom" assert config.port == 9090 # default preserved def test_loads_server_section(self, tmp_path: Path) -> None: config_path = tmp_path / "config.toml" config_path.write_text('[server]\nhost = "1.2.3.4"\nport = 8000\n') config = Config.load(path=str(config_path)) assert config.host == "1.2.3.4" assert config.port == 8000 class TestGenerateDefault: def test_generate_default_writes_template(self, tmp_path: Path) -> None: dest = tmp_path / "sub" / "config.toml" result = Config.generate_default(str(dest)) assert result == str(dest) assert dest.exists() loaded = Config.load(path=str(dest)) assert loaded.port == 9090 def test_generate_default_skips_existing(self, tmp_path: Path) -> None: config_path = tmp_path / "config.toml" config_path.write_text("[server]\nport = 9999\n") result = Config.generate_default(str(config_path)) assert result is None loaded = Config.load(path=str(config_path)) assert loaded.port == 9999 class TestAccessors: def test_host(self) -> None: config = Config.load(path=MISSING, overrides={"host": "127.0.0.1"}) assert config.host == "127.0.0.1" def test_port(self) -> None: assert Config.load(path=MISSING).port == 9090 def test_content_dir(self) -> None: config = Config.load(path=MISSING, overrides={"content": "/tmp/posts"}) assert config.content_dir == "/tmp/posts" def test_users_file(self) -> None: config = Config.load(path=MISSING) assert config.users_file == "/var/lib/volumen/users.toml" def test_site(self) -> None: config = Config.load(path=MISSING) assert isinstance(config.site, dict) assert "title" in config.site def test_admin(self) -> None: config = Config.load(path=MISSING) assert isinstance(config.admin, dict) assert "password_hash" in config.admin def test_language(self) -> None: config = Config.load(path=MISSING) assert config.language == "en"