Skip to content

Commit bd0bb8c

Browse files
OCR/summarize: Fix async test parity
Assisted-by: Codex
1 parent a8ce096 commit bd0bb8c

2 files changed

Lines changed: 193 additions & 0 deletions

File tree

tests/test_ocr_pdf.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,33 @@ def test_ocr_payload_invalid_page_range() -> None:
3838
OcrPdfPayload.model_validate({"files": [file_repr], "pages": ["5-2"]})
3939

4040

41+
@pytest.mark.asyncio
42+
async def test_async_ocr_payload_rejects_non_pdf() -> None:
43+
file_id = str(PdfRestFileID.generate())
44+
text_file = PdfRestFile.model_validate(
45+
{
46+
"id": file_id,
47+
"name": "notes.txt",
48+
"url": f"https://api.pdfrest.com/resource/{file_id}",
49+
"type": "text/plain",
50+
"size": 64,
51+
"modified": "2024-01-01T00:00:00Z",
52+
"scheduledDeletionTimeUtc": None,
53+
}
54+
)
55+
with pytest.raises(ValidationError, match="Must be a PDF file"):
56+
OcrPdfPayload.model_validate({"files": [text_file]})
57+
58+
59+
@pytest.mark.asyncio
60+
async def test_async_ocr_payload_invalid_page_range() -> None:
61+
file_repr = make_pdf_file(PdfRestFileID.generate(1))
62+
with pytest.raises(
63+
ValidationError, match="The start page must be less than or equal to the end"
64+
):
65+
OcrPdfPayload.model_validate({"files": [file_repr], "pages": ["5-2"]})
66+
67+
4168
def test_ocr_payload_languages() -> None:
4269
file_repr = make_pdf_file(PdfRestFileID.generate(1))
4370
payload = OcrPdfPayload.model_validate(
@@ -171,6 +198,67 @@ def handler(request: httpx.Request) -> httpx.Response:
171198
assert timeout_value == pytest.approx(0.4)
172199

173200

201+
@pytest.mark.asyncio
202+
async def test_async_ocr_pdf_request_customization(
203+
monkeypatch: pytest.MonkeyPatch,
204+
) -> None:
205+
monkeypatch.delenv("PDFREST_API_KEY", raising=False)
206+
input_file = make_pdf_file(PdfRestFileID.generate(2))
207+
payload_dump = OcrPdfPayload.model_validate(
208+
{"files": [input_file], "languages": ["English"]}
209+
).model_dump(mode="json", by_alias=True, exclude_none=True, exclude_unset=True)
210+
output_id = str(PdfRestFileID.generate())
211+
captured_timeout: dict[str, float | dict[str, float] | None] = {}
212+
213+
def handler(request: httpx.Request) -> httpx.Response:
214+
if request.method == "POST" and request.url.path == "/pdf-with-ocr-text":
215+
assert request.url.params["trace"] == "true"
216+
assert request.headers["X-Debug"] == "async"
217+
captured_timeout["value"] = request.extensions.get("timeout")
218+
payload = json.loads(request.content.decode("utf-8"))
219+
assert payload == payload_dump | {"debug": True}
220+
return httpx.Response(
221+
200,
222+
json={
223+
"outputId": output_id,
224+
"inputId": str(input_file.id),
225+
},
226+
)
227+
if request.method == "GET" and request.url.path == f"/resource/{output_id}":
228+
assert request.url.params["format"] == "info"
229+
assert request.url.params["trace"] == "true"
230+
assert request.headers["X-Debug"] == "async"
231+
return httpx.Response(
232+
200,
233+
json=make_pdf_file(output_id, "custom-async-ocr.pdf").model_dump(
234+
mode="json", by_alias=True
235+
),
236+
)
237+
msg = f"Unexpected request {request.method} {request.url}"
238+
raise AssertionError(msg)
239+
240+
transport = httpx.MockTransport(handler)
241+
async with AsyncPdfRestClient(api_key=ASYNC_API_KEY, transport=transport) as client:
242+
response = await client.ocr_pdf(
243+
input_file,
244+
extra_query={"trace": "true"},
245+
extra_headers={"X-Debug": "async"},
246+
extra_body={"debug": True},
247+
timeout=0.4,
248+
)
249+
250+
assert isinstance(response, PdfRestFileBasedResponse)
251+
assert response.output_file.id == output_id
252+
timeout_value = captured_timeout["value"]
253+
assert timeout_value is not None
254+
if isinstance(timeout_value, dict):
255+
assert all(
256+
component == pytest.approx(0.4) for component in timeout_value.values()
257+
)
258+
else:
259+
assert timeout_value == pytest.approx(0.4)
260+
261+
174262
@pytest.mark.asyncio
175263
async def test_async_ocr_pdf_success(
176264
monkeypatch: pytest.MonkeyPatch,

tests/test_summarize_pdf_text.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,37 @@ def test_summarize_payload_invalid_page_range() -> None:
6666
SummarizePdfTextPayload.model_validate({"files": [file_repr], "pages": ["5-2"]})
6767

6868

69+
@pytest.mark.asyncio
70+
async def test_async_summarize_payload_rejects_invalid_mime() -> None:
71+
file_id = str(PdfRestFileID.generate())
72+
image_file = PdfRestFile.model_validate(
73+
{
74+
"id": file_id,
75+
"name": "image.png",
76+
"url": f"https://api.pdfrest.com/resource/{file_id}",
77+
"type": "image/png",
78+
"size": 10,
79+
"modified": "2024-01-01T00:00:00Z",
80+
"scheduledDeletionTimeUtc": None,
81+
}
82+
)
83+
84+
with pytest.raises(
85+
ValidationError, match="Must be a PDF, Markdown, or plain text file"
86+
):
87+
SummarizePdfTextPayload.model_validate({"files": [image_file]})
88+
89+
90+
@pytest.mark.asyncio
91+
async def test_async_summarize_payload_invalid_page_range() -> None:
92+
file_repr = make_pdf_file(PdfRestFileID.generate(1))
93+
94+
with pytest.raises(
95+
ValidationError, match="The start page must be less than or equal to the end"
96+
):
97+
SummarizePdfTextPayload.model_validate({"files": [file_repr], "pages": ["5-2"]})
98+
99+
69100
def test_summarize_text_json_success(monkeypatch: pytest.MonkeyPatch) -> None:
70101
monkeypatch.delenv("PDFREST_API_KEY", raising=False)
71102
input_file = _make_text_file(str(PdfRestFileID.generate(1)))
@@ -245,6 +276,80 @@ def handler(request: httpx.Request) -> httpx.Response:
245276
assert timeout_value == pytest.approx(0.25)
246277

247278

279+
@pytest.mark.asyncio
280+
async def test_async_summarize_text_to_file_request_customization(
281+
monkeypatch: pytest.MonkeyPatch,
282+
) -> None:
283+
monkeypatch.delenv("PDFREST_API_KEY", raising=False)
284+
input_file = make_pdf_file(PdfRestFileID.generate(2))
285+
payload_dump = SummarizePdfTextPayload.model_validate(
286+
{
287+
"files": [input_file],
288+
"output_type": "file",
289+
"output_format": "markdown",
290+
"summary_format": "overview",
291+
}
292+
).model_dump(mode="json", by_alias=True, exclude_none=True, exclude_unset=True)
293+
output_id = str(PdfRestFileID.generate())
294+
295+
captured_timeout: dict[str, float | dict[str, float] | None] = {}
296+
seen: dict[str, int] = {"post": 0, "get": 0}
297+
298+
def handler(request: httpx.Request) -> httpx.Response:
299+
if request.method == "POST" and request.url.path == "/summarized-pdf-text":
300+
seen["post"] += 1
301+
assert request.url.params["trace"] == "true"
302+
assert request.headers["X-Debug"] == "async"
303+
captured_timeout["value"] = request.extensions.get("timeout")
304+
payload = json.loads(request.content.decode("utf-8"))
305+
for key, value in payload_dump.items():
306+
assert payload[key] == value
307+
assert payload["debug"] is True
308+
return httpx.Response(
309+
200,
310+
json={
311+
"outputId": output_id,
312+
"inputId": str(input_file.id),
313+
},
314+
)
315+
if request.method == "GET" and request.url.path == f"/resource/{output_id}":
316+
seen["get"] += 1
317+
assert request.url.params["format"] == "info"
318+
assert request.url.params["trace"] == "true"
319+
assert request.headers["X-Debug"] == "async"
320+
return httpx.Response(
321+
200,
322+
json=build_file_info_payload(
323+
output_id, "async-summary.txt", "text/plain"
324+
),
325+
)
326+
msg = f"Unexpected request {request.method} {request.url}"
327+
raise AssertionError(msg)
328+
329+
transport = httpx.MockTransport(handler)
330+
async with AsyncPdfRestClient(api_key=ASYNC_API_KEY, transport=transport) as client:
331+
response = await client.summarize_text_to_file(
332+
input_file,
333+
extra_query={"trace": "true"},
334+
extra_headers={"X-Debug": "async"},
335+
extra_body={"debug": True},
336+
timeout=0.25,
337+
)
338+
339+
assert seen == {"post": 1, "get": 1}
340+
assert isinstance(response, PdfRestFileBasedResponse)
341+
assert response.output_file.id == output_id
342+
assert response.output_file.name == "async-summary.txt"
343+
timeout_value = captured_timeout["value"]
344+
assert timeout_value is not None
345+
if isinstance(timeout_value, dict):
346+
assert all(
347+
component == pytest.approx(0.25) for component in timeout_value.values()
348+
)
349+
else:
350+
assert timeout_value == pytest.approx(0.25)
351+
352+
248353
def test_summarize_text_success(monkeypatch: pytest.MonkeyPatch) -> None:
249354
monkeypatch.delenv("PDFREST_API_KEY", raising=False)
250355
input_file = make_pdf_file(PdfRestFileID.generate(2))

0 commit comments

Comments
 (0)