This commit is contained in:
Yaojia Wang
2026-01-27 00:47:10 +01:00
parent e83a0cae36
commit 58bf75db68
141 changed files with 24814 additions and 3884 deletions

View 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