mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-03 22:04:57 +08:00
fix(site): preserve text category IDs and replay resource configs
This commit is contained in:
@@ -672,7 +672,10 @@ async def site_category(
|
||||
count: CompatibleCountParam = None,
|
||||
) -> Any:
|
||||
"""
|
||||
获取站点分类
|
||||
获取站点分类,排除搜索参数并按配置顺序合并去重。
|
||||
|
||||
:param site_id: 已保存的站点标识
|
||||
:return: 站点分类映射,分类标识支持数字和文本
|
||||
"""
|
||||
site = await query.get(site_id)
|
||||
if not site:
|
||||
|
||||
@@ -128,10 +128,14 @@ class SiteCookieSet(BaseModel):
|
||||
|
||||
class SiteCategory(BaseModel):
|
||||
"""
|
||||
站点资源分类。
|
||||
站点资源分类,标识来自站点索引配置,可以是数字或文本。
|
||||
"""
|
||||
|
||||
id: Optional[int] = Field(default=None, description="记录标识")
|
||||
id: Optional[Union[int, str]] = Field(
|
||||
default=None,
|
||||
union_mode="left_to_right",
|
||||
description="站点分类标识;数字字符串沿用整数响应,其余文本保持原值",
|
||||
)
|
||||
cat: Optional[str] = Field(default=None, description="站点分类标识")
|
||||
desc: Optional[str] = Field(default=None, description="分类说明")
|
||||
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
并传入 `latest_seeding_only=true`,仅窗口内最新记录携带 `seeding_info`,历史统计字段不变。
|
||||
省略该选项时保留每条记录的完整明细;这不会删除或修改采集历史。
|
||||
|
||||
`GET /api/v1/site/category/{site_id}` 只返回分类项,不包含 `field`、`delimiter`、`param`
|
||||
等搜索配置。分类 `id` 支持整数和文本,数字字符串沿用整数响应;客户端应保留返回值,
|
||||
浏览资源时将所选分类用逗号拼接后传入 `site.resource` 的 `query.cat`,不要强制转为整数。
|
||||
|
||||
`GET /api/v1/torrent/cache` 支持可选 `page` / `count`,每页最多 200 条,省略两项时保留全量合同。
|
||||
`title` 为不区分大小写的标题包含条件,`site` 为站点名称精确条件,均在分页前应用。
|
||||
`brief=true` 将描述截至 200 字符,缓存 hash 仍由完整原文生成。
|
||||
|
||||
@@ -327,6 +327,10 @@ Select the operation for the task first, then send only fields declared by that
|
||||
| `download.tasks.active` | none | optional `page`, `count`, `name` |
|
||||
| `site.list` | none | optional `page`, `count`, `name`, `status=all\|active\|inactive` |
|
||||
|
||||
`site.category` 只返回站点分类,不返回分类搜索参数。分类 `id` 可以是整数或文本,
|
||||
数字字符串沿用整数响应。将所选标识用逗号拼接后传入 `site.resource` 的 `query.cat`,
|
||||
保留返回值,不要把文本分类强制转为整数。
|
||||
|
||||
Subscription execution logs are browser resource endpoints:
|
||||
`GET /api/v1/subscribe/{subscription_id}/logs` (SSE, or text with `length=-1`)
|
||||
and `/logs/download` (ZIP). They require the existing resource Cookie and enforce
|
||||
|
||||
485
tests/fixtures/site_categories.json
vendored
Normal file
485
tests/fixtures/site_categories.json
vendored
Normal file
@@ -0,0 +1,485 @@
|
||||
{
|
||||
"source": {
|
||||
"repository": "jxxghp/MoviePilot-Build",
|
||||
"commit": "085e3d3cd2b0a44f83346f2aca97cc658d9adaeb",
|
||||
"files": {
|
||||
"hhanclub": "sites/private/hhanclub.yml",
|
||||
"totheglory": "sites/private/totheglory.yml",
|
||||
"animez": "sites/private/animez.yml",
|
||||
"starspace": "sites/private/starspace.yml",
|
||||
"anibt": "sites/public/anibt.yml"
|
||||
}
|
||||
},
|
||||
"indexers": {
|
||||
"hhanclub": {
|
||||
"id": "hhanclub",
|
||||
"name": "憨憨",
|
||||
"domain": "https://hhanclub.net/",
|
||||
"encoding": "UTF-8",
|
||||
"schema": "NexusHhanclub",
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"method": "get",
|
||||
"type": "all"
|
||||
},
|
||||
{
|
||||
"path": "special.php",
|
||||
"method": "get",
|
||||
"type": "music"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}",
|
||||
"search_area": 4
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
}
|
||||
},
|
||||
"category": {
|
||||
"param": "cat[]",
|
||||
"movie": [
|
||||
{
|
||||
"id": 401,
|
||||
"cat": "Movies",
|
||||
"desc": "Movies/电影"
|
||||
},
|
||||
{
|
||||
"id": 405,
|
||||
"cat": "Anime",
|
||||
"desc": "Animations/动漫"
|
||||
},
|
||||
{
|
||||
"id": 404,
|
||||
"cat": "Documentary",
|
||||
"desc": "Documentaries/纪录片"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": 404,
|
||||
"cat": "Documentary",
|
||||
"desc": "Documentaries/纪录片"
|
||||
},
|
||||
{
|
||||
"id": 405,
|
||||
"cat": "Anime",
|
||||
"desc": "Animations/动漫"
|
||||
},
|
||||
{
|
||||
"id": 402,
|
||||
"cat": "TV",
|
||||
"desc": "TV Series/连续剧"
|
||||
},
|
||||
{
|
||||
"id": 403,
|
||||
"cat": "TV",
|
||||
"desc": "TV Shows/综艺"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": 410,
|
||||
"cat": "Music",
|
||||
"desc": "Music/音乐"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"totheglory": {
|
||||
"id": "ttg",
|
||||
"name": "听听歌",
|
||||
"domain": "https://totheglory.im/",
|
||||
"encoding": "UTF-8",
|
||||
"schema": "NexusPhp",
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "browse.php?c=M"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search_field": "{keyword}",
|
||||
"c": "M"
|
||||
},
|
||||
"imdbid_format": "imdb{imdbid_num}",
|
||||
"batch": {
|
||||
"delimiter": "+",
|
||||
"space_replace": "+"
|
||||
}
|
||||
},
|
||||
"category": {
|
||||
"field": "search_field",
|
||||
"delimiter": " 分类:",
|
||||
"movie": [
|
||||
{
|
||||
"id": "电影DVDRip",
|
||||
"cat": "Movies/SD"
|
||||
},
|
||||
{
|
||||
"id": "电影720p",
|
||||
"cat": "Movies/HD"
|
||||
},
|
||||
{
|
||||
"id": "电影1080i/p",
|
||||
"cat": "Movies/HD"
|
||||
},
|
||||
{
|
||||
"id": "BluRay原盘",
|
||||
"cat": "Movies/BluRay"
|
||||
},
|
||||
{
|
||||
"id": "影视2160p",
|
||||
"cat": "Movies/UHD"
|
||||
},
|
||||
{
|
||||
"id": "UHD原盘",
|
||||
"cat": "Movies/UHD"
|
||||
},
|
||||
{
|
||||
"id": "高清动漫",
|
||||
"cat": "Anime/HD"
|
||||
},
|
||||
{
|
||||
"id": "动漫原盘",
|
||||
"cat": "Anime/BluRay"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "纪录片720p",
|
||||
"cat": "Movies/HD"
|
||||
},
|
||||
{
|
||||
"id": "纪录片1080i/p",
|
||||
"cat": "Movies/HD"
|
||||
},
|
||||
{
|
||||
"id": "纪录片BluRay原盘",
|
||||
"cat": "Movies/BluRay"
|
||||
},
|
||||
{
|
||||
"id": "影视2160p",
|
||||
"cat": "TV/UHD"
|
||||
},
|
||||
{
|
||||
"id": "欧美剧720p",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "欧美剧1080i/p",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "高清日剧",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "大陆港台剧1080i/p",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "大陆港台剧720p",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "高清韩剧",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "欧美剧包",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "日剧包",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "韩剧包",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "华语剧包",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "高清动漫",
|
||||
"cat": "Anime/HD"
|
||||
},
|
||||
{
|
||||
"id": "韩国综艺",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "日本综艺",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "高清综艺",
|
||||
"cat": "TV/HD"
|
||||
},
|
||||
{
|
||||
"id": "动漫原盘",
|
||||
"cat": "Anime/BluRay"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "无损音乐FLAC&APE",
|
||||
"cat": "Music"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"animez": {
|
||||
"id": "animez",
|
||||
"name": "AnimeZ",
|
||||
"domain": "https://animez.to/",
|
||||
"encoding": "UTF-8",
|
||||
"schema": "NexusPhp",
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"method": "get"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
},
|
||||
"result_media_type": "requested"
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "MOVIE",
|
||||
"value": "MOVIE",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/Movie"
|
||||
},
|
||||
{
|
||||
"id": "SPECIAL",
|
||||
"value": "SPECIAL",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/Special"
|
||||
},
|
||||
{
|
||||
"id": "OVA",
|
||||
"value": "OVA",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/OVA"
|
||||
},
|
||||
{
|
||||
"id": "ONA",
|
||||
"value": "ONA",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/ONA"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "TV",
|
||||
"value": "TV",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/TV"
|
||||
},
|
||||
{
|
||||
"id": "TV_SHORT",
|
||||
"value": "TV_SHORT",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/TV Short"
|
||||
},
|
||||
{
|
||||
"id": "SPECIAL",
|
||||
"value": "SPECIAL",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/Special"
|
||||
},
|
||||
{
|
||||
"id": "OVA",
|
||||
"value": "OVA",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/OVA"
|
||||
},
|
||||
{
|
||||
"id": "ONA",
|
||||
"value": "ONA",
|
||||
"param": "format[]",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime/ONA"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "MUSIC",
|
||||
"value": "MUSIC",
|
||||
"param": "format[]",
|
||||
"cat": "Music",
|
||||
"desc": "Anime/Music"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"starspace": {
|
||||
"id": "starspace",
|
||||
"name": "星空",
|
||||
"domain": "https://star-space.net/",
|
||||
"encoding": "UTF-8",
|
||||
"schema": "NexusPhp",
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "p_torrent/video_list_t.php",
|
||||
"method": "get",
|
||||
"type": "all"
|
||||
},
|
||||
{
|
||||
"path": "p_music/music_list_t.php",
|
||||
"method": "get",
|
||||
"type": "music"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}",
|
||||
"area": "name"
|
||||
},
|
||||
"result_media_type": "requested",
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
}
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": 401,
|
||||
"cat": "Movies",
|
||||
"desc": "Movies/电影"
|
||||
},
|
||||
{
|
||||
"id": 405,
|
||||
"cat": "Anime",
|
||||
"desc": "Animations/动漫"
|
||||
},
|
||||
{
|
||||
"id": 404,
|
||||
"cat": "Documentary",
|
||||
"desc": "Documentaries/纪录片"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": 404,
|
||||
"cat": "Documentary",
|
||||
"desc": "Documentaries/纪录片"
|
||||
},
|
||||
{
|
||||
"id": 405,
|
||||
"cat": "Anime",
|
||||
"desc": "Animations/动漫"
|
||||
},
|
||||
{
|
||||
"id": 402,
|
||||
"cat": "TV",
|
||||
"desc": "TV Series/连续剧"
|
||||
},
|
||||
{
|
||||
"id": 403,
|
||||
"cat": "TV",
|
||||
"desc": "TV Shows/综艺"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "music",
|
||||
"cat": "Music",
|
||||
"desc": "音乐区"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"anibt": {
|
||||
"id": "anibt",
|
||||
"name": "AniBT",
|
||||
"domain": "https://anibt.net/",
|
||||
"encoding": "UTF-8",
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "rss/magnets.xml",
|
||||
"method": "get",
|
||||
"type": "all"
|
||||
},
|
||||
{
|
||||
"path": "rss/magnets.xml",
|
||||
"method": "get",
|
||||
"type": "movie"
|
||||
},
|
||||
{
|
||||
"path": "rss/magnets.xml",
|
||||
"method": "get",
|
||||
"type": "tv"
|
||||
},
|
||||
{
|
||||
"path": "rss/other/music.xml",
|
||||
"method": "get",
|
||||
"type": "music"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"q": "{keyword}"
|
||||
},
|
||||
"result_media_type": "requested"
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "anime",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime"
|
||||
},
|
||||
{
|
||||
"id": "raw",
|
||||
"cat": "Anime",
|
||||
"desc": "Raw"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "anime",
|
||||
"cat": "Anime",
|
||||
"desc": "Anime"
|
||||
},
|
||||
{
|
||||
"id": "raw",
|
||||
"cat": "Anime",
|
||||
"desc": "Raw"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "music",
|
||||
"cat": "Music",
|
||||
"desc": "Music"
|
||||
},
|
||||
{
|
||||
"id": "stage",
|
||||
"cat": "Music",
|
||||
"desc": "Stage"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,23 +128,27 @@ def test_site_category_only_projects_category_mappings(category, monkeypatch):
|
||||
|
||||
def test_site_category_skips_search_parameter_settings(monkeypatch):
|
||||
"""
|
||||
分类配置中的 field、delimiter、param 等搜索参数不能被当成分类项逐字符返回。
|
||||
分类搜索参数及非法列表项不进入响应,音乐分类与跨分组去重保持兼容。
|
||||
"""
|
||||
category = {
|
||||
"field": "cat[]",
|
||||
"delimiter": "&",
|
||||
"param": "cat",
|
||||
"param": "cat[]",
|
||||
"movie": [{"id": 401, "cat": "Movies", "desc": "电影"}, "invalid"],
|
||||
"tv": [{"id": 402, "cat": "TV", "desc": "剧集"}],
|
||||
"tv": [{"id": 401, "cat": "Movies", "desc": "电影"}, {"id": 402, "cat": "TV", "desc": "剧集"}],
|
||||
"music": [{"id": 410, "cat": "Music", "desc": "音乐"}],
|
||||
}
|
||||
query = SimpleNamespace(get=AsyncMock(return_value=SimpleNamespace(domain="https://example.test")))
|
||||
helper = SimpleNamespace(async_get_indexer=AsyncMock(return_value={"category": category}))
|
||||
monkeypatch.setattr(site, "SitesHelper", Mock(return_value=helper))
|
||||
result = asyncio.run(site.site_category(1, query=query, _=None))
|
||||
assert result == [{"id": 401, "cat": "Movies", "desc": "电影"}, {"id": 402, "cat": "TV", "desc": "剧集"}]
|
||||
assert result == [
|
||||
{"id": 401, "cat": "Movies", "desc": "电影"},
|
||||
{"id": 402, "cat": "TV", "desc": "剧集"},
|
||||
{"id": 410, "cat": "Music", "desc": "音乐"},
|
||||
]
|
||||
assert TypeAdapter(list[SiteCategory]).validate_python(result) == [
|
||||
SiteCategory(id=401, cat="Movies", desc="电影"),
|
||||
SiteCategory(id=402, cat="TV", desc="剧集"),
|
||||
SiteCategory(id=410, cat="Music", desc="音乐"),
|
||||
]
|
||||
|
||||
|
||||
|
||||
114
tests/test_site_category.py
Normal file
114
tests/test_site_category.py
Normal file
@@ -0,0 +1,114 @@
|
||||
"""
|
||||
回放构建仓的站点分类配置,验证接口序列化和搜索参数兼容性。
|
||||
"""
|
||||
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
import pytest
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from app.api.endpoints import site
|
||||
from app.modules.indexer.spider import SiteSpider
|
||||
from app.schemas.site import SiteCategory
|
||||
from app.schemas.types import MediaType
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def category_indexers():
|
||||
"""
|
||||
读取构建仓的公开 YAML 快照,来源提交和路径记录在载具中。
|
||||
"""
|
||||
fixture_path = Path(__file__).parent / "fixtures" / "site_categories.json"
|
||||
return json.loads(fixture_path.read_text(encoding="utf-8"))["indexers"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("site_id", "expected_ids"),
|
||||
[
|
||||
("hhanclub", [401, 405, 404, 402, 403, 410]),
|
||||
("animez", ["MOVIE", "SPECIAL", "OVA", "ONA", "TV", "TV_SHORT", "MUSIC"]),
|
||||
("starspace", [401, 405, 404, 402, 403, "music"]),
|
||||
("anibt", ["anime", "raw", "music", "stage"]),
|
||||
(
|
||||
"totheglory",
|
||||
[
|
||||
"电影DVDRip", "电影720p", "电影1080i/p", "BluRay原盘", "影视2160p", "UHD原盘",
|
||||
"高清动漫", "动漫原盘", "纪录片720p", "纪录片1080i/p", "纪录片BluRay原盘", "影视2160p",
|
||||
"欧美剧720p", "欧美剧1080i/p", "高清日剧", "大陆港台剧1080i/p", "大陆港台剧720p",
|
||||
"高清韩剧", "欧美剧包", "日剧包", "韩剧包", "华语剧包", "韩国综艺", "日本综艺",
|
||||
"高清综艺", "无损音乐FLAC&APE",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_site_categories_serialize_real_resource_configs(category_indexers, monkeypatch, site_id, expected_ids):
|
||||
"""
|
||||
真实分类经过响应封装后保留数字与文本标识、音乐分组及去重顺序。
|
||||
"""
|
||||
indexer = category_indexers[site_id]
|
||||
snapshot = copy.deepcopy(indexer)
|
||||
query = SimpleNamespace(get=AsyncMock(return_value=SimpleNamespace(domain=indexer["domain"])))
|
||||
helper = SimpleNamespace(async_get_indexer=AsyncMock(return_value=indexer))
|
||||
monkeypatch.setattr(site, "SitesHelper", Mock(return_value=helper))
|
||||
app = FastAPI()
|
||||
app.include_router(site.router, prefix="/api/v1/site")
|
||||
app.dependency_overrides[site.get_site_query_service] = lambda: query
|
||||
app.dependency_overrides[site.verify_token] = lambda: None
|
||||
|
||||
with TestClient(app) as client:
|
||||
response = client.get("/api/v1/site/category/1")
|
||||
|
||||
assert response.status_code == 200
|
||||
body = response.json()
|
||||
assert body["success"] is True
|
||||
assert [item["id"] for item in body["data"]] == expected_ids
|
||||
assert indexer == snapshot
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("category_id", "expected"),
|
||||
[(401, 401), ("401", 401), ("00401", 401), ("music", "music"), ("电影720p", "电影720p"), (None, None)],
|
||||
)
|
||||
def test_category_schema_preserves_text_and_legacy_numeric_ids(category_id, expected):
|
||||
"""
|
||||
数字字符串沿用旧接口的整数输出,真实文本标识保持原值。
|
||||
"""
|
||||
category = SiteCategory(id=category_id)
|
||||
|
||||
assert category.id == expected
|
||||
assert type(category.id) is type(expected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("site_id", "media_type", "category_id", "parameter", "expected_value", "path"),
|
||||
[
|
||||
("hhanclub", MediaType.MOVIE, "401", "cat[]", "401", "/torrents.php"),
|
||||
("hhanclub", MediaType.MUSIC, "410", "cat[]", "410", "/special.php"),
|
||||
("animez", MediaType.MUSIC, "MUSIC", "format[]", "MUSIC", "/torrents.php"),
|
||||
("totheglory", MediaType.MOVIE, "电影DVDRip", "search_field", "回放测试 分类:电影DVDRip", "/browse.php"),
|
||||
(
|
||||
"totheglory", MediaType.MUSIC, "无损音乐FLAC&APE", "search_field",
|
||||
"回放测试 分类:无损音乐FLAC&APE", "/browse.php",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_resource_categories_keep_real_search_parameters(
|
||||
category_indexers, site_id, media_type, category_id, parameter, expected_value, path,
|
||||
):
|
||||
"""
|
||||
接口返回的数字及文本分类仍能生成站点要求的精确搜索参数。
|
||||
"""
|
||||
spider = SiteSpider(
|
||||
indexer=category_indexers[site_id], keyword="回放测试", mtype=media_type, cat=category_id,
|
||||
)
|
||||
|
||||
parsed = urlparse(spider._SiteSpider__get_search_url())
|
||||
|
||||
assert parsed.path == path
|
||||
assert parse_qs(parsed.query)[parameter] == [expected_value]
|
||||
@@ -12,9 +12,10 @@ from app.api.endpoints import site as site_endpoint
|
||||
|
||||
|
||||
@pytest.mark.parametrize("page", [0, 1, 2])
|
||||
def test_site_resource_preserves_zero_based_pages_and_categories(monkeypatch, page):
|
||||
@pytest.mark.parametrize("cat", ["401,402", "电影DVDRip,MUSIC,music"])
|
||||
def test_site_resource_preserves_zero_based_pages_and_categories(monkeypatch, page, cat):
|
||||
"""
|
||||
第一页与后续页必须保持独立偏移,多选分类原样交给浏览链路。
|
||||
第一页与后续页保持独立偏移,数字及文本多选分类原样交给浏览链路。
|
||||
"""
|
||||
query = SimpleNamespace(get=AsyncMock(return_value=SimpleNamespace(domain="https://site.example/")))
|
||||
torrent = SimpleNamespace(to_dict=lambda: {"title": "命中资源"})
|
||||
@@ -22,11 +23,11 @@ def test_site_resource_preserves_zero_based_pages_and_categories(monkeypatch, pa
|
||||
monkeypatch.setattr(site_endpoint, "TorrentsChain", lambda: SimpleNamespace(async_browse=browse))
|
||||
|
||||
result = asyncio.run(site_endpoint.site_resource(
|
||||
site_id=1, keyword="关键词", cat="401,402", page=page, query=query,
|
||||
site_id=1, keyword="关键词", cat=cat, page=page, query=query,
|
||||
))
|
||||
|
||||
assert result == [{"title": "命中资源"}]
|
||||
query.get.assert_awaited_once_with(1)
|
||||
browse.assert_awaited_once_with(
|
||||
domain="https://site.example/", keyword="关键词", cat="401,402", page=page, mtype=None,
|
||||
domain="https://site.example/", keyword="关键词", cat=cat, page=page, mtype=None,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user