fix(client): bind T-103 XML coordinates

This commit is contained in:
QiuSW
2026-08-04 14:04:49 +08:00
parent 946b064470
commit acf7e11114
2 changed files with 27 additions and 27 deletions
@@ -21,7 +21,7 @@ from ..pdd.product_url import ProductUrl, ProductUrlError, parse_product_url
from ..pdd.sku_panel_state import HUMAN_DECLARED_STATES
SANITIZER_VERSION = "t103-privacy-v2"
SANITIZER_VERSION = "t103-privacy-v3"
EXPECTED_GOODS_ID = "937122477375"
EXPECTED_PDD_VERSION = "8.17.0"
EXPECTED_DEVICE_MODEL = "PKG110"
@@ -29,7 +29,7 @@ EXPECTED_ANDROID_VERSION = "16"
EXPECTED_SCREENSHOT_WIDTH = 1080
EXPECTED_SCREENSHOT_HEIGHT = 2376
EXPECTED_XML_WIDTH = 1080
EXPECTED_XML_HEIGHT = 2400
EXPECTED_XML_HEIGHT = 2376
_ARTIFACT_FILES = ("screenshot.png", "hierarchy.xml")
_SHA256_RE = re.compile(r"[0-9a-f]{64}\Z")
_BOUNDS_RE = re.compile(r"\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]\Z")
@@ -48,7 +48,7 @@ def _default_xml() -> str:
return (
"<hierarchy rotation='0'>"
f"<node bounds='[0,0][1080,540]' text='{TEST_ADDRESS}' content-desc='{MASKED_PHONE} {FULL_PHONE}' />"
f"<node bounds='[0,540][1080,2400]' text='{SAFE_TEXT}' />"
f"<node bounds='[0,540][1080,2376]' text='{SAFE_TEXT}' />"
"</hierarchy>"
)
@@ -117,17 +117,17 @@ 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-v2"', manifest)
self.assertIn('"sanitizer_version": "t103-privacy-v3"', manifest)
self.assertIn('"screenshot_space": {', manifest)
self.assertIn('"xml_coordinate_space": {', manifest)
self.assertIn('"height": 2376', manifest)
self.assertIn('"height": 2400', manifest)
self.assertIn('"height": 2376', manifest)
self.assertIn('"privacy_mask_rectangle": [', manifest)
self.assertIn('"removed_nodes": 1', manifest)
self.assertIn('"cleared_crossing_nodes": 0', manifest)
self.assertIn('"retained_below_nodes": 1', manifest)
self.assertIn('"max_right": 1080', manifest)
self.assertIn('"max_bottom": 2400', manifest)
self.assertIn('"max_bottom": 2376', manifest)
self.assertNotIn("canonical_url", manifest)
self.assertNotIn(TEST_SERIAL, manifest)
self.assertNotIn("serial", manifest)
@@ -138,9 +138,9 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_crossing_container_keeps_lower_children_but_clears_its_text(self) -> None:
xml = (
"<hierarchy>"
f"<node bounds='[0,0][1080,2400]' text='{TEST_ADDRESS}' content-desc='{MASKED_PHONE}'>"
f"<node bounds='[0,0][1080,2376]' text='{TEST_ADDRESS}' content-desc='{MASKED_PHONE}'>"
f"<node bounds='[0,0][1080,540]' text='{FULL_PHONE}' />"
f"<node bounds='[0,540][1080,2400]' text='{SAFE_TEXT}' />"
f"<node bounds='[0,540][1080,2376]' text='{SAFE_TEXT}' />"
"</node></hierarchy>"
)
with TemporaryDirectory() as temporary:
@@ -151,7 +151,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
self.assertIsNotNone(crossing)
assert crossing is not None
self.assertEqual(crossing.attrib, {"bounds": "[0,0][1080,2400]"})
self.assertEqual(crossing.attrib, {"bounds": "[0,0][1080,2376]"})
self.assertEqual(len(list(crossing)), 1)
self.assertEqual(list(crossing)[0].get("text"), SAFE_TEXT)
manifest = json.loads(result.manifest_path.read_text(encoding="utf-8"))
@@ -162,7 +162,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
"cleared_crossing_nodes": 1,
"retained_below_nodes": 1,
"max_right": 1080,
"max_bottom": 2400,
"max_bottom": 2376,
},
)
@@ -195,9 +195,9 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
manifest["xml_coordinate_space"],
{
"width": 1080,
"height": 2400,
"height": 2376,
"privacy_mask_rectangle": [0, 0, 1080, 540],
"observed_max": {"right": 1080, "bottom": 2400},
"observed_max": {"right": 1080, "bottom": 2376},
},
)
@@ -243,10 +243,10 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
("bounds", "<hierarchy><node text='missing bounds' /></hierarchy>"),
(
"private-parent-with-lower-child",
"<hierarchy><node bounds='[0,0][1080,540]'><node bounds='[0,540][1080,2400]' text='x' /></node></hierarchy>",
"<hierarchy><node bounds='[0,0][1080,540]'><node bounds='[0,540][1080,2376]' text='x' /></node></hierarchy>",
),
("full-phone-below", f"<hierarchy><node bounds='[0,540][1080,2400]' text='{FULL_PHONE}' /></hierarchy>"),
("masked-phone-below", f"<hierarchy><node bounds='[0,540][1080,2400]' text='{MASKED_PHONE}' /></hierarchy>"),
("full-phone-below", f"<hierarchy><node bounds='[0,540][1080,2376]' text='{FULL_PHONE}' /></hierarchy>"),
("masked-phone-below", f"<hierarchy><node bounds='[0,540][1080,2376]' text='{MASKED_PHONE}' /></hierarchy>"),
)
for kind, xml in malformed:
with self.subTest(kind=kind), TemporaryDirectory() as temporary:
@@ -281,7 +281,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
xml = (
"<hierarchy>"
"<node bounds='[0,0][1080,540]' text='private' />"
f"<node bounds='[0,540][1080,2400]' text='{value}' />"
f"<node bounds='[0,540][1080,2376]' text='{value}' />"
"</hierarchy>"
)
with self.subTest(value=value), TemporaryDirectory() as temporary:
@@ -294,7 +294,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
"<hierarchy>"
"<node bounds='[0,0][1080,540]' text='private' />"
"<node bounds='[0,540][1080,1000]' text='138' content-desc='0013' />"
"<node bounds='[0,1000][1080,2400]' text='8000' />"
"<node bounds='[0,1000][1080,2376]' text='8000' />"
"</hierarchy>"
)
with TemporaryDirectory() as temporary:
@@ -305,7 +305,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_privacy_geometry_requires_removed_and_retained_nodes(self) -> None:
scenarios = (
("no-private", f"<hierarchy><node bounds='[0,540][1080,2400]' text='{SAFE_TEXT}' /></hierarchy>"),
("no-private", f"<hierarchy><node bounds='[0,540][1080,2376]' text='{SAFE_TEXT}' /></hierarchy>"),
("no-below", "<hierarchy><node bounds='[0,0][1080,540]' text='private' /></hierarchy>"),
)
for name, xml in scenarios:
@@ -321,26 +321,26 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
(
"short-width",
"<hierarchy><node bounds='[0,0][1079,540]' text='private' />"
"<node bounds='[0,540][1079,2400]' text='safe' /></hierarchy>",
"1079x2400",
"<node bounds='[0,540][1079,2376]' text='safe' /></hierarchy>",
"1079x2376",
),
(
"short-height",
"<hierarchy><node bounds='[0,0][1080,540]' text='private' />"
"<node bounds='[0,540][1080,2376]' text='safe' /></hierarchy>",
"1080x2376",
"<node bounds='[0,540][1080,2375]' text='safe' /></hierarchy>",
"1080x2375",
),
(
"wide-width",
"<hierarchy><node bounds='[0,0][1081,540]' text='private' />"
"<node bounds='[0,540][1081,2400]' text='safe' /></hierarchy>",
"1081x2400",
"<node bounds='[0,540][1081,2376]' text='safe' /></hierarchy>",
"1081x2376",
),
(
"tall-height",
"old-v2-xml-height",
"<hierarchy><node bounds='[0,0][1080,540]' text='private' />"
"<node bounds='[0,540][1080,2401]' text='safe' /></hierarchy>",
"1080x2401",
"<node bounds='[0,540][1080,2400]' text='safe' /></hierarchy>",
"1080x2400",
),
)
for name, xml, observed in scenarios: