fix: 安全兼容采购规格繁简匹配 (#251)
This commit is contained in:
@@ -1618,6 +1618,35 @@ class U2PddPurchaseAdapterTest(unittest.TestCase):
|
||||
self.assertIn("purchase_select_size", operations)
|
||||
adapter.close()
|
||||
|
||||
def test_failed_option_stage_is_recorded_as_failed(self):
|
||||
cases = (
|
||||
({"color": "不存在的颜色"}, "purchase_select_color"),
|
||||
(
|
||||
{"color": "黑色", "size": "不存在的尺码"},
|
||||
"purchase_select_size",
|
||||
),
|
||||
)
|
||||
for options, expected_operation in cases:
|
||||
with self.subTest(operation=expected_operation):
|
||||
device = FakeDevice()
|
||||
adapter = self._adapter(device, [])
|
||||
records = []
|
||||
trace = TaskPerformanceTrace(sink=records.append)
|
||||
trace.bind_task(f"PUR-{expected_operation}")
|
||||
adapter.open_goods(GOODS_URL)
|
||||
|
||||
with trace.activate(), self.assertRaises(PddPurchaseError):
|
||||
adapter.select_options(options)
|
||||
|
||||
matching = [
|
||||
record
|
||||
for record in records
|
||||
if record["operation"] == expected_operation
|
||||
]
|
||||
self.assertEqual(len(matching), 1)
|
||||
self.assertEqual(matching[0]["result"], "failed")
|
||||
adapter.close()
|
||||
|
||||
def test_same_quantity_does_not_focus_editor(self):
|
||||
device = FakeDevice()
|
||||
adapter = self._adapter(device, [])
|
||||
|
||||
@@ -6,7 +6,10 @@ import xml.etree.ElementTree as ET
|
||||
|
||||
from src.util.select_color_size import (
|
||||
color_selection_failure_reason,
|
||||
normalize_spec_text,
|
||||
select_color,
|
||||
select_size,
|
||||
size_selection_failure_reason,
|
||||
)
|
||||
|
||||
|
||||
@@ -16,9 +19,15 @@ FIXTURES = Path(__file__).parent / "fixtures"
|
||||
class StaticColorDevice:
|
||||
"""模拟没有滚动属性的图片颜色规格面板。"""
|
||||
|
||||
def __init__(self, xml_data: str, confirm_selection: bool = True) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
xml_data: str,
|
||||
confirm_selection: bool = True,
|
||||
selected_text: str = "测试黑色",
|
||||
) -> None:
|
||||
self.xml_data = xml_data
|
||||
self.confirm_selection = confirm_selection
|
||||
self.selected_text = selected_text
|
||||
self.clicks = []
|
||||
self.swipes = []
|
||||
|
||||
@@ -31,10 +40,10 @@ class StaticColorDevice:
|
||||
return
|
||||
root = ET.fromstring(self.xml_data)
|
||||
for node in root.iter("node"):
|
||||
if node.get("text", "").strip() == "测试黑色":
|
||||
if node.get("text", "").strip() == self.selected_text:
|
||||
node.set("selected", "true")
|
||||
if node.get("text", "").strip().startswith("请选择"):
|
||||
node.set("text", "已选: 测试黑色")
|
||||
node.set("text", f"已选: {self.selected_text}")
|
||||
self.xml_data = ET.tostring(root, encoding="unicode")
|
||||
|
||||
def swipe(self, *args, **kwargs) -> None:
|
||||
@@ -122,6 +131,83 @@ class StaticColorSelectionTest(unittest.TestCase):
|
||||
self.assertEqual(device.clicks, [])
|
||||
self.assertEqual(device.swipes, [])
|
||||
|
||||
def test_traditional_color_matches_unique_simplified_card(self):
|
||||
simplified = "缥缈仙姬绾【黑色】"
|
||||
traditional = "縹緲仙姬綰【黑色】"
|
||||
panel_xml = self.panel_xml.replace("测试黑色", simplified)
|
||||
device = StaticColorDevice(panel_xml, selected_text=simplified)
|
||||
|
||||
selected = select_color(
|
||||
device,
|
||||
panel_xml,
|
||||
traditional,
|
||||
action_delay=0.001,
|
||||
)
|
||||
|
||||
self.assertEqual(normalize_spec_text(traditional), simplified.casefold())
|
||||
self.assertTrue(selected)
|
||||
self.assertEqual(device.clicks, [(194, 1389)])
|
||||
|
||||
def test_traditional_size_matches_unique_simplified_option(self):
|
||||
simplified = "均码【40.0-60.0公斤】"
|
||||
traditional = "均碼【40.0-60.0公斤】"
|
||||
panel_xml = self.panel_xml.replace('text="M"', f'text="{simplified}"')
|
||||
device = StaticColorDevice(panel_xml, selected_text=simplified)
|
||||
|
||||
selected = select_size(
|
||||
device,
|
||||
panel_xml,
|
||||
traditional,
|
||||
action_delay=0.001,
|
||||
)
|
||||
|
||||
self.assertTrue(selected)
|
||||
self.assertEqual(device.clicks, [(77, 1762)])
|
||||
|
||||
def test_normalized_duplicate_color_candidates_are_not_clicked(self):
|
||||
simplified = "缥缈仙姬绾【黑色】"
|
||||
traditional = "縹緲仙姬綰【黑色】"
|
||||
panel_xml = self.panel_xml.replace("测试黑色", simplified).replace(
|
||||
"测试红色", simplified
|
||||
)
|
||||
device = StaticColorDevice(panel_xml, selected_text=simplified)
|
||||
|
||||
selected = select_color(
|
||||
device,
|
||||
panel_xml,
|
||||
traditional,
|
||||
action_delay=0.001,
|
||||
)
|
||||
|
||||
self.assertFalse(selected)
|
||||
self.assertEqual(device.clicks, [])
|
||||
self.assertEqual(
|
||||
color_selection_failure_reason(panel_xml, traditional),
|
||||
"target_ambiguous",
|
||||
)
|
||||
|
||||
def test_normalized_duplicate_size_candidates_are_not_clicked(self):
|
||||
simplified = "均码【40.0-60.0公斤】"
|
||||
traditional = "均碼【40.0-60.0公斤】"
|
||||
panel_xml = self.panel_xml.replace('text="M"', f'text="{simplified}"').replace(
|
||||
'text="L"', f'text="{simplified}"'
|
||||
)
|
||||
device = StaticColorDevice(panel_xml, selected_text=simplified)
|
||||
|
||||
selected = select_size(
|
||||
device,
|
||||
panel_xml,
|
||||
traditional,
|
||||
action_delay=0.001,
|
||||
)
|
||||
|
||||
self.assertFalse(selected)
|
||||
self.assertEqual(device.clicks, [])
|
||||
self.assertEqual(
|
||||
size_selection_failure_reason(panel_xml, traditional),
|
||||
"target_ambiguous",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user