Files
learningcircuit--local-deep…/tests/web/queue/test_queue_manager.py
T
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

347 lines
12 KiB
Python

"""
Tests for web/queue/manager.py
Tests cover:
- QueueManager.add_to_queue
- QueueManager.get_queue_position
- QueueManager.remove_from_queue
- QueueManager.get_user_queue
"""
from contextlib import contextmanager
from unittest.mock import MagicMock, patch
import pytest
from local_deep_research.database.session_context import DatabaseSessionError
def _mock_user_db_session(mock_session):
"""Create a mock context manager that yields the given session."""
@contextmanager
def _ctx(username=None, password=None):
yield mock_session
return _ctx
def _mock_user_db_session_error():
"""Create a mock context manager that raises DatabaseSessionError."""
@contextmanager
def _ctx(username=None, password=None):
raise DatabaseSessionError("No database connection")
yield # noqa: unreachable — needed for generator syntax
return _ctx
class TestQueueManagerAddToQueue:
"""Tests for QueueManager.add_to_queue method."""
def test_add_to_queue_success(self):
"""Test successful addition to queue."""
mock_session = MagicMock()
# Mock query chain for max position
mock_query = MagicMock()
mock_query.filter_by.return_value.scalar.return_value = 0
mock_session.query.return_value = mock_query
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
with patch(
"local_deep_research.web.queue.manager.queue_processor"
) as mock_processor:
from local_deep_research.web.queue.manager import (
QueueManager,
)
result = QueueManager.add_to_queue(
username="testuser",
research_id="test-id-123",
query="test query",
mode="detailed",
settings={"key": "value"},
)
assert result == 1
mock_session.add.assert_called_once()
mock_session.commit.assert_called_once()
mock_processor.notify_research_queued.assert_called_once_with(
"testuser", "test-id-123"
)
def test_add_to_queue_no_connection(self):
"""Test add_to_queue raises DatabaseSessionError when no connection."""
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session_error(),
):
from local_deep_research.web.queue.manager import QueueManager
with pytest.raises(DatabaseSessionError):
QueueManager.add_to_queue(
username="testuser",
research_id="test-id-123",
query="test query",
mode="detailed",
settings={},
)
def test_add_to_queue_with_existing_items(self):
"""Test add_to_queue with existing items in queue."""
mock_session = MagicMock()
# Mock query chain for max position - already has 3 items
mock_query = MagicMock()
mock_query.filter_by.return_value.scalar.return_value = 3
mock_session.query.return_value = mock_query
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
with patch("local_deep_research.web.queue.manager.queue_processor"):
from local_deep_research.web.queue.manager import (
QueueManager,
)
result = QueueManager.add_to_queue(
username="testuser",
research_id="test-id-456",
query="another query",
mode="quick",
settings={},
)
# Position should be 4 (max + 1)
assert result == 4
class TestQueueManagerGetQueuePosition:
"""Tests for QueueManager.get_queue_position method."""
def test_get_queue_position_success(self):
"""Test getting queue position successfully."""
mock_session = MagicMock()
# Mock queued research item
mock_queued = MagicMock()
mock_queued.position = 3
# Setup query chain
mock_query = MagicMock()
mock_filter = MagicMock()
mock_filter.first.return_value = mock_queued
mock_filter.count.return_value = 2 # 2 items ahead
mock_query.filter_by.return_value = mock_filter
mock_query.filter.return_value = mock_filter
mock_session.query.return_value = mock_query
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
from local_deep_research.web.queue.manager import QueueManager
result = QueueManager.get_queue_position(
username="testuser", research_id="test-id-123"
)
# Position should be ahead_count + 1
assert result == 3
def test_get_queue_position_not_found(self):
"""Test get_queue_position when research not in queue."""
mock_session = MagicMock()
mock_query = MagicMock()
mock_query.filter_by.return_value.first.return_value = None
mock_session.query.return_value = mock_query
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
from local_deep_research.web.queue.manager import QueueManager
result = QueueManager.get_queue_position(
username="testuser", research_id="nonexistent"
)
assert result is None
def test_get_queue_position_no_connection(self):
"""Test get_queue_position raises DatabaseSessionError when no connection."""
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session_error(),
):
from local_deep_research.web.queue.manager import QueueManager
with pytest.raises(DatabaseSessionError):
QueueManager.get_queue_position(
username="testuser", research_id="test-id-123"
)
class TestQueueManagerRemoveFromQueue:
"""Tests for QueueManager.remove_from_queue method."""
def test_remove_from_queue_success(self):
"""Test successful removal from queue."""
mock_session = MagicMock()
# Mock queued research item
mock_queued = MagicMock()
mock_queued.position = 2
mock_query = MagicMock()
mock_query.filter_by.return_value.first.return_value = mock_queued
mock_query.filter.return_value.update.return_value = None
mock_session.query.return_value = mock_query
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
from local_deep_research.web.queue.manager import QueueManager
result = QueueManager.remove_from_queue(
username="testuser", research_id="test-id-123"
)
assert result is True
mock_session.delete.assert_called_once_with(mock_queued)
mock_session.commit.assert_called_once()
def test_remove_from_queue_not_found(self):
"""Test remove_from_queue when research not in queue."""
mock_session = MagicMock()
mock_query = MagicMock()
mock_query.filter_by.return_value.first.return_value = None
mock_session.query.return_value = mock_query
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
from local_deep_research.web.queue.manager import QueueManager
result = QueueManager.remove_from_queue(
username="testuser", research_id="nonexistent"
)
assert result is False
def test_remove_from_queue_no_connection(self):
"""Test remove_from_queue raises DatabaseSessionError when no connection."""
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session_error(),
):
from local_deep_research.web.queue.manager import QueueManager
with pytest.raises(DatabaseSessionError):
QueueManager.remove_from_queue(
username="testuser", research_id="test-id-123"
)
class TestQueueManagerGetUserQueue:
"""Tests for QueueManager.get_user_queue method."""
def test_get_user_queue_success(self):
"""Test getting user queue successfully."""
mock_session = MagicMock()
# Mock queued items
from datetime import datetime
mock_item1 = MagicMock()
mock_item1.research_id = "id-1"
mock_item1.query = "query 1"
mock_item1.mode = "detailed"
mock_item1.position = 1
mock_item1.created_at = datetime(2025, 1, 1, 12, 0, 0)
mock_item1.is_processing = False
mock_item2 = MagicMock()
mock_item2.research_id = "id-2"
mock_item2.query = "query 2"
mock_item2.mode = "quick"
mock_item2.position = 2
mock_item2.created_at = None
mock_item2.is_processing = True
mock_research1 = MagicMock()
mock_research2 = MagicMock()
def query_side_effect(model):
q = MagicMock()
if "QueuedResearch" in str(model):
q.filter_by.return_value.order_by.return_value.all.return_value = [
mock_item1,
mock_item2,
]
else: # ResearchHistory
# Return research on first call, then second
q.filter_by.return_value.first.side_effect = [
mock_research1,
mock_research2,
]
return q
mock_session.query.side_effect = query_side_effect
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
from local_deep_research.web.queue.manager import QueueManager
result = QueueManager.get_user_queue(username="testuser")
assert len(result) == 2
assert result[0]["research_id"] == "id-1"
assert result[0]["query"] == "query 1"
assert result[0]["mode"] == "detailed"
assert result[0]["position"] == 1
assert result[0]["is_processing"] is False
assert result[1]["research_id"] == "id-2"
assert result[1]["created_at"] is None
def test_get_user_queue_empty(self):
"""Test get_user_queue when queue is empty."""
mock_session = MagicMock()
mock_query = MagicMock()
mock_query.filter_by.return_value.order_by.return_value.all.return_value = []
mock_session.query.return_value = mock_query
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session(mock_session),
):
from local_deep_research.web.queue.manager import QueueManager
result = QueueManager.get_user_queue(username="testuser")
assert result == []
def test_get_user_queue_no_connection(self):
"""Test get_user_queue raises DatabaseSessionError when no connection."""
with patch(
"local_deep_research.web.queue.manager.get_user_db_session",
_mock_user_db_session_error(),
):
from local_deep_research.web.queue.manager import QueueManager
with pytest.raises(DatabaseSessionError):
QueueManager.get_user_queue(username="testuser")