Files
ecm_sync_system/tests/unit/test_update_ops.py
T
2026-03-24 08:40:40 +08:00

89 lines
3.3 KiB
Python

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
from sync_state_machine.domain.construction.sync_strategy import ConstructionTaskSyncStrategy
@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
def test_construction_task_compare_payload_ignores_plan_node_is_audit():
strategy = ConstructionTaskSyncStrategy(
"construction_task",
MagicMock(),
MagicMock(),
MagicMock(),
)
local_payload = {
"plan_node": [{"name": "A", "is_audit": True}],
"task_type": "demo",
}
remote_payload = {
"plan_node": [{"name": "A", "is_audit": False}],
"task_type": "demo",
}
assert strategy.normalize_compare_payload(local_payload) == strategy.normalize_compare_payload(remote_payload)