diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 00000000..66173aec --- /dev/null +++ b/test/__init__.py @@ -0,0 +1 @@ +# Test package diff --git a/test/test_config_validation_edge_cases.py b/test/test_config_validation_edge_cases.py index 6cddb1fe..6de4d2ad 100644 --- a/test/test_config_validation_edge_cases.py +++ b/test/test_config_validation_edge_cases.py @@ -23,6 +23,7 @@ if str(project_root) not in sys.path: sys.path.insert(0, str(project_root)) from src.config_manager import ConfigManager +from src.exceptions import ConfigError from src.plugin_system.schema_manager import SchemaManager @@ -30,35 +31,31 @@ class TestInvalidJson: """Test handling of invalid JSON in config files.""" def test_invalid_json_syntax(self, tmp_path): - """Config with invalid JSON syntax should be handled gracefully.""" + """Config with invalid JSON syntax should raise ConfigError.""" config_file = tmp_path / "config.json" config_file.write_text("{ invalid json }") - with patch.object(ConfigManager, '_get_config_path', return_value=str(config_file)): - config_manager = ConfigManager(config_dir=str(tmp_path)) - # Should not raise, should return empty or default config - config = config_manager.load_config() - assert isinstance(config, dict) + config_manager = ConfigManager(config_path=str(config_file)) + with pytest.raises(ConfigError): + config_manager.load_config() def test_truncated_json(self, tmp_path): - """Config with truncated JSON should be handled gracefully.""" + """Config with truncated JSON should raise ConfigError.""" config_file = tmp_path / "config.json" config_file.write_text('{"plugin": {"enabled": true') # Missing closing braces - with patch.object(ConfigManager, '_get_config_path', return_value=str(config_file)): - config_manager = ConfigManager(config_dir=str(tmp_path)) - config = config_manager.load_config() - assert isinstance(config, dict) + config_manager = ConfigManager(config_path=str(config_file)) + with pytest.raises(ConfigError): + config_manager.load_config() def test_empty_config_file(self, tmp_path): - """Empty config file should be handled gracefully.""" + """Empty config file should raise ConfigError.""" config_file = tmp_path / "config.json" config_file.write_text("") - with patch.object(ConfigManager, '_get_config_path', return_value=str(config_file)): - config_manager = ConfigManager(config_dir=str(tmp_path)) - config = config_manager.load_config() - assert isinstance(config, dict) + config_manager = ConfigManager(config_path=str(config_file)) + with pytest.raises(ConfigError): + config_manager.load_config() class TestTypeValidation: diff --git a/test/test_display_controller.py b/test/test_display_controller.py index 9deafd0d..4c662a61 100644 --- a/test/test_display_controller.py +++ b/test/test_display_controller.py @@ -209,49 +209,47 @@ class TestDisplayControllerSchedule: def test_schedule_disabled(self, test_display_controller): """Test when schedule is disabled.""" controller = test_display_controller - controller.config = {"schedule": {"enabled": False}} - - controller._check_schedule() - assert controller.is_display_active is True - + schedule_config = {"schedule": {"enabled": False}} + with patch.object(controller.config_service, 'get_config', return_value=schedule_config): + controller._check_schedule() + assert controller.is_display_active is True + def test_active_hours(self, test_display_controller): """Test active hours check.""" controller = test_display_controller - # Mock datetime to be within active hours with patch('src.display_controller.datetime') as mock_datetime: mock_datetime.now.return_value.strftime.return_value.lower.return_value = "monday" mock_datetime.now.return_value.time.return_value = datetime.strptime("12:00", "%H:%M").time() mock_datetime.strptime = datetime.strptime - - controller.config = { + + schedule_config = { "schedule": { "enabled": True, "start_time": "09:00", "end_time": "17:00" } } - - controller._check_schedule() - assert controller.is_display_active is True + with patch.object(controller.config_service, 'get_config', return_value=schedule_config): + controller._check_schedule() + assert controller.is_display_active is True def test_inactive_hours(self, test_display_controller): """Test inactive hours check.""" controller = test_display_controller - # Mock datetime to be outside active hours with patch('src.display_controller.datetime') as mock_datetime: mock_datetime.now.return_value.strftime.return_value.lower.return_value = "monday" mock_datetime.now.return_value.time.return_value = datetime.strptime("20:00", "%H:%M").time() mock_datetime.strptime = datetime.strptime - - controller.config = { + + schedule_config = { "schedule": { "enabled": True, "start_time": "09:00", "end_time": "17:00" } } - - controller._check_schedule() - assert controller.is_display_active is False + with patch.object(controller.config_service, 'get_config', return_value=schedule_config): + controller._check_schedule() + assert controller.is_display_active is False from datetime import datetime diff --git a/test/test_web_api.py b/test/test_web_api.py index f5ad2ed5..1226453d 100644 --- a/test/test_web_api.py +++ b/test/test_web_api.py @@ -29,7 +29,13 @@ def mock_config_manager(): } mock.get_config_path.return_value = 'config/config.json' mock.get_secrets_path.return_value = 'config/config_secrets.json' - mock.get_raw_file_content.return_value = {'weather': {'api_key': 'test'}} + mock_config = { + 'display': {'brightness': 50}, + 'plugins': {}, + 'timezone': 'UTC' + } + mock.load_config.return_value = mock_config + mock.get_raw_file_content.return_value = mock_config mock.save_config_atomic.return_value = MagicMock( status=MagicMock(value='success'), message=None @@ -385,17 +391,21 @@ class TestPluginsAPI: def test_get_plugin_config(self, client, mock_config_manager): """Test getting plugin configuration.""" + # Plugin configs live at top-level keys (not under 'plugins') mock_config_manager.load_config.return_value = { - 'plugins': { - 'weather': { - 'enabled': True, - 'api_key': 'test_key' - } + 'weather': { + 'enabled': True, + 'api_key': 'test_key' } } - + + # Ensure schema manager returns serializable values + from web_interface.blueprints.api_v3 import api_v3 + api_v3.schema_manager.generate_default_config.return_value = {'enabled': False} + api_v3.schema_manager.merge_with_defaults.side_effect = lambda config, defaults: {**defaults, **config} + response = client.get('/api/v3/plugins/config?plugin_id=weather') - + assert response.status_code == 200 data = json.loads(response.data) assert 'enabled' in data or 'config' in data or 'data' in data