from __future__ import annotations import json import os from pathlib import Path import pytest from tests.e2e._helpers import e2e_enabled from tests.e2e._helpers import log from tests.e2e._helpers import run_cli_live pytestmark = [pytest.mark.e2e] @pytest.fixture def tr(request): return request.config.pluginmanager.getplugin("terminalreporter") def _privatehd_cookie_file() -> Path: path = os.getenv("WSCRAPER_PRIVATEHD_COOKIE_FILE") or os.getenv("WSCRAPER_COOKIE_FILE", "cookies.txt") return Path(path) def _privatehd_wishlist_url() -> str: return os.getenv("WSCRAPER_PRIVATEHD_WISHLIST_URL", "").strip() @pytest.mark.skipif(not e2e_enabled(), reason="Set WSCRAPER_E2E=1 to run live tests") def test_get_bookmarks_live(tmp_path: Path, tr) -> None: cookie_file = _privatehd_cookie_file() if not cookie_file.exists(): pytest.skip(f"Cookie file not found: {cookie_file}") wishlist_url = _privatehd_wishlist_url() if not wishlist_url: pytest.skip("Set WSCRAPER_PRIVATEHD_WISHLIST_URL to run PrivateHD live bookmark test") output_file = tmp_path / "bookmarks.json" log(tr, f"Output file: {output_file}") return_code, output_text = run_cli_live( [ "privatehd", "--action", "get-bookmarks", "-c", str(cookie_file), "--wishlist-url", wishlist_url, "-o", str(output_file), ], tr, ) assert return_code == 0, f"CLI failed:\n{output_text}" assert output_file.exists(), "bookmarks.json was not created" data = json.loads(output_file.read_text(encoding="utf-8")) assert isinstance(data, list), "bookmarks output must be a JSON list" assert len(data) >= 1, "expected at least one bookmark record" log(tr, f"Extracted records: {len(data)}", kind="ok") first = data[0] assert isinstance(first, dict), "bookmark entry must be an object" for required_key in ("pageURL", "title", "backgroundImage", "downloadURL", "removeToken"): assert required_key in first, f"missing key: {required_key}" assert isinstance(first["pageURL"], str) and first["pageURL"].startswith("http") assert isinstance(first["title"], str) and first["title"].strip() != "" assert isinstance(first["downloadURL"], str) and first["downloadURL"].startswith("http") assert isinstance(first["removeToken"], str) and first["removeToken"].strip() != "" @pytest.mark.skipif(not e2e_enabled(), reason="Set WSCRAPER_E2E=1 to run live tests") def test_download_torrent_file_live(tmp_path: Path, tr) -> None: cookie_file = _privatehd_cookie_file() if not cookie_file.exists(): pytest.skip(f"Cookie file not found: {cookie_file}") wishlist_url = _privatehd_wishlist_url() if not wishlist_url: pytest.skip("Set WSCRAPER_PRIVATEHD_WISHLIST_URL to run PrivateHD live download test") test_url = os.getenv("WSCRAPER_PRIVATEHD_TEST_TORRENT_URL", "").strip() download_url = os.getenv("WSCRAPER_PRIVATEHD_TEST_DOWNLOAD_URL", "").strip() if not test_url or not download_url: pytest.skip("Set WSCRAPER_PRIVATEHD_TEST_TORRENT_URL and WSCRAPER_PRIVATEHD_TEST_DOWNLOAD_URL") output_dir = tmp_path / "torrent" log(tr, f"Output dir: {output_dir}") return_code, output_text = run_cli_live( [ "privatehd", "--action", "download-torrent-files", "-u", test_url, "--download-url", download_url, "-c", str(cookie_file), "--wishlist-url", wishlist_url, "-o", str(output_dir), ], tr, ) assert return_code == 0, f"CLI failed:\n{output_text}" assert output_dir.exists(), "torrent output directory was not created" torrent_files = list(output_dir.glob("*.torrent")) assert len(torrent_files) >= 1, "expected at least one .torrent file" log(tr, f"Downloaded .torrent files: {len(torrent_files)}", kind="ok") content = torrent_files[0].read_bytes() assert content.startswith(b"d"), "torrent file should start with bencode dictionary token 'd'" assert b"4:info" in content[:4096], "torrent file should include 'info' dictionary marker" @pytest.mark.skipif(not e2e_enabled(), reason="Set WSCRAPER_E2E=1 to run live tests") def test_remove_bookmark_live(tr) -> None: cookie_file = _privatehd_cookie_file() if not cookie_file.exists(): pytest.skip(f"Cookie file not found: {cookie_file}") wishlist_url = _privatehd_wishlist_url() if not wishlist_url: pytest.skip("Set WSCRAPER_PRIVATEHD_WISHLIST_URL to run PrivateHD live remove test") test_url = os.getenv("WSCRAPER_PRIVATEHD_TEST_REMOVE_URL", "").strip() remove_token = os.getenv("WSCRAPER_PRIVATEHD_TEST_REMOVE_TOKEN", "").strip() if not test_url or not remove_token: pytest.skip("Set WSCRAPER_PRIVATEHD_TEST_REMOVE_URL and WSCRAPER_PRIVATEHD_TEST_REMOVE_TOKEN") return_code, output_text = run_cli_live( [ "privatehd", "--action", "remove-bookmark", "-u", test_url, "--remove-token", remove_token, "-c", str(cookie_file), "--wishlist-url", wishlist_url, ], tr, timeout=240, ) assert return_code == 0, f"CLI failed:\n{output_text}" assert "Bookmark removed successfully." in output_text log(tr, "PrivateHD bookmark removal completed", kind="ok")