86 lines
2.9 KiB
Python
86 lines
2.9 KiB
Python
"""Test error handling in versions router."""
|
|
|
|
import pytest
|
|
from unittest.mock import AsyncMock, patch, MagicMock
|
|
import httpx
|
|
|
|
from rehearsalhub.routers.versions import _download_with_retry
|
|
from rehearsalhub.storage.nextcloud import NextcloudClient
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_download_with_retry_success():
|
|
"""Test successful download on first attempt."""
|
|
mock_storage = MagicMock()
|
|
mock_storage.download = AsyncMock(return_value=b"test_data")
|
|
|
|
result = await _download_with_retry(mock_storage, "test_path")
|
|
assert result == b"test_data"
|
|
mock_storage.download.assert_awaited_once_with("test_path")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_download_with_retry_connection_error():
|
|
"""Test retry logic on connection errors."""
|
|
mock_storage = MagicMock()
|
|
mock_storage.download = AsyncMock(side_effect=httpx.ConnectError("Connection failed"))
|
|
|
|
with pytest.raises(httpx.ConnectError):
|
|
await _download_with_retry(mock_storage, "test_path", max_retries=2)
|
|
|
|
# Should retry max_retries times
|
|
assert mock_storage.download.await_count == 2
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_download_with_retry_server_error():
|
|
"""Test retry logic on 500 server errors."""
|
|
mock_storage = MagicMock()
|
|
|
|
# Create a mock response with 500 status
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 500
|
|
mock_response.text = "Internal Server Error"
|
|
|
|
mock_storage.download = AsyncMock(side_effect=httpx.HTTPStatusError("Server error", request=MagicMock(), response=mock_response))
|
|
|
|
with pytest.raises(httpx.HTTPStatusError):
|
|
await _download_with_retry(mock_storage, "test_path", max_retries=2)
|
|
|
|
# Should retry max_retries times for 5xx errors
|
|
assert mock_storage.download.await_count == 2
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_download_with_retry_client_error():
|
|
"""Test no retry on 4xx client errors."""
|
|
mock_storage = MagicMock()
|
|
|
|
# Create a mock response with 404 status
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 404
|
|
mock_response.text = "Not Found"
|
|
|
|
mock_storage.download = AsyncMock(side_effect=httpx.HTTPStatusError("Not found", request=MagicMock(), response=mock_response))
|
|
|
|
with pytest.raises(httpx.HTTPStatusError):
|
|
await _download_with_retry(mock_storage, "test_path")
|
|
|
|
# Should not retry on 4xx errors
|
|
assert mock_storage.download.await_count == 1
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_download_with_retry_fallback_error():
|
|
"""Test fallback HTTPException when no specific error is caught."""
|
|
mock_storage = MagicMock()
|
|
mock_storage.download = AsyncMock(side_effect=Exception("Unknown error"))
|
|
|
|
from fastapi import HTTPException
|
|
|
|
with pytest.raises(Exception) as exc_info:
|
|
await _download_with_retry(mock_storage, "test_path")
|
|
|
|
# Should raise the original exception for unknown errors
|
|
assert str(exc_info.value) == "Unknown error"
|