fix: 修正规格返回后的颜色复核顺序 (#266)

This commit is contained in:
chengma
2026-08-18 14:03:57 +08:00
parent 1ce99d4e50
commit b0cddb956b
3 changed files with 110 additions and 3 deletions
+102 -2
View File
@@ -260,10 +260,18 @@ class SoldOutRefreshPurchaseDevice(FakeDevice):
class VerticallyScrolledColorPanelDevice(FakeDevice):
"""模拟 PDD 记住规格面板纵向位置。"""
def __init__(self, *, starts_at_top: bool, restores_on_swipe: bool = True):
def __init__(
self,
*,
starts_at_top: bool,
restores_on_swipe: bool = True,
selected_color: str = "",
):
super().__init__()
self.at_color_top = starts_at_top
self.restores_on_swipe = restores_on_swipe
self.selected_color = selected_color
self.selected_size = ""
self.swipes = []
def dump_hierarchy(self):
@@ -272,9 +280,20 @@ class VerticallyScrolledColorPanelDevice(FakeDevice):
if self.mode == "home":
return home_xml()
if self.mode == "panel":
return vertically_scrolled_purchase_panel_xml(
xml_data = vertically_scrolled_purchase_panel_xml(
at_color_top=self.at_color_top
)
if self.at_color_top and self.selected_color == "黑色":
xml_data = xml_data.replace(
'<node text="黑色" clickable="true"',
'<node text="黑色" selected="true" clickable="true"',
)
if self.at_color_top and self.selected_size == "均码":
xml_data = xml_data.replace(
'<node text="均码" clickable="true"',
'<node text="均码" selected="true" clickable="true"',
)
return xml_data
return super().dump_hierarchy()
def swipe(self, x1, y1, x2, y2, duration=0.0):
@@ -1098,6 +1117,87 @@ class U2PddPurchaseAdapterTest(unittest.TestCase):
)
adapter.close()
def test_apply_resolved_size_restores_hidden_selected_color_before_recheck(self):
clock = FakeClock()
device = VerticallyScrolledColorPanelDevice(
starts_at_top=False,
selected_color="黑色",
)
selected_sizes = []
snapshot = PurchaseSpecCandidateSnapshot.build(
goods_id="753136429979",
selected_color="黑色",
target_size="50公斤",
dimension_name="尺码",
observations=(PurchaseSizeObservation("均码", True),),
observed_at="2026-08-18T04:00:00Z",
)
def select_size(_device, _xml, target, **_kwargs):
selected_sizes.append(target)
device.selected_size = target
return True
adapter = U2PddPurchaseAdapter(
"USB-001",
device_service=PddDeviceService(connector=lambda _serial: device),
sleeper=clock.sleep,
monotonic=clock.monotonic,
select_size_fn=select_size,
size_candidate_collector=lambda _device: SpecDimension(
"size", "尺码", (DimensionValue("均码", True),)
),
)
adapter.open_goods(GOODS_URL)
device.mode = "panel"
adapter.apply_resolved_size(snapshot, snapshot.candidates[0])
self.assertEqual(len(device.swipes), 1)
self.assertLess(device.swipes[0][1], device.swipes[0][3])
self.assertEqual(selected_sizes, ["均码"])
adapter.close()
def test_apply_resolved_size_stops_when_hidden_color_cannot_be_restored(self):
clock = FakeClock()
device = VerticallyScrolledColorPanelDevice(
starts_at_top=False,
restores_on_swipe=False,
selected_color="黑色",
)
selected_sizes = []
candidate_scans = []
snapshot = PurchaseSpecCandidateSnapshot.build(
goods_id="753136429979",
selected_color="黑色",
target_size="50公斤",
dimension_name="尺码",
observations=(PurchaseSizeObservation("均码", True),),
observed_at="2026-08-18T04:00:00Z",
)
adapter = U2PddPurchaseAdapter(
"USB-001",
device_service=PddDeviceService(connector=lambda _serial: device),
sleeper=clock.sleep,
monotonic=clock.monotonic,
select_size_fn=lambda *_args, **_kwargs: selected_sizes.append(True),
size_candidate_collector=lambda _device: candidate_scans.append(True),
)
adapter.open_goods(GOODS_URL)
device.mode = "panel"
with self.assertRaises(PddPurchaseError) as raised:
adapter.apply_resolved_size(snapshot, snapshot.candidates[0])
self.assertEqual(
raised.exception.code,
"PURCHASE_PANEL_COLOR_REGION_NOT_FOUND",
)
self.assertEqual(len(device.swipes), 2)
self.assertEqual(candidate_scans, [])
self.assertEqual(selected_sizes, [])
adapter.close()
def test_apply_resolved_size_distinguishes_page_and_color_context_changes(self):
resolved_size = "均码【80-120斤】"
snapshot = PurchaseSpecCandidateSnapshot.build(