"""pytest 全局夹具 鉴权采用 app.api.deps 的会话体系(UserStore / SessionStore): - 文档变更类端点(POST /documents、/documents/upload、DELETE /documents/{id})、 /auth/* 与 Settings 变更端点需要登录; - 查询类端点(POST /search、GET /knowledge/*、GET /documents*、 GET /documents/{id}/file)免登录。 auth_stores / admin_headers 夹具注入内存存储并签发真实 session token, 供需要登录的接口测试使用;查询类端点测试直接无 token 调用即可,无需覆盖依赖。 另外清理 LLM 客户端 / 解析插件 / 去重策略三处进程级缓存,避免跨测试串扰 (不同测试可能注入不同的 redis/ollama 实例,缓存按配置签名而非实例区分)。 """ import asyncio from typing import Any import pytest @pytest.fixture def auth_stores(monkeypatch: pytest.MonkeyPatch): """注入内存 UserStore/SessionStore 到 deps 单例,并预置 admin 账号(admin/admin-pass-123) 同时关闭 lifespan 的默认管理员引导,避免测试库被写入随机密码账号。 返回 (user_store, session_store),测试可直接操作用户数据。 """ import app.main as main_module from app.api import deps from app.core.sessions import SessionStore from app.core.users import UserStore user_store = UserStore(None) session_store = SessionStore(None) monkeypatch.setattr(deps, "_user_store", user_store) monkeypatch.setattr(deps, "_session_store", session_store) async def _noop_bootstrap(*args: Any, **kwargs: Any) -> None: return None monkeypatch.setattr(main_module, "bootstrap_admin", _noop_bootstrap) async def _seed() -> None: await user_store.create("admin", "admin-pass-123", role="admin") asyncio.run(_seed()) return user_store, session_store @pytest.fixture def admin_headers(auth_stores) -> dict[str, str]: """为内存 admin 签发真实 session,返回 Authorization Bearer 请求头""" _, session_store = auth_stores async def _login() -> str: return await session_store.create("admin", "admin") token = asyncio.run(_login()) return {"Authorization": f"Bearer {token}"} @pytest.fixture(autouse=True) def _invalidate_runtime_caches(): """每个测试前后清理 LLM/解析插件/去重策略进程级缓存 这三处缓存按 runtime_settings 配置签名而非实例区分,跨测试若配置相同 会复用旧实例(绑定到上个测试的 redis/ollama 替身),导致串扰。 """ # 延迟导入避免循环依赖 from app.core.dedup import invalidate_dedup_strategy_cache from app.core.file_parser import invalidate_parser_plugin_cache from app.services.llm import invalidate_llm_client_cache invalidate_llm_client_cache() invalidate_parser_plugin_cache() invalidate_dedup_strategy_cache() yield invalidate_llm_client_cache() invalidate_parser_plugin_cache() invalidate_dedup_strategy_cache()