优化大量推送问题
This commit is contained in:
@@ -57,6 +57,23 @@ class _FailingApiClient:
|
||||
return {"code": 500, "message": "boom"}
|
||||
|
||||
|
||||
class _RecordingApiClient:
|
||||
def __init__(self) -> None:
|
||||
self.calls = []
|
||||
|
||||
async def request(self, method, endpoint, params=None, data=None, **kwargs):
|
||||
self.calls.append(
|
||||
{
|
||||
"method": method,
|
||||
"endpoint": endpoint,
|
||||
"params": params,
|
||||
"data": data,
|
||||
"kwargs": kwargs,
|
||||
}
|
||||
)
|
||||
return {"code": 200, "message": "OK"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_detail_create_failure_preserves_push_id_and_biz_id() -> None:
|
||||
collection = DataCollection("remote")
|
||||
@@ -96,6 +113,117 @@ async def test_project_detail_create_failure_preserves_push_id_and_biz_id() -> N
|
||||
assert result.metadata["key"] == "production"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_detail_production_payload_excludes_ic_plan_dates() -> None:
|
||||
collection = DataCollection("remote")
|
||||
|
||||
project = _ProjectNode(
|
||||
node_id="project-node-1",
|
||||
data_id="project-1",
|
||||
data={"id": "project-1"},
|
||||
context={"all_info": {"project_detail": []}},
|
||||
)
|
||||
await collection.add(project)
|
||||
|
||||
node = ProjectDetailSyncNode(
|
||||
node_id="detail-node-1",
|
||||
data_id="local-detail-1",
|
||||
data={
|
||||
"id": "local-detail-1",
|
||||
"project_id": "project-1",
|
||||
"key": "production",
|
||||
"value": [{"date": "2026-01-01", "capacity": 1.0}],
|
||||
"plan_production_date": "2026-01-01",
|
||||
"plan_full_production_date": "2026-06-01",
|
||||
"ic_plan_first_production_date": "2026-02-01",
|
||||
"ic_plan_full_production_date": "2026-07-01",
|
||||
"actual_production_date": "2026-01-15",
|
||||
"actual_full_production_date": "2026-03-15",
|
||||
},
|
||||
)
|
||||
|
||||
handler = ProjectDetailApiHandler()
|
||||
handler.set_collection(collection)
|
||||
handler.api_client = _RecordingApiClient()
|
||||
|
||||
results = await handler.create_all([node])
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status == TaskStatus.IN_PROGRESS
|
||||
assert len(handler.api_client.calls) == 1
|
||||
|
||||
request_payload = handler.api_client.calls[0]["data"]["data"]
|
||||
assert request_payload["plan_production_date"] == "2026-01-01"
|
||||
assert request_payload["plan_full_production_date"] == "2026-06-01"
|
||||
assert request_payload["actual_production_date"] == "2026-01-15"
|
||||
assert request_payload["actual_full_production_date"] == "2026-03-15"
|
||||
assert "ic_plan_first_production_date" not in request_payload
|
||||
assert "ic_plan_full_production_date" not in request_payload
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_detail_create_all_keeps_partial_results_when_schema_check_errors() -> None:
|
||||
collection = DataCollection("remote")
|
||||
|
||||
project = _ProjectNode(
|
||||
node_id="project-node-1",
|
||||
data_id="project-1",
|
||||
data={"id": "project-1"},
|
||||
context={"all_info": {"project_detail": []}},
|
||||
)
|
||||
await collection.add(project)
|
||||
|
||||
valid_node = ProjectDetailSyncNode(
|
||||
node_id="detail-node-1",
|
||||
data_id="local-detail-1",
|
||||
data={
|
||||
"id": "local-detail-1",
|
||||
"project_id": "project-1",
|
||||
"key": "plan_construction",
|
||||
"value": [{"date": "2026-01-01", "capacity": 1.0}],
|
||||
},
|
||||
)
|
||||
invalid_node = ProjectDetailSyncNode(
|
||||
node_id="detail-node-2",
|
||||
data_id="local-detail-2",
|
||||
data={
|
||||
"id": "local-detail-2",
|
||||
"project_id": "project-1",
|
||||
"key": "production",
|
||||
"value": [{"date": "2026-01-02", "capacity": 2.0}],
|
||||
},
|
||||
)
|
||||
|
||||
handler = ProjectDetailApiHandler()
|
||||
handler.set_collection(collection)
|
||||
handler.api_client = _RecordingApiClient()
|
||||
|
||||
class _ExplodingSchema:
|
||||
@classmethod
|
||||
def model_validate(cls, data):
|
||||
raise RuntimeError("schema exploded")
|
||||
|
||||
original_get_update_config = handler._get_update_config
|
||||
|
||||
def _patched_get_update_config(key):
|
||||
config = original_get_update_config(key)
|
||||
if key == "production":
|
||||
assert config is not None
|
||||
return _ExplodingSchema, config[1]
|
||||
return config
|
||||
|
||||
handler._get_update_config = _patched_get_update_config
|
||||
|
||||
results = await handler.create_all([valid_node, invalid_node])
|
||||
|
||||
assert len(results) == 2
|
||||
assert results[0].status == TaskStatus.IN_PROGRESS
|
||||
assert results[1].status == TaskStatus.FAILED
|
||||
assert results[1].error == "schema exploded"
|
||||
assert len(handler.api_client.calls) == 1
|
||||
assert handler.api_client.calls[0]["endpoint"] == "/project/plan_construction"
|
||||
|
||||
|
||||
def test_project_detail_load_allows_same_project_key_with_different_data_id() -> None:
|
||||
collection = DataCollection("remote")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user