ETL 完成

This commit is contained in:
Neo
2026-01-18 22:37:38 +08:00
parent 8da6cb6563
commit 7ca19a4a2c
159 changed files with 31225 additions and 467 deletions

View File

@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
"""Unit tests for recent/former endpoint routing."""
import sys
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo
import pytest
PROJECT_ROOT = Path(__file__).resolve().parents[2]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from api.endpoint_routing import plan_calls, recent_boundary
TZ = ZoneInfo("Asia/Shanghai")
def _now():
return datetime(2025, 12, 18, 10, 0, 0, tzinfo=TZ)
def test_recent_boundary_month_start():
b = recent_boundary(_now())
assert b.isoformat() == "2025-09-01T00:00:00+08:00"
def test_paylog_routes_to_former_when_old_window():
params = {"siteId": 1, "StartPayTime": "2025-08-01 00:00:00", "EndPayTime": "2025-08-02 00:00:00"}
calls = plan_calls("/PayLog/GetPayLogListPage", params, now=_now(), tz=TZ)
assert [c.endpoint for c in calls] == ["/PayLog/GetFormerPayLogListPage"]
def test_coupon_usage_stays_same_path_even_when_old():
params = {"siteId": 1, "startTime": "2025-08-01 00:00:00", "endTime": "2025-08-02 00:00:00"}
calls = plan_calls("/Promotion/GetOfflineCouponConsumePageList", params, now=_now(), tz=TZ)
assert [c.endpoint for c in calls] == ["/Promotion/GetOfflineCouponConsumePageList"]
def test_goods_outbound_routes_to_queryformer_when_old():
params = {"siteId": 1, "startTime": "2025-08-01 00:00:00", "endTime": "2025-08-02 00:00:00"}
calls = plan_calls("/GoodsStockManage/QueryGoodsOutboundReceipt", params, now=_now(), tz=TZ)
assert [c.endpoint for c in calls] == ["/GoodsStockManage/QueryFormerGoodsOutboundReceipt"]
def test_settlement_records_split_when_crossing_boundary():
params = {"siteId": 1, "rangeStartTime": "2025-08-15 00:00:00", "rangeEndTime": "2025-09-10 00:00:00"}
calls = plan_calls("/Site/GetAllOrderSettleList", params, now=_now(), tz=TZ)
assert [c.endpoint for c in calls] == ["/Site/GetFormerOrderSettleList", "/Site/GetAllOrderSettleList"]
assert calls[0].params["rangeEndTime"] == "2025-09-01 00:00:00"
assert calls[1].params["rangeStartTime"] == "2025-09-01 00:00:00"
@pytest.mark.parametrize(
"endpoint",
[
"/PayLog/GetFormerPayLogListPage",
"/Site/GetFormerOrderSettleList",
"/GoodsStockManage/QueryFormerGoodsOutboundReceipt",
],
)
def test_explicit_former_endpoint_not_rerouted(endpoint):
params = {"siteId": 1, "startTime": "2025-08-01 00:00:00", "endTime": "2025-08-02 00:00:00"}
calls = plan_calls(endpoint, params, now=_now(), tz=TZ)
assert [c.endpoint for c in calls] == [endpoint]

View File

@@ -23,7 +23,7 @@ def _build_config(tmp_path):
def test_assistant_accounts_masters_ingest(tmp_path):
"""Ensure assistant_accounts_masterS task stores raw payload with record_index dedup keys."""
"""Ensure ODS_ASSISTANT_ACCOUNT stores raw payload with record_index dedup keys."""
config = _build_config(tmp_path)
sample = [
{
@@ -33,7 +33,7 @@ def test_assistant_accounts_masters_ingest(tmp_path):
}
]
api = FakeAPIClient({"/PersonnelManagement/SearchAssistantInfo": sample})
task_cls = ODS_TASK_CLASSES["assistant_accounts_masterS"]
task_cls = ODS_TASK_CLASSES["ODS_ASSISTANT_ACCOUNT"]
with get_db_operations() as db_ops:
task = task_cls(config, db_ops, api, logging.getLogger("test_assistant_accounts_masters"))
@@ -50,7 +50,7 @@ def test_assistant_accounts_masters_ingest(tmp_path):
def test_goods_stock_movements_ingest(tmp_path):
"""Ensure goods_stock_movements task stores raw payload with record_index dedup keys."""
"""Ensure ODS_INVENTORY_CHANGE stores raw payload with record_index dedup keys."""
config = _build_config(tmp_path)
sample = [
{
@@ -60,7 +60,7 @@ def test_goods_stock_movements_ingest(tmp_path):
}
]
api = FakeAPIClient({"/GoodsStockManage/QueryGoodsOutboundReceipt": sample})
task_cls = ODS_TASK_CLASSES["goods_stock_movements"]
task_cls = ODS_TASK_CLASSES["ODS_INVENTORY_CHANGE"]
with get_db_operations() as db_ops:
task = task_cls(config, db_ops, api, logging.getLogger("test_goods_stock_movements"))
@@ -110,11 +110,11 @@ def test_ods_payment_ingest(tmp_path):
def test_ods_settlement_records_ingest(tmp_path):
"""Ensure settlement_records task stores settleList raw JSON."""
"""Ensure ODS_SETTLEMENT_RECORDS stores settleList raw JSON."""
config = _build_config(tmp_path)
sample = [{"data": {"settleList": [{"id": 701, "orderTradeNo": 8001}]}}]
sample = [{"id": 701, "orderTradeNo": 8001}]
api = FakeAPIClient({"/Site/GetAllOrderSettleList": sample})
task_cls = ODS_TASK_CLASSES["settlement_records"]
task_cls = ODS_TASK_CLASSES["ODS_SETTLEMENT_RECORDS"]
with get_db_operations() as db_ops:
task = task_cls(config, db_ops, api, logging.getLogger("test_settlement_records"))