更新
This commit is contained in:
@@ -18,9 +18,12 @@ if str(BACKEND_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(BACKEND_DIR))
|
||||
|
||||
from rpa_engine.douyin_im import http_client as http_client_module
|
||||
from rpa_engine.douyin_im.auth import DouyinAuth
|
||||
from rpa_engine.douyin_im.frontier import ensure_frontier_ws
|
||||
from rpa_engine.douyin_im.http_client import DouyinImHttpClient
|
||||
from rpa_engine.douyin_im.session import DouyinImSession
|
||||
from rpa_engine.egress_channels import EgressChannel
|
||||
from rpa_engine import playwright_worker as playwright_worker_module
|
||||
from rpa_engine.playwright_worker import DouyinWorker
|
||||
|
||||
|
||||
@@ -33,6 +36,75 @@ class SendTextMessageEntryTests(unittest.IsolatedAsyncioTestCase):
|
||||
)
|
||||
return DouyinImHttpClient(session, account_id=account_id)
|
||||
|
||||
def test_query_user_does_not_replace_existing_im_uid(self):
|
||||
client = self._make_client()
|
||||
auth = SimpleNamespace(
|
||||
source_ip="",
|
||||
get_uid=MagicMock(return_value=938334054809296),
|
||||
)
|
||||
|
||||
resolved = client._resolve_authoritative_uid(auth)
|
||||
|
||||
self.assertEqual(resolved, 10001)
|
||||
self.assertEqual(client.session.my_uid, 10001)
|
||||
auth.get_uid.assert_not_called()
|
||||
|
||||
def test_verified_uid_does_not_replace_the_runtime_device_id(self):
|
||||
# device_id 是 query/user 返回的设备注册号,my_uid 是账号 UID。
|
||||
# 拿 my_uid 顶替 device_id 会让 frontier 订阅到另一个地址:握手照样
|
||||
# 成功,却永远收不到这个账号的私信。
|
||||
session = DouyinImSession(
|
||||
cookies={"sessionid": "test-session"},
|
||||
my_uid=2609567359568155,
|
||||
device_id="7678285795559818786",
|
||||
web_id="7678286623234475535",
|
||||
uid_verified=True,
|
||||
)
|
||||
|
||||
auth = DouyinAuth.from_im_session(session)
|
||||
|
||||
self.assertEqual(auth.device_id, "7678285795559818786")
|
||||
self.assertEqual(session.device_id, "7678285795559818786")
|
||||
|
||||
def test_captured_tokenless_browser_frontier_url_is_kept(self):
|
||||
url = (
|
||||
"wss://frontier100-normal.zijieapi.com/ws/v2?aid=6383&"
|
||||
"device_platform=web&fpid=9&device_id=7678285795559818786&"
|
||||
"access_key=0123456789abcdef0123456789abcdef&version_code=fws_1.0.0"
|
||||
)
|
||||
session = DouyinImSession(
|
||||
cookies={"sessionid": "test-session"},
|
||||
ws_urls=[url],
|
||||
my_uid=2609567359568155,
|
||||
device_id="7678285795559818786",
|
||||
)
|
||||
|
||||
resolved = ensure_frontier_ws(session)
|
||||
|
||||
self.assertEqual(resolved, url)
|
||||
self.assertEqual(session.ws_urls, [url])
|
||||
|
||||
def test_non_im_frontier_product_is_rejected(self):
|
||||
url = (
|
||||
"wss://frontier100-normal.zijieapi.com/ws/v2?aid=6383&"
|
||||
"device_platform=web&fpid=971&device_id=7678285795559818786&"
|
||||
"access_key=0123456789abcdef0123456789abcdef"
|
||||
)
|
||||
session = DouyinImSession(
|
||||
cookies={"sessionid": "test-session"},
|
||||
ws_urls=[url],
|
||||
my_uid=2609567359568155,
|
||||
device_id="7678285795559818786",
|
||||
uid_verified=True,
|
||||
)
|
||||
|
||||
resolved = ensure_frontier_ws(session)
|
||||
|
||||
self.assertIn("frontier-im.douyin.com", resolved)
|
||||
self.assertIn("fpid=9", resolved)
|
||||
self.assertIn("device_id=7678285795559818786", resolved)
|
||||
self.assertNotIn("fpid=971", resolved)
|
||||
|
||||
async def test_public_entry_submits_the_whole_send_to_outbound_queue(self):
|
||||
client = self._make_client(account_id=73)
|
||||
submit = AsyncMock(return_value=True)
|
||||
@@ -194,6 +266,59 @@ class SendTextMessageEntryTests(unittest.IsolatedAsyncioTestCase):
|
||||
|
||||
|
||||
class WorkerLifecycleTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_virtual_display_starts_before_playwright_driver(self):
|
||||
ensure_display = AsyncMock()
|
||||
|
||||
async def start_driver():
|
||||
ensure_display.assert_awaited_once_with(False)
|
||||
return "playwright-driver"
|
||||
|
||||
manager = SimpleNamespace(start=AsyncMock(side_effect=start_driver))
|
||||
with (
|
||||
patch.object(
|
||||
playwright_worker_module,
|
||||
"resolve_headless",
|
||||
return_value=False,
|
||||
),
|
||||
patch.object(
|
||||
playwright_worker_module,
|
||||
"ensure_browser_display",
|
||||
ensure_display,
|
||||
),
|
||||
patch.object(
|
||||
playwright_worker_module,
|
||||
"async_playwright",
|
||||
return_value=manager,
|
||||
),
|
||||
):
|
||||
driver, headless = await playwright_worker_module._start_playwright_for_browser()
|
||||
|
||||
self.assertEqual(driver, "playwright-driver")
|
||||
self.assertFalse(headless)
|
||||
manager.start.assert_awaited_once_with()
|
||||
|
||||
async def test_visible_login_prompt_overrides_stale_sessionid(self):
|
||||
worker = DouyinWorker(account_id=917, login_mode="browser")
|
||||
worker._has_visible_login_prompt = AsyncMock(return_value=True)
|
||||
worker.check_homepage_login_status = AsyncMock(return_value=True)
|
||||
worker.check_logged_in_by_cookie = AsyncMock(return_value=True)
|
||||
|
||||
logged_in = await worker._verify_login_state()
|
||||
|
||||
self.assertFalse(logged_in)
|
||||
worker.check_homepage_login_status.assert_not_awaited()
|
||||
worker.check_logged_in_by_cookie.assert_not_awaited()
|
||||
|
||||
async def test_homepage_message_entry_is_not_login_evidence(self):
|
||||
worker = DouyinWorker(account_id=918, login_mode="browser")
|
||||
worker._has_visible_login_prompt = AsyncMock(return_value=False)
|
||||
worker.page = SimpleNamespace(query_selector=AsyncMock(return_value=None))
|
||||
|
||||
logged_in = await worker.check_homepage_login_status()
|
||||
|
||||
self.assertFalse(logged_in)
|
||||
worker.page.query_selector.assert_awaited_once()
|
||||
|
||||
async def test_start_saves_task_and_stop_waits_until_it_is_done(self):
|
||||
worker = DouyinWorker(account_id=919, login_mode="im_direct")
|
||||
loop_started = asyncio.Event()
|
||||
|
||||
Reference in New Issue
Block a user