# 接口 4 Oracle 取数:SQL 按非空 contractNo 整组截断;一次 UPDATE 回写。不连真库。 from __future__ import annotations import pytest from app.inbound.repo import RepoUnavailable from app.outbound.oracle_repo import _LIST_AGREEMENT_SQL, OracleContractAgreementRepo from tests.fake_oracle import FakeDb, ora_error # 构造一条表 4 未推行。 def _agreement(**overrides) -> dict: row = { "fid": 1, "oms_id": 1, "action_code": 1, "contract_status": 1, "contract_fail_reason": None, "contract_no": "HT1", "agreement_status": None, "agreement_fail_reason": None, "agreement_id": None, "agreement_dtl_id": None, "org_code": "901", "push_status": 0, } row.update(overrides) return row # 取数 SQL 只捞 push_status=0,按非空合同号分组,并用 :limit 在库侧截断。 def test_list_sql_filters_unpushed_and_partitions_by_contract_no(): sql = " ".join(_LIST_AGREEMENT_SQL.split()).lower() assert "rpa_contract_agreement_result" in sql assert "push_status = 0" in sql assert "partition by" in sql assert "contract_no" in sql assert ":limit" in sql assert "running_start" in sql # limit=3 时同一非空 contractNo 三行整组进批,多出的另一组留下。 def test_list_unpushed_keeps_whole_contract_no_group_when_limit_is_3(): db = FakeDb() db.agreements[1] = _agreement(fid=1, oms_id=1, contract_no="HT-A") db.agreements[2] = _agreement(fid=2, oms_id=2, contract_no="HT-A") db.agreements[3] = _agreement(fid=3, oms_id=3, contract_no="HT-A") db.agreements[4] = _agreement(fid=4, oms_id=4, contract_no="HT-B") repo = OracleContractAgreementRepo(db.connection()) rows = repo.list_unpushed(limit=3) assert [row["fid"] for row in rows] == [1, 2, 3] execute_calls = [call for call in db.calls if call[0] == "execute"] sql, params = execute_calls[-1][1], execute_calls[-1][2] 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 = OracleContractAgreementRepo(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.agreements[1] = _agreement(fid=1) db.agreements[2] = _agreement(fid=2) repo = OracleContractAgreementRepo(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_CONTRACT_AGREEMENT_RESULT" in sql assert "FID IN" in sql assert db.agreements[1]["push_status"] == 1 assert db.agreements[2]["push_result"] == "ok" assert db.commits == 1