"""Tests for XFA (dynamic Adobe LiveCycle form) support. Pins behavior against the synthetic XFA fixture contributed via the agent-thread at ``docs/agent-threads/xfa-form-support/`` (specifically the expected-output table in ``005-iar-attaches-fixture.md``). Each assertion here corresponds to a row in that table. The fixture is hand-built, license-clean, and small (~2 KB). Its README at ``tests/fixtures/xfa/README.md`` documents what each field exercises. """ from __future__ import annotations import asyncio from pathlib import Path import pytest from mcp_pdf.xfa import ( canonicalize, classify_fields, extract_xfa_parts, extract_xfa_schema, fields_from_pdf, is_xfa_pdf, parse_fields, _ZIPFORM_PROFILE, _GENERIC_PROFILE, ) FIXTURE_DIR = Path(__file__).parent / "fixtures" / "xfa" SYNTHETIC_FIXTURE = FIXTURE_DIR / "synthetic_dynamic_xfa.pdf" # --------------------------------------------------------------------------- # Detection # --------------------------------------------------------------------------- class TestXfaDetection: """is_xfa_pdf and the catalog /NeedsRendering flag.""" def test_synthetic_fixture_detected_as_dynamic_xfa(self): result = is_xfa_pdf(str(SYNTHETIC_FIXTURE)) assert result["is_xfa"] is True assert result["xfa_type"] == "dynamic" assert result["has_acroform"] is True def test_nonexistent_pdf_returns_not_xfa(self): result = is_xfa_pdf("/nonexistent/path.pdf") assert result["is_xfa"] is False assert result["xfa_type"] is None # --------------------------------------------------------------------------- # XFA packet extraction (array-form parsing) # --------------------------------------------------------------------------- class TestXfaPartsExtraction: """The fixture uses the array form [template, datasets] — exercises the name/stream-pair parsing path, not the single-stream path.""" def test_extracts_template_and_datasets(self): parts = extract_xfa_parts(str(SYNTHETIC_FIXTURE)) assert "template" in parts assert "datasets" in parts assert isinstance(parts["template"], bytes) assert isinstance(parts["datasets"], bytes) def test_template_is_parseable_xml(self): parts = extract_xfa_parts(str(SYNTHETIC_FIXTURE)) # If