"""虎牙四段式账号 (账号----密码----手机号----接码链接) 导入与短信自动求解测试。""" from __future__ import annotations from unittest.mock import MagicMock, patch import pytest from core.huya.verification.solver import ( HuyaSmsAuthRequiredError, HuyaVerificationSolver, ) from web.backend.services.huya_service import ( import_huya_password_accounts, split_huya_password_line, ) def test_parse_password_line_with_sms_url(): """测试四段式账号行解析 (账号----密码----手机号----接码链接)。""" line = ( "hy_299112483----aa778899----+14504409332----" "http://194.163.45.144/api/get_sms?key=c16fe33219924363fa362ed69dc6fd4f" ) parsed = split_huya_password_line(line) assert parsed is not None assert parsed.username == "hy_299112483" assert parsed.password == "aa778899" assert parsed.phone == "+14504409332" assert ( parsed.sms_url == "http://194.163.45.144/api/get_sms?key=c16fe33219924363fa362ed69dc6fd4f" ) def test_parse_password_line_backward_compatible(): """测试老格式向后兼容性。""" # 2段 p2 = split_huya_password_line("user123----pass456") assert p2 is not None assert p2.username == "user123" assert p2.password == "pass456" assert p2.phone == "" assert p2.sms_url == "" # 3段 (带手机号或cookie) p3 = split_huya_password_line("user123----pass456----13800138000") assert p3 is not None assert p3.username == "user123" assert p3.password == "pass456" assert p3.cookie == "13800138000" assert p3.sms_url == "" def test_import_password_accounts_persists_sms_url(): """测试导入账号密码服务会正确写入 sms_url 和 game_phone。""" mock_db = MagicMock() # 模拟无现有账号 mock_db.query().filter().first.return_value = None text = ( "hy_299112483----aa778899----+14504409332----" "http://194.163.45.144/api/get_sms?key=c16fe33219924363fa362ed69dc6fd4f" ) created, skipped = import_huya_password_accounts(mock_db, text, tag="测试接码") assert created == 1 assert skipped == 0 added_account = mock_db.add.call_args[0][0] assert added_account.username == "hy_299112483" assert added_account.game_phone == "+14504409332" assert ( added_account.sms_url == "http://194.163.45.144/api/get_sms?key=c16fe33219924363fa362ed69dc6fd4f" ) assert added_account.tag == "测试接码" def test_import_password_accounts_strictly_four_segments(): """测试账号密码导入默认严格限制仅允许四段格式。""" mock_db = MagicMock() mock_db.query().filter().first.return_value = None # 两段、三段会被跳过;仅四段有效行会被导入 text = ( "user1----pass1\n" "user2----pass2----13800138000\n" "user3----pass3----+14504409332----http://194.163.45.144/api/get_sms?key=xxx\n" "user4----pass4----not_a_url\n" ) created, skipped = import_huya_password_accounts(mock_db, text, tag="四段测试") assert created == 1 assert skipped == 3 def test_solver_strategy_with_and_without_sms_url(): """测试在遇到 sms_auth2 时,有接码链接不抛异常,无接码链接抛出短信异常。""" url = "https://aq.huya.com/p/safe_auth/sms_auth2.html?param=xyz&mobile=14504409332" # 无 sms_url,应触发 HuyaSmsAuthRequiredError solver_no_sms = HuyaVerificationSolver(page_url=url) with pytest.raises(HuyaSmsAuthRequiredError): solver_no_sms._parse_strategy(url) # 有 sms_url,应正常解析为 sms_auth solver_with_sms = HuyaVerificationSolver( page_url=url, sms_url="http://194.163.45.144/api/get_sms?key=test", ) solver_with_sms._parse_strategy(url) assert solver_with_sms.auth_type == "sms_auth" def test_solver_sms_flow(): """测试 solver._solve_sms_strategy 自动发码、接码与提码闭环。""" from core.sms_provider import SmsPollResult url = "https://aq.huya.com/p/safe_auth/sms_auth2.html?param=mock_param&mobile=14504409332&appId=5002" solver = HuyaVerificationSolver( page_url=url, sms_url="http://194.163.45.144/api/get_sms?key=test_key", account="hy_test", ) solver._parse_strategy(url) mock_send_res = {"returnCode": 0, "message": "发送成功"} mock_verify_res = { "returnCode": 0, "data": {"authId": "auth_token_success_123"}, } with ( patch.object( solver, "_request_json", return_value=mock_send_res, ) as mock_req_json, patch.object( solver, "_submit_verify", return_value=mock_verify_res["data"], ) as mock_submit, patch( "core.sms_provider.SmsProviderClient.poll", return_value=SmsPollResult(status="code", code="654321"), ) as mock_poll, ): data = solver._solve_sms_strategy() assert data["authId"] == "auth_token_success_123" mock_req_json.assert_called_once() assert "send-sms-code" in mock_req_json.call_args[0][1] mock_poll.assert_called_once() mock_submit.assert_called_once() verify_url, verify_payload = mock_submit.call_args[0] assert "verify-sms-code" in verify_url assert verify_payload["data"]["smsCode"] == b"654321".hex()