311 lines
12 KiB
Python
311 lines
12 KiB
Python
import json
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from tests.test_pixelrag_rag_candidate_replay_service import _write_receipt
|
|
|
|
|
|
def _patch_receipt(path, **updates):
|
|
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
for key, value in updates.items():
|
|
if key == "page_metrics":
|
|
payload.setdefault("page_metrics", {}).update(value)
|
|
else:
|
|
payload[key] = value
|
|
path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8")
|
|
return payload
|
|
|
|
|
|
def test_pixelrag_platform_probe_worker_dry_run_splits_capture_and_structured(tmp_path):
|
|
from services.pixelrag_platform_probe_worker_service import (
|
|
POLICY,
|
|
run_pixelrag_platform_probe_worker,
|
|
)
|
|
|
|
shopee_receipt = _write_receipt(
|
|
tmp_path,
|
|
platform="shopee_tw",
|
|
manifest_id="shopee-traffic",
|
|
title="蝦皮購物 | 花得更少買得更好",
|
|
url="https://shopee.tw/search?keyword=sunscreen",
|
|
)
|
|
_patch_receipt(
|
|
shopee_receipt,
|
|
page_metrics={
|
|
"final_url": "https://shopee.tw/verify/traffic/error?home_url=https%3A%2F%2Fshopee.tw",
|
|
"title": "蝦皮購物 | 花得更少買得更好",
|
|
},
|
|
)
|
|
_write_receipt(
|
|
tmp_path,
|
|
platform="coupang_tw",
|
|
manifest_id="coupang-403",
|
|
title="Access Denied",
|
|
url="https://www.tw.coupang.com/search?q=iphone",
|
|
http_status=403,
|
|
)
|
|
|
|
payload = run_pixelrag_platform_probe_worker(
|
|
artifact_root=tmp_path,
|
|
platform=("shopee_tw", "coupang_tw"),
|
|
)
|
|
by_platform = {item["platform"]: item for item in payload["worker_items"]}
|
|
|
|
assert payload["policy"] == POLICY
|
|
assert payload["status"] == "ok"
|
|
assert payload["execute"] is False
|
|
assert payload["summary"]["probe_candidate_count"] == 2
|
|
assert payload["summary"]["ready_count"] == 2
|
|
assert payload["summary"]["dry_run_count"] == 2
|
|
assert payload["summary"]["capture_ready_count"] == 1
|
|
assert payload["summary"]["structured_fallback_count"] == 1
|
|
assert payload["summary"]["network_call_performed"] is False
|
|
assert payload["summary"]["writes_database_count"] == 0
|
|
assert payload["controlled_apply"]["primary_human_gate_count"] == 0
|
|
assert payload["next_machine_action"] == "run_pixelrag_platform_probe_worker_execute"
|
|
assert by_platform["shopee_tw"]["worker_status"] == "dry_run_ready_for_public_context_capture"
|
|
assert by_platform["shopee_tw"]["public_browser_context_policy"] == (
|
|
"public_empty_browser_context_no_login"
|
|
)
|
|
assert by_platform["coupang_tw"]["worker_status"] == (
|
|
"dry_run_structured_source_fallback_ready"
|
|
)
|
|
assert by_platform["coupang_tw"]["structured_source_fallback_available"] is True
|
|
|
|
|
|
def test_pixelrag_platform_probe_worker_execute_capture_writes_receipt(tmp_path, monkeypatch):
|
|
from services import pixelrag_platform_probe_worker_service as service
|
|
|
|
shopee_receipt = _write_receipt(
|
|
tmp_path,
|
|
platform="shopee_tw",
|
|
manifest_id="shopee-traffic",
|
|
title="蝦皮購物 | 花得更少買得更好",
|
|
url="https://shopee.tw/search?keyword=sunscreen",
|
|
)
|
|
_patch_receipt(
|
|
shopee_receipt,
|
|
page_metrics={
|
|
"final_url": "https://shopee.tw/verify/traffic/error?home_url=https%3A%2F%2Fshopee.tw",
|
|
"title": "蝦皮購物 | 花得更少買得更好",
|
|
},
|
|
)
|
|
|
|
def fake_capture_subprocess(**kwargs):
|
|
manifest = kwargs["manifest"]
|
|
capture_root = Path(kwargs["capture_output_root"])
|
|
receipt_path = capture_root / "shopee_tw" / manifest["manifest_id"] / "capture_receipt.json"
|
|
return {
|
|
"returncode": 0,
|
|
"stdout_json": {
|
|
"success": True,
|
|
"status": "captured",
|
|
"http_status": 200,
|
|
"planned_output": {"receipt": str(receipt_path)},
|
|
"files": [
|
|
{"kind": "fullpage_screenshot", "path": str(receipt_path.parent / "fullpage.png")},
|
|
{"kind": "tile", "path": str(receipt_path.parent / "tiles" / "tile_000.png")},
|
|
{"kind": "receipt", "path": str(receipt_path)},
|
|
],
|
|
},
|
|
"stdout_excerpt": "",
|
|
"stderr_excerpt": "",
|
|
}
|
|
|
|
monkeypatch.setattr(service, "_run_capture_subprocess", fake_capture_subprocess)
|
|
payload = service.run_pixelrag_platform_probe_worker(
|
|
artifact_root=tmp_path,
|
|
output_root=tmp_path / "worker_receipts",
|
|
capture_output_root=tmp_path / "capture_output",
|
|
platform="shopee_tw",
|
|
execute=True,
|
|
write_receipt=True,
|
|
)
|
|
|
|
assert payload["status"] == "ok"
|
|
assert payload["summary"]["capture_execute_count"] == 1
|
|
assert payload["summary"]["capture_ok_count"] == 1
|
|
assert payload["summary"]["receipt_written_count"] == 1
|
|
assert payload["summary"]["network_call_performed"] is True
|
|
assert payload["controlled_apply"]["network_call"] is True
|
|
assert payload["controlled_apply"]["writes_database"] is False
|
|
item = payload["worker_items"][0]
|
|
assert item["worker_status"] == "executed_capture_ok"
|
|
assert item["next_machine_action"] == "run_pixelrag_rag_candidate_replay_after_probe_capture"
|
|
receipt_path = (
|
|
tmp_path
|
|
/ "worker_receipts"
|
|
/ "shopee_tw"
|
|
/ "shopee-traffic"
|
|
/ "platform_probe_worker_receipt.json"
|
|
)
|
|
assert receipt_path.exists()
|
|
receipt = json.loads(receipt_path.read_text(encoding="utf-8"))
|
|
assert receipt["worker_status"] == "executed_capture_ok"
|
|
assert receipt["artifact_write_performed"] is True
|
|
assert receipt["receipt_path"] == str(receipt_path)
|
|
|
|
|
|
def test_pixelrag_platform_probe_worker_missing_playwright_falls_back_to_structured_receipt(
|
|
tmp_path,
|
|
monkeypatch,
|
|
):
|
|
from services import pixelrag_platform_probe_worker_service as service
|
|
|
|
shopee_receipt = _write_receipt(
|
|
tmp_path,
|
|
platform="shopee_tw",
|
|
manifest_id="shopee-traffic",
|
|
title="蝦皮購物 | 花得更少買得更好",
|
|
url="https://shopee.tw/search?keyword=sunscreen",
|
|
)
|
|
_patch_receipt(
|
|
shopee_receipt,
|
|
page_metrics={
|
|
"final_url": "https://shopee.tw/verify/traffic/error?home_url=https%3A%2F%2Fshopee.tw",
|
|
"title": "蝦皮購物 | 花得更少買得更好",
|
|
},
|
|
)
|
|
|
|
monkeypatch.setattr(
|
|
service,
|
|
"_run_capture_subprocess",
|
|
lambda **kwargs: {
|
|
"returncode": 1,
|
|
"stdout_json": {},
|
|
"stdout_excerpt": "",
|
|
"stderr_excerpt": "ModuleNotFoundError: No module named 'playwright'",
|
|
},
|
|
)
|
|
payload = service.run_pixelrag_platform_probe_worker(
|
|
artifact_root=tmp_path,
|
|
output_root=tmp_path / "worker_receipts",
|
|
platform="shopee_tw",
|
|
execute=True,
|
|
write_receipt=True,
|
|
)
|
|
|
|
assert payload["status"] == "ok"
|
|
assert payload["summary"]["capture_error_count"] == 0
|
|
assert payload["summary"]["structured_fallback_count"] == 1
|
|
assert payload["summary"]["executed_structured_count"] == 1
|
|
assert payload["summary"]["network_call_performed"] is False
|
|
assert payload["summary"]["receipt_written_count"] == 1
|
|
item = payload["worker_items"][0]
|
|
assert item["worker_status"] == "capture_runtime_unavailable_structured_fallback_package"
|
|
assert item["structured_source_package"]["capture_runtime_unavailable"] is True
|
|
assert item["next_machine_action"] == "run_structured_source_or_install_pixelrag_capture_runtime"
|
|
receipt_path = (
|
|
tmp_path
|
|
/ "worker_receipts"
|
|
/ "shopee_tw"
|
|
/ "shopee-traffic"
|
|
/ "platform_probe_worker_receipt.json"
|
|
)
|
|
receipt = json.loads(receipt_path.read_text(encoding="utf-8"))
|
|
assert receipt["worker_status"] == "capture_runtime_unavailable_structured_fallback_package"
|
|
assert receipt["artifact_write_performed"] is True
|
|
assert receipt["network_call_performed"] is False
|
|
|
|
|
|
def test_pixelrag_platform_probe_worker_execute_structured_fallback_writes_receipt(tmp_path):
|
|
from services.pixelrag_platform_probe_worker_service import run_pixelrag_platform_probe_worker
|
|
|
|
_write_receipt(
|
|
tmp_path,
|
|
platform="coupang_tw",
|
|
manifest_id="coupang-403",
|
|
title="Access Denied",
|
|
url="https://www.tw.coupang.com/search?q=iphone",
|
|
http_status=403,
|
|
)
|
|
|
|
payload = run_pixelrag_platform_probe_worker(
|
|
artifact_root=tmp_path,
|
|
output_root=tmp_path / "worker_receipts",
|
|
platform="coupang_tw",
|
|
execute=True,
|
|
write_receipt=True,
|
|
)
|
|
|
|
assert payload["status"] == "ok"
|
|
assert payload["summary"]["executed_structured_count"] == 1
|
|
assert payload["summary"]["capture_execute_count"] == 0
|
|
assert payload["summary"]["network_call_performed"] is False
|
|
assert payload["summary"]["receipt_written_count"] == 1
|
|
item = payload["worker_items"][0]
|
|
assert item["worker_status"] == "executed_structured_source_fallback_package"
|
|
assert item["structured_source_package"]["adapter_code"] == "coupang"
|
|
assert item["structured_source_package"]["database_write_allowed"] is False
|
|
receipt_path = (
|
|
tmp_path
|
|
/ "worker_receipts"
|
|
/ "coupang_tw"
|
|
/ "coupang-403"
|
|
/ "platform_probe_worker_receipt.json"
|
|
)
|
|
receipt = json.loads(receipt_path.read_text(encoding="utf-8"))
|
|
assert receipt["worker_status"] == "executed_structured_source_fallback_package"
|
|
assert receipt["artifact_write_performed"] is True
|
|
|
|
|
|
def test_pixelrag_platform_probe_worker_cli_outputs_machine_readable_json(tmp_path):
|
|
_write_receipt(
|
|
tmp_path,
|
|
platform="coupang_tw",
|
|
manifest_id="coupang-403",
|
|
title="Access Denied",
|
|
url="https://www.tw.coupang.com/search?q=iphone",
|
|
http_status=403,
|
|
)
|
|
|
|
completed = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"scripts/ops/run_pixelrag_platform_probe_worker.py",
|
|
"--artifact-root",
|
|
str(tmp_path),
|
|
"--platform",
|
|
"coupang_tw",
|
|
],
|
|
capture_output=True,
|
|
check=False,
|
|
text=True,
|
|
)
|
|
|
|
assert completed.returncode == 0
|
|
payload = json.loads(completed.stdout)
|
|
assert payload["summary"]["probe_candidate_count"] == 1
|
|
assert payload["summary"]["structured_fallback_count"] == 1
|
|
assert payload["controlled_apply"]["network_call"] is False
|
|
assert payload["controlled_apply"]["writes_database"] is False
|
|
|
|
|
|
def test_pixelrag_platform_probe_worker_route_returns_readback(tmp_path, monkeypatch):
|
|
from flask import Flask
|
|
from routes import system_public_routes as routes
|
|
from services import pixelrag_platform_probe_worker_service as service
|
|
|
|
_write_receipt(
|
|
tmp_path,
|
|
platform="coupang_tw",
|
|
manifest_id="coupang-403",
|
|
title="Access Denied",
|
|
url="https://www.tw.coupang.com/search?q=iphone",
|
|
http_status=403,
|
|
)
|
|
monkeypatch.setattr(service, "DEFAULT_ARTIFACT_ROOT", str(tmp_path))
|
|
|
|
app = Flask(__name__)
|
|
with app.test_request_context(
|
|
"/api/ai-automation/pixelrag-platform-probe-worker?platform=coupang_tw"
|
|
):
|
|
response = routes.ai_automation_pixelrag_platform_probe_worker_api.__wrapped__()
|
|
payload = response.get_json()
|
|
|
|
assert payload["policy"] == "controlled_pixelrag_platform_probe_worker_v1"
|
|
assert payload["summary"]["probe_candidate_count"] == 1
|
|
assert payload["summary"]["structured_fallback_count"] == 1
|
|
assert payload["controlled_apply"]["writes_database"] is False
|