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