Files
X-Financial/server/tests/test_risk_rule_flow_diagram_model.py

109 lines
3.8 KiB
Python
Raw Permalink Normal View History

from __future__ import annotations
from app.services.risk_rule_flow_diagram import (
RiskRuleFlowDiagramField,
RiskRuleFlowDiagramRenderer,
build_risk_rule_flow_diagram_spec,
)
FIELDS = (
RiskRuleFlowDiagramField(key="claim.amount", label="申请金额"),
RiskRuleFlowDiagramField(key="budget.remaining_amount", label="可用预算"),
RiskRuleFlowDiagramField(key="claim.reason", label="申请事由"),
)
def test_flow_diagram_spec_prefers_flow_model_nodes() -> None:
spec = build_risk_rule_flow_diagram_spec(
{"name": "预算余额校验", "metadata": {"condition_summary": "legacy summary"}},
fields=FIELDS,
domain_label="差旅费",
severity="high",
severity_label="高风险",
flow_model={
"nodes": [
{"id": "start", "type": "start", "title": "开始", "description": "费用申请提交"},
{
"id": "evidence",
"type": "evidence",
"title": "字段事实",
"description": "读取申请金额与可用预算",
"fields": ["claim.amount", "budget.remaining_amount"],
},
{
"id": "amount_exceeds_budget",
"type": "decision",
"title": "金额超过预算",
"description": "申请金额大于可用预算余额",
},
{"id": "pass", "type": "pass", "description": "预算充足,继续流转"},
{"id": "hit", "type": "risk", "description": "进入预算复核"},
],
"metadata": {"hit_logic": "amount_exceeds_budget"},
},
)
assert spec.start == "费用申请提交"
assert spec.fact_lines[:2] == (
"A=申请金额[claim.amount]",
"B=可用预算[budget.remaining_amount]",
)
assert spec.condition_lines == ("金额超过预算: 申请金额大于可用预算余额",)
assert spec.hit_logic == "amount_exceeds_budget"
svg = RiskRuleFlowDiagramRenderer().render(spec)
assert "金额超过预算" in svg
assert "#dc2626" in svg
def test_flow_diagram_spec_falls_back_to_dsl_when_flow_model_missing() -> None:
spec = build_risk_rule_flow_diagram_spec(
{
"name": "重复发票校验",
"params": {
"conditions": [
{
"id": "same_invoice_no_repeated",
"operator": "duplicate_value",
"fields": ["claim.reason"],
}
],
"hit_logic": {"all": ["same_invoice_no_repeated"]},
},
"metadata": {"condition_summary": "发票号重复时命中"},
},
fields=FIELDS,
domain_label="通用",
severity="medium",
severity_label="中风险",
flow_model={},
)
assert spec.condition_lines == ("same_invoice_no_repeated: 申请事由 出现重复值",)
assert spec.hit_logic == "same_invoice_no_repeated"
assert "发票号重复时命中" in spec.basis
def test_flow_diagram_spec_compresses_too_many_decision_nodes() -> None:
nodes = [{"id": "start", "type": "start", "description": "提交单据"}]
nodes.extend(
{
"id": f"condition_{index}",
"type": "decision",
"title": f"判断{index}",
"description": f"{index}个判断条件",
}
for index in range(1, 7)
)
spec = build_risk_rule_flow_diagram_spec(
{"name": "复杂规则"},
fields=FIELDS,
domain_label="通用",
severity="low",
severity_label="低风险",
flow_model={"nodes": nodes},
)
assert len(spec.condition_lines) == 4
assert "另有 2 个判断节点" in spec.condition_lines[-1]