feat: Implement background extraction processor with concurrency control
- Added `ExtractionProcessor` class to handle extraction queue processing in the background. - Implemented methods for starting, stopping, and queuing extractions with concurrency limits. - Integrated logging for monitoring the processor's status and actions. - Created tests for the extraction processor to ensure functionality and error handling. test: Add unit tests for extraction API endpoints - Created tests for successful extraction creation, authentication checks, and processor status retrieval. - Ensured proper responses for authenticated and unauthenticated requests. test: Implement unit tests for extraction repository - Added tests for creating, retrieving, and updating extractions in the repository. - Mocked database interactions to validate repository behavior without actual database access. test: Add comprehensive tests for extraction service - Developed tests for extraction creation, service detection, and sound record creation. - Included tests for handling duplicate extractions and invalid URLs. test: Add unit tests for extraction background processor - Created tests for the `ExtractionProcessor` class to validate its behavior under various conditions. - Ensured proper handling of extraction queuing, processing, and completion callbacks. fix: Update OAuth service tests to use AsyncMock - Modified OAuth provider tests to use `AsyncMock` for mocking asynchronous HTTP requests.
This commit is contained in:
128
tests/repositories/test_extraction.py
Normal file
128
tests/repositories/test_extraction.py
Normal file
@@ -0,0 +1,128 @@
|
||||
"""Tests for extraction repository."""
|
||||
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
|
||||
import pytest
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
|
||||
from app.models.extraction import Extraction
|
||||
from app.repositories.extraction import ExtractionRepository
|
||||
|
||||
|
||||
class TestExtractionRepository:
|
||||
"""Test extraction repository."""
|
||||
|
||||
@pytest.fixture
|
||||
def mock_session(self):
|
||||
"""Create a mock session."""
|
||||
return Mock(spec=AsyncSession)
|
||||
|
||||
@pytest.fixture
|
||||
def extraction_repo(self, mock_session):
|
||||
"""Create an extraction repository with mock session."""
|
||||
return ExtractionRepository(mock_session)
|
||||
|
||||
def test_init(self, extraction_repo):
|
||||
"""Test repository initialization."""
|
||||
assert extraction_repo.session is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_extraction(self, extraction_repo):
|
||||
"""Test creating an extraction."""
|
||||
extraction_data = {
|
||||
"url": "https://www.youtube.com/watch?v=test",
|
||||
"user_id": 1,
|
||||
"service": "youtube",
|
||||
"service_id": "test123",
|
||||
"title": "Test Video",
|
||||
"status": "pending",
|
||||
}
|
||||
|
||||
# Mock the session operations
|
||||
mock_extraction = Extraction(**extraction_data, id=1)
|
||||
extraction_repo.session.add = Mock()
|
||||
extraction_repo.session.commit = AsyncMock()
|
||||
extraction_repo.session.refresh = AsyncMock()
|
||||
|
||||
# Mock the Extraction constructor to return our mock
|
||||
with pytest.MonkeyPatch().context() as m:
|
||||
m.setattr(
|
||||
"app.repositories.extraction.Extraction",
|
||||
lambda **kwargs: mock_extraction,
|
||||
)
|
||||
|
||||
result = await extraction_repo.create(extraction_data)
|
||||
|
||||
assert result == mock_extraction
|
||||
extraction_repo.session.add.assert_called_once()
|
||||
extraction_repo.session.commit.assert_called_once()
|
||||
extraction_repo.session.refresh.assert_called_once_with(mock_extraction)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_by_service_and_id(self, extraction_repo):
|
||||
"""Test getting extraction by service and service_id."""
|
||||
mock_result = Mock()
|
||||
mock_result.first.return_value = Extraction(
|
||||
id=1,
|
||||
service="youtube",
|
||||
service_id="test123",
|
||||
url="https://www.youtube.com/watch?v=test",
|
||||
user_id=1,
|
||||
status="pending",
|
||||
)
|
||||
|
||||
extraction_repo.session.exec = AsyncMock(return_value=mock_result)
|
||||
|
||||
result = await extraction_repo.get_by_service_and_id("youtube", "test123")
|
||||
|
||||
assert result is not None
|
||||
assert result.service == "youtube"
|
||||
assert result.service_id == "test123"
|
||||
extraction_repo.session.exec.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_pending_extractions(self, extraction_repo):
|
||||
"""Test getting pending extractions."""
|
||||
mock_extraction = Extraction(
|
||||
id=1,
|
||||
service="youtube",
|
||||
service_id="test123",
|
||||
url="https://www.youtube.com/watch?v=test",
|
||||
user_id=1,
|
||||
status="pending",
|
||||
)
|
||||
|
||||
mock_result = Mock()
|
||||
mock_result.all.return_value = [mock_extraction]
|
||||
|
||||
extraction_repo.session.exec = AsyncMock(return_value=mock_result)
|
||||
|
||||
result = await extraction_repo.get_pending_extractions()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "pending"
|
||||
extraction_repo.session.exec.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_extraction(self, extraction_repo):
|
||||
"""Test updating an extraction."""
|
||||
extraction = Extraction(
|
||||
id=1,
|
||||
service="youtube",
|
||||
service_id="test123",
|
||||
url="https://www.youtube.com/watch?v=test",
|
||||
user_id=1,
|
||||
status="pending",
|
||||
)
|
||||
|
||||
update_data = {"status": "completed", "sound_id": 42}
|
||||
|
||||
extraction_repo.session.commit = AsyncMock()
|
||||
extraction_repo.session.refresh = AsyncMock()
|
||||
|
||||
result = await extraction_repo.update(extraction, update_data)
|
||||
|
||||
assert result.status == "completed"
|
||||
assert result.sound_id == 42
|
||||
extraction_repo.session.commit.assert_called_once()
|
||||
extraction_repo.session.refresh.assert_called_once_with(extraction)
|
||||
Reference in New Issue
Block a user