"""Tests for file validation.""" import io from unittest.mock import AsyncMock, Mock import pytest from fastapi import HTTPException, UploadFile from app.images.validation import sanitize_filename, validate_image_file class TestSanitizeFilename: """Tests for filename sanitization.""" def test_sanitize_normal_filename(self): """Test sanitizing normal filename.""" assert sanitize_filename("image.jpg") == "image.jpg" assert sanitize_filename("my_photo-2025.png") == "my_photo-2025.png" def test_sanitize_path_traversal(self): """Test preventing path traversal.""" assert "/" not in sanitize_filename("../../../etc/passwd") assert "\\" not in sanitize_filename("..\\..\\..\\windows\\system32") def test_sanitize_special_characters(self): """Test removing special characters.""" result = sanitize_filename("file name with spaces!@#.jpg") assert " " not in result or result == "file_name_with_spaces___.jpg" def test_sanitize_long_filename(self): """Test truncating long filenames.""" long_name = "a" * 300 + ".jpg" result = sanitize_filename(long_name) assert len(result) <= 255 assert result.endswith(".jpg") @pytest.mark.asyncio class TestValidateImageFile: """Tests for image file validation.""" async def test_validate_empty_file(self): """Test rejection of empty files.""" mock_file = AsyncMock(spec=UploadFile) mock_file.read = AsyncMock(return_value=b"") mock_file.seek = AsyncMock() mock_file.filename = "empty.jpg" with pytest.raises(HTTPException) as exc: await validate_image_file(mock_file) assert exc.value.status_code == 400 assert "empty" in exc.value.detail.lower() async def test_validate_file_too_large(self): """Test rejection of oversized files.""" # Create 60MB file large_data = b"x" * (60 * 1024 * 1024) mock_file = AsyncMock(spec=UploadFile) mock_file.read = AsyncMock(return_value=large_data) mock_file.seek = AsyncMock() mock_file.filename = "large.jpg" with pytest.raises(HTTPException) as exc: await validate_image_file(mock_file) assert exc.value.status_code == 413 assert "too large" in exc.value.detail.lower() async def test_validate_invalid_extension(self): """Test rejection of invalid extensions.""" mock_file = AsyncMock(spec=UploadFile) mock_file.read = AsyncMock(return_value=b"fake image data") mock_file.seek = AsyncMock() mock_file.filename = "document.pdf" with pytest.raises(HTTPException) as exc: await validate_image_file(mock_file) assert exc.value.status_code == 400 assert "extension" in exc.value.detail.lower()