nonebot-bison/tests/platforms/test_bilibili_live.py
Azide af72b6c3d0
🐛 B站蹲饼修复 (#525)
*  使用新接口

* ♻️ 调整刷新逻辑

* 🐛 调整刷新逻辑

* ♻️ 将单个哔哩哔哩文件拆开

* 🐛 修修补补边界情况

*  添加UID:xxx匹配

*  调整测试中的导入

*  调整测试的断言

* 🐛 添加unicode字符的escape

*  不再主动刷新cookies

* 🔀 适配新版Site

* 🐛 解析live_rcmd中的json string

* 🚨 make ruff happy

* 🐛 调整并测试bilibili retry函数

*  修正测试

* ♻️ 按review意见调整

* ♻️ 清理一些遗留的复杂写法

* ♻️ 移出函数内的NameTuple

* 🔇 删除不必要的日志输出

Co-authored-by: felinae98 <731499577@qq.com>

* Update nonebot_bison/platform/bilibili/scheduler.py

* Update scheduler.py

---------

Co-authored-by: felinae98 <731499577@qq.com>
2024-06-17 13:24:04 +08:00

320 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from copy import deepcopy
from typing import TYPE_CHECKING
import respx
import pytest
from httpx import Response
from nonebug.app import App
from .utils import get_json
if TYPE_CHECKING:
from nonebot_bison.platform.bilibili import Bilibililive
@pytest.fixture()
def bili_live(app: App):
from nonebot_bison.platform import platform_manager
from nonebot_bison.utils import ProcessContext, DefaultClientManager
return platform_manager["bilibili-live"](ProcessContext(DefaultClientManager()))
@pytest.fixture()
def dummy_only_open_user_subinfo(app: App):
from nonebot_plugin_saa import TargetQQGroup
from nonebot_bison.types import UserSubInfo
user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[1], tags=[])
@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_no_room(bili_live, dummy_only_open_user_subinfo):
from nonebot_bison.types import Target, SubUnit
mock_bili_live_status = get_json("bili_live_status.json")
mock_bili_live_status["data"] = {}
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))
target = Target("13164144")
res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0
@pytest.mark.asyncio
@respx.mock
async def test_fetch_first_live(bili_live, dummy_only_open_user_subinfo):
from nonebot_bison.post import Post
from nonebot_bison.types import Target, SubUnit
mock_bili_live_status = get_json("bili_live_status.json")
empty_bili_live_status = deepcopy(mock_bili_live_status)
empty_bili_live_status["data"] = {}
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=empty_bili_live_status))
bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))
target = Target("13164144")
res1 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res1) == 0
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res2) == 1
post2: Post = res2[0][1][0]
assert post2.platform.name == "Bilibili直播"
assert post2.title == "[开播] 【Zc】从0挑战到15肉鸽目前10难度"
assert post2.content == ""
assert post2.url == "https://live.bilibili.com/3044248"
assert post2.nickname == "魔法Zc目录 其他单机"
assert post2.images == ["https://i0.hdslb.com/bfs/live/new_room_cover/fd357f0f3cbbb48e9acfbcda616b946c2454c56c.jpg"]
assert post2.compress is True
assert "brief" == post2.get_priority_themes()[0]
@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_only_live_open(bili_live: "Bilibililive", dummy_only_open_user_subinfo):
from nonebot_bison.post import Post
from nonebot_bison.types import Target, SubUnit
mock_bili_live_status = get_json("bili_live_status.json")
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))
target = Target("13164144")
bili_live.set_stored_data(target, None)
res1 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res1) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
post2: Post = res2[0][1][0]
assert post2.platform.name == "Bilibili直播"
assert post2.title == "[开播] 【Zc】从0挑战到15肉鸽目前10难度"
assert post2.url == "https://live.bilibili.com/3044248"
assert post2.nickname == "魔法Zc目录 其他单机"
assert post2.images == ["https://i0.hdslb.com/bfs/live/new_room_cover/fd357f0f3cbbb48e9acfbcda616b946c2454c56c.jpg"]
assert post2.compress is True
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 3
assert len(res3[0][1]) == 0
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_open_user_subinfo]))])
assert bili_live_router.call_count == 4
assert len(res4[0][1]) == 0
@pytest.fixture()
def dummy_only_title_user_subinfo(app: App):
from nonebot_plugin_saa import TargetQQGroup
from nonebot_bison.types import UserSubInfo
user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[2], tags=[])
@pytest.mark.asyncio()
@respx.mock
async def test_fetch_bililive_only_title_change(bili_live, dummy_only_title_user_subinfo):
from nonebot_bison.post import Post
from nonebot_bison.types import Target, SubUnit
mock_bili_live_status = get_json("bili_live_status.json")
target = Target("13164144")
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))
res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0
# 未开播前标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res0 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res0) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 3
assert len(res2[0][1]) == 0
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽目前12难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
post3: Post = res3[0][1][0]
assert post3.platform.name == "Bilibili直播"
assert post3.title == "[标题更新] 【Zc】从0挑战到15肉鸽目前12难度"
assert post3.url == "https://live.bilibili.com/3044248"
assert post3.nickname == "魔法Zc目录 其他单机"
assert post3.images == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post3.compress is True
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_title_user_subinfo]))])
assert bili_live_router.call_count == 5
assert len(res4[0][1]) == 0
@pytest.fixture()
def dummy_only_close_user_subinfo(app: App):
from nonebot_plugin_saa import TargetQQGroup
from nonebot_bison.types import UserSubInfo
user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[3], tags=[])
@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_only_close(bili_live, dummy_only_close_user_subinfo):
from nonebot_bison.post import Post
from nonebot_bison.types import Target, SubUnit
mock_bili_live_status = get_json("bili_live_status.json")
target = Target("13164144")
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))
res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0
# 未开播前标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res0 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res0) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 3
assert len(res2[0][1]) == 0
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽目前12难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 4
assert len(res3[0][1]) == 0
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_only_close_user_subinfo]))])
assert bili_live_router.call_count == 5
post4: Post = res4[0][1][0]
assert post4.platform.name == "Bilibili直播"
assert post4.title == "[下播] 【Zc】从0挑战到15肉鸽目前12难度"
assert post4.url == "https://live.bilibili.com/3044248"
assert post4.nickname == "魔法Zc目录 其他单机"
assert post4.images == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post4.compress is True
@pytest.fixture()
def dummy_bililive_user_subinfo(app: App):
from nonebot_plugin_saa import TargetQQGroup
from nonebot_bison.types import UserSubInfo
user = TargetQQGroup(group_id=123)
return UserSubInfo(user=user, categories=[1, 2, 3], tags=[])
@pytest.mark.asyncio
@respx.mock
async def test_fetch_bililive_combo(bili_live, dummy_bililive_user_subinfo):
from nonebot_bison.post import Post
from nonebot_bison.types import Target, SubUnit
mock_bili_live_status = get_json("bili_live_status.json")
target = Target("13164144")
bili_live_router = respx.get("https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids?uids[]=13164144")
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
bilibili_main_page_router = respx.get("https://www.bilibili.com/")
bilibili_main_page_router.mock(return_value=Response(200))
res = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
assert bili_live_router.call_count == 1
assert len(res) == 0
# 未开播前标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽目前11难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res0 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
assert bili_live_router.call_count == 2
assert len(res0) == 0
# 直播状态更新-上播
mock_bili_live_status["data"][target]["live_status"] = 1
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res2 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
post2: Post = res2[0][1][0]
assert post2.platform.name == "Bilibili直播"
assert post2.title == "[开播] 【Zc】从0挑战到15肉鸽目前11难度"
assert post2.url == "https://live.bilibili.com/3044248"
assert post2.nickname == "魔法Zc目录 其他单机"
assert post2.images == ["https://i0.hdslb.com/bfs/live/new_room_cover/fd357f0f3cbbb48e9acfbcda616b946c2454c56c.jpg"]
assert post2.compress is True
# 标题变更
mock_bili_live_status["data"][target]["title"] = "【Zc】从0挑战到15肉鸽目前12难度"
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res3 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
post3: Post = res3[0][1][0]
assert post3.platform.name == "Bilibili直播"
assert post3.title == "[标题更新] 【Zc】从0挑战到15肉鸽目前12难度"
assert post3.url == "https://live.bilibili.com/3044248"
assert post3.nickname == "魔法Zc目录 其他单机"
assert post3.images == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post3.compress is True
# 直播状态更新-下播
mock_bili_live_status["data"][target]["live_status"] = 0
bili_live_router.mock(return_value=Response(200, json=mock_bili_live_status))
res4 = await bili_live.batch_fetch_new_post([(SubUnit(target, [dummy_bililive_user_subinfo]))])
post4: Post = res4[0][1][0]
assert post4.platform.name == "Bilibili直播"
assert post4.title == "[下播] 【Zc】从0挑战到15肉鸽目前12难度"
assert post4.url == "https://live.bilibili.com/3044248"
assert post4.nickname == "魔法Zc目录 其他单机"
assert post4.images == ["https://i0.hdslb.com/bfs/live-key-frame/keyframe10170435000003044248mwowx0.jpg"]
assert post4.compress is True