WIP
This commit is contained in:
164
tests/web/test_admin_routes.py
Normal file
164
tests/web/test_admin_routes.py
Normal file
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Tests for Admin Document Routes.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import HTTPException
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from src.data.admin_models import AdminDocument, AdminToken
|
||||
from src.web.api.v1.admin.documents import _validate_uuid, create_admin_router
|
||||
|
||||
|
||||
# Test UUID
|
||||
TEST_DOC_UUID = "550e8400-e29b-41d4-a716-446655440000"
|
||||
TEST_TOKEN = "test-admin-token-12345"
|
||||
|
||||
|
||||
class TestValidateUUID:
|
||||
"""Tests for UUID validation."""
|
||||
|
||||
def test_valid_uuid(self):
|
||||
"""Test valid UUID passes validation."""
|
||||
_validate_uuid(TEST_DOC_UUID, "test") # Should not raise
|
||||
|
||||
def test_invalid_uuid_raises_400(self):
|
||||
"""Test invalid UUID raises 400."""
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
_validate_uuid("not-a-uuid", "document_id")
|
||||
|
||||
assert exc_info.value.status_code == 400
|
||||
assert "Invalid document_id format" in exc_info.value.detail
|
||||
|
||||
|
||||
class TestAdminRouter:
|
||||
"""Tests for admin router creation."""
|
||||
|
||||
def test_creates_router_with_endpoints(self):
|
||||
"""Test router is created with expected endpoints."""
|
||||
router = create_admin_router((".pdf", ".png", ".jpg"))
|
||||
|
||||
# Get route paths (include prefix from router)
|
||||
paths = [route.path for route in router.routes]
|
||||
|
||||
# Paths include the /admin prefix
|
||||
assert any("/auth/token" in p for p in paths)
|
||||
assert any("/documents" in p for p in paths)
|
||||
assert any("/documents/stats" in p for p in paths)
|
||||
assert any("{document_id}" in p for p in paths)
|
||||
|
||||
|
||||
class TestCreateTokenEndpoint:
|
||||
"""Tests for POST /admin/auth/token endpoint."""
|
||||
|
||||
@pytest.fixture
|
||||
def mock_db(self):
|
||||
"""Create mock AdminDB."""
|
||||
db = MagicMock()
|
||||
db.is_valid_admin_token.return_value = True
|
||||
return db
|
||||
|
||||
def test_create_token_success(self, mock_db):
|
||||
"""Test successful token creation."""
|
||||
from src.web.schemas.admin import AdminTokenCreate
|
||||
|
||||
request = AdminTokenCreate(name="Test Token", expires_in_days=30)
|
||||
|
||||
# The actual endpoint would generate a token
|
||||
# This tests the schema validation
|
||||
assert request.name == "Test Token"
|
||||
assert request.expires_in_days == 30
|
||||
|
||||
|
||||
class TestDocumentUploadEndpoint:
|
||||
"""Tests for POST /admin/documents endpoint."""
|
||||
|
||||
@pytest.fixture
|
||||
def sample_pdf_bytes(self):
|
||||
"""Create sample PDF-like bytes."""
|
||||
# Minimal PDF header
|
||||
return b"%PDF-1.4\n%\xe2\xe3\xcf\xd3\n"
|
||||
|
||||
@pytest.fixture
|
||||
def mock_admin_db(self):
|
||||
"""Create mock AdminDB."""
|
||||
db = MagicMock()
|
||||
db.is_valid_admin_token.return_value = True
|
||||
db.create_document.return_value = TEST_DOC_UUID
|
||||
return db
|
||||
|
||||
def test_rejects_invalid_extension(self):
|
||||
"""Test that invalid file extensions are rejected."""
|
||||
# Schema validation would happen at the route level
|
||||
allowed = (".pdf", ".png", ".jpg")
|
||||
file_ext = ".exe"
|
||||
|
||||
assert file_ext not in allowed
|
||||
|
||||
|
||||
class TestDocumentListEndpoint:
|
||||
"""Tests for GET /admin/documents endpoint."""
|
||||
|
||||
@pytest.fixture
|
||||
def sample_documents(self):
|
||||
"""Create sample documents."""
|
||||
return [
|
||||
AdminDocument(
|
||||
document_id=UUID(TEST_DOC_UUID),
|
||||
admin_token=TEST_TOKEN,
|
||||
filename="test.pdf",
|
||||
file_size=1024,
|
||||
content_type="application/pdf",
|
||||
file_path="/tmp/test.pdf",
|
||||
page_count=1,
|
||||
status="pending",
|
||||
),
|
||||
]
|
||||
|
||||
def test_validates_status_filter(self):
|
||||
"""Test that invalid status filter is rejected."""
|
||||
valid_statuses = ("pending", "auto_labeling", "labeled", "exported")
|
||||
|
||||
assert "invalid_status" not in valid_statuses
|
||||
assert "pending" in valid_statuses
|
||||
|
||||
|
||||
class TestDocumentDetailEndpoint:
|
||||
"""Tests for GET /admin/documents/{document_id} endpoint."""
|
||||
|
||||
def test_requires_valid_uuid(self):
|
||||
"""Test that invalid UUID is rejected."""
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
_validate_uuid("invalid", "document_id")
|
||||
|
||||
assert exc_info.value.status_code == 400
|
||||
|
||||
|
||||
class TestDocumentDeleteEndpoint:
|
||||
"""Tests for DELETE /admin/documents/{document_id} endpoint."""
|
||||
|
||||
def test_validates_document_id(self):
|
||||
"""Test that document_id is validated."""
|
||||
# Valid UUID should not raise
|
||||
_validate_uuid(TEST_DOC_UUID, "document_id")
|
||||
|
||||
# Invalid should raise
|
||||
with pytest.raises(HTTPException):
|
||||
_validate_uuid("bad-id", "document_id")
|
||||
|
||||
|
||||
class TestDocumentStatusUpdateEndpoint:
|
||||
"""Tests for PATCH /admin/documents/{document_id}/status endpoint."""
|
||||
|
||||
def test_validates_status_values(self):
|
||||
"""Test that only valid statuses are accepted."""
|
||||
valid_statuses = ("pending", "labeled", "exported")
|
||||
|
||||
assert "pending" in valid_statuses
|
||||
assert "invalid" not in valid_statuses
|
||||
Reference in New Issue
Block a user