| 1 | import importlib |
| 2 | from types import SimpleNamespace |
| 3 | |
| 4 | import pytest |
| 5 | |
| 6 | main_module = importlib.import_module("cli.main") |
| 7 | |
| 8 | |
| 9 | class _FakeCookieManager: |
| 10 | def get_cookies(self): |
| 11 | return {"msToken": "token-1"} |
| 12 | |
| 13 | |
| 14 | class _FakeAPIClient: |
| 15 | def __init__(self, _cookies, proxy=None): |
| 16 | self.proxy = proxy |
| 17 | self.resolved_urls = [] |
| 18 | |
| 19 | async def __aenter__(self): |
| 20 | return self |
| 21 | |
| 22 | async def __aexit__(self, exc_type, exc, tb): |
| 23 | return None |
| 24 | |
| 25 | async def resolve_short_url(self, short_url: str): |
| 26 | self.resolved_urls.append(short_url) |
| 27 | return "https://www.douyin.com/video/7604129988555574538" |
| 28 | |
| 29 | |
| 30 | class _FakeDownloader: |
| 31 | async def download(self, parsed): |
| 32 | return SimpleNamespace(total=1, success=1, failed=0, skipped=0, parsed=parsed) |
| 33 | |
| 34 | |
| 35 | @pytest.mark.asyncio |
| 36 | async def test_download_url_resolves_short_link_before_parsing(monkeypatch, tmp_path): |
| 37 | config = main_module.ConfigLoader() |
| 38 | config.update(path=str(tmp_path)) |
| 39 | |
| 40 | parsed_inputs = [] |
| 41 | |
| 42 | def _fake_parse(url: str): |
| 43 | parsed_inputs.append(url) |
| 44 | return {"type": "video", "aweme_id": "7604129988555574538"} |
| 45 | |
| 46 | fake_downloader = _FakeDownloader() |
| 47 | |
| 48 | monkeypatch.setattr(main_module, "DouyinAPIClient", _FakeAPIClient) |
| 49 | monkeypatch.setattr(main_module.URLParser, "parse", _fake_parse) |
| 50 | monkeypatch.setattr( |
| 51 | main_module.DownloaderFactory, |
| 52 | "create", |
| 53 | lambda *_args, **_kwargs: fake_downloader, |
| 54 | ) |
| 55 | |
| 56 | result = await main_module.download_url( |
| 57 | "https://v.douyin.com/short-link/", |
| 58 | config, |
| 59 | _FakeCookieManager(), |
| 60 | database=None, |
| 61 | progress_reporter=None, |
| 62 | ) |
| 63 | |
| 64 | assert result is not None |
| 65 | assert result.success == 1 |
| 66 | assert parsed_inputs == ["https://www.douyin.com/video/7604129988555574538"] |
| 67 | |
| 68 | |
| 69 | @pytest.mark.asyncio |
| 70 | async def test_download_url_passes_proxy_to_api_client(monkeypatch, tmp_path): |
| 71 | config = main_module.ConfigLoader() |
| 72 | config.update(path=str(tmp_path), proxy="http://127.0.0.1:8899") |
| 73 | |
| 74 | captured = {} |
| 75 | |
| 76 | class _ProxyAPIClient(_FakeAPIClient): |
| 77 | def __init__(self, cookies, proxy=None): |
| 78 | captured["cookies"] = cookies |
| 79 | captured["proxy"] = proxy |
| 80 | super().__init__(cookies, proxy=proxy) |
| 81 | |
| 82 | monkeypatch.setattr(main_module, "DouyinAPIClient", _ProxyAPIClient) |
| 83 | monkeypatch.setattr( |
| 84 | main_module.URLParser, |
| 85 | "parse", |
| 86 | lambda _url: {"type": "video", "aweme_id": "7604129988555574538"}, |
| 87 | ) |
| 88 | monkeypatch.setattr( |
| 89 | main_module.DownloaderFactory, |
| 90 | "create", |
| 91 | lambda *_args, **_kwargs: _FakeDownloader(), |
| 92 | ) |
| 93 | |
| 94 | result = await main_module.download_url( |
| 95 | "https://www.douyin.com/video/7604129988555574538", |
| 96 | config, |
| 97 | _FakeCookieManager(), |
| 98 | database=None, |
| 99 | progress_reporter=None, |
| 100 | ) |
| 101 | |
| 102 | assert result is not None |
| 103 | assert result.success == 1 |
| 104 | assert captured["proxy"] == "http://127.0.0.1:8899" |
| 105 |