refactor(favsort): send bilibili requests through httpx

Reuse a pooled httpx client for favsort GET and POST requests, share the raw-request-derived browser headers, and add folder-specific referers for ids, infos and sort. Add transport tests for header parity and anonymous-to-authenticated fallback.
This commit is contained in:
kairee committed 2026-10-31 22:36:48 +08:00
1 parent 5b22ed1c5d
commit 8a87ebfb7c
5 files changed
+160 -22

No files matched your search

+91
View File
@@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
"""favsort HTTP 层测试(httpx MockTransport,不联网):
uv run python tests/test_favsort_http.py
"""
import os
import sys
import httpx
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.stdout.reconfigure(encoding="utf-8")
import favsort # noqa: E402
def with_client(handler):
client = httpx.Client(transport=httpx.MockTransport(handler))
original = favsort._HTTP_CLIENT
favsort._HTTP_CLIENT = client
return client, original
def test_get_json_and_post_form_headers():
calls = []
def handler(request):
calls.append(request)
return httpx.Response(200, json={"code": 0, "data": []})
client, original = with_client(handler)
try:
cfg = {"cookie": "SESSDATA=x; buvid3=y"}
assert favsort.get_json(
cfg, "https://api.bilibili.com/x/test", auth=False
) == {"code": 0, "data": []}
first = calls[0]
assert first.headers["origin"] == "https://space.bilibili.com"
assert first.headers["priority"] == "u=1, i"
assert "Chrome/155.0.0.0" in first.headers["user-agent"]
assert "SESSDATA" not in first.headers["cookie"]
assert "buvid3=y" in first.headers["cookie"]
favsort.post_form(
cfg,
"https://api.bilibili.com/x/v3/fav/resource/sort",
{"a": "b"},
referer="https://space.bilibili.com/1/favlist?fid=2",
)
post = calls[1]
assert post.method == "POST"
assert post.headers["content-type"] == "application/x-www-form-urlencoded"
assert post.headers["referer"] == "https://space.bilibili.com/1/favlist?fid=2"
assert post.content == b"a=b"
assert "SESSDATA=x" in post.headers["cookie"]
finally:
favsort._HTTP_CLIENT = original
client.close()
def test_anonymous_failure_falls_back_to_full_cookie():
calls = []
def handler(request):
calls.append(request)
if len(calls) == 1:
return httpx.Response(200, json={"code": -101, "message": "未登录"})
return httpx.Response(200, json={"code": 0, "data": []})
client, original = with_client(handler)
try:
cfg = {"cookie": "SESSDATA=x; buvid3=y"}
assert favsort.get_json(cfg, "https://api.bilibili.com/x/test") == {
"code": 0, "data": [],
}
assert len(calls) == 2
assert "SESSDATA" not in calls[0].headers["cookie"]
assert "SESSDATA=x" in calls[1].headers["cookie"]
finally:
favsort._HTTP_CLIENT = original
client.close()
def main():
test_get_json_and_post_form_headers()
test_anonymous_failure_falls_back_to_full_cookie()
print("OK: favsort httpx 请求头与匿名回退测试全部通过")
if __name__ == "__main__":
main()
+3 -1
View File
@@ -74,7 +74,9 @@ def test_sort_preserves_resource_types():
return [{"id": aid} for aid in order]
favsort.fetch_ids = fetch_ids
favsort.post_form = lambda cfg, url, body: bodies.append(body) or {"code": 0}
favsort.post_form = (
lambda cfg, url, body, referer=None: bodies.append(body) or {"code": 0}
)
args = Args()
try:
code = favsort.cmd_run(config(), args)