91 lines
4.0 KiB
Python
91 lines
4.0 KiB
Python
# Mapping Function Unit Test
|
|
"""
|
|
Unit test harness for mapping Adobe Sign form fields to DocuSign tab config.
|
|
Validates that compose_docusign_template.py produces correctly structured output:
|
|
- Tabs are grouped into typed arrays (textTabs, signHereTabs, etc.)
|
|
- required / locked are strings "true" / "false", not booleans
|
|
- listTabs have listItems: [{text, value}], not a string array
|
|
- radioGroupTabs have groupName + radios[]
|
|
- No top-level "status" field
|
|
- No email/name on signer role placeholders
|
|
"""
|
|
import json
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
# Support running from src/ or project root
|
|
BASE = Path(__file__).parent.parent
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
from compose_docusign_template import compose_template
|
|
|
|
|
|
def test_onboarding_mapping(tmp_path):
|
|
template_dir = BASE / "downloads" / "David Tag Demo Form__CBJCHBCA"
|
|
output_path = tmp_path / "compose-doc-template-complete.json"
|
|
compose_template(str(template_dir), str(output_path))
|
|
|
|
template = json.loads(output_path.read_text())
|
|
|
|
# -- No top-level status field --
|
|
assert "status" not in template, "Template must not have a top-level 'status' field"
|
|
|
|
signers = template["recipients"]["signers"]
|
|
assert len(signers) == 1, f"Expected 1 signer, got {len(signers)}"
|
|
|
|
signer0_tabs = signers[0]["tabs"]
|
|
|
|
# -- No email/name on role placeholders --
|
|
for s in signers:
|
|
assert "email" not in s, f"Signer should not have 'email' in template role: {s['roleName']}"
|
|
assert "name" not in s, f"Signer should not have 'name' in template role: {s['roleName']}"
|
|
|
|
# -- Tab groups present and properly typed --
|
|
assert "textTabs" in signer0_tabs, "Signer 0 missing textTabs"
|
|
assert "dateSignedTabs" in signer0_tabs, "Signer 0 missing dateSignedTabs"
|
|
assert "listTabs" in signer0_tabs, "Signer 0 missing listTabs"
|
|
assert "checkboxTabs" in signer0_tabs, "Signer 0 missing checkboxTabs"
|
|
assert "radioGroupTabs" in signer0_tabs, "Signer 0 missing radioGroupTabs"
|
|
assert "signHereTabs" in signer0_tabs, "Signer 0 missing signHereTabs"
|
|
|
|
# -- required / locked are strings --
|
|
for tab in signer0_tabs.get("textTabs", []):
|
|
assert isinstance(tab.get("required"), str), f"required must be string, got {type(tab.get('required'))}"
|
|
for tab in signer0_tabs.get("listTabs", []):
|
|
assert isinstance(tab.get("required"), str), f"required must be string on listTab"
|
|
|
|
# -- listItems are objects --
|
|
list_tab = signer0_tabs["listTabs"][0]
|
|
assert "listItems" in list_tab, "listTab missing listItems"
|
|
assert isinstance(list_tab["listItems"][0], dict), "listItems entries must be {text, value} dicts"
|
|
assert "text" in list_tab["listItems"][0], "listItems entries must have 'text'"
|
|
assert "value" in list_tab["listItems"][0], "listItems entries must have 'value'"
|
|
|
|
# -- radioGroupTabs structure --
|
|
radio_tab = signer0_tabs["radioGroupTabs"][0]
|
|
assert "groupName" in radio_tab, "radioGroupTab missing groupName"
|
|
assert "radios" in radio_tab, "radioGroupTab missing radios"
|
|
assert len(radio_tab["radios"]) >= 1, "Expected at least one radio option"
|
|
for r in radio_tab["radios"]:
|
|
assert "pageNumber" in r, "radio missing pageNumber"
|
|
assert "xPosition" in r, "radio missing xPosition"
|
|
assert "yPosition" in r, "radio missing yPosition"
|
|
assert "value" in r, "radio missing value"
|
|
|
|
# -- All tabs have required placement fields --
|
|
all_single_tabs = (
|
|
signer0_tabs.get("textTabs", [])
|
|
+ signer0_tabs.get("dateSignedTabs", [])
|
|
+ signer0_tabs.get("signHereTabs", [])
|
|
+ signer0_tabs.get("listTabs", [])
|
|
+ signer0_tabs.get("checkboxTabs", [])
|
|
)
|
|
for tab in all_single_tabs:
|
|
for field in ("documentId", "pageNumber", "xPosition", "yPosition"):
|
|
assert field in tab, f"Tab '{tab.get('tabLabel')}' missing '{field}'"
|
|
|
|
if __name__ == "__main__":
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
test_onboarding_mapping(Path(tmpdir))
|