125 lines
4.7 KiB
Python
125 lines
4.7 KiB
Python
from datetime import date
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from yuqei_sdk.ai_platform import ContractReviewRequest
|
|
from yuqei_sdk.review_material_preflight import (
|
|
REVIEW_MATERIAL_PREFLIGHT_VERSION,
|
|
build_review_material_preflight,
|
|
preflight_prompt_context,
|
|
verify_review_material_preflight,
|
|
)
|
|
|
|
|
|
REFERENCE = "甲方:华北设备有限公司\n乙方:远航租赁有限公司\n双方签署设备租赁合同。"
|
|
|
|
|
|
def test_signing_preflight_detects_types_parties_expiry_duplicates_and_versions():
|
|
text = """【材料一:授权委托书 版本 V1】
|
|
甲方:华北设备有限公司
|
|
有效期至:2025年12月31日
|
|
授权代表张三签署设备租赁合同。
|
|
【材料二:授权委托书 版本 V2】
|
|
甲方:华北设备有限公司
|
|
有效期至:2027年12月31日
|
|
授权代表李四签署设备租赁合同。
|
|
【材料三:重复扫描件】
|
|
甲方:华北设备有限公司
|
|
有效期至:2027年12月31日
|
|
授权代表李四签署设备租赁合同。"""
|
|
|
|
result = build_review_material_preflight(
|
|
review_target="signing_package",
|
|
source_title="签署材料包.txt",
|
|
source_text=text,
|
|
reference_contract_text=REFERENCE,
|
|
source_content_type="text/plain",
|
|
as_of_date=date(2026, 8, 29),
|
|
)
|
|
|
|
assert result.policy_version == REVIEW_MATERIAL_PREFLIGHT_VERSION
|
|
assert result.status == "needs_attention" and not result.blocks_submission
|
|
assert "power_of_attorney" in result.detected_document_types
|
|
assert result.version_labels == ["V1", "V2"]
|
|
codes = {item.code for item in result.issues}
|
|
assert {"EXPIRED_MATERIAL", "MULTIPLE_MATERIAL_VERSIONS", "DUPLICATE_MATERIAL"}.issubset(codes)
|
|
assert result.items[2].duplicate_of == result.items[1].id
|
|
assert verify_review_material_preflight(
|
|
result,
|
|
review_target="signing_package",
|
|
source_text=text,
|
|
reference_contract_text=REFERENCE,
|
|
)
|
|
|
|
|
|
def test_unreadable_material_blocks_before_model_but_unclear_readable_material_does_not():
|
|
blocked = build_review_material_preflight(
|
|
review_target="performance_evidence",
|
|
source_title="空材料.txt",
|
|
source_text="",
|
|
reference_contract_text=REFERENCE,
|
|
as_of_date=date(2026, 8, 29),
|
|
)
|
|
assert blocked.status == "blocked" and blocked.blocks_submission
|
|
assert "MATERIAL_TEXT_EMPTY" in {item.code for item in blocked.issues}
|
|
|
|
unclear = build_review_material_preflight(
|
|
review_target="performance_evidence",
|
|
source_title="说明.txt",
|
|
source_text="甲方:华北设备有限公司\n现场情况已经记录,待进一步核对。",
|
|
reference_contract_text=REFERENCE,
|
|
as_of_date=date(2026, 8, 29),
|
|
)
|
|
assert unclear.status == "needs_attention" and not unclear.blocks_submission
|
|
assert "MATERIAL_TYPE_UNCLEAR" in {item.code for item in unclear.issues}
|
|
|
|
|
|
def test_contract_text_preflight_is_explicitly_not_applicable_and_hash_stable():
|
|
first = build_review_material_preflight(
|
|
review_target="contract_text",
|
|
source_title="合同正文",
|
|
source_text=REFERENCE,
|
|
as_of_date=date(2026, 8, 29),
|
|
)
|
|
second = build_review_material_preflight(
|
|
review_target="contract_text",
|
|
source_title="合同正文",
|
|
source_text=REFERENCE,
|
|
as_of_date=date(2026, 8, 29),
|
|
)
|
|
assert first.status == "not_applicable"
|
|
assert first.evidence_sha256 == second.evidence_sha256
|
|
assert preflight_prompt_context(first) == ""
|
|
|
|
|
|
def test_review_request_rejects_tampered_or_rebound_preflight():
|
|
text = "甲方:华北设备有限公司\n签署页由授权代表签字并加盖合同章。"
|
|
preflight = build_review_material_preflight(
|
|
review_target="signing_package",
|
|
source_title="签署页.txt",
|
|
source_text=text,
|
|
reference_contract_text=REFERENCE,
|
|
as_of_date=date(2026, 8, 29),
|
|
)
|
|
request = ContractReviewRequest(
|
|
contract_title="设备租赁合同",
|
|
contract_text=text,
|
|
reference_contract_text=REFERENCE,
|
|
review_target="signing_package",
|
|
review_profile="scene_evaluation_v3",
|
|
material_preflight=preflight,
|
|
)
|
|
assert request.material_preflight.evidence_sha256 == preflight.evidence_sha256
|
|
|
|
tampered = preflight.model_copy(update={"status": "blocked"})
|
|
with pytest.raises(ValidationError, match="immutable review inputs"):
|
|
ContractReviewRequest(
|
|
contract_title="设备租赁合同",
|
|
contract_text=text,
|
|
reference_contract_text=REFERENCE,
|
|
review_target="signing_package",
|
|
review_profile="scene_evaluation_v3",
|
|
material_preflight=tampered,
|
|
)
|