import pytest from unittest.mock import AsyncMock, patch, MagicMock from sync_state_machine.sync_system.config import UpdateDirection from sync_state_machine.sync_system.strategy_ops.update_ops import run_update @pytest.mark.asyncio async def test_run_update_with_direction_overrides(): class FakeNode: def __init__(self, data): self._data = data def get_data(self): return self._data # Setup mock strategy strategy = MagicMock() strategy.node_type = "TestNode" strategy.config.field_direction_key = "sync_direction" strategy.config.field_direction_overrides = { "local_only": UpdateDirection.PUSH, "remote_only": UpdateDirection.PULL, "ignore": UpdateDirection.BIDIRECTIONAL # Just to check filtering } strategy.config.update_direction = UpdateDirection.PUSH strategy.local_collection = MagicMock() strategy.remote_collection = MagicMock() with patch('sync_state_machine.sync_system.strategy_ops.update_ops.add_update_action', new_callable=AsyncMock) as mock_add_action: mock_add_action.return_value = [] await run_update(strategy) # In the active directions, PUSH and PULL should be handled because of overrides. # Check PUSH call assert mock_add_action.call_count == 2 push_call = mock_add_action.call_args_list[0] assert push_call.kwargs['source_is_local'] is True assert push_call.kwargs['from_collection'] == strategy.local_collection pull_call = mock_add_action.call_args_list[1] assert pull_call.kwargs['source_is_local'] is False assert pull_call.kwargs['from_collection'] == strategy.remote_collection # Test the node filters push_filter = push_call.kwargs['node_filter'] pull_filter = pull_call.kwargs['node_filter'] # Node that has 'local_only' -> PUSH node_push = FakeNode({"sync_direction": "local_only"}) assert push_filter(node_push) is True assert pull_filter(node_push) is False # Node that has 'remote_only' -> PULL node_pull = FakeNode({"sync_direction": "remote_only"}) assert push_filter(node_pull) is False assert pull_filter(node_pull) is True # Node with unknown key -> default direction (PUSH) node_default = FakeNode({"sync_direction": "unknown"}) assert push_filter(node_default) is True assert pull_filter(node_default) is False # Node with empty data -> default direction (PUSH) node_empty = FakeNode(None) assert push_filter(node_empty) is True assert pull_filter(node_empty) is False