"""Unit tests for configuration repositories.""" from unittest.mock import AsyncMock, MagicMock import pytest from arbitrade.config.service import ( ConfigPairing, ConfigSetting, ) from arbitrade.storage.repositories import ( ConfigBacktestingDefaultsRepository, ConfigPairingRepository, ConfigSettingRepository, ) @pytest.fixture def mock_store(): """Create a mock database store with async pool.""" store = MagicMock() conn = AsyncMock() conn.fetchone = AsyncMock(return_value=None) conn.fetchall = AsyncMock(return_value=[]) conn.fetch = AsyncMock(return_value=[]) conn.execute = AsyncMock(return_value=conn) store.pool = MagicMock() cm = AsyncMock() cm.__aenter__.return_value = conn store.pool.acquire.return_value = cm return store def _make_row(mapping: dict): row = MagicMock() row.__getitem__.side_effect = lambda k: mapping[k] return row SETTING_ROW = { "key": "test_key", "section": "test_section", "value_json": "test_value", "value_type": "str", "is_secret": False, "is_runtime_reloadable": False, "updated_at": "2023-01-01T00:00:00", "updated_by": "test_user", } PAIRING_ROW = { "id": 1, "base_asset": "BTC", "quote_asset": "USD", "enabled": True, "source": "Kraken", "created_at": "2023-01-01T00:00:00", "updated_at": "2023-01-01T00:00:00", } def test_config_setting_repository_initialization(mock_store): """Test ConfigSettingRepository initialization.""" repo = ConfigSettingRepository(mock_store) assert repo._store == mock_store @pytest.mark.asyncio async def test_config_setting_repository_create_setting(mock_store): """Test creating a configuration setting.""" repo = ConfigSettingRepository(mock_store) conn = await mock_store.pool.acquire().__aenter__() conn.fetchrow = AsyncMock(return_value=_make_row(SETTING_ROW)) setting = ConfigSetting( key="test_key", section="test_section", value_json="test_value", value_type="str", is_secret=False, is_runtime_reloadable=False, updated_by="test_user", ) result = await repo.create_setting(setting) assert result.key == "test_key" assert result.section == "test_section" assert result.value_json == "test_value" assert result.value_type == "str" assert result.updated_by == "test_user" @pytest.mark.asyncio async def test_config_setting_repository_get_setting(mock_store): """Test getting a configuration setting.""" repo = ConfigSettingRepository(mock_store) conn = await mock_store.pool.acquire().__aenter__() conn.fetchrow = AsyncMock(return_value=_make_row(SETTING_ROW)) result = await repo.get_setting("test_key") assert result is not None assert result.key == "test_key" assert result.section == "test_section" assert result.value_json == "test_value" assert result.value_type == "str" assert result.updated_by == "test_user" @pytest.mark.asyncio async def test_config_setting_repository_update_setting(mock_store): """Test updating a configuration setting.""" repo = ConfigSettingRepository(mock_store) conn = await mock_store.pool.acquire().__aenter__() conn.fetchrow = AsyncMock(return_value=_make_row(SETTING_ROW)) setting = ConfigSetting( key="test_key", section="test_section", value_json="updated_value", value_type="str", is_secret=False, is_runtime_reloadable=False, updated_by="test_user", ) result = await repo.update_setting("test_key", setting) assert result.key == "test_key" @pytest.mark.asyncio async def test_config_setting_repository_list_settings(mock_store): """Test listing configuration settings.""" repo = ConfigSettingRepository(mock_store) conn = await mock_store.pool.acquire().__aenter__() row1 = _make_row({**SETTING_ROW, "key": "test_key1", "value_json": "test_value1"}) row2 = _make_row({**SETTING_ROW, "key": "test_key2", "value_json": "test_value2"}) conn.fetch = AsyncMock(return_value=[row1, row2]) result = await repo.list_settings() assert len(result) == 2 assert result[0].key == "test_key1" assert result[1].key == "test_key2" @pytest.mark.asyncio async def test_config_setting_repository_get_latest_updated_at(mock_store): """Test getting latest updated timestamp.""" repo = ConfigSettingRepository(mock_store) conn = await mock_store.pool.acquire().__aenter__() row = _make_row({"latest_updated_at": "2023-01-01T00:00:00"}) conn.fetchrow = AsyncMock(return_value=row) result = await repo.get_latest_updated_at() assert result is not None def test_config_pairing_repository_initialization(mock_store): """Test ConfigPairingRepository initialization.""" repo = ConfigPairingRepository(mock_store) assert repo._store == mock_store @pytest.mark.asyncio async def test_config_pairing_repository_create_pairing(mock_store): """Test creating a currency pairing.""" repo = ConfigPairingRepository(mock_store) conn = await mock_store.pool.acquire().__aenter__() conn.fetchrow = AsyncMock(return_value=_make_row(PAIRING_ROW)) pairing = ConfigPairing(base_asset="BTC", quote_asset="USD", enabled=True, source="Kraken") result = await repo.create_pairing(pairing) assert result.base_asset == "BTC" assert result.quote_asset == "USD" assert result.enabled is True assert result.source == "Kraken" @pytest.mark.asyncio async def test_config_pairing_repository_get_pairing(mock_store): """Test getting a currency pairing.""" repo = ConfigPairingRepository(mock_store) conn = await mock_store.pool.acquire().__aenter__() conn.fetchrow = AsyncMock(return_value=_make_row(PAIRING_ROW)) result = await repo.get_pairing("BTC", "USD") assert result.base_asset == "BTC" assert result.quote_asset == "USD" assert result.enabled is True assert result.source == "Kraken" def test_config_backtesting_defaults_repository_initialization(mock_store): """Test ConfigBacktestingDefaultsRepository initialization.""" repo = ConfigBacktestingDefaultsRepository(mock_store) assert repo._store == mock_store