import unittest from importlib.machinery import SourceFileLoader from pathlib import Path from unittest.mock import patch ROOT = Path(__file__).resolve().parents[1] MODULE = SourceFileLoader("ppnix_spider", str(ROOT / "PPnix.py")).load_module() Spider = MODULE.Spider class TestPPnixSpider(unittest.TestCase): def setUp(self): Spider._instance = None self.spider = Spider() self.spider.init() def test_home_content_exposes_expected_categories_and_filter_keys(self): content = self.spider.homeContent(False) self.assertEqual([item["type_id"] for item in content["class"]], ["1", "2"]) self.assertEqual([item["key"] for item in content["filters"]["1"]], ["class", "by"]) self.assertEqual([item["key"] for item in content["filters"]["2"]], ["class", "by"]) def test_build_category_url_maps_first_page_and_sort_values(self): self.assertEqual( self.spider._build_category_url("1", "1", {}), "https://www.ppnix.com/cn/movie/----newstime.html", ) self.assertEqual( self.spider._build_category_url("2", "3", {"class": "爱情", "by": "hits"}), "https://www.ppnix.com/cn/tv/爱情---2-onclick.html", ) def test_build_search_url_uses_ppnix_pattern(self): self.assertEqual( self.spider._build_search_url("繁花", "1"), "https://www.ppnix.com/cn/search/%E7%B9%81%E8%8A%B1--.html", ) self.assertEqual( self.spider._build_search_url("繁花", "2"), "https://www.ppnix.com/cn/search/%E7%B9%81%E8%8A%B1--.html-page-2", ) def test_parse_cards_extracts_short_vod_id_title_cover_and_remarks(self): html = """
""" self.assertEqual( self.spider._parse_cards(html), [ { "vod_id": "movie/123.html", "vod_name": "示例影片", "vod_pic": "https://www.ppnix.com/poster.jpg", "vod_remarks": "HD", } ], ) @patch.object(Spider, "_request_html") def test_home_video_content_merges_movie_and_tv_cards(self, mock_request_html): mock_request_html.return_value = """ """ result = self.spider.homeVideoContent() self.assertEqual([item["vod_id"] for item in result["list"]], ["movie/101.html", "tv/201.html"]) @patch.object(Spider, "_request_html") def test_category_content_uses_expected_listing_url(self, mock_request_html): mock_request_html.return_value = """ """ result = self.spider.categoryContent("1", "2", False, {"class": "动作", "by": "score"}) self.assertEqual( mock_request_html.call_args.args[0], "https://www.ppnix.com/cn/movie/动作---1-rating.html", ) self.assertEqual(result["page"], 2) self.assertEqual(result["list"][0]["vod_id"], "movie/301.html") self.assertNotIn("pagecount", result) @patch.object(Spider, "_request_html") def test_search_content_parses_only_movie_and_tv_ids(self, mock_request_html): mock_request_html.return_value = """ """ result = self.spider.searchContent("搜索词", False, "1") self.assertEqual( mock_request_html.call_args.args[0], "https://www.ppnix.com/cn/search/%E6%90%9C%E7%B4%A2%E8%AF%8D--.html", ) self.assertEqual([item["vod_id"] for item in result["list"]], ["movie/401.html"]) self.assertNotIn("pagecount", result) def test_extract_m3u8_items_reads_infoid_and_episode_names(self): html = """ """ self.assertEqual( self.spider._extract_m3u8_items(html), {"info_id": "7788", "items": ["第1集", "第2集"]}, ) @patch.object(Spider, "_request_html") def test_detail_content_builds_ppnix_play_group(self, mock_request_html): mock_request_html.return_value = """