fix: 安全处理采购数量输入法 (#117)
This commit is contained in:
@@ -65,7 +65,10 @@ class FakeEditor:
|
||||
self.count = 1
|
||||
|
||||
def set_text(self, value: str) -> None:
|
||||
self.device.editor_values.append(value)
|
||||
self.device.quantity = int(value)
|
||||
if self.device.show_keyboard_on_edit:
|
||||
self.device.keyboard_shown = True
|
||||
|
||||
|
||||
class FakeDevice:
|
||||
@@ -78,6 +81,13 @@ class FakeDevice:
|
||||
self.app_wait_calls = 0
|
||||
self.app_current_calls = 0
|
||||
self.has_opened = False
|
||||
self.editor_values = []
|
||||
self.show_keyboard_on_edit = True
|
||||
self.keyboard_shown = False
|
||||
self.keyboard_status_known = True
|
||||
self.keyboard_can_dismiss = True
|
||||
self.close_panel_on_back = False
|
||||
self.presses = []
|
||||
|
||||
def app_current(self):
|
||||
self.app_current_calls += 1
|
||||
@@ -103,8 +113,28 @@ class FakeDevice:
|
||||
|
||||
def click(self, x, y):
|
||||
self.clicks.append((x, y))
|
||||
if self.mode == "panel" and 570 <= x <= 650 and 700 <= y <= 780:
|
||||
self.quantity += 1
|
||||
return
|
||||
if self.mode == "panel" and 390 <= x <= 470 and 700 <= y <= 780:
|
||||
self.quantity -= 1
|
||||
return
|
||||
self.mode = "panel"
|
||||
|
||||
def shell(self, command):
|
||||
self.asserted_shell_command = command
|
||||
if not self.keyboard_status_known:
|
||||
return "input method state unavailable"
|
||||
value = "true" if self.keyboard_shown else "false"
|
||||
return f"mInputShown={value} mIsInputViewShown={value}"
|
||||
|
||||
def press(self, key):
|
||||
self.presses.append(key)
|
||||
if key == "back" and self.keyboard_can_dismiss:
|
||||
self.keyboard_shown = False
|
||||
if self.close_panel_on_back:
|
||||
self.mode = "home"
|
||||
|
||||
def __call__(self, **selector):
|
||||
if selector == {"className": "android.widget.EditText"}:
|
||||
return FakeEditor(self)
|
||||
@@ -216,10 +246,107 @@ class U2PddPurchaseAdapterTest(unittest.TestCase):
|
||||
self.assertEqual(confirmation.price_cent, 503)
|
||||
self.assertEqual(confirmation.page_kind, "order_confirmation")
|
||||
self.assertEqual(calls, [("color", "黑色"), ("size", "3XL【140-165斤】")])
|
||||
# 只点击一次商品页采购入口;最终“提交订单”从不点击。
|
||||
self.assertEqual(len(device.clicks), 1)
|
||||
# 点击一次商品页采购入口和一次加号;最终“提交订单”从不点击。
|
||||
self.assertEqual(len(device.clicks), 2)
|
||||
self.assertEqual(device.editor_values, [])
|
||||
self.assertEqual(device.app_wait_calls, 0)
|
||||
|
||||
def test_same_quantity_does_not_focus_editor(self):
|
||||
device = FakeDevice()
|
||||
adapter = self._adapter(device, [])
|
||||
adapter.open_goods(GOODS_URL)
|
||||
adapter.select_options({"color": "黑色", "size": "3XL【140-165斤】"})
|
||||
|
||||
adapter.set_quantity(1)
|
||||
|
||||
self.assertEqual(device.editor_values, [])
|
||||
self.assertEqual(device.presses, [])
|
||||
self.assertEqual(len(device.clicks), 1)
|
||||
adapter.close()
|
||||
|
||||
def test_small_quantity_difference_uses_buttons(self):
|
||||
device = FakeDevice()
|
||||
adapter = self._adapter(device, [])
|
||||
adapter.open_goods(GOODS_URL)
|
||||
adapter.select_options({"color": "黑色", "size": "3XL【140-165斤】"})
|
||||
|
||||
adapter.set_quantity(4)
|
||||
|
||||
self.assertEqual(device.quantity, 4)
|
||||
self.assertEqual(device.editor_values, [])
|
||||
self.assertEqual(device.presses, [])
|
||||
# 采购入口一次,加号三次。
|
||||
self.assertEqual(len(device.clicks), 4)
|
||||
adapter.close()
|
||||
|
||||
def test_large_quantity_difference_closes_visible_keyboard_once(self):
|
||||
device = FakeDevice()
|
||||
adapter = self._adapter(device, [])
|
||||
adapter.open_goods(GOODS_URL)
|
||||
adapter.select_options({"color": "黑色", "size": "3XL【140-165斤】"})
|
||||
|
||||
adapter.set_quantity(7)
|
||||
|
||||
self.assertEqual(device.editor_values, ["7"])
|
||||
self.assertEqual(device.presses, ["back"])
|
||||
self.assertFalse(device.keyboard_shown)
|
||||
adapter.close()
|
||||
|
||||
def test_editor_does_not_press_back_when_keyboard_is_already_hidden(self):
|
||||
device = FakeDevice()
|
||||
device.show_keyboard_on_edit = False
|
||||
adapter = self._adapter(device, [])
|
||||
adapter.open_goods(GOODS_URL)
|
||||
adapter.select_options({"color": "黑色", "size": "3XL【140-165斤】"})
|
||||
|
||||
adapter.set_quantity(7)
|
||||
|
||||
self.assertEqual(device.editor_values, ["7"])
|
||||
self.assertEqual(device.presses, [])
|
||||
adapter.close()
|
||||
|
||||
def test_editor_stops_when_keyboard_cannot_be_closed(self):
|
||||
device = FakeDevice()
|
||||
device.keyboard_can_dismiss = False
|
||||
adapter = self._adapter(device, [])
|
||||
adapter.open_goods(GOODS_URL)
|
||||
adapter.select_options({"color": "黑色", "size": "3XL【140-165斤】"})
|
||||
|
||||
with self.assertRaises(PddPurchaseError) as raised:
|
||||
adapter.set_quantity(7)
|
||||
|
||||
self.assertEqual(raised.exception.code, "PURCHASE_KEYBOARD_DISMISS_FAILED")
|
||||
self.assertEqual(device.presses, ["back"])
|
||||
adapter.close()
|
||||
|
||||
def test_editor_does_not_press_back_when_keyboard_state_is_unknown(self):
|
||||
device = FakeDevice()
|
||||
device.keyboard_status_known = False
|
||||
adapter = self._adapter(device, [])
|
||||
adapter.open_goods(GOODS_URL)
|
||||
adapter.select_options({"color": "黑色", "size": "3XL【140-165斤】"})
|
||||
|
||||
with self.assertRaises(PddPurchaseError) as raised:
|
||||
adapter.set_quantity(7)
|
||||
|
||||
self.assertEqual(raised.exception.code, "PURCHASE_KEYBOARD_DISMISS_FAILED")
|
||||
self.assertEqual(device.presses, [])
|
||||
adapter.close()
|
||||
|
||||
def test_editor_stops_when_back_closes_specification_panel(self):
|
||||
device = FakeDevice()
|
||||
device.close_panel_on_back = True
|
||||
adapter = self._adapter(device, [])
|
||||
adapter.open_goods(GOODS_URL)
|
||||
adapter.select_options({"color": "黑色", "size": "3XL【140-165斤】"})
|
||||
|
||||
with self.assertRaises(PddPurchaseError) as raised:
|
||||
adapter.set_quantity(7)
|
||||
|
||||
self.assertEqual(raised.exception.code, "PURCHASE_PANEL_LOST_AFTER_KEYBOARD")
|
||||
self.assertEqual(device.presses, ["back"])
|
||||
adapter.close()
|
||||
|
||||
def test_unsupported_dynamic_option_stops_before_click(self):
|
||||
device = FakeDevice()
|
||||
adapter = self._adapter(device, [])
|
||||
@@ -396,8 +523,8 @@ class U2PddPurchaseAdapterTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(state.submit_candidate_count, 1)
|
||||
self.assertEqual(raised.exception.code, "PURCHASE_SUBMIT_ALREADY_ATTEMPTED")
|
||||
# 第一次点击采购入口,第二次且仅一次点击最终提交。
|
||||
self.assertEqual(len(device.clicks), 2)
|
||||
# 依次点击采购入口、数量加号和最终提交。
|
||||
self.assertEqual(len(device.clicks), 3)
|
||||
adapter.close()
|
||||
|
||||
def test_live_adapter_rejects_multiple_submit_targets_without_click(self):
|
||||
|
||||
Reference in New Issue
Block a user