Ctrl K
ComunidadGuías…

tests/test_metadata_1pondo.py

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""一本道官网作品 JSON 的取页与解析。"""
import json
import unittest

from peach.http import HttpResponse
from peach.sources import FailureReason, Page, Session, SourceFailure
from peach.sources.onepondo import ONEPONDO, STUDIO, OnePondoSource, movie_id, names_this_studio

COVER = "https://www.1pondo.tv/moviepages/112312_478/images/str.jpg"
DETAIL = "https://www.1pondo.tv/dyn/phpauto/movie_details/movie_id/112312_478.json"


def details(movie="112312_478", title="裸演奏 〜第5回演奏会・ホルン〜", release="2012-11-23",
            duration=3874, series="裸演奏", actresses=("飯岡かなこ",), english=("Kanako Iioka",),
            tags=("AV女優", "スレンダー", "中出し", "720p"), thumbs=True):
    raw = {"MovieID": movie, "Title": title, "Release": release, "Duration": duration,
           "Desc": "楽器とエロスのハーモニー。", "DescEn": None,
           "Series": series, "SeriesEn": "Hadaka Enso",
           "Actor": actresses[0] if actresses else "",
           "ActressesJa": list(actresses), "ActressesEn": list(english),
           "UCNAME": list(tags), "SiteID": 2470, "Status": True,
           "MovieThumb": f"https://www.1pondo.tv/moviepages/{movie}/images/thum_b.jpg"}
    if thumbs:
        for field in ("ThumbLow", "ThumbMed", "ThumbHigh", "ThumbUltra"):
            raw[field] = f"https://www.1pondo.tv/moviepages/{movie}/images/str.jpg"
    return json.dumps(raw, ensure_ascii=False)


def parse_details(body, code):
    return OnePondoSource().parse(Page(DETAIL, body.encode()), code).payload()


def serve(pages):
    calls = []

    def call(request, timeout, limit):
        calls.append((request.url, request.headers.get("Referer"), limit))
        body = pages.get(request.url)
        return HttpResponse(200 if body is not None else 404, {}, (body or "").encode(), request.url)

    call.calls = calls
    return call


class OnePondoCodeTests(unittest.TestCase):
    def test_the_shop_writes_the_code_with_an_underscore(self):
        # 分隔符是片商标识,账本两种写法都有:文件名带进来的那个可能是连字号。
        self.assertEqual(movie_id("112312_478"), "112312_478")
        self.assertEqual(movie_id("092415-001"), "092415_001")
        self.assertEqual(OnePondoSource().detail_url("092415-001"),
                         "https://www.1pondo.tv/dyn/phpauto/movie_details/movie_id/092415_001.json")

    def test_codes_that_are_not_dated_ask_nowhere(self):
        # `125735_816` 是手机录像 `VID_20220818_125735_816.mp4` 剪出来的,12 月 57 日不存在。
        for code in ("ABW-358", "FC2-PPV-4364209", "n1234", "125735-816", "", None):
            self.assertEqual(movie_id(code), "", repr(code))
            self.assertEqual(OnePondoSource().detail_url(code), "", repr(code))
        transport = serve({})
        with self.assertRaises(SourceFailure) as caught:
            OnePondoSource().query("ABW-358", session=Session(transport))
        self.assertEqual((caught.exception.reason, str(caught.exception)),
                         (FailureReason.NOT_FOUND, "这个番号不是一本道的写法"))
        self.assertEqual(transport.calls, [])

    def test_only_local_evidence_names_this_studio(self):
        # 一本道与カリビアンコム 的番号同形,拿另一家的番号去问,答回来的是同一天发行的
        # 另一部片。所以问不问它看本机手上的路径、文件名与账本厂牌。
        self.assertTrue(names_this_studio("B:/云下载/[JAV] [Uncensored] 1pon 112312_478/x.mp4", "", ""))
        self.assertTrue(names_this_studio("B:/MVP/1pondo-092415_159-001-FHD/x.mp4", "x.mp4", None))
        self.assertTrue(names_this_studio("", "", "一本道"))
        self.assertFalse(names_this_studio("B:/云下载/Carib-040221-001-FHD/x.mp4", "x.mp4", "カリビアンコム"))
        self.assertFalse(names_this_studio())


class OnePondoDetailTests(unittest.TestCase):
    def test_the_work_json_gives_every_field_the_review_card_shows(self):
        found = parse_details(details(), "112312_478")
        self.assertEqual(found["id"], "112312_478")
        self.assertEqual(found["content_id"], "112312_478")
        self.assertEqual(found["source_url"], "https://www.1pondo.tv/movies/112312_478/")
        self.assertEqual(found["title"], "裸演奏 〜第5回演奏会・ホルン〜")
        self.assertEqual(found["release_date"], "2012-11-23")
        self.assertEqual(found["maker"], STUDIO)
        self.assertEqual(found["series"], "裸演奏")
        self.assertEqual(found["genres"], ["AV女優", "スレンダー", "中出し", "720p"])
        self.assertEqual(found["cover_url"], COVER)
        self.assertEqual(found["cover_urls"], [COVER])

    def test_the_whole_payload_matches_the_snapshot_shape_key_by_key(self):
        self.assertEqual(parse_details(details(), "112312_478"), {
            "id": "112312_478", "content_id": "112312_478", "source_url": "https://www.1pondo.tv/movies/112312_478/",
            "title": "裸演奏 〜第5回演奏会・ホルン〜", "description": "楽器とエロスのハーモニー。",
            "actresses": [{"japanese_name": "飯岡かなこ", "name_romaji": "Kanako Iioka"}],
            "maker": "一本道", "label": "", "series": "裸演奏", "director": "", "release_date": "2012-11-23",
            "runtime": 64.57, "genres": ["AV女優", "スレンダー", "中出し", "720p"],
            "cover_urls": [COVER], "cover_url": COVER})

    def test_the_runtime_arrives_in_seconds_and_lands_in_minutes(self):
        self.assertEqual(parse_details(details(), "112312_478")["runtime"], 64.57)
        self.assertIsNone(parse_details(details(duration=0), "112312_478")["runtime"])
        self.assertIsNone(parse_details(details(duration=None), "112312_478")["runtime"])

    def test_the_japanese_name_is_the_identity_and_the_romaji_follows_as_an_alias(self):
        found = parse_details(details(actresses=("白咲碧", "陽菜"), english=("Aoi Shirosaki", "Hina")),
                              "112312_478")
        self.assertEqual(found["actresses"],
                         [{"japanese_name": "白咲碧", "name_romaji": "Aoi Shirosaki"},
                          {"japanese_name": "陽菜", "name_romaji": "Hina"}])

    def test_a_work_with_only_the_single_actor_field_still_names_her(self):
        found = parse_details(details(actresses=("飯岡かなこ",), english=()), "112312_478")
        self.assertEqual(found["actresses"], [{"japanese_name": "飯岡かなこ", "name_romaji": ""}])

    def test_another_works_json_is_not_this_ones_data(self):
        # 番号同形的另一家片子问到这里时,官网回的作品号对不上,那份资料一个字都不能用。
        for body, code, wording in ((details(movie="092415_001"), "112312_478", "一本道回的作品号对不上这个番号"),
                                    ("null", "112312_478", "一本道回的作品号对不上这个番号"),
                                    (details(), "ABW-358", "这个番号不是一本道的写法")):
            with self.subTest(code=code, body=body[:30]), self.assertRaises(SourceFailure) as caught:
                parse_details(body, code)
            self.assertEqual((caught.exception.reason, str(caught.exception)), (FailureReason.NOT_FOUND, wording))

    def test_a_body_that_is_not_json_is_a_changed_site_not_a_missing_work(self):
        with self.assertRaises(SourceFailure) as caught:
            parse_details("<html>维护中</html>", "112312_478")
        self.assertEqual((caught.exception.reason, str(caught.exception)),
                         (FailureReason.PARSE_ERROR, "一本道返回的不是作品 JSON"))

    def test_the_cover_falls_back_to_the_list_thumb_when_the_still_is_missing(self):
        found = parse_details(details(thumbs=False), "112312_478")
        self.assertEqual(found["cover_url"],
                         "https://www.1pondo.tv/moviepages/112312_478/images/thum_b.jpg")
        self.assertEqual(ONEPONDO.name, "1pondo")


class OnePondoQueryTests(unittest.TestCase):
    def test_the_json_is_asked_on_the_shop_host_with_its_own_page_limit(self):
        transport = serve({DETAIL: details()})
        found = OnePondoSource().query("112312-478", session=Session(transport))
        self.assertEqual(found.title, "裸演奏 〜第5回演奏会・ホルン〜")
        self.assertEqual(transport.calls, [(DETAIL, "https://www.1pondo.tv/", 1024 * 1024)])

    def test_a_withdrawn_work_answers_404_and_reads_as_absent(self):
        with self.assertRaises(SourceFailure) as caught:
            OnePondoSource().query("112312_478", session=Session(serve({})))
        self.assertEqual((caught.exception.kind, str(caught.exception)), ("not_found", "一本道站上没有这部片"))


if __name__ == "__main__":
    unittest.main()