mirror of
https://github.com/blw1138/Zordon.git
synced 2026-06-09 13:39:24 -05:00
24eb7b5616
* Add tests and new github workflow * Add new unit tests * Add Github CI workflow * Workflow fix * Add pytest install to workflow file * More CI / test updates * More test cleanup * Whitespace cleanup and link complexity override * More whitespace cleanup * Make lint less strict * More lint tweaks
173 lines
5.2 KiB
Python
173 lines
5.2 KiB
Python
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from src.utilities.config import Config, _CONFIG_ATTRS
|
|
|
|
|
|
class TestConfigDefaults:
|
|
"""Default attribute values."""
|
|
|
|
def test_default_upload_folder(self):
|
|
assert Config.upload_folder == '~/zordon-uploads/'
|
|
|
|
def test_default_port(self):
|
|
assert Config.port_number == 8080
|
|
|
|
def test_default_server_log_level(self):
|
|
assert Config.server_log_level == 'debug'
|
|
|
|
def test_default_enable_split_jobs(self):
|
|
assert Config.enable_split_jobs is True
|
|
|
|
def test_default_worker_timeout(self):
|
|
assert Config.worker_process_timeout == 120
|
|
|
|
|
|
class TestConfigInstance:
|
|
"""Instance creation and attribute initialisation."""
|
|
|
|
def test_init_copies_class_attrs(self):
|
|
cfg = Config()
|
|
assert cfg.upload_folder == '~/zordon-uploads/'
|
|
assert cfg.port_number == 8080
|
|
|
|
def test_init_has_all_attrs(self):
|
|
cfg = Config()
|
|
for attr in _CONFIG_ATTRS:
|
|
assert hasattr(cfg, attr), f'missing attr: {attr}'
|
|
|
|
|
|
class TestConfigLoad:
|
|
"""Loading configuration from YAML."""
|
|
|
|
def test_load_sets_attributes(self, tmp_path):
|
|
config_file = tmp_path / 'config.yaml'
|
|
config_file.write_text('port_number: 9090\nserver_log_level: info\n')
|
|
|
|
cfg = Config()
|
|
cfg.load(config_file)
|
|
|
|
assert cfg.port_number == 9090
|
|
assert cfg.server_log_level == 'info'
|
|
|
|
def test_load_expands_upload_folder(self, tmp_path):
|
|
config_file = tmp_path / 'config.yaml'
|
|
config_file.write_text('upload_folder: ~/custom-uploads/\n')
|
|
|
|
cfg = Config()
|
|
cfg.load(config_file)
|
|
|
|
# expanduser strips trailing slash
|
|
assert cfg.upload_folder.endswith('/custom-uploads')
|
|
|
|
def test_load_ignores_unknown_keys(self, tmp_path):
|
|
config_file = tmp_path / 'config.yaml'
|
|
config_file.write_text('nonexistent_key: value\nport_number: 7070\n')
|
|
|
|
cfg = Config()
|
|
cfg.load(config_file)
|
|
|
|
assert cfg.port_number == 7070
|
|
|
|
def test_load_raises_on_missing_file(self):
|
|
cfg = Config()
|
|
try:
|
|
cfg.load(Path('/nonexistent/path.yaml'))
|
|
assert False, 'expected FileNotFoundError'
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
|
|
class TestConfigSyncClass:
|
|
"""_sync_class propagates instance attrs to class level."""
|
|
|
|
def test_sync_class_propagates_attrs(self):
|
|
orig = Config._default_instance
|
|
try:
|
|
cfg = Config()
|
|
cfg.port_number = 7777
|
|
Config._default_instance = cfg
|
|
|
|
Config._sync_class()
|
|
|
|
assert Config.port_number == 7777
|
|
finally:
|
|
Config._default_instance = orig
|
|
Config._sync_class()
|
|
|
|
def test_sync_class_noop_when_no_instance(self):
|
|
orig = Config._default_instance
|
|
try:
|
|
Config._default_instance = None
|
|
Config._sync_class()
|
|
finally:
|
|
Config._default_instance = orig
|
|
Config._sync_class()
|
|
|
|
|
|
class TestConfigLoadConfig:
|
|
"""Classmethod load_config — full bootstrap."""
|
|
|
|
def test_load_config_sets_default_instance(self, tmp_path):
|
|
orig = Config._default_instance
|
|
try:
|
|
config_file = tmp_path / 'config.yaml'
|
|
config_file.write_text('port_number: 9999\n')
|
|
|
|
Config._default_instance = None
|
|
Config.load_config(config_file)
|
|
|
|
assert Config._default_instance is not None
|
|
assert Config.port_number == 9999
|
|
finally:
|
|
Config._default_instance = orig
|
|
Config._sync_class()
|
|
|
|
|
|
class TestConfigDir:
|
|
"""config_dir() returns OS-specific path."""
|
|
|
|
@patch('src.utilities.config.current_system_os')
|
|
def test_config_dir_macos(self, mock_os):
|
|
mock_os.return_value = 'macos'
|
|
result = Config.config_dir()
|
|
assert 'Library/Application Support/Zordon' in str(result)
|
|
|
|
@patch('src.utilities.config.current_system_os')
|
|
def test_config_dir_windows(self, mock_os):
|
|
mock_os.return_value = 'windows'
|
|
with patch.dict('os.environ', {'APPDATA': 'C:\\Users\\Test\\AppData\\Roaming'}):
|
|
result = Config.config_dir()
|
|
assert 'Zordon' in str(result)
|
|
|
|
@patch('src.utilities.config.current_system_os')
|
|
def test_config_dir_linux(self, mock_os):
|
|
mock_os.return_value = 'linux'
|
|
result = Config.config_dir()
|
|
assert '.config/Zordon' in str(result)
|
|
|
|
|
|
class TestSetupConfigDir:
|
|
"""setup_config_dir creates dir and copies template."""
|
|
|
|
@patch('src.utilities.config.copy_directory_contents')
|
|
@patch('src.utilities.config.os.makedirs')
|
|
@patch('src.utilities.config.os.path.exists')
|
|
def test_creates_dir_when_missing(self, mock_exists, mock_makedirs, mock_copy):
|
|
mock_exists.return_value = False
|
|
|
|
Config.setup_config_dir()
|
|
|
|
mock_makedirs.assert_called_once()
|
|
|
|
@patch('src.utilities.config.copy_directory_contents')
|
|
@patch('src.utilities.config.os.makedirs')
|
|
@patch('src.utilities.config.os.path.exists')
|
|
def test_skips_when_dir_exists(self, mock_exists, mock_makedirs, mock_copy):
|
|
mock_exists.return_value = True
|
|
|
|
Config.setup_config_dir()
|
|
|
|
mock_makedirs.assert_not_called()
|
|
mock_copy.assert_not_called()
|