fix(test): update url_upload test mocks from requests to httpx

The tests were patching `app.api.url_upload.requests.get` but the module
uses `httpx.AsyncClient`. Updated 4 tests across 2 files to use the
correct `httpx.AsyncClient.stream` mock pattern with `AsyncMock`,
matching the existing working tests in test_url_upload.py.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-16 13:03:18 +00:00
parent 7bd667e271
commit 0444b14d87
2 changed files with 50 additions and 22 deletions
+13 -6
View File
@@ -5,7 +5,7 @@ in files listed in the 90%+ coverage push issue.
Each test class maps to a single source module. Each test class maps to a single source module.
""" """
from unittest.mock import MagicMock, Mock, patch from unittest.mock import AsyncMock, MagicMock, Mock, patch
import pytest import pytest
from dropbox.exceptions import ApiError from dropbox.exceptions import ApiError
@@ -547,16 +547,23 @@ class TestURLUploadAdditionalCoverage:
assert validate_file_type("", "noextfile") is False assert validate_file_type("", "noextfile") is False
@patch("app.api.url_upload.requests.get") @patch("app.api.url_upload.httpx.AsyncClient.stream")
@patch("app.api.url_upload.process_document") @patch("app.api.url_upload.process_document")
def test_process_url_empty_url_path(self, mock_process, mock_get, client): def test_process_url_empty_url_path(self, mock_process, mock_stream, client):
"""URL with empty path defaults to 'download' filename (line 197-202).""" """URL with empty path defaults to 'download' filename (line 197-202)."""
mock_response = Mock() mock_response = AsyncMock()
mock_response.status_code = 200 mock_response.status_code = 200
mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "50"} mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "50"}
mock_response.iter_content = Mock(return_value=[b"PDF"])
async def mock_aiter_bytes(chunk_size=None):
yield b"PDF"
mock_response.aiter_bytes = mock_aiter_bytes
mock_response.raise_for_status = Mock() mock_response.raise_for_status = Mock()
mock_get.return_value = mock_response
mock_context = AsyncMock()
mock_context.__aenter__.return_value = mock_response
mock_stream.return_value = mock_context
mock_task = Mock() mock_task = Mock()
mock_task.id = "task-empty-path" mock_task.id = "task-empty-path"
+37 -16
View File
@@ -5,7 +5,7 @@ This test module serves as a regression prevention mechanism to ensure
that endpoints remain accessible after code refactoring or reorganization. that endpoints remain accessible after code refactoring or reorganization.
""" """
from unittest.mock import Mock, patch from unittest.mock import AsyncMock, Mock, patch
import pytest import pytest
@@ -17,17 +17,24 @@ TEST_URL = "https://example.com/test.pdf"
class TestEndpointRegistration: class TestEndpointRegistration:
"""Verify that critical API endpoints are registered in the FastAPI app""" """Verify that critical API endpoints are registered in the FastAPI app"""
@patch("app.api.url_upload.requests.get") @patch("app.api.url_upload.httpx.AsyncClient.stream")
@patch("app.api.url_upload.process_document") @patch("app.api.url_upload.process_document")
def test_process_url_endpoint_exists(self, mock_process_document, mock_requests_get, client): def test_process_url_endpoint_exists(self, mock_process_document, mock_stream, client):
"""Verify that /api/process-url endpoint is registered and accessible""" """Verify that /api/process-url endpoint is registered and accessible"""
# Mock successful download to prevent actual HTTP requests # Mock successful download to prevent actual HTTP requests
mock_response = Mock() mock_response = AsyncMock()
mock_response.status_code = 200 mock_response.status_code = 200
mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "1024"} mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "1024"}
mock_response.iter_content = Mock(return_value=[b"PDF content"])
async def mock_aiter_bytes(chunk_size=None):
yield b"PDF content"
mock_response.aiter_bytes = mock_aiter_bytes
mock_response.raise_for_status = Mock() mock_response.raise_for_status = Mock()
mock_requests_get.return_value = mock_response
mock_context = AsyncMock()
mock_context.__aenter__.return_value = mock_response
mock_stream.return_value = mock_context
# Mock Celery task # Mock Celery task
mock_task = Mock() mock_task = Mock()
@@ -46,17 +53,24 @@ class TestEndpointRegistration:
"Verify that url_upload_router is included in app/api/__init__.py" "Verify that url_upload_router is included in app/api/__init__.py"
) )
@patch("app.api.url_upload.requests.get") @patch("app.api.url_upload.httpx.AsyncClient.stream")
@patch("app.api.url_upload.process_document") @patch("app.api.url_upload.process_document")
def test_process_url_endpoint_accepts_post(self, mock_process_document, mock_requests_get, client): def test_process_url_endpoint_accepts_post(self, mock_process_document, mock_stream, client):
"""Verify that /api/process-url accepts POST requests""" """Verify that /api/process-url accepts POST requests"""
# Mock successful download to prevent actual HTTP requests # Mock successful download to prevent actual HTTP requests
mock_response = Mock() mock_response = AsyncMock()
mock_response.status_code = 200 mock_response.status_code = 200
mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "1024"} mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "1024"}
mock_response.iter_content = Mock(return_value=[b"PDF content"])
async def mock_aiter_bytes(chunk_size=None):
yield b"PDF content"
mock_response.aiter_bytes = mock_aiter_bytes
mock_response.raise_for_status = Mock() mock_response.raise_for_status = Mock()
mock_requests_get.return_value = mock_response
mock_context = AsyncMock()
mock_context.__aenter__.return_value = mock_response
mock_stream.return_value = mock_context
# Mock Celery task # Mock Celery task
mock_task = Mock() mock_task = Mock()
@@ -72,17 +86,24 @@ class TestEndpointRegistration:
"Verify the endpoint is decorated with @router.post()" "Verify the endpoint is decorated with @router.post()"
) )
@patch("app.api.url_upload.requests.get") @patch("app.api.url_upload.httpx.AsyncClient.stream")
@patch("app.api.url_upload.process_document") @patch("app.api.url_upload.process_document")
def test_api_router_included_in_app(self, mock_process_document, mock_requests_get, client): def test_api_router_included_in_app(self, mock_process_document, mock_stream, client):
"""Verify that the main API router is included in the FastAPI app""" """Verify that the main API router is included in the FastAPI app"""
# Mock successful download for /api/process-url test # Mock successful download for /api/process-url test
mock_response = Mock() mock_response = AsyncMock()
mock_response.status_code = 200 mock_response.status_code = 200
mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "1024"} mock_response.headers = {"Content-Type": "application/pdf", "Content-Length": "1024"}
mock_response.iter_content = Mock(return_value=[b"PDF content"])
async def mock_aiter_bytes(chunk_size=None):
yield b"PDF content"
mock_response.aiter_bytes = mock_aiter_bytes
mock_response.raise_for_status = Mock() mock_response.raise_for_status = Mock()
mock_requests_get.return_value = mock_response
mock_context = AsyncMock()
mock_context.__aenter__.return_value = mock_response
mock_stream.return_value = mock_context
# Mock Celery task # Mock Celery task
mock_task = Mock() mock_task = Mock()