140 lines
5.1 KiB
Python
140 lines
5.1 KiB
Python
"""
|
|
Tests for Phase 8: normalized intermediate schema and mapping service.
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from src.models.normalized_template import (
|
|
ActionType,
|
|
NormalizedDocument,
|
|
NormalizedField,
|
|
NormalizedRole,
|
|
NormalizedTemplate,
|
|
)
|
|
from src.services.mapping_service import adobe_folder_to_normalized
|
|
|
|
|
|
DOWNLOADS = Path(__file__).parent.parent / "downloads"
|
|
DAVID_DIR = DOWNLOADS / "David Tag Demo Form__CBJCHBCA"
|
|
NDA_DIR = DOWNLOADS / "_DEMO USE ONLY_ NDA__CBJCHBCA"
|
|
ROB_DIR = DOWNLOADS / "Rob Test__CBJCHBCA"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Model construction
|
|
# ---------------------------------------------------------------------------
|
|
|
|
class TestNormalizedModels:
|
|
def test_normalized_role_defaults(self):
|
|
r = NormalizedRole(name="Customer", order=1)
|
|
assert r.action_type == ActionType.SIGN
|
|
assert r.order == 1
|
|
|
|
def test_normalized_field_defaults(self):
|
|
f = NormalizedField(type="text", label="Name", page=1, x=10, y=20, width=120, height=24)
|
|
assert f.required is False
|
|
assert f.read_only is False
|
|
assert f.options == []
|
|
assert f.conditional_parent_label is None
|
|
|
|
def test_normalized_template_construction(self):
|
|
t = NormalizedTemplate(
|
|
name="My Template",
|
|
roles=[NormalizedRole(name="Signer 1", order=1)],
|
|
fields=[
|
|
NormalizedField(type="signature", label="sig1", page=1, x=0, y=0, width=140, height=28)
|
|
],
|
|
)
|
|
assert t.name == "My Template"
|
|
assert len(t.roles) == 1
|
|
assert len(t.fields) == 1
|
|
|
|
def test_role_names(self):
|
|
t = NormalizedTemplate(
|
|
name="T",
|
|
roles=[
|
|
NormalizedRole(name="Customer", order=1),
|
|
NormalizedRole(name="Company", order=2),
|
|
],
|
|
)
|
|
assert t.role_names() == ["Customer", "Company"]
|
|
|
|
def test_fields_for_role(self):
|
|
t = NormalizedTemplate(
|
|
name="T",
|
|
roles=[NormalizedRole(name="Signer 1", order=1)],
|
|
fields=[
|
|
NormalizedField(type="signature", label="s1", page=1, x=0, y=0, width=140, height=28, role_name="Signer 1"),
|
|
NormalizedField(type="text", label="name", page=1, x=0, y=50, width=120, height=24, role_name="Signer 2"),
|
|
],
|
|
)
|
|
assert len(t.fields_for_role("Signer 1")) == 1
|
|
assert len(t.fields_for_role("Signer 2")) == 1
|
|
assert len(t.fields_for_role("Nobody")) == 0
|
|
|
|
def test_normalized_document_checksum(self):
|
|
doc = NormalizedDocument(
|
|
name="test.pdf",
|
|
content_base64="dGVzdA==",
|
|
checksum_sha256="9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
|
|
)
|
|
assert doc.checksum_sha256 != ""
|
|
|
|
def test_serialization_roundtrip(self):
|
|
t = NormalizedTemplate(
|
|
name="Round Trip",
|
|
roles=[NormalizedRole(name="Signer 1", order=1)],
|
|
)
|
|
dumped = t.model_dump()
|
|
restored = NormalizedTemplate(**dumped)
|
|
assert restored.name == t.name
|
|
assert len(restored.roles) == 1
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Mapping service — requires real download fixtures
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@pytest.mark.skipif(not DAVID_DIR.exists(), reason="Downloads fixtures not present")
|
|
class TestMappingService:
|
|
def test_david_template_normalizes(self):
|
|
norm, warnings = adobe_folder_to_normalized(str(DAVID_DIR))
|
|
assert isinstance(norm, NormalizedTemplate)
|
|
assert norm.name != ""
|
|
assert len(norm.roles) >= 1
|
|
assert len(norm.fields) > 0
|
|
|
|
def test_david_fields_have_roles(self):
|
|
norm, _ = adobe_folder_to_normalized(str(DAVID_DIR))
|
|
role_names = norm.role_names()
|
|
for f in norm.fields:
|
|
assert f.role_name in role_names, f"Field '{f.label}' has unresolved role '{f.role_name}'"
|
|
|
|
def test_david_documents_have_checksum(self):
|
|
norm, _ = adobe_folder_to_normalized(str(DAVID_DIR))
|
|
assert len(norm.documents) >= 1
|
|
for doc in norm.documents:
|
|
assert doc.checksum_sha256 != "", f"Document '{doc.name}' missing checksum"
|
|
assert len(doc.checksum_sha256) == 64 # SHA-256 hex
|
|
|
|
def test_exclude_documents_option(self):
|
|
norm, _ = adobe_folder_to_normalized(str(DAVID_DIR), include_documents=False)
|
|
for doc in norm.documents:
|
|
assert doc.content_base64 == ""
|
|
# checksum still computed even when content excluded
|
|
assert doc.checksum_sha256 != ""
|
|
|
|
@pytest.mark.skipif(not NDA_DIR.exists(), reason="NDA fixture not present")
|
|
def test_nda_template_normalizes(self):
|
|
norm, _ = adobe_folder_to_normalized(str(NDA_DIR))
|
|
assert norm.name != ""
|
|
assert len(norm.fields) > 0
|
|
|
|
@pytest.mark.skipif(not ROB_DIR.exists(), reason="Rob fixture not present")
|
|
def test_rob_template_normalizes(self):
|
|
norm, _ = adobe_folder_to_normalized(str(ROB_DIR))
|
|
assert norm.name != ""
|