121 lines
4 KiB
Python
121 lines
4 KiB
Python
"""End-to-end coverage for the user-critical backend workflows."""
|
|
|
|
import os
|
|
import shutil
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
import pymupdf
|
|
from fastapi.testclient import TestClient
|
|
|
|
_ROOT = Path.cwd() / ".pytest-paperjet-api"
|
|
shutil.rmtree(_ROOT, ignore_errors=True)
|
|
_ROOT.mkdir()
|
|
os.environ.update(
|
|
{
|
|
"PAPERJET_SECRET_KEY": "test-secret-key",
|
|
"PAPERJET_DATABASE_PATH": str(_ROOT / "db" / "app.sqlite"),
|
|
"PAPERJET_PDF_STORAGE_PATH": str(_ROOT / "pdfs"),
|
|
"PAPERJET_THUMBNAILS_PATH": str(_ROOT / "thumbnails"),
|
|
"PAPERJET_DEBUG": "false",
|
|
}
|
|
)
|
|
|
|
from app.main import app # noqa: E402
|
|
|
|
|
|
def _pdf_bytes() -> bytes:
|
|
document = pymupdf.open()
|
|
document.new_page(width=240, height=320)
|
|
content = document.tobytes()
|
|
document.close()
|
|
return content
|
|
|
|
|
|
def test_setup_upload_annotate_version_export_and_trash_restore() -> None:
|
|
csrf = {"X-Requested-With": "XMLHttpRequest"}
|
|
annotation_id = str(uuid.uuid4())
|
|
annotation = {
|
|
"id": annotation_id,
|
|
"page": 0,
|
|
"type": "text",
|
|
"rect": {"x": 20, "y": 30, "width": 120, "height": 30},
|
|
"rotation": 0,
|
|
"z": 0,
|
|
"props": {
|
|
"text": "Persisted note",
|
|
"fontFamily": "Liberation Sans",
|
|
"fontSize": 14,
|
|
"color": "#000000",
|
|
},
|
|
"createdAt": "2026-08-14T00:00:00Z",
|
|
"updatedAt": "2026-08-14T00:00:00Z",
|
|
}
|
|
|
|
with TestClient(app) as client:
|
|
assert client.get("/api/v1/health").json()["status"] == "ok"
|
|
assert client.get("/api/v1/auth/status").json()["setupRequired"] is True
|
|
|
|
setup = client.post("/api/v1/auth/setup", json={"password": "correct horse"}, headers=csrf)
|
|
assert setup.status_code == 200
|
|
assert client.get("/api/v1/auth/status").json()["loggedIn"] is True
|
|
|
|
upload = client.post(
|
|
"/api/v1/documents",
|
|
files={"file": ("sample.pdf", _pdf_bytes(), "application/pdf")},
|
|
headers=csrf,
|
|
)
|
|
assert upload.status_code == 201
|
|
document_id = upload.json()["id"]
|
|
|
|
saved = client.put(
|
|
f"/api/v1/documents/{document_id}/annotations",
|
|
json={"data": [annotation]},
|
|
headers=csrf,
|
|
)
|
|
assert saved.status_code == 200
|
|
assert client.get(f"/api/v1/documents/{document_id}/annotations").json()["data"] == [
|
|
annotation
|
|
]
|
|
|
|
version = client.post(
|
|
f"/api/v1/documents/{document_id}/versions",
|
|
json={"label": "Before export"},
|
|
headers=csrf,
|
|
)
|
|
assert version.status_code == 201
|
|
version_id = version.json()["id"]
|
|
|
|
changed = {**annotation, "props": {**annotation["props"], "text": "Changed"}}
|
|
client.put(
|
|
f"/api/v1/documents/{document_id}/annotations",
|
|
json={"data": [changed]},
|
|
headers=csrf,
|
|
)
|
|
restored = client.post(
|
|
f"/api/v1/documents/{document_id}/versions/{version_id}/restore",
|
|
headers=csrf,
|
|
)
|
|
assert restored.status_code == 200
|
|
assert client.get(f"/api/v1/documents/{document_id}/annotations").json()["data"] == [
|
|
annotation
|
|
]
|
|
|
|
exported = client.post(
|
|
f"/api/v1/documents/{document_id}/export",
|
|
json={"flatten": True},
|
|
headers=csrf,
|
|
)
|
|
assert exported.status_code == 200
|
|
with pymupdf.open(stream=exported.content, filetype="pdf") as document:
|
|
assert "Persisted note" in document[0].get_text("text")
|
|
|
|
assert client.delete(f"/api/v1/documents/{document_id}", headers=csrf).status_code == 200
|
|
assert client.get("/api/v1/documents").json()["total"] == 0
|
|
assert client.get("/api/v1/documents/trash").json()["total"] == 1
|
|
assert (
|
|
client.post(f"/api/v1/documents/{document_id}/restore", headers=csrf).status_code == 200
|
|
)
|
|
assert client.get("/api/v1/documents").json()["total"] == 1
|
|
|
|
shutil.rmtree(_ROOT, ignore_errors=True)
|