"""End-to-end conversion through the HTTP API (Flask test client). Covers: upload -> 202 job_id -> poll -> done -> download valid PDF. """ import io import app from tests.helpers import download_bytes, wait_for_job def test_convert_happy_path_end_to_end(client, submit_epub): resp = submit_epub(filename="book.epub") assert resp.status_code == 202, resp.get_json() job_id = resp.get_json()["job_id"] assert isinstance(job_id, str) and job_id job = wait_for_job(client, job_id) assert job["status"] == "done", job assert job["progress"] == 100 assert job["filename"].endswith(".pdf") assert job["epub"] == "book.epub" assert job["error"] is None data = download_bytes(client, job["filename"]) assert data[:4] == b"%PDF", "downloaded body is not a PDF" def test_convert_records_intermediate_working_state(client, submit_epub): """A fresh job must be visible as queued/working before it finishes.""" job_id = submit_epub().get_json()["job_id"] snap = client.get(f"/api/jobs/{job_id}").get_json() # The worker thread starts asynchronously; allow queued or working. assert snap["status"] in ("queued", "working") assert snap["progress"] >= 0.0 def test_convert_uppercase_extension_is_accepted(client, submit_epub): """Extension check is case-insensitive (.EPUB must not be rejected).""" resp = submit_epub(filename="BOOK.EPUB") assert resp.status_code == 202 job = wait_for_job(client, resp.get_json()["job_id"]) assert job["status"] == "done", job def test_convert_output_file_written_to_output_dir(client, submit_epub): job_id = submit_epub().get_json()["job_id"] job = wait_for_job(client, job_id) out = app.OUTPUT_DIR / job["filename"] assert out.is_file() assert out.stat().st_size > 1024 def test_convert_no_file_field_returns_400(client): resp = client.post("/api/convert", content_type="multipart/form-data") assert resp.status_code == 400 assert "No file" in resp.get_json()["error"]