113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
# 接口 3 Oracle 仓库:INSERT 绑 fid;按主键认重复;一批 executemany。不连真库。
|
||
|
||
from __future__ import annotations
|
||
|
||
from datetime import date
|
||
from decimal import Decimal
|
||
|
||
import pytest
|
||
|
||
from app.inbound.repo import RepoUnavailable
|
||
from tests.fake_oracle import FakeDb
|
||
|
||
|
||
# 构造一条表 3 落库记录。
|
||
def _record(**overrides):
|
||
row = {
|
||
"fid": 200001,
|
||
"oms_id": 20260928000001,
|
||
"supplier_id": "SUP001",
|
||
"supplier_name": "示例供应商",
|
||
"contract_sign_date": date(2026, 9, 28),
|
||
"contract_start_date": date(2026, 10, 1),
|
||
"contract_end_date": date(2027, 9, 30),
|
||
"payment_term": 90,
|
||
"goods_id": "G000123456789",
|
||
"goods_name": "阿莫西林胶囊",
|
||
"reg_no": "国药准字H20201234",
|
||
"spec": "0.25g*24粒",
|
||
"unit": "盒",
|
||
"qty": Decimal("10.0000"),
|
||
"purchase_tax_rate": Decimal("0.1300"),
|
||
"unit_price": Decimal("100.0000"),
|
||
"goods_source_id": "GS001",
|
||
"purchaser_id": "P001",
|
||
"purchaser_name": "张三",
|
||
"planner_id": "PL001",
|
||
"planner_name": "李四",
|
||
"contract_entry_status": None,
|
||
"contract_no": None,
|
||
"org_code": "901",
|
||
"customer_type": 1,
|
||
"goods_mdm_code": "QX0100167583",
|
||
"supplier_mdm_code": "DW0100046361",
|
||
"process_status": 0,
|
||
}
|
||
row.update(overrides)
|
||
return row
|
||
|
||
|
||
# 缺 host 时 get_pool 抛「数据库不可用」。
|
||
def test_from_env_without_host_raises(monkeypatch):
|
||
monkeypatch.delenv("RPA_ORACLE_HOST", raising=False)
|
||
import app.main as main
|
||
|
||
main._pool = None
|
||
with pytest.raises(RepoUnavailable) as caught:
|
||
main.get_pool()
|
||
assert caught.value.message == "数据库不可用"
|
||
|
||
|
||
# pk_rpa_pcd 冲突时 insert_many 把该 fid 放进重复集合。
|
||
def test_insert_unique_violation_is_duplicate_fid():
|
||
from app.inbound.oracle_contract_repo import OraclePurchaseContractRepo
|
||
|
||
db = FakeDb()
|
||
db.collide_contracts.add(200001)
|
||
repo = OraclePurchaseContractRepo(db.connection())
|
||
collided = repo.insert_many([_record()])
|
||
assert collided == {200001}
|
||
|
||
|
||
# 未知唯一约束不当成 fid 重复,抛「数据库不可用」。
|
||
def test_unknown_unique_constraint_raises_unavailable():
|
||
from app.inbound.oracle_contract_repo import OraclePurchaseContractRepo
|
||
|
||
db = FakeDb()
|
||
db.collide_contracts.add(200001)
|
||
db.collide_constraint = "UK_SOMETHING_ELSE"
|
||
repo = OraclePurchaseContractRepo(db.connection())
|
||
with pytest.raises(RepoUnavailable) as caught:
|
||
repo.insert_many([_record()])
|
||
assert caught.value.message == "数据库不可用"
|
||
|
||
|
||
# 待插入多行时一次 executemany,且 batcherrors=True。
|
||
def test_insert_many_uses_executemany():
|
||
from app.inbound.oracle_contract_repo import OraclePurchaseContractRepo
|
||
|
||
db = FakeDb()
|
||
repo = OraclePurchaseContractRepo(db.connection())
|
||
assert repo.existing_fids([1, 2]) == set()
|
||
collided = repo.insert_many([_record(fid=1, oms_id=1), _record(fid=2, oms_id=2)])
|
||
assert collided == set()
|
||
assert set(db.contracts) == {1, 2}
|
||
many = [c for c in db.calls if c[0] == "executemany"]
|
||
assert len(many) == 1
|
||
assert many[0][3] is True
|
||
|
||
|
||
# INSERT 绑来源 fid,process_status 用字面量 0。
|
||
def test_insert_sql_binds_source_fid_and_pending_status():
|
||
from app.inbound.oracle_contract_repo import _BIND_KEYS, _INSERT_SQL
|
||
|
||
sql = " ".join(_INSERT_SQL.split())
|
||
assert "fid" in sql
|
||
assert ":fid" in sql
|
||
assert "process_status" in sql
|
||
assert "SYSTIMESTAMP" in sql
|
||
assert "fid" in _BIND_KEYS
|
||
assert "oms_id" in _BIND_KEYS
|
||
assert "goods_mdm_code" in _BIND_KEYS
|
||
assert "supplier_mdm_code" in _BIND_KEYS
|