from __future__ import annotations from datetime import datetime, timedelta, timezone from data.customer_portal.token import issue_portal_token from data.orders.dao import OrdersDAO from data.orders.intake_store import IntakeStore from data.orders.models import Order from data.payments.service import PaymentService def _expire_retention_window(db_path: str, order_id: str, days: int = 200) -> None: """把订单的 status_updated_at 拨到 N 天前, 让保留期门禁放行。 真实 180 天窗口太慢, 测试场景需要可重现的"已过保留期"状态。 """ backdated = ( (datetime.now(timezone.utc) - timedelta(days=days)) .replace(microsecond=0) .isoformat() ) with OrdersDAO.connect(db_path) as dao: dao.conn.execute( "UPDATE orders SET status_updated_at=? WHERE id=?", (backdated, order_id), ) dao.conn.commit() def _seed_order(db_path: str, order_id: str = "GKO-20260614-INFO") -> Order: order = Order( id=order_id, source="web", service_version="standard", amount_cents=9900, status="pending", customer_name="张家长", customer_phone="13800138000", candidate_name="张三", candidate_province="湖南", ) with OrdersDAO.connect(db_path) as dao: return dao.create(order, actor="test", reason="seed") def _mark_paid(settings, order: Order) -> None: service = PaymentService.for_db( settings.orders_db_path, base_url=settings.payment_base_url, webhook_secret=settings.payment_webhook_secret, ) checkout = service.create_checkout(order.id, portal_token="portal-token") payload, headers = service.provider.build_webhook_request( payment_id=checkout.payment_id, amount_cents=order.amount_cents, provider_trade_no=f"MOCK-{order.id}", ) handled = service.handle_webhook(payload, headers["X-Mock-Signature"]) assert handled.order_status == "paid" def test_order_info_form_accepts_draft_and_submit(client, settings): order = _seed_order(settings.orders_db_path) _mark_paid(settings, order) token = issue_portal_token(order.id, settings.portal_token_secret) page = client.get(f"/portal/{token}/info") assert page.status_code == 200, page.text assert "资料填写向导" in page.text assert "五步资料向导" in page.text assert "当前资料状态" in page.text assert "/static/portal-ui.css" in page.text assert "目标城市" in page.text assert "目标专业" in page.text assert "已有方案说明" in page.text assert "基础信息" in page.text assert "院校偏好" in page.text assert "专业偏好" in page.text assert "其他偏好与确认" in page.text assert "已有方案与附件" in page.text assert "当前还需要补充" in page.text assert "分数" in page.text assert "位次" in page.text assert page.text.count("