douyin-crawler-poc/test_login_douyin.py

99 lines
4.1 KiB
Python

import importlib
import io
import tempfile
import unittest
from contextlib import redirect_stdout
from pathlib import Path
from unittest import mock
class LoginDouyinModuleTests(unittest.TestCase):
def test_build_login_command_uses_expected_chrome_arguments(self) -> None:
module = importlib.import_module("login_douyin")
command = module.build_login_command(
chrome_path="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
profile_dir=Path("/tmp/douyin-profile"),
browser_port=9223,
user_url="https://www.douyin.com/user/example",
)
self.assertEqual(
command,
[
"open",
"-na",
"/Applications/Google Chrome.app",
"--args",
"--user-data-dir=/tmp/douyin-profile",
"--remote-debugging-port=9223",
"https://www.douyin.com/user/example",
],
)
def test_build_parser_uses_expected_defaults(self) -> None:
module = importlib.import_module("login_douyin")
args = module.build_parser().parse_args([])
self.assertEqual(args.browser_port, 9223)
self.assertEqual(args.chrome_path, module.DEFAULT_CHROME_PATH)
self.assertEqual(args.user_url, module.DEFAULT_USER_URL)
def test_main_creates_profile_dir_and_prints_next_step(self) -> None:
module = importlib.import_module("login_douyin")
with tempfile.TemporaryDirectory() as temp_dir:
profile_dir = Path(temp_dir) / "profile"
stdout = io.StringIO()
with redirect_stdout(stdout):
with mock.patch.object(module, "launch_browser") as mocked_launch:
with mock.patch.object(module, "wait_for_browser_debug_port") as mocked_wait:
exit_code = module.main(
[
"--chrome-path",
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"--profile-dir",
str(profile_dir),
"--browser-port",
"9333",
]
)
self.assertEqual(exit_code, 0)
self.assertTrue(profile_dir.exists())
mocked_launch.assert_called_once()
mocked_wait.assert_called_once_with(9333)
self.assertIn("9333", stdout.getvalue())
self.assertIn("./.venv/bin/python Douyin.py --browser-port 9333", stdout.getvalue())
def test_main_returns_error_when_chrome_path_missing(self) -> None:
module = importlib.import_module("login_douyin")
stdout = io.StringIO()
with redirect_stdout(stdout):
exit_code = module.main(["--chrome-path", "/tmp/does-not-exist-chrome"])
self.assertEqual(exit_code, 1)
self.assertIn("Chrome", stdout.getvalue())
self.assertIn("不存在", stdout.getvalue())
def test_main_returns_error_when_debug_port_never_becomes_ready(self) -> None:
module = importlib.import_module("login_douyin")
with tempfile.TemporaryDirectory() as temp_dir:
profile_dir = Path(temp_dir) / "profile"
stdout = io.StringIO()
with redirect_stdout(stdout):
with mock.patch.object(module, "launch_browser"):
with mock.patch.object(
module,
"wait_for_browser_debug_port",
side_effect=RuntimeError("端口未就绪"),
):
exit_code = module.main(
[
"--chrome-path",
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
"--profile-dir",
str(profile_dir),
]
)
self.assertEqual(exit_code, 1)
self.assertIn("端口未就绪", stdout.getvalue())
if __name__ == "__main__":
unittest.main()