88 lines
3.6 KiB
Python
88 lines
3.6 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from server.aps_domain.drawing_dxf import (
|
|
build_drawing_master_candidates,
|
|
inspect_dxf,
|
|
render_dxf_preview,
|
|
)
|
|
|
|
SAMPLE = Path(r"D:\ItemSpace\14.工业智核\锐扬\5060102101-001-e(1).dxf")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def parsed_sample():
|
|
if not SAMPLE.exists():
|
|
pytest.skip(f"real DXF fixture not available: {SAMPLE}")
|
|
return inspect_dxf(SAMPLE)
|
|
|
|
|
|
def test_real_dxf_inspection_contract(parsed_sample):
|
|
parsed = parsed_sample
|
|
assert parsed["contractVersion"] == "drawing-dxf.v1"
|
|
assert parsed["asset"]["sha256"] == "b9a5f5cdd62b2a4060a7ce03dfe4fc2d08ba0fcd017f4d1bec049363f4472d79"
|
|
assert parsed["asset"]["id"] == "drawing_510289c4effd56ce1265"
|
|
assert parsed["asset"]["idempotencyKey"] == f"drawing:{parsed['asset']['sha256']}"
|
|
assert parsed["drawing"]["drawingNumber"] == "5060102101-001"
|
|
assert parsed["drawing"]["revision"] == "e"
|
|
assert parsed["drawing"]["metadata"]["acadVersion"] == "AC1015"
|
|
assert parsed["drawing"]["modelspaceEntityCount"] == 9619
|
|
assert parsed["entityStatistics"]["ARC"] == 6288
|
|
assert parsed["entityStatistics"]["DIMENSION"] == 105
|
|
assert len(parsed["texts"]) == 102
|
|
assert len(parsed["dimensions"]) == 105
|
|
assert len(parsed["layers"]) == 41
|
|
assert parsed["drawing"]["bbox"]["width"] > 6000
|
|
assert all("confidence" in row and "evidence" in row for row in parsed["fieldCandidates"])
|
|
|
|
|
|
def test_real_dxf_ids_are_idempotent(parsed_sample):
|
|
again = inspect_dxf(SAMPLE)
|
|
assert again["asset"]["id"] == parsed_sample["asset"]["id"]
|
|
assert again["asset"]["sha256"] == parsed_sample["asset"]["sha256"]
|
|
assert [row["id"] for row in again["texts"]] == [row["id"] for row in parsed_sample["texts"]]
|
|
assert [row["id"] for row in again["dimensions"]] == [row["id"] for row in parsed_sample["dimensions"]]
|
|
|
|
|
|
def test_master_candidates_are_review_gated_and_do_not_invent_values(parsed_sample):
|
|
candidates = build_drawing_master_candidates(parsed_sample)
|
|
assert candidates["status"] == "PENDING_REVIEW"
|
|
assert candidates["reviewRequired"] is True
|
|
assert candidates["materials"][0]["code"] == "5060102101-001"
|
|
assert candidates["materials"][0]["reviewRequired"] is True
|
|
assert candidates["bomReferences"]
|
|
assert all(row["quantity"] is None for row in candidates["bomReferences"])
|
|
assert all(row["unit"] is None for row in candidates["bomReferences"])
|
|
assert all(row["componentMaterialCode"] is None for row in candidates["bomReferences"])
|
|
assert candidates["routingOperations"]
|
|
assert all(row["standardTime"] is None for row in candidates["routingOperations"])
|
|
assert all(row["resourceCode"] is None for row in candidates["routingOperations"])
|
|
|
|
|
|
def test_svg_preview_is_bounded_and_contains_no_active_or_external_content():
|
|
if not SAMPLE.exists():
|
|
pytest.skip(f"real DXF fixture not available: {SAMPLE}")
|
|
svg = render_dxf_preview(SAMPLE)
|
|
lowered = svg.lower()
|
|
assert svg.startswith('<svg xmlns="http://www.w3.org/2000/svg"')
|
|
assert len(svg.encode("utf-8")) < 5 * 1024 * 1024
|
|
assert "<script" not in lowered
|
|
assert "foreignobject" not in lowered
|
|
assert "href=" not in lowered
|
|
assert "http://" not in lowered.replace('xmlns="http://www.w3.org/2000/svg"', "")
|
|
assert parsed_sha(SAMPLE) in svg
|
|
|
|
|
|
def test_rejects_non_dxf(tmp_path):
|
|
path = tmp_path / "drawing.txt"
|
|
path.write_text("not a drawing", encoding="utf-8")
|
|
with pytest.raises(ValueError, match="Only an existing .dxf"):
|
|
inspect_dxf(path)
|
|
|
|
|
|
def parsed_sha(path: Path) -> str:
|
|
return inspect_dxf(path)["asset"]["sha256"]
|