255 lines
8.7 KiB
Python
255 lines
8.7 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy.orm import Session
|
|
|
|
from tests.conftest import (
|
|
create_test_document,
|
|
create_test_fingerprint,
|
|
create_test_page,
|
|
create_test_template,
|
|
create_test_text_block,
|
|
create_test_user,
|
|
get_auth_headers,
|
|
)
|
|
|
|
|
|
class TestListTemplates:
|
|
"""Tests for listing templates."""
|
|
|
|
def test_list_templates_empty(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.get("/api/v1/templates", headers=headers)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "items" in data
|
|
assert "total" in data
|
|
assert "page" in data
|
|
|
|
def test_list_templates_with_data(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
create_test_template(db, name="Template_A", created_by=user)
|
|
create_test_template(db, name="Template_B", created_by=user)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.get("/api/v1/templates", headers=headers)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["total"] >= 2
|
|
|
|
def test_list_templates_pagination(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
for i in range(5):
|
|
create_test_template(db, name=f"PagTemplate_{i}", created_by=user)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.get("/api/v1/templates?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
|
|
|
|
|
|
class TestGetTemplate:
|
|
"""Tests for getting a template by ID."""
|
|
|
|
def test_get_template_success(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
template = create_test_template(db, name="GetMe", created_by=user)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.get(f"/api/v1/templates/{template.id}", headers=headers)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["id"] == str(template.id)
|
|
assert data["name"] == "GetMe"
|
|
assert data["page_width"] == 612.0
|
|
assert data["page_height"] == 792.0
|
|
assert data["is_active"] is True
|
|
|
|
def test_get_template_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/templates/{fake_id}", headers=headers)
|
|
assert response.status_code == 404
|
|
|
|
def test_get_template_includes_components(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
template = create_test_template(db, name="ComponentTemplate", created_by=user)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.get(f"/api/v1/templates/{template.id}", headers=headers)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "cells" in data
|
|
assert "regions" in data
|
|
assert "table_formats" in data
|
|
assert "watermarks" in data
|
|
assert "image_regions" in data
|
|
|
|
|
|
class TestDeleteTemplate:
|
|
"""Tests for template soft-deletion."""
|
|
|
|
def test_delete_template_success(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
template = create_test_template(db, name="DeleteMe", created_by=user)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.delete(f"/api/v1/templates/{template.id}", headers=headers)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "message" in data
|
|
|
|
# Verify template is deactivated (soft-deleted), not hard-deleted
|
|
get_response = client.get(f"/api/v1/templates/{template.id}", headers=headers)
|
|
assert get_response.status_code == 200
|
|
assert get_response.json()["is_active"] is False
|
|
|
|
def test_delete_template_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/templates/{fake_id}", headers=headers)
|
|
assert response.status_code == 404
|
|
|
|
|
|
class TestMatchTemplate:
|
|
"""Tests for document-to-template matching endpoint."""
|
|
|
|
def test_match_document_not_found(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
fake_doc_id = uuid.uuid4()
|
|
response = client.post(
|
|
"/api/v1/templates/match",
|
|
json={"document_id": str(fake_doc_id), "min_confidence": 0.5, "max_results": 5},
|
|
headers=headers,
|
|
)
|
|
assert response.status_code == 404
|
|
|
|
def test_match_document_not_completed(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
doc = create_test_document(db, user=user, status="pending")
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.post(
|
|
"/api/v1/templates/match",
|
|
json={"document_id": str(doc.id), "min_confidence": 0.5, "max_results": 5},
|
|
headers=headers,
|
|
)
|
|
assert response.status_code == 400
|
|
|
|
def test_match_completed_document_no_templates(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
doc = create_test_document(db, user=user, status="completed")
|
|
page = create_test_page(db, doc)
|
|
create_test_text_block(db, page, text="Content")
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.post(
|
|
"/api/v1/templates/match",
|
|
json={"document_id": str(doc.id), "min_confidence": 0.0, "max_results": 5},
|
|
headers=headers,
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert isinstance(data, list)
|
|
|
|
|
|
class TestRenderTemplate:
|
|
"""Tests for template rendering endpoint."""
|
|
|
|
def test_render_template_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.post(
|
|
"/api/v1/templates/render",
|
|
json={
|
|
"template_id": str(fake_id),
|
|
"data": {},
|
|
},
|
|
headers=headers,
|
|
)
|
|
assert response.status_code == 404
|
|
|
|
def test_render_inactive_template(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
template = create_test_template(db, name="InactiveRender", created_by=user)
|
|
template.is_active = False
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.post(
|
|
"/api/v1/templates/render",
|
|
json={
|
|
"template_id": str(template.id),
|
|
"data": {},
|
|
},
|
|
headers=headers,
|
|
)
|
|
assert response.status_code == 400
|
|
|
|
def test_render_template_success(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
template = create_test_template(db, name="RenderOK", created_by=user)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.post(
|
|
"/api/v1/templates/render",
|
|
json={
|
|
"template_id": str(template.id),
|
|
"data": {"field_1": "Hello World"},
|
|
"output_filename": "test_render.pdf",
|
|
},
|
|
headers=headers,
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["filename"] == "test_render.pdf"
|
|
assert data["file_size"] > 0
|
|
assert data["page_count"] == template.page_count
|
|
assert "output_path" in data
|
|
assert "rendered_at" in data
|
|
|
|
|
|
class TestDownloadRenderedPDF:
|
|
"""Tests for downloading rendered PDFs."""
|
|
|
|
def test_download_not_found(self, client: TestClient, db: Session) -> None:
|
|
user = create_test_user(db)
|
|
template = create_test_template(db, name="DLTemplate", created_by=user)
|
|
db.flush()
|
|
headers = get_auth_headers(user)
|
|
|
|
response = client.get(
|
|
f"/api/v1/templates/{template.id}/download?filename=nonexistent.pdf",
|
|
headers=headers,
|
|
)
|
|
assert response.status_code == 404
|