Implemented endpoints for generating presigned URLs and handling file uploads. Added corresponding test cases to ensure proper functionality and error handling. Updated the main router to include the new uploads API.
106 lines
3.4 KiB
Python
106 lines
3.4 KiB
Python
# tests/api/routes/test_uploads.py
|
|
import json
|
|
import uuid
|
|
from unittest.mock import patch, MagicMock
|
|
from datetime import datetime, timezone
|
|
|
|
import pytest
|
|
from fastapi import FastAPI
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.api.routes.uploads import router as uploads_router
|
|
from app.core.database import get_db
|
|
from app.api.dependencies.auth import get_current_user
|
|
from app.api.dependencies.common import get_storage_provider
|
|
from app.core.storage import StorageProvider
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_storage_provider():
|
|
"""Mock storage provider for testing."""
|
|
provider = MagicMock(spec=StorageProvider)
|
|
# Configure generate_presigned_url to return predictable values
|
|
provider.generate_presigned_url.return_value = (
|
|
"/api/v1/uploads/mock-token-123",
|
|
"/files/uploads/test-image.jpg"
|
|
)
|
|
provider.get_file_url.return_value = "/files/uploads/test-image.jpg"
|
|
return provider
|
|
|
|
|
|
@pytest.fixture
|
|
def app(db_session, mock_user, mock_storage_provider):
|
|
"""Create a FastAPI test application with overridden dependencies."""
|
|
app = FastAPI()
|
|
app.include_router(uploads_router, prefix="/api/v1/uploads", tags=["uploads"])
|
|
|
|
# Override dependencies
|
|
app.dependency_overrides[get_db] = lambda: db_session
|
|
app.dependency_overrides[get_current_user] = lambda: mock_user
|
|
app.dependency_overrides[get_storage_provider] = lambda: mock_storage_provider
|
|
|
|
return app
|
|
|
|
|
|
@pytest.fixture
|
|
def client(app):
|
|
"""Create a FastAPI test client."""
|
|
return TestClient(app)
|
|
|
|
|
|
class TestPresignedUrl:
|
|
"""Tests for the generate_presigned_url endpoint."""
|
|
|
|
def test_generate_presigned_url_success(self, client):
|
|
"""Test successful generation of presigned URL."""
|
|
# Test request
|
|
response = client.post(
|
|
"/api/v1/uploads/presigned-url",
|
|
json={
|
|
"filename": "test-image.jpg",
|
|
"content_type": "image/jpeg",
|
|
"folder": "event-themes"
|
|
}
|
|
)
|
|
|
|
# Assertions
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["upload_url"] == "/api/v1/uploads/mock-token-123"
|
|
assert data["file_url"] == "/files/uploads/test-image.jpg"
|
|
assert data["expires_in"] > 0
|
|
|
|
def test_generate_presigned_url_invalid_content_type(self, client):
|
|
"""Test generating presigned URL with invalid content type."""
|
|
# Test request with unsupported content type
|
|
response = client.post(
|
|
"/api/v1/uploads/presigned-url",
|
|
json={
|
|
"filename": "test-file.txt",
|
|
"content_type": "text/plain",
|
|
"folder": "event-themes"
|
|
}
|
|
)
|
|
|
|
# Assertions
|
|
assert response.status_code == 400
|
|
assert "not allowed" in response.json()["detail"]
|
|
|
|
def test_generate_presigned_url_unauthorized(self, app, client):
|
|
"""Test generating presigned URL without authentication."""
|
|
# Remove authentication
|
|
app.dependency_overrides[get_current_user] = lambda: None
|
|
|
|
# Test request
|
|
response = client.post(
|
|
"/api/v1/uploads/presigned-url",
|
|
json={
|
|
"filename": "test-image.jpg",
|
|
"content_type": "image/jpeg",
|
|
"folder": "event-themes"
|
|
}
|
|
)
|
|
|
|
# Assertions
|
|
assert response.status_code == 401
|
|
assert "Invalid authentication" in response.json()["detail"] |