Files
gaokao-volunteer-system/admin/tests/test_web_public_review_flow.py
Hermes Agent 092f8cc907
Some checks failed
CI / pytest (Python 3.10) (push) Has been cancelled
CI / pytest (Python 3.11) (push) Has been cancelled
CI / pytest (Python 3.12) (push) Has been cancelled
frontend: 五轮首页与复核页结构减法,逼近高信任付费服务页标准
改版主线:
- /review/start: 从系统运营页改成用户结果页(不再暴露 JSON/go_step1)
- 首页:省份改下拉,表单压缩为 3 字段并移出 hero 核心区
- hero: 副文案压缩为一句,去掉三张说明卡与了解流程链接
- trust strip: 4→3,右侧判断块压缩为一句风险+上传能力
- browser_vision 复验确认:说明书感已显著下降,结构已从功能堆叠过渡到决策引导

测试基线同步:
- test_web_public.py: 首页副文案/流程编号/说明卡断言更新
- test_web_public_review_flow.py: 复核页断言改为用户视角文案

文档:
- docs/FRONTEND_PRODUCTION_REMEDIATION_PLAN_2026-06-26.md 记录整改真相源
2026-06-26 12:30:43 +08:00

1020 lines
36 KiB
Python

"""用户端复核、冲稳保、报告与工作台链路测试。"""
from __future__ import annotations
from data.orders.dao import OrdersDAO
def test_landing_page_provides_review_entry_source_link(client):
resp = client.get("/")
assert resp.status_code == 200, resp.text
assert 'href="/review/start?source=home"' in resp.text
def test_landing_page_review_consult_form_targets_review_start(client):
resp = client.get("/")
assert resp.status_code == 200, resp.text
assert 'form action="/review/start" method="get"' in resp.text
assert 'name="source" value="home"' in resp.text
def test_landing_page_uses_review_as_workspace_primary_action_when_step1_complete(
client, settings
):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
payment_id = body["checkout_url"].split("/pay/mock/")[1].split("?")[0]
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="submit",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
consent_version="portal-v1",
consent_scope="step1",
privacy_accepted=True,
service_terms_accepted=True,
guardian_confirmed=True,
),
settings,
)
landing = client.get(f"/?token={token}")
assert landing.status_code == 200, landing.text
assert "工作台主动作" in landing.text
assert "开始方案复核" in landing.text
assert f"/review/start?source=home&token={token}" in landing.text
def test_review_start_page_renders_user_facing_result_not_ops_process_page(
client, settings
):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
payment_id = body["checkout_url"].split("/pay/mock/")[1].split("?")[0]
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="draft",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
existing_plan_summary="已有一版志愿方案,想先看有没有明显风险",
),
settings,
)
resp = client.get(f"/review/start?source=status&token={token}")
assert resp.status_code == 200, resp.text
# 新口径:这是用户结果页,不是系统入口/流程说明页
assert "复核结果" in resp.text or "初步评估结果" in resp.text
assert "方案复核入口" not in resp.text
assert "审核输入" not in resp.text
assert "最小约束" not in resp.text
assert "审核输出摘要" not in resp.text
assert "下一步分流" not in resp.text
# 必须保留用户可理解的结果与下一步
assert "风险等级" in resp.text
assert "核心问题" in resp.text
assert "下一步建议" in resp.text
assert "已有一版志愿方案,想先看有没有明显风险" in resp.text
assert "物理 / 化学 / 生物" in resp.text
# 不得暴露内部 JSON / review_result_id / action slug
assert "review_result_id" not in resp.text
assert '"risk_level"' not in resp.text
assert "go_step1" not in resp.text
assert "go_cwb" not in resp.text
assert "go_full_plan" not in resp.text
def test_status_page_provides_review_entry_source_link(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
resp = client.get(f"/portal/{token}/status")
assert resp.status_code == 200, resp.text
assert f"/review/start?source=status&token={token}" in resp.text
def test_report_page_provides_review_entry_source_link(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
payment_id = body["checkout_url"].split("/pay/mock/")[1].split("?")[0]
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
with OrdersDAO.connect(settings.orders_db_path) as dao:
dao.transition_status(
body["order_id"], "serving", actor="test", reason="seed_report_serving"
)
dao.transition_status(
body["order_id"], "delivered", actor="test", reason="seed_report_ready"
)
dao.update(
body["order_id"],
{
"audit_report": "data/examples/gaokao_report_李明_20260611_122443.html",
"pdf_path": "data/examples/gaokao_report_李明_20260611_122443.pdf",
},
actor="test",
reason="seed_report_ready_paths",
)
resp = client.get(f"/portal/{token}/report")
assert resp.status_code == 200, resp.text
assert "/review/start?source=report&token=" in resp.text
def test_review_start_persists_result_contract_and_source(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
resp = client.get(f"/review/start?source=status&token={token}")
assert resp.status_code == 200, resp.text
# 页面已改为用户结果页,不再暴露内部 JSON 字段
assert "复核结果" in resp.text or "初步评估结果" in resp.text
assert "风险等级" in resp.text
assert "核心问题" in resp.text
assert "下一步建议" in resp.text
# 不再暴露内部 action slug
assert "go_step1" not in resp.text
assert "go_cwb" not in resp.text
assert "go_full_plan" not in resp.text
def test_review_action_updates_followup_action(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
start = client.get(f"/review/start?source=status&token={token}")
assert start.status_code == 200, start.text
action = client.post(
"/review/action",
data={"token": token, "action": "step1"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
assert action.headers["location"].endswith(f"/portal/{token}/info")
def test_review_action_cwb_redirects_to_real_cwb_page(route_client, client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
start = client.get(f"/review/start?source=status&token={token}")
assert start.status_code == 200, start.text
action = client.post(
"/review/action",
data={"token": token, "action": "cwb"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
assert action.headers["location"].endswith(f"/portal/{token}/cwb")
cwb = client.get(action.headers["location"])
assert cwb.status_code == 200, cwb.text
assert "冲稳保建议页" in cwb.text
assert "当前建议" in cwb.text
assert "冲刺建议" in cwb.text
def test_cwb_page_is_first_class_three_column_workspace(route_client, client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
start = client.get(f"/review/start?source=status&token={token}")
assert start.status_code == 200, start.text
action = client.post(
"/review/action",
data={"token": token, "action": "cwb"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
cwb = client.get(f"/portal/{token}/cwb")
assert cwb.status_code == 200, cwb.text
assert "冲稳保建议页" in cwb.text
assert "冲刺建议" in cwb.text
assert "稳妥建议" in cwb.text
assert "保底建议" in cwb.text
assert "当前建议" in cwb.text
def test_cwb_page_exposes_review_summary_and_next_actions(
route_client, client, settings
):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
client.get(f"/review/start?source=report&token={token}")
client.post(
"/review/action",
data={"token": token, "action": "cwb"},
follow_redirects=False,
)
cwb = client.get(f"/portal/{token}/cwb")
assert cwb.status_code == 200, cwb.text
assert "当前复核摘要" in cwb.text
assert "下一步建议" in cwb.text
assert f"/portal/{token}/full-plan" in cwb.text
assert f"/portal/{token}/status" in cwb.text
def test_cwb_page_no_longer_claims_placeholder_future_work(
route_client, client, settings
):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
client.get(f"/review/start?source=status&token={token}")
action = client.post(
"/review/action",
data={"token": token, "action": "cwb"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
cwb = client.get(action.headers["location"])
assert cwb.status_code == 200, cwb.text
assert "后续再接真实推荐结果" not in cwb.text
assert "建议冲刺" in cwb.text or "冲刺建议" in cwb.text
def test_cwb_page_links_policy_same_score_and_auxiliary_factors(client, settings):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
payment_id = create_resp.json()["checkout_url"].split("/pay/mock/")[1].split("?")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="draft",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
target_cities=["长沙", "深圳"],
family_background="家长更希望省内优先",
interest_assessment_type="holland",
interest_assessment_result="R型+I型",
interest_assessment_notes="只作辅助,不作唯一判断",
),
settings,
)
client.get(f"/review/start?source=status&token={token}")
client.post(
"/review/action", data={"token": token, "action": "cwb"}, follow_redirects=False
)
cwb = client.get(f"/portal/{token}/cwb")
assert cwb.status_code == 200, cwb.text
assert "/policy-center?province=湖南" in cwb.text
assert "/same-score-reference?province=湖南" in cwb.text and "score=578" in cwb.text
assert "辅助判断因子" in cwb.text
assert "R型+I型" in cwb.text
assert "家长更希望省内优先" in cwb.text
def test_review_action_full_plan_redirects_to_real_full_plan_page(
route_client, client, settings
):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
start = client.get(f"/review/start?source=status&token={token}")
assert start.status_code == 200, start.text
action = client.post(
"/review/action",
data={"token": token, "action": "full_plan"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
assert action.headers["location"].endswith(f"/portal/{token}/full-plan")
full_plan = client.get(action.headers["location"])
assert full_plan.status_code == 200, full_plan.text
assert "完整规划建议页" in full_plan.text
assert "方案优先级" in full_plan.text
assert "版本历史" in full_plan.text
def test_full_plan_page_shows_profile_versions_and_assessment_context(
route_client, client, settings
):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
payment_id = create_resp.json()["checkout_url"].split("/pay/mock/")[1].split("?")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="draft",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
family_background="家长更希望省内优先",
interest_assessment_type="mbti",
interest_assessment_result="INTJ",
interest_assessment_notes="只作辅助,不作唯一判断",
),
settings,
)
client.get(f"/review/start?source=status&token={token}")
action = client.post(
"/review/action",
data={"token": token, "action": "full_plan"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
full_plan = client.get(action.headers["location"])
assert full_plan.status_code == 200, full_plan.text
assert "完整规划建议页" in full_plan.text
assert "方案优先级" in full_plan.text
assert "版本历史" in full_plan.text
assert "初始档案方案" in full_plan.text
assert "辅助判断因子" in full_plan.text
assert "INTJ" in full_plan.text
def test_full_plan_page_no_longer_claims_entry_only_placeholder(
route_client, client, settings
):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
payment_id = create_resp.json()["checkout_url"].split("/pay/mock/")[1].split("?")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="draft",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
),
settings,
)
client.get(f"/review/start?source=status&token={token}")
action = client.post(
"/review/action",
data={"token": token, "action": "full_plan"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
full_plan = client.get(action.headers["location"])
assert full_plan.status_code == 200, full_plan.text
assert "当前从 review 分流进入完整规划入口" not in full_plan.text
assert "方案优先级" in full_plan.text or "规划建议" in full_plan.text
def test_report_page_shows_version_summary_and_next_actions(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
client.get(f"/review/start?source=report&token={token}")
client.post(
"/review/action",
data={"token": token, "action": "full_plan"},
follow_redirects=False,
)
payment_id = body["checkout_url"].split("/pay/mock/")[1].split("?")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
with OrdersDAO.connect(settings.orders_db_path) as dao:
dao.transition_status(
body["order_id"], "serving", actor="test", reason="report_ready_serving"
)
dao.transition_status(
body["order_id"], "delivered", actor="test", reason="report_ready_delivered"
)
dao.update(
body["order_id"],
{
"audit_report": "data/examples/gaokao_report_李明_20260611_122443.html",
"pdf_path": "data/examples/gaokao_report_李明_20260611_122443.pdf",
},
actor="test",
reason="report_ready_paths",
)
report_page = client.get(f"/portal/{token}/report")
assert report_page.status_code == 200, report_page.text
assert "报告版本" in report_page.text
assert "基于哪个档案版本" in report_page.text
assert "当前复核摘要" in report_page.text
assert "下一步建议" in report_page.text
assert "/portal/" in report_page.text and "/full-plan" in report_page.text
def test_report_page_routes_followup_step1_to_info(client, settings):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
payment_id = create_resp.json()["checkout_url"].split("/pay/mock/")[1].split("?")[0]
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="draft",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
),
settings,
)
with OrdersDAO.connect(settings.orders_db_path) as dao:
order_id = create_resp.json()["order_id"]
dao.transition_status(
order_id, "serving", actor="test", reason="report_ready_serving"
)
dao.transition_status(
order_id, "delivered", actor="test", reason="report_ready_delivered"
)
dao.update(
order_id,
{
"audit_report": "data/examples/gaokao_report_李明_20260611_122443.html",
"pdf_path": "data/examples/gaokao_report_李明_20260611_122443.pdf",
},
actor="test",
reason="report_ready_paths",
)
client.get(f"/review/start?source=report&token={token}")
action = client.post(
"/review/action",
data={"token": token, "action": "step1"},
follow_redirects=False,
)
assert action.status_code == 303, action.text
report = client.get(f"/portal/{token}/report")
assert report.status_code == 200, report.text
assert f"/portal/{token}/info" in report.text
def test_review_result_is_saved_as_independent_lightweight_object(client, settings):
from data.orders.intake_store import IntakeStore
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
resp = client.get(f"/review/start?source=home&token={token}")
assert resp.status_code == 200, resp.text
intake_store = IntakeStore.for_db(settings.orders_db_path)
try:
intake = intake_store.get(body["order_id"])
finally:
intake_store.close()
assert intake is not None
assert "review_result_contract" not in intake.payload
assert "latest_review_result_id" in intake.payload
assert intake.payload["latest_review_result_id"].startswith("rvw_")
def test_review_result_has_version_anchor_and_history_summary(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
first = client.get(f"/review/start?source=home&token={token}")
assert first.status_code == 200, first.text
second = client.get(f"/review/start?source=status&token={token}")
assert second.status_code == 200, second.text
landing = client.get(f"/?token={token}")
assert landing.status_code == 200, landing.text
assert "最近一次复核结果" in landing.text
assert "最新版本" in landing.text or "版本" in landing.text
def test_report_page_shows_profile_and_review_versions(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
payment_id = body["checkout_url"].split("/pay/mock/")[1].split("?")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
client.get(f"/review/start?source=home&token={token}")
client.get(f"/review/start?source=status&token={token}")
with OrdersDAO.connect(settings.orders_db_path) as dao:
dao.transition_status(
body["order_id"], "serving", actor="test", reason="report_ready_serving"
)
dao.transition_status(
body["order_id"], "delivered", actor="test", reason="report_ready_delivered"
)
dao.update(
body["order_id"],
{
"audit_report": "data/examples/gaokao_report_李明_20260611_122443.html",
"pdf_path": "data/examples/gaokao_report_李明_20260611_122443.pdf",
},
actor="test",
reason="report_ready_paths",
)
report_page = client.get(f"/portal/{token}/report")
assert report_page.status_code == 200, report_page.text
assert "报告版本" in report_page.text
assert "基于哪个档案版本" in report_page.text
assert "当前复核摘要" in report_page.text
assert "最新版本" in report_page.text or "版本历史" in report_page.text
def test_report_page_shows_latest_profile_state_and_helper_links(client, settings):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
payment_id = body["checkout_url"].split("/pay/mock/")[1].split("?")[0]
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="draft",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
target_cities=["长沙", "深圳"],
interest_assessment_type="mbti",
interest_assessment_result="INTJ",
interest_assessment_notes="只作辅助,不作唯一判断",
),
settings,
)
client.get(f"/review/start?source=report&token={token}")
client.post(
"/review/action",
data={"token": token, "action": "full_plan"},
follow_redirects=False,
)
with OrdersDAO.connect(settings.orders_db_path) as dao:
dao.transition_status(
body["order_id"], "serving", actor="test", reason="report_ready_serving"
)
dao.transition_status(
body["order_id"], "delivered", actor="test", reason="report_ready_delivered"
)
dao.update(
body["order_id"],
{
"audit_report": "data/examples/gaokao_report_李明_20260611_122443.html",
"pdf_path": "data/examples/gaokao_report_李明_20260611_122443.pdf",
},
actor="test",
reason="report_ready_paths",
)
report_page = client.get(f"/portal/{token}/report")
assert report_page.status_code == 200, report_page.text
assert "基于最新档案生成" in report_page.text
assert "/policy-center?province=湖南" in report_page.text
assert (
"/same-score-reference?province=湖南" in report_page.text
and "score=578" in report_page.text
)
assert "辅助判断因子" in report_page.text
assert "INTJ" in report_page.text
def test_report_page_warns_when_based_on_historical_profile_version(client, settings):
from admin.routes.web_public import submit_order_info
from data.orders.intake_schema import IntakePayload
from data.orders.intake_store import IntakeStore
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
body = create_resp.json()
payment_id = body["checkout_url"].split("/pay/mock/")[1].split("?")[0]
token = body["portal_status_url"].split("/portal/")[1].split("/status")[0]
paid = client.post(f"/pay/mock/{payment_id}/complete", follow_redirects=False)
assert paid.status_code == 303, paid.text
submit_order_info(
token,
IntakePayload(
mode="draft",
candidate_province="湖南",
candidate_subjects=["物理", "化学", "生物"],
candidate_score=578,
candidate_rank=12345,
),
settings,
)
with OrdersDAO.connect(settings.orders_db_path) as dao:
dao.transition_status(
body["order_id"], "serving", actor="test", reason="report_ready_serving"
)
dao.transition_status(
body["order_id"], "delivered", actor="test", reason="report_ready_delivered"
)
dao.update(
body["order_id"],
{
"audit_report": "data/examples/gaokao_report_李明_20260611_122443.html",
"pdf_path": "data/examples/gaokao_report_李明_20260611_122443.pdf",
},
actor="test",
reason="report_ready_paths",
)
first = client.get(f"/portal/{token}/report")
assert first.status_code == 200, first.text
intake_store = IntakeStore.for_db(settings.orders_db_path)
try:
intake = intake_store.get(body["order_id"])
assert intake is not None
payload = dict(intake.payload)
payload["candidate_score"] = 579
payload["candidate_rank"] = 12001
payload["profile_versions"] = [
{
"profile_version_id": "profile_v1",
"stage_label": "初始档案方案",
"snapshot_payload": {
"candidate_province": "湖南",
"candidate_subjects": ["物理", "化学", "生物"],
"candidate_score": 578,
"candidate_rank": 12345,
},
"created_at": "2026-06-23T00:00:00+00:00",
"source": "portal",
},
{
"profile_version_id": "profile_v2",
"stage_label": "查分后校准方案",
"snapshot_payload": {
"candidate_province": "湖南",
"candidate_subjects": ["物理", "化学", "生物"],
"candidate_score": 579,
"candidate_rank": 12001,
},
"created_at": "2026-06-23T00:00:00+00:00",
"source": "admin",
},
]
payload["latest_profile_version_id"] = "profile_v2"
intake_store.save(order_id=body["order_id"], payload=payload, submit=True)
finally:
intake_store.close()
report_page = client.get(f"/portal/{token}/report")
assert report_page.status_code == 200, report_page.text
assert "基于历史档案版本生成,建议刷新" in report_page.text
def test_landing_page_shows_recent_review_result_entry_when_present(client, settings):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
start = client.get(f"/review/start?source=home&token={token}")
assert start.status_code == 200, start.text
landing = client.get(f"/?token={token}")
assert landing.status_code == 200, landing.text
assert "最近一次复核结果" in landing.text
assert f"/review/start?source=home&token={token}" in landing.text
def test_landing_page_shows_workspace_primary_action_for_incomplete_step1(client):
resp = client.get("/?token=test-token")
assert resp.status_code == 200, resp.text
assert "工作台主动作" in resp.text
assert "继续补充 Step 1" in resp.text
def test_landing_page_shows_workspace_primary_action_for_recent_review_result(
route_client, client, settings
):
create_resp = client.post(
"/api/public/orders",
json={
"service_version": "standard",
"amount_cents": 9900,
"customer_phone": "13800138000",
"candidate_name": "张三",
"candidate_province": "湖南",
},
)
assert create_resp.status_code == 201, create_resp.text
token = (
create_resp.json()["portal_status_url"].split("/portal/")[1].split("/status")[0]
)
start = client.get(f"/review/start?source=home&token={token}")
assert start.status_code == 200, start.text
landing = client.get(f"/?token={token}")
assert landing.status_code == 200, landing.text
assert "工作台主动作" in landing.text
assert "继续查看最近一次复核" in landing.text
assert f"/review/start?source=home&token={token}" in landing.text