first commit

This commit is contained in:
2026-08-15 14:43:56 +08:00
commit 63b8c28e1d
340 changed files with 59515 additions and 0 deletions
+156
View File
@@ -0,0 +1,156 @@
import logging
import unittest
import urllib.error
from unittest.mock import AsyncMock, Mock, patch
from app.bilibili_cookie_refresh import BilibiliQrLogin, _request_json
class _JsonResponse:
def __init__(self, payload=b'{"code": 0}'):
self.payload = payload
def read(self):
return self.payload
class BilibiliRequestTests(unittest.TestCase):
def test_get_retries_transient_connection_failures(self):
opener = Mock()
response = _JsonResponse()
opener.open.side_effect = [
urllib.error.URLError(ConnectionRefusedError(10061, "connection refused")),
urllib.error.URLError(ConnectionRefusedError(10061, "connection refused")),
response,
]
with patch("app.bilibili_cookie_refresh.time.sleep") as sleep:
payload, actual_response = _request_json(
"https://passport.bilibili.com/test",
opener=opener,
retries=2,
)
self.assertEqual(payload, {"code": 0})
self.assertIs(actual_response, response)
self.assertEqual(opener.open.call_count, 3)
self.assertEqual([call.args[0] for call in sleep.call_args_list], [0.4, 0.8])
def test_exhausted_retries_hide_low_level_network_error(self):
opener = Mock()
opener.open.side_effect = urllib.error.URLError(
ConnectionRefusedError(10061, "connection refused")
)
with patch("app.bilibili_cookie_refresh.time.sleep"), self.assertRaisesRegex(
RuntimeError,
"^连接B站登录服务失败,请稍后重试$",
) as raised:
_request_json(
"https://passport.bilibili.com/test",
opener=opener,
retries=2,
)
self.assertEqual(opener.open.call_count, 3)
self.assertNotIn("10061", str(raised.exception))
class _CredentialStore:
def __init__(self):
self.refresh_token = ""
def save_refresh_token(self, refresh_token):
self.refresh_token = refresh_token
def is_configured(self):
return bool(self.refresh_token)
class BilibiliQrLoginTests(unittest.IsolatedAsyncioTestCase):
def setUp(self):
self.store = _CredentialStore()
self.updated_cookies = []
self.on_logged_in = AsyncMock()
self.login = BilibiliQrLogin(
credential_store=self.store,
update_cookie=self.updated_cookies.append,
logger=logging.getLogger("test-bilibili-qr"),
on_logged_in=self.on_logged_in,
)
@staticmethod
def _generate_response():
return ({
"code": 0,
"data": {
"url": "https://passport.bilibili.com/h5-app/passport/login/scan?navhide=1",
"qrcode_key": "private-qrcode-key",
},
}, None)
async def test_start_keeps_qrcode_key_on_server(self):
with patch("app.bilibili_cookie_refresh._request_json", return_value=self._generate_response()):
result = await self.login.start()
self.assertEqual(result["state"], "awaiting_scan")
self.assertTrue(result["has_qr_image"])
self.assertNotIn("qr_key", result)
self.assertNotIn("qr_url", result)
self.assertFalse(result["credential_configured"])
async def test_poll_reports_scanned_without_saving_credentials(self):
with patch("app.bilibili_cookie_refresh._request_json", return_value=self._generate_response()):
await self.login.start()
with patch("app.bilibili_cookie_refresh._request_json", return_value=({
"code": 0,
"data": {"code": 86090, "message": "二维码已扫码未确认"},
}, None)):
result = await self.login.poll()
self.assertEqual(result["state"], "awaiting_confirm")
self.assertEqual(self.store.refresh_token, "")
self.assertEqual(self.updated_cookies, [])
self.on_logged_in.assert_not_awaited()
async def test_success_saves_refresh_token_and_updates_cookie(self):
with patch("app.bilibili_cookie_refresh._request_json", return_value=self._generate_response()):
await self.login.start()
login_url = (
"https://www.bilibili.com/?SESSDATA=session-value&bili_jct=csrf-value"
"&DedeUserID=123456"
)
def request_side_effect(url, **_kwargs):
if "qrcode/poll" in url:
return ({
"code": 0,
"data": {
"code": 0,
"url": login_url,
"refresh_token": "refresh-token-value",
},
}, None)
if "x/web-interface/nav" in url:
return ({
"code": 0,
"data": {"isLogin": True, "mid": 123456, "uname": "测试账号"},
}, None)
raise AssertionError(f"unexpected url: {url}")
with patch("app.bilibili_cookie_refresh._request_json", side_effect=request_side_effect):
result = await self.login.poll()
self.assertEqual(result["state"], "completed")
self.assertEqual(result["account"]["uname"], "测试账号")
self.assertTrue(result["credential_configured"])
self.assertNotIn("refresh_token", result)
self.assertEqual(self.store.refresh_token, "refresh-token-value")
self.assertEqual(self.updated_cookies[0]["SESSDATA"], "session-value")
self.assertEqual(self.updated_cookies[0]["bili_jct"], "csrf-value")
self.on_logged_in.assert_awaited_once()
if __name__ == "__main__":
unittest.main()