# -*- coding: utf-8 -*- """凭据变化时客户端重建测试(不联网): uv run python tests/test_provider.py""" import json import os import sys import tempfile import time from pathlib import Path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.stdout.reconfigure(encoding="utf-8") from reaction_board.bilibili.client import BilibiliClient, Pacer # noqa: E402 from reaction_board.bilibili.provider import ClientProvider # noqa: E402 from reaction_board.config import ConfigStore # noqa: E402 def write_config(path: Path, *, cookie: str, mid: int) -> None: path.write_text(json.dumps({ "bilibili": { "read": {"mid": mid, "csrf": "read-csrf", "cookie": cookie}, "write": {"mid": 2, "csrf": "write-csrf", "cookie": "write-cookie"}, }, "folders": [], }, ensure_ascii=False), encoding="utf-8") def bump(path: Path) -> None: target = max(path.stat().st_mtime_ns, time.time_ns()) + 1_000_000 os.utime(path, ns=(target, target)) def test_rebuild_only_when_credentials_change(): with tempfile.TemporaryDirectory() as tmp: path = Path(tmp) / "config.json" write_config(path, cookie="cookie-a", mid=1) store = ConfigStore(path, env={}) created = [] def factory(credentials): created.append((credentials.mid, credentials.cookie)) return BilibiliClient( cookie=credentials.cookie, csrf=credentials.csrf, mid=credentials.mid, pacer=Pacer(1.0, 1.6), ) provider = ClientProvider(store, "read", factory) first = provider.get() assert provider.get() is first assert created == [(1, "cookie-a")] write_config(path, cookie="cookie-b", mid=1) bump(path) second = provider.get() assert second is not first assert created == [(1, "cookie-a"), (1, "cookie-b")] assert second.pacer.min_delay == 1.0 assert second.pacer.max_delay == 1.6 # 仅 mtime 变化但凭据相同:不重建 bump(path) assert provider.get() is second assert len(created) == 2 def test_mid_change_rebuilds(): with tempfile.TemporaryDirectory() as tmp: path = Path(tmp) / "config.json" write_config(path, cookie="cookie-a", mid=1) store = ConfigStore(path, env={}) provider = ClientProvider( store, "read", lambda credentials: BilibiliClient(mid=credentials.mid), ) assert provider.get().mid == 1 write_config(path, cookie="cookie-a", mid=9) bump(path) assert provider.get().mid == 9 def test_config_revision_increments(): with tempfile.TemporaryDirectory() as tmp: path = Path(tmp) / "config.json" write_config(path, cookie="cookie-a", mid=1) store = ConfigStore(path, env={}) assert store.revision == 0 write_config(path, cookie="cookie-b", mid=1) bump(path) store.get() assert store.revision == 1 store.get() assert store.revision == 1 def main(): test_rebuild_only_when_credentials_change() test_mid_change_rebuilds() test_config_revision_increments() print("OK: 凭据变化重建客户端与配置 revision 测试全部通过") if __name__ == "__main__": main()