Skip to content

Commit b672901

Browse files
models: Add location validation for new signature configurations
- Updated `_PdfSignatureConfigurationModel` to enforce location requirements for `type="new"` via a model validator. - Extended `type` field to include `"existing"` in both the model and the public `PdfSignatureConfiguration` type. - Added tests to verify: - Validation error is raised when `type="new"` and location is missing. - `type="existing"` does not require location fields. Assisted-by: Codex
1 parent 6d718a1 commit b672901

3 files changed

Lines changed: 40 additions & 4 deletions

File tree

src/pdfrest/models/_internal.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,16 +630,19 @@ class _PdfSignatureDisplayModel(BaseModel):
630630

631631

632632
class _PdfSignatureConfigurationModel(BaseModel):
633-
type: Literal["new"]
633+
type: Literal["new", "existing"]
634634
name: str | None = None
635635
logo_opacity: Annotated[float | None, Field(ge=0, le=1, default=None)] = None
636636
location: _PdfSignatureLocationModel | None = None
637637
display: _PdfSignatureDisplayModel | None = None
638638

639639
@model_validator(mode="after")
640-
def _validate_location_for_new_type(self) -> _PdfSignatureConfigurationModel:
640+
def _validate_location_requirements(self) -> _PdfSignatureConfigurationModel:
641641
if self.type == "new" and self.location is None:
642-
msg = "Missing location information for a new digital signature field."
642+
msg = (
643+
"Missing location information for a new digital signature field. "
644+
"See documentation for required fields."
645+
)
643646
raise ValueError(msg)
644647
return self
645648

src/pdfrest/types/public.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ class PdfSignatureDisplay(TypedDict, total=False):
162162

163163

164164
class PdfSignatureConfiguration(TypedDict, total=False):
165-
type: Required[Literal["new"]]
165+
type: Required[Literal["new", "existing"]]
166166
location: Required[PdfSignatureLocation]
167167
name: str
168168
logo_opacity: float

tests/test_sign_pdf.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,36 @@ def handler(request: httpx.Request) -> httpx.Response:
305305
assert all(pytest.approx(0.5) == value for value in timeout_value.values())
306306
else:
307307
assert timeout_value == pytest.approx(0.5)
308+
309+
310+
def test_sign_payload_requires_location_when_type_new() -> None:
311+
input_file = make_pdf_file(PdfRestFileID.generate())
312+
pfx_file = make_pfx_file(str(PdfRestFileID.generate()))
313+
passphrase_file = make_passphrase_file(str(PdfRestFileID.generate()))
314+
315+
with pytest.raises(
316+
ValidationError,
317+
match=r"Missing location information for a new digital signature field",
318+
):
319+
PdfSignPayload.model_validate(
320+
{
321+
"files": [input_file],
322+
"signature_configuration": {"type": "new", "name": "sig"},
323+
"credentials": {"pfx": pfx_file, "passphrase": passphrase_file},
324+
}
325+
)
326+
327+
328+
def test_sign_payload_allows_existing_without_location() -> None:
329+
input_file = make_pdf_file(PdfRestFileID.generate())
330+
pfx_file = make_pfx_file(str(PdfRestFileID.generate()))
331+
passphrase_file = make_passphrase_file(str(PdfRestFileID.generate()))
332+
333+
payload = PdfSignPayload.model_validate(
334+
{
335+
"files": [input_file],
336+
"signature_configuration": {"type": "existing", "name": "sig"},
337+
"credentials": {"pfx": pfx_file, "passphrase": passphrase_file},
338+
}
339+
)
340+
assert payload.signature_configuration.type == "existing"

0 commit comments

Comments
 (0)