AutoRpa/rpa_oms/tests/test_oracle_cart_repo.py

137 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 接口 2 Oracle 取数:SQL 按 oms_id 整组截断;一次 UPDATE 回写。不连真库。
from __future__ import annotations
import pytest
from app.inbound.repo import RepoUnavailable
from app.outbound.oracle_repo import _LIST_UNPUSHED_SQL, OracleCartSettlementRepo
from tests.fake_oracle import FakeDb, ora_error
# 构造一条表 2 未推行。
def _cart(**overrides) -> dict:
row = {
"fid": 1,
"operate_type": 1,
"oms_id": 1,
"platform_type": 48,
"supplier_name": "示例供应商",
"bar_code": "06901234567890",
"purchase_price": 128.5,
"purchase_qty": 10,
"purchase_total": 1285,
"status": 1,
"fail_reason": None,
"pay_order_no": None,
"pay_order_dtl_id": None,
"org_code": "901",
"push_status": 0,
}
row.update(overrides)
return row
# 取数 SQL 只捞 push_status=0,按 oms_id 分组,并用 :limit 在库侧截断。
def test_list_sql_filters_unpushed_and_partitions_by_oms_id():
sql = " ".join(_LIST_UNPUSHED_SQL.split()).lower()
assert "rpa_cart_settlement_goods_data" in sql
assert "push_status = 0" in sql
assert "partition by" in sql
assert "oms_id" in sql
assert ":limit" in sql
assert "running_start" in sql
assert "order by" in sql and "oms_id" in sql
# 假连接返回的列名转小写后能对上组装层字段。
def test_list_unpushed_maps_columns():
db = FakeDb()
db.carts[100001] = _cart(
fid=100001,
oms_id=20260928000001,
bar_code="06901234567890",
)
repo = OracleCartSettlementRepo(db.connection())
rows = repo.list_unpushed(limit=500)
assert rows[0]["fid"] == 100001
assert rows[0]["operate_type"] == 1
assert rows[0]["bar_code"] == "06901234567890"
assert rows[0]["push_status"] == 0
assert db.closes == 0
# limit=3 时同一 omsId 三行整组进批,多出的另一组留下。
def test_list_unpushed_keeps_whole_oms_group_when_limit_is_3():
db = FakeDb()
db.carts[1] = _cart(fid=1, oms_id=1)
db.carts[2] = _cart(fid=2, oms_id=1)
db.carts[3] = _cart(fid=3, oms_id=1)
db.carts[4] = _cart(fid=4, oms_id=2)
repo = OracleCartSettlementRepo(db.connection())
rows = repo.list_unpushed(limit=3)
assert [row["fid"] for row in rows] == [1, 2, 3]
sql, params = _last_execute(db)
assert "partition by" in sql.lower()
assert params["limit"] == 3
# 库故障对外固定「数据库不可用」,不含 ORA 原文。
def test_list_unpushed_hides_ora_text():
db = FakeDb()
db.raise_execute = ora_error(12541, "ORA-12541: TNS:no listener")
repo = OracleCartSettlementRepo(db.connection())
with pytest.raises(RepoUnavailable) as caught:
repo.list_unpushed(limit=500)
assert caught.value.message == "数据库不可用"
assert "ORA-" not in str(caught.value)
# 回写 push_status 只发一条 UPDATE ... WHERE fid IN (...)。
def test_mark_pushed_updates_in_one_statement():
db = FakeDb()
db.carts[1] = _cart(fid=1)
db.carts[2] = _cart(fid=2)
repo = OracleCartSettlementRepo(db.connection())
repo.mark_pushed([1, 2], status=1, reason="ok")
updates = [
call for call in db.calls if call[0] == "execute" and "UPDATE" in call[1].upper()
]
assert len(updates) == 1
sql = updates[0][1].upper()
assert "RPA_CART_SETTLEMENT_GOODS_DATA" in sql
assert "FID IN" in sql
assert db.carts[1]["push_status"] == 1
assert db.carts[2]["push_status"] == 1
assert db.carts[1]["push_result"] == "ok"
assert db.commits == 1
# 空 fid 列表不发 SQL、不 commit。
def test_mark_pushed_empty_fids_does_not_touch_db():
db = FakeDb()
repo = OracleCartSettlementRepo(db.connection())
repo.mark_pushed([], status=1, reason=None)
assert db.calls == []
assert db.commits == 0
# 回写失败对外固定「数据库不可用」。
def test_mark_pushed_hides_ora_text():
db = FakeDb()
db.carts[1] = _cart(fid=1)
db.raise_execute = ora_error(3113, "ORA-03113: end-of-file on communication channel")
repo = OracleCartSettlementRepo(db.connection())
with pytest.raises(RepoUnavailable) as caught:
repo.mark_pushed([1], status=2, reason="fail")
assert caught.value.message == "数据库不可用"
assert "ORA-" not in str(caught.value)
# 取出最近一次 execute 的 SQL 和绑定。
def _last_execute(db: FakeDb) -> tuple[str, dict]:
execute_calls = [call for call in db.calls if call[0] == "execute"]
assert execute_calls
_, sql, params = execute_calls[-1]
return sql, params or {}