mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2026-05-09 18:27:56 +08:00
reconstruct
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||
<meta name="keywords" content="明日方舟,明日方舟官网,明日方舟手游,二次元,明日方舟Arknights,魔物娘,战棋,策略,塔防,塔防RPG,Arknights,人外,Monster" />
|
||||
<meta name="description" content="《明日方舟》是一款魔物主题的策略手游。在游戏中,玩家将管理一艘满载“ 魔物干员”的方舟,为调查来源神秘的矿石灾难而踏上旅途。在这个宽广而危机四伏的世界中,你或许会看到废土中的城市废墟,或许会看到仿若幻境的亚人国度,或许会遭遇无法解读的神秘,或许参与无比残酷的战争。在有关幻想与异种生命的世界中,体验史诗与想象,情感与牵绊!" />
|
||||
<link rel="icon" href="data:;base64,=" />
|
||||
<title>公告</title>
|
||||
<link rel="stylesheet" href="../../assets/css/announcement.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="banner-image-container cover">
|
||||
<a class="cover-jumper" href="uniwebview://move?target=recruit&param1=NORM_19_0_4">
|
||||
<img class="banner-image" src="https://ak-fs.hypergryph.com/announce/images/20210623/e6f49aeb9547a2278678368a43b95b07.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,108 @@
|
||||
{
|
||||
"focusAnnounceId": "677",
|
||||
"announceList": [
|
||||
{
|
||||
"announceId": "677",
|
||||
"title": "联锁竞赛预告\n「荷谟伊智境」",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/677.html",
|
||||
"day": 28,
|
||||
"month": 6,
|
||||
"group": "ACTIVITY"
|
||||
},
|
||||
{
|
||||
"announceId": "676",
|
||||
"title": "「制作组通讯」\n#12期",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/676.html",
|
||||
"day": 23,
|
||||
"month": 6,
|
||||
"group": "SYSTEM"
|
||||
},
|
||||
{
|
||||
"announceId": "672",
|
||||
"title": "时代系列\n复刻限时上架",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/672.html",
|
||||
"day": 17,
|
||||
"month": 6,
|
||||
"group": "ACTIVITY"
|
||||
},
|
||||
{
|
||||
"announceId": "671",
|
||||
"title": "生命之地系列\n新装限时上架",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/671.html",
|
||||
"day": 17,
|
||||
"month": 6,
|
||||
"group": "ACTIVITY"
|
||||
},
|
||||
{
|
||||
"announceId": "670",
|
||||
"title": "【君影轻灵】\n复刻寻访开启",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/670.html",
|
||||
"day": 17,
|
||||
"month": 6,
|
||||
"group": "ACTIVITY"
|
||||
},
|
||||
{
|
||||
"announceId": "667",
|
||||
"title": "沃伦姆德的薄暮\n限时复刻开启",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/667.html",
|
||||
"day": 17,
|
||||
"month": 6,
|
||||
"group": "ACTIVITY"
|
||||
},
|
||||
{
|
||||
"announceId": "97",
|
||||
"title": "新人寻访特惠\n必得六星干员",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/97.html",
|
||||
"day": 30,
|
||||
"month": 4,
|
||||
"group": "ACTIVITY"
|
||||
},
|
||||
{
|
||||
"announceId": "95",
|
||||
"title": "通关特定关卡\n赠送专属时装",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/95.html",
|
||||
"day": 30,
|
||||
"month": 4,
|
||||
"group": "ACTIVITY"
|
||||
},
|
||||
{
|
||||
"announceId": "192",
|
||||
"title": "《明日方舟》\n公测开启说明",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/192.html",
|
||||
"day": 30,
|
||||
"month": 4,
|
||||
"group": "SYSTEM"
|
||||
},
|
||||
{
|
||||
"announceId": "98",
|
||||
"title": "《明日方舟》\n公平运营申明",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/98.html",
|
||||
"day": 30,
|
||||
"month": 4,
|
||||
"group": "SYSTEM"
|
||||
},
|
||||
{
|
||||
"announceId": "94",
|
||||
"title": "常驻活动介绍",
|
||||
"isWebUrl": true,
|
||||
"webUrl": "https://ak-fs.hypergryph.com/announce/IOS/announcement/94.html",
|
||||
"day": 30,
|
||||
"month": 4,
|
||||
"group": "ACTIVITY"
|
||||
}
|
||||
],
|
||||
"extra": {
|
||||
"enable": false,
|
||||
"name": "额外活动"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"focusAnnounceId":"677","announceList":[{"announceId":"677","title":"联锁竞赛预告\n「荷谟伊智境」","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/677.html","day":28,"month":6,"group":"ACTIVITY"},{"announceId":"675","title":"特定干员\n限时出率上升","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/675.html","day":24,"month":6,"group":"ACTIVITY"},{"announceId":"676","title":"「制作组通讯」\n#12期","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/676.html","day":23,"month":6,"group":"SYSTEM"},{"announceId":"672","title":"时代系列\n复刻限时上架","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/672.html","day":17,"month":6,"group":"ACTIVITY"},{"announceId":"671","title":"生命之地系列\n新装限时上架","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/671.html","day":17,"month":6,"group":"ACTIVITY"},{"announceId":"670","title":"【君影轻灵】\n复刻寻访开启","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/670.html","day":17,"month":6,"group":"ACTIVITY"},{"announceId":"667","title":"沃伦姆德的薄暮\n限时复刻开启","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/667.html","day":17,"month":6,"group":"ACTIVITY"},{"announceId":"97","title":"新人寻访特惠\n必得六星干员","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/97.html","day":30,"month":4,"group":"ACTIVITY"},{"announceId":"95","title":"通关特定关卡\n赠送专属时装","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/95.html","day":30,"month":4,"group":"ACTIVITY"},{"announceId":"192","title":"《明日方舟》\n公测开启说明","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/192.html","day":30,"month":4,"group":"SYSTEM"},{"announceId":"98","title":"《明日方舟》\n公平运营申明","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/98.html","day":30,"month":4,"group":"SYSTEM"},{"announceId":"94","title":"常驻活动介绍","isWebUrl":true,"webUrl":"https://ak-fs.hypergryph.com/announce/IOS/announcement/94.html","day":30,"month":4,"group":"ACTIVITY"}],"extra":{"enable":false,"name":"额外活动"}}
|
||||
@@ -0,0 +1,49 @@
|
||||
import pytest
|
||||
import typing
|
||||
import respx
|
||||
from httpx import Response
|
||||
import feedparser
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import sys
|
||||
sys.path.append('./src/plugins')
|
||||
import nonebot_hk_reporter
|
||||
|
||||
from .utils import get_json, get_file
|
||||
|
||||
@pytest.fixture
|
||||
def arknights(plugin_module: 'nonebot_hk_reporter'):
|
||||
return plugin_module.platform.platform_manager['arknights']
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def arknights_list_0():
|
||||
return get_json('arknights_list_0.json')
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def arknights_list_1():
|
||||
return get_json('arknights_list_1.json')
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_fetch_new(arknights, dummy_user_subinfo, arknights_list_0, arknights_list_1):
|
||||
ak_list_router = respx.get("http://ak-fs.hypergryph.com/announce/IOS/announcement.meta.json")
|
||||
detail_router = respx.get("https://ak-fs.hypergryph.com/announce/IOS/announcement/675.html")
|
||||
ak_list_router.mock(return_value=Response(200, json=arknights_list_0))
|
||||
detail_router.mock(return_value=Response(200, text=get_file('arknights-detail-675.html')))
|
||||
target = ''
|
||||
res = await arknights.fetch_new_post(target, [dummy_user_subinfo])
|
||||
assert(ak_list_router.called)
|
||||
assert(len(res) == 0)
|
||||
assert(not detail_router.called)
|
||||
mock_data = arknights_list_1
|
||||
ak_list_router.mock(return_value=Response(200, json=mock_data))
|
||||
res3 = await arknights.fetch_new_post(target, [dummy_user_subinfo])
|
||||
assert(len(res3[0][1]) == 1)
|
||||
assert(detail_router.called)
|
||||
post = res3[0][1][0]
|
||||
assert(post.target_type == 'arknights')
|
||||
assert(post.text == '')
|
||||
assert(post.url == '')
|
||||
assert(post.target_name == '明日方舟游戏内公告')
|
||||
assert(len(post.pics) == 1)
|
||||
assert(post.pics == ['https://ak-fs.hypergryph.com/announce/images/20210623/e6f49aeb9547a2278678368a43b95b07.jpg'])
|
||||
@@ -0,0 +1,232 @@
|
||||
import sys
|
||||
import typing
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import sys
|
||||
sys.path.append('./src/plugins')
|
||||
import nonebot_hk_reporter
|
||||
from nonebot_hk_reporter.types import *
|
||||
from nonebot_hk_reporter.post import Post
|
||||
|
||||
from time import time
|
||||
now = time()
|
||||
passed = now - 3 * 60 * 60
|
||||
|
||||
raw_post_list_1 = [
|
||||
{'id': 1, 'text': 'p1', 'date': now, 'tags': ['tag1'], 'category': 1}
|
||||
]
|
||||
|
||||
raw_post_list_2 = raw_post_list_1 + [
|
||||
{'id': 2, 'text': 'p2', 'date': now, 'tags': ['tag1'], 'category': 1},
|
||||
{'id': 3, 'text': 'p3', 'date': now, 'tags': ['tag2'], 'category': 2},
|
||||
{'id': 4, 'text': 'p4', 'date': now, 'tags': ['tag2'], 'category': 3}
|
||||
]
|
||||
|
||||
@pytest.fixture
|
||||
def dummy_user(plugin_module: 'nonebot_hk_reporter'):
|
||||
user = plugin_module.types.User('123', 'group')
|
||||
return user
|
||||
|
||||
@pytest.fixture
|
||||
def user_info_factory(plugin_module: 'nonebot_hk_reporter', dummy_user):
|
||||
def _user_info(category_getter, tag_getter):
|
||||
return plugin_module.types.UserSubInfo(dummy_user, category_getter, tag_getter)
|
||||
return _user_info
|
||||
|
||||
@pytest.fixture
|
||||
def mock_platform_without_cats_tags(plugin_module: 'nonebot_hk_reporter'):
|
||||
class MockPlatform(plugin_module.platform.platform.NewMessage,
|
||||
plugin_module.platform.platform.TargetMixin):
|
||||
|
||||
platform_name = 'mock_platform'
|
||||
name = 'Mock Platform'
|
||||
enabled = True
|
||||
is_common = True
|
||||
schedule_interval = 10
|
||||
enable_tag = False
|
||||
categories = {}
|
||||
|
||||
def __init__(self):
|
||||
self.sub_index = 0
|
||||
super().__init__()
|
||||
|
||||
@staticmethod
|
||||
async def get_target_name(_: 'Target'):
|
||||
return 'MockPlatform'
|
||||
|
||||
def get_id(self, post: 'RawPost') -> Any:
|
||||
return post['id']
|
||||
|
||||
def get_date(self, raw_post: 'RawPost') -> float:
|
||||
return raw_post['date']
|
||||
|
||||
async def parse(self, raw_post: 'RawPost') -> 'Post':
|
||||
return plugin_module.post.Post('mock_platform', raw_post['text'], 'http://t.tt/' + str(self.get_id(raw_post)), target_name='Mock')
|
||||
|
||||
async def get_sub_list(self, _: 'Target'):
|
||||
if self.sub_index == 0:
|
||||
self.sub_index += 1
|
||||
return raw_post_list_1
|
||||
else:
|
||||
return raw_post_list_2
|
||||
|
||||
return MockPlatform()
|
||||
|
||||
@pytest.fixture
|
||||
def mock_platform(plugin_module: 'nonebot_hk_reporter'):
|
||||
class MockPlatform(plugin_module.platform.platform.NewMessage,
|
||||
plugin_module.platform.platform.TargetMixin):
|
||||
|
||||
platform_name = 'mock_platform'
|
||||
name = 'Mock Platform'
|
||||
enabled = True
|
||||
is_common = True
|
||||
schedule_interval = 10
|
||||
enable_tag = True
|
||||
categories = {
|
||||
1: '转发',
|
||||
2: '视频',
|
||||
}
|
||||
def __init__(self):
|
||||
self.sub_index = 0
|
||||
super().__init__()
|
||||
|
||||
@staticmethod
|
||||
async def get_target_name(_: 'Target'):
|
||||
return 'MockPlatform'
|
||||
|
||||
def get_id(self, post: 'RawPost') -> Any:
|
||||
return post['id']
|
||||
|
||||
def get_date(self, raw_post: 'RawPost') -> float:
|
||||
return raw_post['date']
|
||||
|
||||
def get_tags(self, raw_post: 'RawPost') -> list['Tag']:
|
||||
return raw_post['tags']
|
||||
|
||||
def get_category(self, raw_post: 'RawPost') -> 'Category':
|
||||
return raw_post['category']
|
||||
|
||||
async def parse(self, raw_post: 'RawPost') -> 'Post':
|
||||
return plugin_module.post.Post('mock_platform', raw_post['text'], 'http://t.tt/' + str(self.get_id(raw_post)), target_name='Mock')
|
||||
|
||||
async def get_sub_list(self, _: 'Target'):
|
||||
if self.sub_index == 0:
|
||||
self.sub_index += 1
|
||||
return raw_post_list_1
|
||||
else:
|
||||
return raw_post_list_2
|
||||
|
||||
return MockPlatform()
|
||||
|
||||
@pytest.fixture
|
||||
def mock_platform_no_target(plugin_module: 'nonebot_hk_reporter'):
|
||||
class MockPlatform(plugin_module.platform.platform.NewMessage,
|
||||
plugin_module.platform.platform.NoTargetMixin):
|
||||
|
||||
platform_name = 'mock_platform'
|
||||
name = 'Mock Platform'
|
||||
enabled = True
|
||||
is_common = True
|
||||
schedule_interval = 10
|
||||
enable_tag = True
|
||||
categories = {
|
||||
1: '转发',
|
||||
2: '视频',
|
||||
3: '不支持'
|
||||
}
|
||||
def __init__(self):
|
||||
self.sub_index = 0
|
||||
super().__init__()
|
||||
|
||||
@staticmethod
|
||||
async def get_target_name(_: 'Target'):
|
||||
return 'MockPlatform'
|
||||
|
||||
def get_id(self, post: 'RawPost') -> Any:
|
||||
return post['id']
|
||||
|
||||
def get_date(self, raw_post: 'RawPost') -> float:
|
||||
return raw_post['date']
|
||||
|
||||
def get_tags(self, raw_post: 'RawPost') -> list['Tag']:
|
||||
return raw_post['tags']
|
||||
|
||||
def get_category(self, raw_post: 'RawPost') -> 'Category':
|
||||
if raw_post['category'] == 3:
|
||||
raise plugin_module.platform.platform.CategoryNotSupport()
|
||||
return raw_post['category']
|
||||
|
||||
async def parse(self, raw_post: 'RawPost') -> 'Post':
|
||||
return plugin_module.post.Post('mock_platform', raw_post['text'], 'http://t.tt/' + str(self.get_id(raw_post)), target_name='Mock')
|
||||
|
||||
async def get_sub_list(self, _: 'Target'):
|
||||
if self.sub_index == 0:
|
||||
self.sub_index += 1
|
||||
return raw_post_list_1
|
||||
else:
|
||||
return raw_post_list_2
|
||||
|
||||
return MockPlatform()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_message_target_without_cats_tags(mock_platform_without_cats_tags, user_info_factory):
|
||||
res1 = await mock_platform_without_cats_tags.fetch_new_post('dummy', [user_info_factory(lambda _: [1,2], lambda _: [])])
|
||||
assert(len(res1) == 0)
|
||||
res2 = await mock_platform_without_cats_tags.fetch_new_post('dummy', [
|
||||
user_info_factory(lambda _: [], lambda _: []),
|
||||
])
|
||||
assert(len(res2) == 1)
|
||||
posts_1 = res2[0][1]
|
||||
assert(len(posts_1) == 3)
|
||||
id_set_1 = set(map(lambda x: x.text, posts_1))
|
||||
assert('p2' in id_set_1 and 'p3' in id_set_1 and 'p4' in id_set_1)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_message_target(mock_platform, user_info_factory):
|
||||
res1 = await mock_platform.fetch_new_post('dummy', [user_info_factory(lambda _: [1,2], lambda _: [])])
|
||||
assert(len(res1) == 0)
|
||||
res2 = await mock_platform.fetch_new_post('dummy', [
|
||||
user_info_factory(lambda _: [1,2], lambda _: []),
|
||||
user_info_factory(lambda _: [1], lambda _: []),
|
||||
user_info_factory(lambda _: [1,2], lambda _: ['tag1'])
|
||||
])
|
||||
assert(len(res2) == 3)
|
||||
posts_1 = res2[0][1]
|
||||
posts_2 = res2[1][1]
|
||||
posts_3 = res2[2][1]
|
||||
assert(len(posts_1) == 2)
|
||||
assert(len(posts_2) == 1)
|
||||
assert(len(posts_3) == 1)
|
||||
id_set_1 = set(map(lambda x: x.text, posts_1))
|
||||
id_set_2 = set(map(lambda x: x.text, posts_2))
|
||||
id_set_3 = set(map(lambda x: x.text, posts_3))
|
||||
assert('p2' in id_set_1 and 'p3' in id_set_1)
|
||||
assert('p2' in id_set_2)
|
||||
assert('p2' in id_set_3)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_message_no_target(mock_platform_no_target, user_info_factory):
|
||||
res1 = await mock_platform_no_target.fetch_new_post('dummy', [user_info_factory(lambda _: [1,2], lambda _: [])])
|
||||
assert(len(res1) == 0)
|
||||
res2 = await mock_platform_no_target.fetch_new_post('dummy', [
|
||||
user_info_factory(lambda _: [1,2], lambda _: []),
|
||||
user_info_factory(lambda _: [1], lambda _: []),
|
||||
user_info_factory(lambda _: [1,2], lambda _: ['tag1'])
|
||||
])
|
||||
assert(len(res2) == 3)
|
||||
posts_1 = res2[0][1]
|
||||
posts_2 = res2[1][1]
|
||||
posts_3 = res2[2][1]
|
||||
assert(len(posts_1) == 2)
|
||||
assert(len(posts_2) == 1)
|
||||
assert(len(posts_3) == 1)
|
||||
id_set_1 = set(map(lambda x: x.text, posts_1))
|
||||
id_set_2 = set(map(lambda x: x.text, posts_2))
|
||||
id_set_3 = set(map(lambda x: x.text, posts_3))
|
||||
assert('p2' in id_set_1 and 'p3' in id_set_1)
|
||||
assert('p2' in id_set_2)
|
||||
assert('p2' in id_set_3)
|
||||
@@ -23,7 +23,7 @@ def weibo_ak_list_1():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_name(weibo):
|
||||
name = await weibo.get_account_name('6279793937')
|
||||
name = await weibo.get_target_name('6279793937')
|
||||
assert(name == "明日方舟Arknights")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -40,6 +40,7 @@ async def test_fetch_new(weibo, dummy_user_subinfo):
|
||||
assert(not detail_router.called)
|
||||
mock_data = get_json('weibo_ak_list_1.json')
|
||||
ak_list_router.mock(return_value=Response(200, json=mock_data))
|
||||
# import ipdb; ipdb.set_trace()
|
||||
res2 = await weibo.fetch_new_post(target, [dummy_user_subinfo])
|
||||
assert(len(res2) == 0)
|
||||
mock_data['data']['cards'][1]['mblog']['created_at'] = \
|
||||
@@ -80,7 +81,7 @@ def test_tag(weibo, weibo_ak_list_1):
|
||||
assert(weibo.get_tags(raw_post) == ['明日方舟', '音律联觉'])
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_rsshub_compare(weibo, dummy_user_subinfo):
|
||||
async def test_rsshub_compare(weibo):
|
||||
target = '6279793937'
|
||||
raw_posts = filter(weibo.filter_platform_custom, await weibo.get_sub_list(target))
|
||||
posts = []
|
||||
|
||||
Reference in New Issue
Block a user