"""对齐 Muse P10 结账检测测试:detect_checkout 纯函数。 只用标准库,不启动浏览器、不联网。覆盖: - URL 信号(结账路径 / 购物车 / 普通页 / 坏 URL); - 无障碍树信号(支付字段 / 密码字段 / 下单按钮 / 金额文本); - 中英文特征;节点为空;页面金额只作展示信号。 """ import importlib.util import os import sys import tempfile import unittest from pathlib import Path try: from cloud.chv.checkout_detect import detect_checkout except ImportError: sys.path.insert(0, str(Path(__file__).resolve().parents[2])) from cloud.chv.checkout_detect import detect_checkout def _node(role: str, name: str) -> dict: return {"role": role, "name": name} class CheckoutUrlTest(unittest.TestCase): def test_checkout_path_is_checkout_high(self) -> None: verdict = detect_checkout("https://shop.example.com/checkout") self.assertTrue(verdict.is_checkout) self.assertEqual(verdict.confidence, "medium") self.assertIn("checkout_url", verdict.reasons) def test_payment_path_is_checkout(self) -> None: verdict = detect_checkout( "https://shop.example.com/order/payment?step=2") self.assertTrue(verdict.is_checkout) self.assertIn("checkout_url", verdict.reasons) def test_cart_path_is_not_checkout(self) -> None: verdict = detect_checkout("https://shop.example.com/cart") self.assertFalse(verdict.is_checkout) self.assertEqual(verdict.confidence, "low") self.assertIn("cart_url", verdict.reasons) def test_plain_page_is_not_checkout(self) -> None: verdict = detect_checkout("https://shop.example.com/products/1") self.assertFalse(verdict.is_checkout) self.assertEqual(verdict.confidence, "low") self.assertEqual(verdict.reasons, []) def test_bad_url_does_not_crash(self) -> None: verdict = detect_checkout("::::not a url::::") self.assertFalse(verdict.is_checkout) def test_no_nodes_url_only_decision(self) -> None: verdict = detect_checkout( "https://shop.example.com/checkout", None) self.assertTrue(verdict.is_checkout) class CheckoutNodesTest(unittest.TestCase): def test_payment_fields_make_checkout_high(self) -> None: nodes = [_node("textbox", "Card number"), _node("textbox", "Expiry date"), _node("textbox", "Security code (CVC)")] verdict = detect_checkout("https://shop.example.com/buy", nodes) self.assertTrue(verdict.is_checkout) self.assertEqual(verdict.confidence, "high") self.assertEqual(verdict.form_risk, "payment") self.assertIn("payment_fields", verdict.reasons) def test_password_field_marks_form_risk(self) -> None: nodes = [_node("textbox", "Password")] verdict = detect_checkout("https://shop.example.com/login", nodes) self.assertFalse(verdict.is_checkout) self.assertEqual(verdict.form_risk, "password") def test_order_button_plus_amount_is_checkout(self) -> None: nodes = [_node("button", "Place order"), _node("text", "Total: $50.00")] verdict = detect_checkout("https://shop.example.com/review", nodes) self.assertTrue(verdict.is_checkout) self.assertEqual(verdict.confidence, "medium") self.assertEqual(verdict.amount_text, "$50.00") def test_order_button_alone_is_not_checkout(self) -> None: nodes = [_node("button", "Place order")] verdict = detect_checkout("https://shop.example.com/review", nodes) self.assertFalse(verdict.is_checkout) def test_amount_only_is_not_checkout(self) -> None: nodes = [_node("text", "Total: $50.00")] verdict = detect_checkout("https://shop.example.com/review", nodes) self.assertFalse(verdict.is_checkout) self.assertEqual(verdict.amount_text, "$50.00") def test_chinese_payment_hints(self) -> None: nodes = [_node("textbox", "卡号"), _node("button", "立即支付")] verdict = detect_checkout("https://shop.example.com/buy", nodes) self.assertTrue(verdict.is_checkout) self.assertEqual(verdict.form_risk, "payment") def test_checkout_url_plus_payment_fields_high(self) -> None: nodes = [_node("textbox", "Card number"), _node("button", "Pay now")] verdict = detect_checkout("https://shop.example.com/checkout", nodes) self.assertTrue(verdict.is_checkout) self.assertEqual(verdict.confidence, "high") self.assertIn("checkout_url", verdict.reasons) self.assertIn("payment_fields", verdict.reasons) def test_yen_and_currency_code_amounts(self) -> None: nodes = [_node("text", "合計:¥1,200"), _node("text", "Total 25.00 USD")] verdict = detect_checkout("https://shop.example.com/review", nodes) self.assertEqual(verdict.amount_text, "¥1,200") def test_empty_nodes_plain_page(self) -> None: verdict = detect_checkout("https://shop.example.com/", []) self.assertFalse(verdict.is_checkout) self.assertIsNone(verdict.form_risk) self.assertIsNone(verdict.amount_text) class BuildInfoContentsTest(unittest.TestCase): """round-12 修复轮(项 4,P10):checkout_detect 是条件拷入 件——存在时经 extra_contents 登记进 BUILDINFO contents (不在 BASE_CONTENTS 里,缺失的构建绝不谎称已进镜像, 与 P3 叶子模块同款口径)。""" def test_extra_contents_include_checkout_detect(self): root = Path(__file__).resolve().parents[2] path = root / "chv-guest" / "buildinfo.py" spec = importlib.util.spec_from_file_location( "chv_guest_p10_buildinfo", str(path)) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) self.assertNotIn("checkout_detect", module.BASE_CONTENTS) with tempfile.TemporaryDirectory() as tmp: out = os.path.join(tmp, "out") os.makedirs(out) for name, content in (("disk.raw", b"D"), ("vmlinux", b"K")): with open(os.path.join(out, name), "wb") as fh: fh.write(content) for name, lines in ( ("guest-versions-dpkg.txt", ["git 9.9.9-9ubuntu9"]), ("guest-versions-pip.txt", ["playwright==9.9.9"]), ("guest-versions-gt.txt", ["gt version 1.0.0"]), ("guest-versions-chromium.txt", ["chromium_headless_shell-1248"])): with open(os.path.join(out, name), "w") as fh: fh.write("\n".join(lines) + "\n") info = module.build( out, "chv-guest-24.04-0.164.0-alpha.9-abc1234", "24.04", "0.164.0-alpha.9", "abc1234", "0" * 64, True, "1248", ["cloud/chv/checkout_detect.py"]) self.assertIn("cloud/chv/checkout_detect.py", info["contents"]) if __name__ == "__main__": unittest.main()