Refine travel reimbursement steward flow
Align planner, runtime rules, and policy assets so travel guidance matches the updated reimbursement workflow.
This commit is contained in:
138
server/tests/test_steward_flow_state.py
Normal file
138
server/tests/test_steward_flow_state.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from app.schemas.steward import (
|
||||
StewardCandidateFlow,
|
||||
StewardFlowStatePatch,
|
||||
StewardPendingFlowConfirmation,
|
||||
StewardPlanResponse,
|
||||
)
|
||||
from app.services.steward_flow_state import StewardFlowStateService
|
||||
|
||||
|
||||
def test_state_merge_keeps_application_and_reimbursement_flows() -> None:
|
||||
service = StewardFlowStateService()
|
||||
|
||||
state = service.merge_state(
|
||||
{},
|
||||
StewardFlowStatePatch(
|
||||
active_flow="travel_application",
|
||||
flow_id="travel_application",
|
||||
intent="travel_application_create",
|
||||
fields={"expense_type": "travel", "location": "上海", "reason": "客户现场支撑"},
|
||||
missing_fields=["transport_mode"],
|
||||
),
|
||||
)
|
||||
state = service.merge_state(
|
||||
state,
|
||||
StewardFlowStatePatch(
|
||||
active_flow="travel_reimbursement",
|
||||
flow_id="travel_reimbursement",
|
||||
intent="travel_reimbursement_draft",
|
||||
fields={"amount": "708.00", "invoice_no": "NO-1"},
|
||||
linked_application_claim_id="claim-app-001",
|
||||
),
|
||||
)
|
||||
|
||||
assert state["active_flow"] == "travel_reimbursement"
|
||||
assert state["flows"]["travel_application"]["fields"]["location"] == "上海"
|
||||
assert state["flows"]["travel_application"]["missing_fields"] == ["transport_mode"]
|
||||
assert state["flows"]["travel_reimbursement"]["fields"]["amount"] == "708.00"
|
||||
assert state["flows"]["travel_reimbursement"]["linked_application_claim_id"] == "claim-app-001"
|
||||
|
||||
|
||||
def test_state_merge_filters_non_ontology_fields() -> None:
|
||||
service = StewardFlowStateService()
|
||||
|
||||
state = service.merge_state(
|
||||
{},
|
||||
StewardFlowStatePatch(
|
||||
active_flow="travel_application",
|
||||
flow_id="travel_application",
|
||||
intent="travel_application_create",
|
||||
fields={
|
||||
"location": "上海",
|
||||
"invented_field": "x",
|
||||
"occurred_date": "2026-06-15",
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
assert state["flows"]["travel_application"]["fields"] == {
|
||||
"location": "上海",
|
||||
"time_range": "2026-06-15",
|
||||
}
|
||||
|
||||
|
||||
def test_state_merge_appends_traceable_events() -> None:
|
||||
service = StewardFlowStateService()
|
||||
|
||||
state = service.merge_state(
|
||||
{},
|
||||
StewardFlowStatePatch(
|
||||
active_flow="travel_application",
|
||||
flow_id="travel_application",
|
||||
intent="travel_application_create",
|
||||
fields={"location": "北京"},
|
||||
evidence=[{"source": "user_message", "field": "location", "text": "去北京出差"}],
|
||||
),
|
||||
)
|
||||
|
||||
assert len(state["events"]) == 1
|
||||
assert state["events"][0]["flow_id"] == "travel_application"
|
||||
assert state["events"][0]["intent"] == "travel_application_create"
|
||||
assert state["events"][0]["fields"] == {"location": "北京"}
|
||||
assert state["events"][0]["evidence"][0]["text"] == "去北京出差"
|
||||
|
||||
|
||||
def test_state_merge_plan_keeps_pending_flow_confirmation() -> None:
|
||||
service = StewardFlowStateService()
|
||||
|
||||
state = service.merge_plan(
|
||||
{},
|
||||
StewardPlanResponse(
|
||||
plan_id="steward_plan_pending",
|
||||
plan_status="needs_flow_confirmation",
|
||||
planning_source="llm_function_call",
|
||||
next_action="confirm_flow",
|
||||
summary="需要先确认是申请还是报销。",
|
||||
pending_flow_confirmation=StewardPendingFlowConfirmation(
|
||||
status="pending",
|
||||
source_message="2月20-23日去上海出差辅助国网仿生产环境部署",
|
||||
reason="缺少申请或报销动作词。",
|
||||
candidate_flows=[
|
||||
StewardCandidateFlow(
|
||||
flow_id="travel_application",
|
||||
label="补办出差申请",
|
||||
confidence=0.52,
|
||||
reason="可能是补办申请。",
|
||||
ontology_fields={
|
||||
"time_range": "2026-02-20",
|
||||
"location": "上海",
|
||||
"expense_type": "travel",
|
||||
"reason": "辅助国网仿生产环境部署",
|
||||
},
|
||||
missing_fields=["transport_mode"],
|
||||
),
|
||||
StewardCandidateFlow(
|
||||
flow_id="travel_reimbursement",
|
||||
label="发起费用报销",
|
||||
confidence=0.48,
|
||||
reason="可能是发起报销。",
|
||||
ontology_fields={
|
||||
"time_range": "2026-02-20",
|
||||
"location": "上海",
|
||||
"expense_type": "travel",
|
||||
"reason": "辅助国网仿生产环境部署",
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assert state["active_flow"] == ""
|
||||
assert state["pending_flow_confirmation"]["status"] == "pending"
|
||||
assert state["flows"]["travel_application"]["status"] == "pending_flow_confirmation"
|
||||
assert state["flows"]["travel_application"]["fields"]["location"] == "上海"
|
||||
assert state["flows"]["travel_application"]["missing_fields"] == ["transport_mode"]
|
||||
assert state["flows"]["travel_reimbursement"]["fields"]["time_range"] == "2026-02-20"
|
||||
Reference in New Issue
Block a user