Files
re-xxm/tests/web_fixtures.py
T

178 lines
6.1 KiB
Python

# -*- coding: utf-8 -*-
"""Web 查询/服务测试共用的临时数据库与配置。"""
from __future__ import annotations
import json
from datetime import date
from pathlib import Path
from reaction_board.bilibili.models import FavResource
from reaction_board.config import FolderConfig
from reaction_board.database import Database
from reaction_board.repository import Repository
from reaction_board.timeutil import day_bounds
FOLDER = FolderConfig(year=2026, media_id=3700023351, title="2026")
DATES = ("2026-10-29", "2026-10-30", "2026-10-31")
def write_config(
tmp: str | Path,
*,
token: str = "",
host: str = "127.0.0.1",
port: int = 8080,
) -> Path:
root = Path(tmp)
path = root / "config.json"
path.write_text(json.dumps({
"bilibili": {
"read": {"mid": 1, "csrf": "read-csrf", "cookie": "SESSDATA=fake-read"},
"write": {"mid": 2, "csrf": "write-csrf", "cookie": "SESSDATA=fake-write"},
},
"telegram": {"enabled": False, "bot_token": "", "chat_id": 0},
"web": {
"host": host, "port": port, "auth_token": token,
"public_base_url": "",
},
"storage": {
"database_path": str(root / "app.db"),
"backup_dir": str(root / "backup"),
"backup_keep_days": 7,
},
"folders": [
{"year": 2026, "media_id": 3700023351, "title": "2026"},
],
"track_fans": [37754047],
"up_blacklist_seed": [],
"schedule": {
"discover_minutes": 60,
"folder_sync_minutes": 60,
"full_folder_refresh_hours": 6,
"snapshot_at": "00:01",
"candidate_ttl_days": 7,
},
}, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def resource(
aid: int,
*,
up_mid: int,
up_name: str,
pubdate: int,
attr: int = 0,
title: str | None = None,
) -> FavResource:
return FavResource(
aid=aid,
bvid=f"BV{aid}",
title=title or f"咻咻满 reaction 视频 {aid}",
up_mid=up_mid,
up_name=up_name,
pubdate=pubdate,
duration=7200,
cover=f"//i0.hdslb.com/{aid}.jpg",
attr=attr,
fav_time=None,
)
def build_db(tmp: str | Path) -> Path:
root = Path(tmp)
path = root / "app.db"
db = Database(path)
db.initialize()
try:
repo = Repository(db)
repo.ensure_folder(FOLDER)
repo.seed_blacklist([2])
def ts(day: str) -> int:
return int(day_bounds(day)[0])
videos = {
101: (1, "UP A", int(day_bounds("2026-10-30")[0]), 0, "2026-10-29"),
102: (1, "UP A", int(day_bounds("2026-10-20")[0]), 0, "2026-10-29"),
103: (2, "UP B", int(day_bounds("2026-10-31")[0]), 0, "2026-10-31"),
104: (3, "UP C", int(day_bounds("2026-09-01")[0]), 9, "2026-10-29"),
}
for aid, (up_mid, up_name, pubdate, attr, first_day) in videos.items():
repo.upsert_from_fav(
resource(aid, up_mid=up_mid, up_name=up_name, pubdate=pubdate, attr=attr),
FOLDER.media_id,
was_added=True,
now=ts(first_day),
)
repo.set_video_status(103, "unfaved")
metrics = {
101: {"view": 1000, "like": 100, "coin": 20, "favorite": 30, "share": 2, "reply": 10, "danmaku": 12},
102: {"view": 5000, "like": 200, "coin": 50, "favorite": 100, "share": 10, "reply": 30, "danmaku": 40},
104: {"view": 50, "like": 1, "coin": 0, "favorite": 0, "share": 0, "reply": 0, "danmaku": 0},
}
for index, day in enumerate(DATES):
for aid in (101, 102):
base = metrics[aid]
values = {}
for key, value in base.items():
values[key] = value + (index * 100 if key == "view" else index * 2)
repo.upsert_snapshot(
day, aid, metrics=values, ok=True, err=None,
captured_at=ts(day) + 60,
)
repo.upsert_up_stat(
day, 37754047, follower=1000 + index * 10, following=5,
ok=True, captured_at=ts(day) + 60,
)
# 103 只有最后一天快照,用于验证样本不足;104 另加一条失败快照
repo.upsert_snapshot(
DATES[-1], 103,
metrics={"view": 120, "like": 5, "coin": 1, "favorite": 2, "share": 0, "reply": 1, "danmaku": 1},
ok=True, err=None, captured_at=ts(DATES[-1]) + 60,
)
repo.upsert_snapshot(
"2026-10-30", 104,
metrics=None, ok=False, err="simulated failure",
captured_at=ts("2026-10-30") + 60,
)
repo.upsert_candidate(
aid=201, bvid="BV201", title="咻咻满 reaction 候选",
up_mid=9, up_name="候选UP", pubdate=1_790_000_000,
cover=None, score=6, channel="search:test#p1",
now=ts("2026-10-30"), play=1000, like=50,
)
repo.mark_notified(
201, channel="telegram", batch_id="b1", ok=True,
now=ts("2026-10-30") + 10,
)
repo.upsert_candidate(
aid=202, bvid="BV202", title="咻咻满 切片候选",
up_mid=10, up_name="切片UP", pubdate=1_790_000_000,
cover=None, score=1, channel="search:test#p1",
now=ts("2026-10-29"),
)
repo.mark_candidate_decision(202, "rejected", now=ts("2026-10-30"))
repo.finish_folder_sync(FOLDER, media_count=3, full_refresh=True)
repo.kv_set("snapshot:last_completed", DATES[-1])
repo.kv_set("auth:ok", "1")
repo.kv_set("auth:message", "OK")
repo.kv_set(
"task:last:snapshot",
json.dumps({
"name": "snapshot", "ok": True,
"started_at": ts(DATES[-1]), "finished_at": ts(DATES[-1]) + 60,
"error": None, "summary": {"completed": True},
}),
)
finally:
db.close()
return path
def day_date(value: str) -> date:
return date.fromisoformat(value)