Files
OCR/docengine/tests/api/test_documents.py
2026-06-01 21:49:53 +05:30

225 lines
7.8 KiB
Python

from __future__ import annotations
import io
import uuid
import pytest
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
from tests.conftest import (
create_test_document,
create_test_page,
create_test_text_block,
create_test_user,
get_auth_headers,
)
class TestUploadDocument:
"""Tests for the document upload endpoint."""
def test_upload_pdf_success(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
file_content = b"%PDF-1.4 fake pdf content for testing"
response = client.post(
"/api/v1/documents/upload",
files={"file": ("test.pdf", io.BytesIO(file_content), "application/pdf")},
headers=headers,
)
assert response.status_code == 201
data = response.json()
assert data["original_filename"] == "test.pdf"
assert data["content_type"] == "application/pdf"
assert data["status"] == "pending"
assert data["file_size"] == len(file_content)
assert "id" in data
assert "checksum" in data
def test_upload_image_success(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
# Minimal valid PNG header
png_header = (
b"\x89PNG\r\n\x1a\n"
b"\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01"
b"\x08\x02\x00\x00\x00\x90wS\xde"
)
response = client.post(
"/api/v1/documents/upload",
files={"file": ("scan.png", io.BytesIO(png_header), "image/png")},
headers=headers,
)
assert response.status_code == 201
data = response.json()
assert data["content_type"] == "image/png"
def test_upload_unsupported_type_rejected(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
response = client.post(
"/api/v1/documents/upload",
files={"file": ("doc.exe", io.BytesIO(b"malware"), "application/octet-stream")},
headers=headers,
)
assert response.status_code in (415, 422)
def test_upload_no_file_rejected(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
response = client.post("/api/v1/documents/upload", headers=headers)
assert response.status_code == 422
class TestGetDocument:
"""Tests for getting a document by ID."""
def test_get_document_success(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
doc = create_test_document(db, user=user, status="completed")
db.flush()
headers = get_auth_headers(user)
response = client.get(f"/api/v1/documents/{doc.id}", headers=headers)
assert response.status_code == 200
data = response.json()
assert data["id"] == str(doc.id)
assert data["original_filename"] == doc.original_filename
assert data["status"] == "completed"
def test_get_document_not_found(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
fake_id = uuid.uuid4()
response = client.get(f"/api/v1/documents/{fake_id}", headers=headers)
assert response.status_code == 404
def test_get_document_invalid_uuid(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
response = client.get("/api/v1/documents/not-a-uuid", headers=headers)
assert response.status_code == 422
class TestListDocuments:
"""Tests for listing documents."""
def test_list_documents_empty(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
response = client.get("/api/v1/documents", headers=headers)
assert response.status_code == 200
data = response.json()
assert "items" in data
assert "total" in data
assert "page" in data
assert "page_size" in data
def test_list_documents_with_data(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
create_test_document(db, user=user, filename="doc1.pdf")
create_test_document(db, user=user, filename="doc2.pdf")
db.flush()
headers = get_auth_headers(user)
response = client.get("/api/v1/documents", headers=headers)
assert response.status_code == 200
data = response.json()
assert data["total"] >= 2
assert len(data["items"]) >= 2
def test_list_documents_pagination(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
for i in range(5):
create_test_document(db, user=user, filename=f"page_doc_{i}.pdf")
db.flush()
headers = get_auth_headers(user)
response = client.get("/api/v1/documents?page=1&page_size=2", headers=headers)
assert response.status_code == 200
data = response.json()
assert data["page"] == 1
assert data["page_size"] == 2
assert len(data["items"]) <= 2
def test_list_documents_status_filter(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
create_test_document(db, user=user, filename="pending.pdf", status="pending")
create_test_document(db, user=user, filename="completed.pdf", status="completed")
db.flush()
headers = get_auth_headers(user)
response = client.get("/api/v1/documents?status=completed", headers=headers)
assert response.status_code == 200
data = response.json()
for item in data["items"]:
assert item["status"] == "completed"
class TestDeleteDocument:
"""Tests for deleting a document."""
def test_delete_document_success(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
doc = create_test_document(db, user=user)
db.flush()
headers = get_auth_headers(user)
response = client.delete(f"/api/v1/documents/{doc.id}", headers=headers)
assert response.status_code == 200
data = response.json()
assert "message" in data
# Verify document is gone
get_response = client.get(f"/api/v1/documents/{doc.id}", headers=headers)
assert get_response.status_code == 404
def test_delete_document_not_found(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
fake_id = uuid.uuid4()
response = client.delete(f"/api/v1/documents/{fake_id}", headers=headers)
assert response.status_code == 404
class TestGetDocumentTemplateMatches:
"""Tests for document template match retrieval."""
def test_get_matches_empty(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
doc = create_test_document(db, user=user, status="completed")
db.flush()
headers = get_auth_headers(user)
response = client.get(f"/api/v1/documents/{doc.id}/template", headers=headers)
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
assert len(data) == 0
def test_get_matches_document_not_found(self, client: TestClient, db: Session) -> None:
user = create_test_user(db)
db.flush()
headers = get_auth_headers(user)
fake_id = uuid.uuid4()
response = client.get(f"/api/v1/documents/{fake_id}/template", headers=headers)
assert response.status_code == 404