"""L2+ 共用 fixture:每測試重置 DB(in-memory)+ disable rate-limit。""" from __future__ import annotations import os import tempfile import pytest # 必須在 import app 之前設定,避免污染 os.environ.setdefault("KBV5_DB", ":memory:") os.environ.setdefault("KBV5_ENV", "dev") os.environ.setdefault("JWT_SECRET", "test-secret-please-change-me-32chars-or-longer-ok") os.environ.setdefault("KBV5_SEED", "0") # 測試跳過 admin / department seed os.environ.setdefault("KBV5_RATE_LIMIT", "0") # 測試 no-op 限流 os.environ.setdefault("ALLOWED_EMAIL_DOMAINS", "demo.local,x.tw") # 測試允許 x.tw os.environ.setdefault("KBV5_DISABLE_EMBEDDINGS", "1") # 預設停用 ML(層3/4),加速;需要的測試自行開啟 os.environ.setdefault("FEATURE_GUEST", "1") # 測試開啟 guest(正式預設關閉;前端尚無 guest UX) os.environ.setdefault("KBV5_HIBP_OFFLINE", "1") # 測試走 HIBP 離線模式(僅比內建清單,不打外網) # 變體詞典指向暫存檔,避免測試寫入/污染真實 data/sys/variant_dictionary.json os.environ.setdefault("KBV5_VARIANT_DICT", os.path.join(tempfile.gettempdir(), "kbv5_test_variants.json")) # vault / history 寫入暫存目錄,避免測試污染真實 vault/ os.environ.setdefault("KBV5_VAULT_DIR", os.path.join(tempfile.gettempdir(), "kbv5_test_vault")) os.environ.setdefault("KBV5_HISTORY_DIR", os.path.join(tempfile.gettempdir(), "kbv5_test_history")) os.environ.setdefault("KBV5_TRASH_DIR", os.path.join(tempfile.gettempdir(), "kbv5_test_trash")) @pytest.fixture(autouse=True) def _isolate_db(monkeypatch): """每個 test 用獨立 in-memory DB,並重置 jwt secret 快取與 limiter。""" import app.db as db from app import rate_limit as rl from app.auth import jwt_utils # 重置全域連線 db._GLOBAL_CONN = None jwt_utils.reset_secret_for_tests() # 重置 embeddings 載入狀態(讓切換 KBV5_DISABLE_EMBEDDINGS 的測試生效) try: from app.services import embeddings as _emb _emb.reset_for_tests() except Exception: pass # 每測試清掉變體詞典暫存 + 快取,確保乾淨 try: from app.services import variant_gen as _vg p = _vg.dict_path() if p.exists(): p.unlink() _vg.reload_dict() except Exception: pass # 關閉 rate limit rl.disable_for_tests() yield # 收尾:關閉連線 if db._GLOBAL_CONN is not None: try: db._GLOBAL_CONN.close() except Exception: pass db._GLOBAL_CONN = None