Implement configuration management, drag-and-drop functionality, and logging utilities for WebDrop Bridge
This commit is contained in:
parent
04ef84cf9a
commit
6bef2f6119
9 changed files with 1154 additions and 0 deletions
148
tests/unit/test_config.py
Normal file
148
tests/unit/test_config.py
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
"""Unit tests for configuration system."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from webdrop_bridge.config import Config, ConfigurationError
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def clear_env():
|
||||
"""Clear environment variables before each test to avoid persistence."""
|
||||
# Save current env
|
||||
saved_env = os.environ.copy()
|
||||
|
||||
# Clear relevant variables
|
||||
for key in list(os.environ.keys()):
|
||||
if key.startswith(('APP_', 'LOG_', 'ALLOWED_', 'WEBAPP_', 'WINDOW_', 'ENABLE_')):
|
||||
del os.environ[key]
|
||||
|
||||
yield
|
||||
|
||||
# Restore env (cleanup)
|
||||
os.environ.clear()
|
||||
os.environ.update(saved_env)
|
||||
|
||||
|
||||
class TestConfigFromEnv:
|
||||
"""Test Config.from_env() loading from environment."""
|
||||
|
||||
def test_from_env_with_all_values(self, tmp_path):
|
||||
"""Test loading config with all environment variables set."""
|
||||
# Create .env file
|
||||
env_file = tmp_path / ".env"
|
||||
root1 = tmp_path / "root1"
|
||||
root2 = tmp_path / "root2"
|
||||
root1.mkdir()
|
||||
root2.mkdir()
|
||||
|
||||
env_file.write_text(
|
||||
f"APP_NAME=TestApp\n"
|
||||
f"APP_VERSION=2.0.0\n"
|
||||
f"LOG_LEVEL=DEBUG\n"
|
||||
f"LOG_FILE={tmp_path / 'test.log'}\n"
|
||||
f"ALLOWED_ROOTS={root1},{root2}\n"
|
||||
f"WEBAPP_URL=http://localhost:8000\n"
|
||||
f"WINDOW_WIDTH=1200\n"
|
||||
f"WINDOW_HEIGHT=800\n"
|
||||
)
|
||||
|
||||
# Load config (env vars from file, not system)
|
||||
config = Config.from_env(str(env_file))
|
||||
|
||||
assert config.app_name == "TestApp"
|
||||
assert config.app_version == "2.0.0"
|
||||
assert config.log_level == "DEBUG"
|
||||
assert config.allowed_roots == [root1.resolve(), root2.resolve()]
|
||||
assert config.webapp_url == "http://localhost:8000"
|
||||
assert config.window_width == 1200
|
||||
assert config.window_height == 800
|
||||
|
||||
def test_from_env_with_defaults(self, tmp_path):
|
||||
"""Test loading config uses defaults when env vars not set."""
|
||||
# Create empty .env file
|
||||
env_file = tmp_path / ".env"
|
||||
env_file.write_text("")
|
||||
|
||||
config = Config.from_env(str(env_file))
|
||||
|
||||
assert config.app_name == "WebDrop Bridge"
|
||||
assert config.app_version == "1.0.0"
|
||||
assert config.log_level == "INFO"
|
||||
assert config.window_width == 1024
|
||||
assert config.window_height == 768
|
||||
|
||||
def test_from_env_invalid_log_level(self, tmp_path):
|
||||
"""Test that invalid log level raises ConfigurationError."""
|
||||
env_file = tmp_path / ".env"
|
||||
root1 = tmp_path / "root1"
|
||||
root1.mkdir()
|
||||
env_file.write_text(f"LOG_LEVEL=INVALID\nALLOWED_ROOTS={root1}\n")
|
||||
|
||||
with pytest.raises(ConfigurationError, match="Invalid LOG_LEVEL"):
|
||||
Config.from_env(str(env_file))
|
||||
|
||||
def test_from_env_invalid_window_dimension(self, tmp_path):
|
||||
"""Test that negative window dimensions raise ConfigurationError."""
|
||||
env_file = tmp_path / ".env"
|
||||
root1 = tmp_path / "root1"
|
||||
root1.mkdir()
|
||||
env_file.write_text(f"WINDOW_WIDTH=-100\nALLOWED_ROOTS={root1}\n")
|
||||
|
||||
with pytest.raises(ConfigurationError, match="Window dimensions"):
|
||||
Config.from_env(str(env_file))
|
||||
|
||||
def test_from_env_invalid_root_path(self, tmp_path):
|
||||
"""Test that non-existent root paths raise ConfigurationError."""
|
||||
env_file = tmp_path / ".env"
|
||||
env_file.write_text("ALLOWED_ROOTS=/nonexistent/path/that/does/not/exist\n")
|
||||
|
||||
with pytest.raises(ConfigurationError, match="does not exist"):
|
||||
Config.from_env(str(env_file))
|
||||
|
||||
def test_from_env_empty_webapp_url(self, tmp_path):
|
||||
"""Test that empty webapp URL raises ConfigurationError."""
|
||||
env_file = tmp_path / ".env"
|
||||
root1 = tmp_path / "root1"
|
||||
root1.mkdir()
|
||||
env_file.write_text(f"WEBAPP_URL=\nALLOWED_ROOTS={root1}\n")
|
||||
|
||||
with pytest.raises(ConfigurationError, match="WEBAPP_URL"):
|
||||
Config.from_env(str(env_file))
|
||||
|
||||
|
||||
class TestConfigValidation:
|
||||
"""Test Config field validation."""
|
||||
|
||||
def test_root_path_resolution(self, tmp_path):
|
||||
"""Test that root paths are resolved to absolute paths."""
|
||||
env_file = tmp_path / ".env"
|
||||
root_dir = tmp_path / "allowed"
|
||||
root_dir.mkdir()
|
||||
|
||||
env_file.write_text(f"ALLOWED_ROOTS={root_dir}\n")
|
||||
|
||||
config = Config.from_env(str(env_file))
|
||||
|
||||
# Should be resolved to absolute path
|
||||
assert config.allowed_roots[0].is_absolute()
|
||||
|
||||
def test_multiple_root_paths(self, tmp_path):
|
||||
"""Test loading multiple root paths."""
|
||||
dir1 = tmp_path / "dir1"
|
||||
dir2 = tmp_path / "dir2"
|
||||
dir1.mkdir()
|
||||
dir2.mkdir()
|
||||
|
||||
env_file = tmp_path / ".env"
|
||||
env_file.write_text(f"ALLOWED_ROOTS={dir1},{dir2}\n")
|
||||
|
||||
config = Config.from_env(str(env_file))
|
||||
|
||||
assert len(config.allowed_roots) == 2
|
||||
assert config.allowed_roots[0] == dir1.resolve()
|
||||
assert config.allowed_roots[1] == dir2.resolve()
|
||||
Loading…
Add table
Add a link
Reference in a new issue