Files
gaokao-volunteer-system/admin/tests/conftest.py
Hermes Agent 3f46811e49
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
release: cut v2.1
2026-06-13 14:49:58 +08:00

116 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""pytest 配置 (T6.1).
提供 fixture:
- settings: 内存 SQLite + 安全 JWT 密钥 + 短过期
- app: FastAPI 实例(lifespan 已运行 → admin 表已建 + bootstrap 用户)
- client: httpx TestClient
- auth_token: 登录后的 Bearer JWT
- auth_headers: {"Authorization": f"Bearer ..."}
"""
from __future__ import annotations
import sys
from pathlib import Path
import pytest
# 确保项目根在 sys.path
_ROOT = Path(__file__).resolve().parent.parent.parent
if str(_ROOT) not in sys.path:
sys.path.insert(0, str(_ROOT))
@pytest.fixture
def secure_secret() -> str:
"""64-char 安全 JWT 密钥。"""
return "x" * 64 # 确定性,便于测试断言
@pytest.fixture
def settings(tmp_path, secure_secret, monkeypatch):
"""隔离的 Settings 实例:tmp_path SQLite + 安全密钥 + 短过期。
用真实文件而不是 :memory: 是因为 admin/db.py 中每次 get_connection
都新建连接,:memory: 在 SQLite 下不共享状态。
"""
db_path = str(tmp_path / "admin.db")
orders_db_path = str(tmp_path / "orders.db")
share_db_path = str(tmp_path / "short_links.db")
share_report_dir = str(tmp_path / "share_reports")
monkeypatch.setenv("GAOKAO_ENV", "dev")
monkeypatch.setenv("GAOKAO_DB_PATH", db_path)
monkeypatch.setenv("GAOKAO_ORDERS_DB_PATH", orders_db_path)
monkeypatch.setenv("GAOKAO_SHARE_DB_PATH", share_db_path)
monkeypatch.setenv("GAOKAO_SHARE_REPORT_DIR", share_report_dir)
monkeypatch.setenv("GAOKAO_JWT_SECRET", secure_secret)
monkeypatch.setenv("GAOKAO_JWT_EXP_MIN", "5")
monkeypatch.setenv("GAOKAO_ADMIN_USER", "admin")
monkeypatch.setenv("GAOKAO_ADMIN_PASS", "test-pass-123")
from admin.config import load_settings
return load_settings()
@pytest.fixture
def orders_db(settings):
"""T6.2 起:管理后台统计端点会读 orders 表,因此 conftest 顺带建一个
空 orders DB (T4.1 schema),后续 dashboard 测试可在里面塞 fixture 数据。
"""
from data.orders.schema import apply_schema
conn = apply_schema(settings.orders_db_path)
conn.close()
return settings.orders_db_path
@pytest.fixture(autouse=True)
def _auto_orders_db(settings, orders_db):
"""所有测试都默认有空 orders DB 可用,避免 T6.2 端点在不相关测试里
'no such table: orders'。``orders_db`` 显式依赖确保已建。
"""
return orders_db
@pytest.fixture(autouse=True)
def _reset_login_rate_limit():
from admin.routes.auth import reset_login_rate_limit_for_tests
reset_login_rate_limit_for_tests()
yield
reset_login_rate_limit_for_tests()
@pytest.fixture
def app(settings):
"""FastAPI 实例lifespan 已运行)。"""
from admin.app import create_app
return create_app(settings)
@pytest.fixture
def client(app):
"""httpx TestClient。"""
from fastapi.testclient import TestClient
with TestClient(app) as c:
yield c
@pytest.fixture
def auth_token(client) -> str:
"""登录后返回 Bearer JWT。"""
resp = client.post(
"/api/auth/login",
json={"username": "admin", "password": "test-pass-123"},
)
assert resp.status_code == 200, resp.text
return resp.json()["access_token"]
@pytest.fixture
def auth_headers(auth_token) -> dict:
return {"Authorization": f"Bearer {auth_token}"}