"""Unit tests for configuration management system.""" from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest from arbitrade.config.service import ConfigurationService from arbitrade.config.settings import Settings from arbitrade.storage.repositories import AuditRepository @pytest.fixture def mock_settings(): """Create a mock settings object.""" settings = Mock(spec=Settings) settings.app_env = "test" return settings @pytest.fixture def mock_store(): """Create a mock database store (sync — repos are patched).""" store = MagicMock() store.pool = MagicMock() return store @pytest.fixture def mock_audit_repo(): """Create a mock audit repository.""" audit_repo = Mock(spec=AuditRepository) return audit_repo def test_configuration_service_initialization(mock_settings, mock_store, mock_audit_repo): """Test that ConfigurationService initializes correctly.""" service = ConfigurationService(mock_settings, mock_store, mock_audit_repo) assert service._settings == mock_settings assert service._store == mock_store assert service._audit_repo == mock_audit_repo assert service._config_version == 0 assert isinstance(service._loaded_settings, dict) def test_configuration_service_get_setting(mock_settings, mock_store, mock_audit_repo): """Test getting configuration settings.""" service = ConfigurationService(mock_settings, mock_store, mock_audit_repo) service._loaded_settings = {"test_key": "test_value"} assert service.get_setting("test_key", "default") == "test_value" assert service.get_setting("non_existing", "default") == "default" @pytest.mark.asyncio async def test_configuration_service_set_setting(mock_settings, mock_store, mock_audit_repo): """Test setting configuration settings.""" service = ConfigurationService(mock_settings, mock_store, mock_audit_repo) with patch("arbitrade.storage.repositories.ConfigSettingRepository") as mock_repo_class: mock_repo_instance = Mock() mock_repo_class.return_value = mock_repo_instance mock_created_setting = Mock() mock_created_setting.updated_at = "2023-01-01T00:00:00" mock_repo_instance.create_setting = AsyncMock(return_value=mock_created_setting) mock_repo_instance.get_setting = AsyncMock(return_value=None) await service.set_setting("test_key", "test_value", "test_user") mock_repo_instance.create_setting.assert_awaited_once() @pytest.mark.asyncio async def test_configuration_service_hot_reload_detection( mock_settings, mock_store, mock_audit_repo ): """Test hot-reload detection functionality.""" service = ConfigurationService(mock_settings, mock_store, mock_audit_repo) with patch("arbitrade.storage.repositories.ConfigSettingRepository") as mock_repo_class: mock_repo_instance = Mock() mock_repo_class.return_value = mock_repo_instance mock_repo_instance.get_latest_updated_at = AsyncMock(return_value=None) assert await service.is_config_outdated() is False from datetime import datetime mock_repo_instance.get_latest_updated_at = AsyncMock(return_value=datetime.now()) assert await service.is_config_outdated() is True @pytest.mark.asyncio async def test_configuration_service_reload_if_changed(mock_settings, mock_store, mock_audit_repo): """Test hot-reload functionality.""" service = ConfigurationService(mock_settings, mock_store, mock_audit_repo) with patch("arbitrade.storage.repositories.ConfigSettingRepository") as mock_repo_class: mock_repo_instance = Mock() mock_repo_class.return_value = mock_repo_instance mock_repo_instance.get_latest_updated_at = AsyncMock(return_value=None) mock_repo_instance.list_settings = AsyncMock(return_value=[]) from datetime import datetime mock_repo_instance.get_latest_updated_at = AsyncMock(return_value=datetime.now()) result = await service.reload_if_changed() assert result is True assert service.get_config_version() == 1 @pytest.mark.asyncio async def test_configuration_service_get_config_version(mock_settings, mock_store, mock_audit_repo): """Test getting configuration version.""" service = ConfigurationService(mock_settings, mock_store, mock_audit_repo) assert service.get_config_version() == 0 with patch("arbitrade.storage.repositories.ConfigSettingRepository") as mock_repo_class: mock_repo_instance = Mock() mock_repo_class.return_value = mock_repo_instance mock_created_setting = Mock() mock_created_setting.updated_at = "2023-01-01T00:00:00" mock_repo_instance.create_setting = AsyncMock(return_value=mock_created_setting) mock_repo_instance.get_setting = AsyncMock(return_value=None) await service.set_setting("test_key", "test_value", "test_user") assert service.get_config_version() == 1 @pytest.mark.asyncio async def test_configuration_service_get_last_updated_at( mock_settings, mock_store, mock_audit_repo ): """Test getting last updated timestamp.""" service = ConfigurationService(mock_settings, mock_store, mock_audit_repo) assert service.get_last_updated_at() is None with patch("arbitrade.storage.repositories.ConfigSettingRepository") as mock_repo_class: mock_repo_instance = Mock() mock_repo_class.return_value = mock_repo_instance mock_created_setting = Mock() mock_created_setting.updated_at = "2023-01-01T00:00:00" mock_repo_instance.create_setting = AsyncMock(return_value=mock_created_setting) mock_repo_instance.get_setting = AsyncMock(return_value=None) await service.set_setting("test_key", "test_value", "test_user") assert service.get_last_updated_at() is not None