fix: 识别失效商品链接返回首页 (#111)
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
"""PDD 页面分类与商品深链状态机测试。"""
|
||||
|
||||
from pathlib import Path
|
||||
import unittest
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from src.pdd_page_classifier import (
|
||||
ACTION_NETWORK_ERROR,
|
||||
ACTION_READY,
|
||||
ACTION_REOPEN,
|
||||
ACTION_UNAVAILABLE,
|
||||
ACTION_WAIT,
|
||||
PAGE_CAPTCHA,
|
||||
PAGE_EXTERNAL,
|
||||
PAGE_GOODS,
|
||||
PAGE_HOME,
|
||||
PAGE_LOADING,
|
||||
PAGE_LOGIN_REQUIRED,
|
||||
PAGE_NETWORK_ERROR,
|
||||
PAGE_RISK_CONTROL,
|
||||
GoodsOpenTracker,
|
||||
classify_pdd_page,
|
||||
)
|
||||
|
||||
|
||||
FIXTURES = Path(__file__).parent / "fixtures"
|
||||
PDD = "com.xunmeng.pinduoduo"
|
||||
|
||||
|
||||
def observation(text: str, package: str = PDD):
|
||||
xml = (
|
||||
'<hierarchy><node package="{0}" class="android.widget.TextView" '
|
||||
'text="{1}" bounds="[0,0][900,300]" visible-to-user="true"/>'
|
||||
'<node package="{0}" text="占位一"/><node package="{0}" '
|
||||
'text="占位二"/></hierarchy>'
|
||||
).format(package, text)
|
||||
return classify_pdd_page(ET.fromstring(xml), package)
|
||||
|
||||
|
||||
class PddPageClassifierTest(unittest.TestCase):
|
||||
def test_real_home_fixture_ignores_incorrect_focused_package(self) -> None:
|
||||
root = ET.parse(FIXTURES / "pdd_home_page.xml").getroot()
|
||||
|
||||
result = classify_pdd_page(root, "com.android.settings")
|
||||
|
||||
self.assertEqual(PAGE_HOME, result.kind)
|
||||
self.assertTrue(result.pdd_hierarchy)
|
||||
|
||||
def test_special_pages_are_not_home(self) -> None:
|
||||
cases = {
|
||||
"加载中": PAGE_LOADING,
|
||||
"网络不给力": PAGE_NETWORK_ERROR,
|
||||
"手机号登录": PAGE_LOGIN_REQUIRED,
|
||||
"请完成验证": PAGE_CAPTCHA,
|
||||
"操作频繁": PAGE_RISK_CONTROL,
|
||||
"立即购买": PAGE_GOODS,
|
||||
}
|
||||
for label, expected in cases.items():
|
||||
with self.subTest(label=label):
|
||||
self.assertEqual(expected, observation(label).kind)
|
||||
|
||||
def test_browser_word_does_not_count_as_goods(self) -> None:
|
||||
result = observation("立即购买", "com.android.chrome")
|
||||
self.assertEqual(PAGE_EXTERNAL, result.kind)
|
||||
|
||||
def test_transient_home_can_reach_goods_without_reopen(self) -> None:
|
||||
home = classify_pdd_page(
|
||||
ET.parse(FIXTURES / "pdd_home_page.xml").getroot(), PDD
|
||||
)
|
||||
tracker = GoodsOpenTracker(None, 0.0)
|
||||
|
||||
self.assertEqual(ACTION_WAIT, tracker.observe(home, 2.0).action)
|
||||
self.assertEqual(ACTION_WAIT, tracker.observe(home, 2.1).action)
|
||||
self.assertEqual(
|
||||
ACTION_READY, tracker.observe(observation("立即购买"), 2.2).action
|
||||
)
|
||||
|
||||
def test_stable_home_reopens_once_then_marks_unavailable(self) -> None:
|
||||
home = classify_pdd_page(
|
||||
ET.parse(FIXTURES / "pdd_home_page.xml").getroot(), PDD
|
||||
)
|
||||
tracker = GoodsOpenTracker(None, 0.0)
|
||||
|
||||
for at in (2.0, 2.1):
|
||||
self.assertEqual(ACTION_WAIT, tracker.observe(home, at).action)
|
||||
self.assertEqual(ACTION_REOPEN, tracker.observe(home, 2.2).action)
|
||||
tracker.reopened(3.0)
|
||||
for at in (5.0, 5.1):
|
||||
self.assertEqual(ACTION_WAIT, tracker.observe(home, at).action)
|
||||
self.assertEqual(ACTION_UNAVAILABLE, tracker.observe(home, 5.2).action)
|
||||
|
||||
def test_old_goods_tree_is_not_accepted_as_new_target(self) -> None:
|
||||
old = observation("旧商品标题 立即购买")
|
||||
tracker = GoodsOpenTracker(old, 0.0)
|
||||
|
||||
self.assertEqual(ACTION_WAIT, tracker.observe(old, 0.2).action)
|
||||
self.assertTrue(tracker.stale_goods_seen)
|
||||
new = observation("目标商品标题 立即购买")
|
||||
self.assertEqual(ACTION_READY, tracker.observe(new, 0.3).action)
|
||||
|
||||
def test_network_error_has_own_decision(self) -> None:
|
||||
tracker = GoodsOpenTracker(None, 0.0)
|
||||
decision = tracker.observe(observation("网络不给力"), 3.0)
|
||||
self.assertEqual(ACTION_NETWORK_ERROR, decision.action)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user