fix(ingest): raise ref cap to 50 and clarify invalid bvid error
This commit is contained in:
1 parent
b5bf7d9b8f
commit
b0c53e8a2f
7 files changed
+107
-9
No files matched your search
+49
-2
@@ -13,7 +13,10 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
|
||||
from fixtures import view_for # noqa: E402
|
||||
from reaction_board.bilibili.client import BilibiliError # noqa: E402
|
||||
from reaction_board.bilibili.client import ( # noqa: E402
|
||||
BilibiliAPIError,
|
||||
BilibiliError,
|
||||
)
|
||||
from reaction_board.bilibili.models import VideoDetail # noqa: E402
|
||||
from reaction_board.config import ConfigStore # noqa: E402
|
||||
from reaction_board.database import Database # noqa: E402
|
||||
@@ -51,14 +54,18 @@ def detail(
|
||||
|
||||
|
||||
class FakeReadClient:
|
||||
def __init__(self, by_bvid=None, by_aid=None, short_map=None, fail_bvids=()):
|
||||
def __init__(self, by_bvid=None, by_aid=None, short_map=None, fail_bvids=(),
|
||||
api_errors=None):
|
||||
self.by_bvid = by_bvid or {}
|
||||
self.by_aid = by_aid or {}
|
||||
self.short_map = short_map or {}
|
||||
self.fail_bvids = set(fail_bvids)
|
||||
self.api_errors = dict(api_errors or {})
|
||||
|
||||
def view_detail(self, *, aid=None, bvid=None):
|
||||
if bvid is not None:
|
||||
if bvid in self.api_errors:
|
||||
raise BilibiliAPIError(self.api_errors[bvid], "请求错误")
|
||||
if bvid in self.fail_bvids:
|
||||
raise BilibiliError(f"view 失败: {bvid}")
|
||||
if bvid in self.by_bvid:
|
||||
@@ -263,6 +270,44 @@ def test_snapshot_not_overwritten():
|
||||
db.close()
|
||||
|
||||
|
||||
def test_manual_ingest_truncation():
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
bvs = {
|
||||
"BV1x8x166E00": detail(1, bvid="BV1x8x166E00"),
|
||||
"BV1x8x166E01": detail(2, bvid="BV1x8x166E01"),
|
||||
"BV1x8x166E02": detail(3, bvid="BV1x8x166E02"),
|
||||
}
|
||||
client = FakeReadClient(by_bvid=bvs)
|
||||
store = ConfigStore(write_config(tmp), env={})
|
||||
db = Database(Path(tmp) / "app.db", backup_dir=Path(tmp) / "backup")
|
||||
db.initialize()
|
||||
try:
|
||||
repo = Repository(db, clock=lambda: NOW)
|
||||
service = LibraryService(
|
||||
store, repo, FakeProvider(client), clock=lambda: NOW, max_refs=2
|
||||
)
|
||||
result = service.ingest_text(" ".join(bvs))
|
||||
assert result.refs == 2
|
||||
assert result.truncated == 1
|
||||
assert result.added == 2
|
||||
assert len(result.results) == 2
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_manual_ingest_invalid_bvid_message():
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
client = FakeReadClient(api_errors={"BV1x8x166E00": -400})
|
||||
db, repo, service = setup(tmp, client)
|
||||
try:
|
||||
result = service.ingest_text("BV1x8x166E00")
|
||||
assert result.refs == 1
|
||||
assert result.results[0].state == "error"
|
||||
assert "无效或视频不存在" in result.results[0].message
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_ignore_and_blacklist():
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
client = FakeReadClient()
|
||||
@@ -289,6 +334,8 @@ def main():
|
||||
test_manual_ingest_forms_and_multiple()
|
||||
test_manual_ingest_error_isolation()
|
||||
test_snapshot_not_overwritten()
|
||||
test_manual_ingest_truncation()
|
||||
test_manual_ingest_invalid_bvid_message()
|
||||
test_ignore_and_blacklist()
|
||||
print("OK: 入库、手动入库、忽略、拉黑测试全部通过")
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ from reaction_board.notify.telegram import ( # noqa: E402
|
||||
TelegramClient,
|
||||
TelegramError,
|
||||
format_duration,
|
||||
format_manual_reply,
|
||||
)
|
||||
from reaction_board.services.library import ( # noqa: E402
|
||||
ActionResult,
|
||||
@@ -51,6 +52,19 @@ def test_format_duration():
|
||||
assert format_duration(3725) == "1:02:05"
|
||||
|
||||
|
||||
def test_manual_reply_truncation_notice():
|
||||
result = ManualIngestResult(
|
||||
refs=50, added=1, truncated=2,
|
||||
results=[IngestResult(True, 1, "added", title="t", message="已入库")],
|
||||
)
|
||||
text = format_manual_reply(result)
|
||||
assert "共识别 50 个引用" in text
|
||||
assert "还有 2 个引用未处理" in text
|
||||
assert format_manual_reply(ManualIngestResult()) == (
|
||||
"未识别到 B 站视频引用,请发送视频链接或 BV 号,例如 BV1x8x166EzY。"
|
||||
)
|
||||
|
||||
|
||||
def test_send_candidates_and_chunking():
|
||||
transport = FakeTransport()
|
||||
bot = TelegramClient("token", 42, transport=transport)
|
||||
@@ -300,6 +314,7 @@ def test_poller_backoff_and_recovery():
|
||||
|
||||
def main():
|
||||
test_format_duration()
|
||||
test_manual_reply_truncation_notice()
|
||||
test_send_candidates_and_chunking()
|
||||
test_send_candidates_dedupes_by_aid()
|
||||
test_get_updates_and_answer()
|
||||
|
||||
@@ -63,6 +63,17 @@ def test_limit():
|
||||
assert len(extract_video_refs(text, limit=None)) == 3
|
||||
|
||||
|
||||
def test_default_cap_allows_bulk_paste():
|
||||
from reaction_board.video_ref import DEFAULT_MAX_REFS
|
||||
|
||||
assert DEFAULT_MAX_REFS >= 15
|
||||
text = " ".join(f"BV1x8x166E{i:02d}" for i in range(15))
|
||||
assert len(extract_video_refs(text)) == 15
|
||||
assert len(extract_video_refs(" ".join(
|
||||
f"BV1x8x166E{i:02d}" for i in range(DEFAULT_MAX_REFS + 5)
|
||||
))) == DEFAULT_MAX_REFS
|
||||
|
||||
|
||||
def test_invalid_and_boundaries():
|
||||
assert extract_video_refs("") == []
|
||||
assert extract_video_refs(None) == []
|
||||
@@ -85,6 +96,7 @@ def main():
|
||||
test_short_link()
|
||||
test_multiple_and_order_and_dedup()
|
||||
test_limit()
|
||||
test_default_cap_allows_bulk_paste()
|
||||
test_invalid_and_boundaries()
|
||||
print("OK: 视频引用(BV/av/URL/短链)解析测试全部通过")
|
||||
|
||||
|
||||
Reference in new issue
Block a user