fix(client): bind T-103 observed price prefix

This commit is contained in:
QiuSW
2026-08-04 15:23:02 +08:00
parent 6e001b2729
commit 76a522f13f
2 changed files with 42 additions and 27 deletions
@@ -34,7 +34,7 @@ TEST_ADDRESS = "SYNTHETIC_ADDRESS_NEVER_PUBLISH"
FULL_PHONE = "13800138000"
MASKED_PHONE = "138****0000"
SAFE_TEXT = "synthetic-safe-lower-content"
CURRENT_PRICE = "快卖光 ¥12.88"
CURRENT_PRICE = "快卖完 ¥12.88"
ORIGINAL_PRICE = "¥29.00"
PRICE_CURRENT_BOUNDS = "[396,503][712,570]"
PRICE_ORIGINAL_BOUNDS = "[730,503][895,570]"
@@ -166,7 +166,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
self.assertNotIn(MASKED_PHONE, derived_xml)
self.assertIn(f'"human_declared_state": "{state}"', manifest)
self.assertIn('"privacy_tier": "SANITIZED"', manifest)
self.assertIn('"sanitizer_version": "t103-privacy-v4"', manifest)
self.assertIn('"sanitizer_version": "t103-privacy-v5"', manifest)
self.assertIn('"screenshot_space": {', manifest)
self.assertIn('"xml_coordinate_space": {', manifest)
self.assertIn('"height": 2376', manifest)
@@ -256,16 +256,16 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_crossing_price_window_rejects_text_and_structure_drift(self) -> None:
bad_texts = (
f"快卖光 ¥12.88 {TEST_ADDRESS}",
f"快卖光 ¥12.88 {FULL_PHONE}",
"快卖光 ¥12.88 使用微信支付",
"快卖光 ¥12.88 提交订单",
"快卖光 ¥12.88 优惠-11元",
f"快卖完 ¥12.88 {TEST_ADDRESS}",
f"快卖完 ¥12.88 {FULL_PHONE}",
"快卖完 ¥12.88 使用微信支付",
"快卖完 ¥12.88 提交订单",
"快卖完 ¥12.88 优惠-11元",
"快要抢光 ¥12.88",
"快卖光 ¥0.00",
"快卖光 ¥12.8",
"快卖光 ¥12.880",
"快卖光 ¥12.88",
"快卖完 ¥0.00",
"快卖完 ¥12.8",
"快卖完 ¥12.880",
"快卖完 ¥12.88",
)
for text in bad_texts:
with self.subTest(text=text), TemporaryDirectory() as temporary:
@@ -276,13 +276,13 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_crossing_price_text_mismatch_reports_only_fixed_slot_and_reason(self) -> None:
newline_node = _price_node(CURRENT_PRICE, PRICE_CURRENT_BOUNDS).replace(
"快卖光 ¥12.88", "快卖光
¥12.88"
"快卖完 ¥12.88", "快卖完
¥12.88"
)
cases = (
("newline", _xml_with_prices(current_node=newline_node), "newline", PRICE_CURRENT_BOUNDS),
(
"non-ascii-whitespace",
_xml_with_prices(current="快卖光 ¥12.88"),
_xml_with_prices(current="快卖完 ¥12.88"),
"non_ascii_whitespace",
PRICE_CURRENT_BOUNDS,
),
@@ -300,13 +300,13 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
),
(
"currency-missing",
_xml_with_prices(current="快卖光 12.88"),
_xml_with_prices(current="快卖完 12.88"),
"currency_missing",
PRICE_CURRENT_BOUNDS,
),
(
"amount-shape",
_xml_with_prices(current="快卖光 ¥12.8"),
_xml_with_prices(current="快卖完 ¥12.8"),
"amount_shape",
PRICE_CURRENT_BOUNDS,
),
@@ -343,10 +343,10 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_crossing_price_text_mismatch_never_echoes_sensitive_or_order_text(self) -> None:
cases = (
f"快卖光 ¥12.88 {TEST_ADDRESS}",
f"快卖光 ¥12.88 {FULL_PHONE}",
"快卖光 ¥12.88 使用微信支付",
"快卖光 ¥12.88 提交订单",
f"快卖完 ¥12.88 {TEST_ADDRESS}",
f"快卖完 ¥12.88 {FULL_PHONE}",
"快卖完 ¥12.88 使用微信支付",
"快卖完 ¥12.88 提交订单",
)
for text in cases:
with self.subTest(text=text), TemporaryDirectory() as temporary:
@@ -378,13 +378,26 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
self.assertNotIn("¥12.88", message)
def test_crossing_price_projection_allows_only_limited_ascii_spaces_and_yen_variants(self) -> None:
for current in ("快卖光 ¥12.88", " 快卖光 ¥ 12.88 ", "快卖光 ¥12.88"):
for current in ("快卖完 ¥12.88", " 快卖完 ¥ 12.88 ", "快卖完 ¥12.88"):
with self.subTest(current=current), TemporaryDirectory() as temporary:
raw = _write_raw(Path(temporary), xml=_xml_with_prices(current=current))
result = sanitize_sku_panel_evidence(raw, raw.parent / "derived")
hierarchy = result.hierarchy_path.read_text(encoding="utf-8")
self.assertIn(current, hierarchy)
def test_unverified_or_missing_current_price_prefixes_fail_closed(self) -> None:
cases = (
("old-prefix", "快卖光 ¥12.88"),
("bottom-button-prefix", "快要抢光 ¥12.88"),
("missing-prefix", "¥12.88"),
)
for name, current in cases:
with self.subTest(name=name), TemporaryDirectory() as temporary:
raw = _write_raw(Path(temporary), xml=_xml_with_prices(current=current))
with self.assertRaises(SkuEvidenceSanitizationError):
sanitize_sku_panel_evidence(raw, raw.parent / "derived")
self.assertFalse((raw.parent / "derived").exists())
def test_unique_current_price_without_original_price_is_published(self) -> None:
with TemporaryDirectory() as temporary:
raw = _write_raw(Path(temporary), xml=_xml_with_prices(include_original=False))
@@ -398,7 +411,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_crossing_price_projection_rejects_newline_and_structure_drift(self) -> None:
encoded_newline = _price_node(CURRENT_PRICE, PRICE_CURRENT_BOUNDS).replace(
"快卖光 ¥12.88", "快卖光
¥12.88"
"快卖完 ¥12.88", "快卖完
¥12.88"
)
with TemporaryDirectory() as temporary:
raw = _write_raw(Path(temporary), xml=_xml_with_prices(current_node=encoded_newline))
@@ -432,7 +445,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
),
(
"duplicate-current",
_xml_with_prices(current=CURRENT_PRICE, original=f"快卖光 {ORIGINAL_PRICE}"),
_xml_with_prices(current=CURRENT_PRICE, original=f"快卖完 {ORIGINAL_PRICE}"),
),
(
"multiple-original",