"""Behavioral tests for notify_queue_processor(). The existing test_queue_middleware_extended.py only checks importability (``assert callable(...)``). These tests exercise actual request-time logic: skip conditions, session lookups, queue processor calls, and error handling. """ from unittest.mock import MagicMock, patch import flask import pytest @pytest.fixture() def app(): """Minimal Flask app for request context.""" app = flask.Flask(__name__) app.secret_key = "test" return app class TestNotifyQueueProcessor: """Tests for notify_queue_processor() before_request handler.""" def test_skips_when_should_skip_returns_true(self, app): """Early return when should_skip_queue_checks() is True.""" with app.test_request_context(): with patch( "local_deep_research.web.auth.queue_middleware_v2.should_skip_queue_checks", return_value=True, ): from local_deep_research.web.auth.queue_middleware_v2 import ( notify_queue_processor, ) # Should not touch session at all with patch( "local_deep_research.web.auth.queue_middleware_v2.session" ) as mock_session: notify_queue_processor() mock_session.get.assert_not_called() def test_noop_when_username_missing(self, app): """No queue processing when session lacks username.""" with app.test_request_context(): with ( patch( "local_deep_research.web.auth.queue_middleware_v2.should_skip_queue_checks", return_value=False, ), patch( "local_deep_research.web.auth.queue_middleware_v2.session", {"session_id": "sid123"}, ), ): from local_deep_research.web.auth.queue_middleware_v2 import ( notify_queue_processor, ) notify_queue_processor() # No assertion on queue_processor — it shouldn't be imported def test_noop_when_session_id_missing(self, app): """No queue processing when session lacks session_id.""" with app.test_request_context(): with ( patch( "local_deep_research.web.auth.queue_middleware_v2.should_skip_queue_checks", return_value=False, ), patch( "local_deep_research.web.auth.queue_middleware_v2.session", {"username": "alice"}, ), ): from local_deep_research.web.auth.queue_middleware_v2 import ( notify_queue_processor, ) notify_queue_processor() def test_noop_when_db_not_connected(self, app): """No queue calls when user's database is not connected.""" with app.test_request_context(): with ( patch( "local_deep_research.web.auth.queue_middleware_v2.should_skip_queue_checks", return_value=False, ), patch( "local_deep_research.web.auth.queue_middleware_v2.session", {"username": "alice", "session_id": "sid123"}, ), patch( "local_deep_research.web.auth.queue_middleware_v2.db_manager" ) as mock_db, ): mock_db.is_user_connected.return_value = False from local_deep_research.web.auth.queue_middleware_v2 import ( notify_queue_processor, ) notify_queue_processor() def test_calls_queue_processor_on_success(self, app): """Full success path: notifies activity and processes request.""" mock_processor = MagicMock() mock_processor.process_user_request.return_value = 2 with app.test_request_context(): with ( patch( "local_deep_research.web.auth.queue_middleware_v2.should_skip_queue_checks", return_value=False, ), patch( "local_deep_research.web.auth.queue_middleware_v2.session", {"username": "alice", "session_id": "sid123"}, ), patch( "local_deep_research.web.auth.queue_middleware_v2.db_manager" ) as mock_db, patch.dict( "sys.modules", { "local_deep_research.web.queue.processor_v2": MagicMock( queue_processor=mock_processor ) }, ), ): mock_db.is_user_connected.return_value = True from local_deep_research.web.auth.queue_middleware_v2 import ( notify_queue_processor, ) notify_queue_processor() mock_processor.notify_user_activity.assert_called_once_with( "alice", "sid123" ) mock_processor.process_user_request.assert_called_once_with( "alice", "sid123" ) def test_zero_queued_items_no_debug_log(self, app): """When process_user_request returns 0, no debug log emitted.""" mock_processor = MagicMock() mock_processor.process_user_request.return_value = 0 with app.test_request_context(): with ( patch( "local_deep_research.web.auth.queue_middleware_v2.should_skip_queue_checks", return_value=False, ), patch( "local_deep_research.web.auth.queue_middleware_v2.session", {"username": "alice", "session_id": "sid123"}, ), patch( "local_deep_research.web.auth.queue_middleware_v2.db_manager" ) as mock_db, patch.dict( "sys.modules", { "local_deep_research.web.queue.processor_v2": MagicMock( queue_processor=mock_processor ) }, ), patch( "local_deep_research.web.auth.queue_middleware_v2.logger" ) as mock_logger, ): mock_db.is_user_connected.return_value = True from local_deep_research.web.auth.queue_middleware_v2 import ( notify_queue_processor, ) notify_queue_processor() mock_logger.debug.assert_not_called() def test_exception_caught_silently(self, app): """Exceptions in queue processing must not propagate.""" mock_processor = MagicMock() mock_processor.notify_user_activity.side_effect = RuntimeError("boom") with app.test_request_context(): with ( patch( "local_deep_research.web.auth.queue_middleware_v2.should_skip_queue_checks", return_value=False, ), patch( "local_deep_research.web.auth.queue_middleware_v2.session", {"username": "alice", "session_id": "sid123"}, ), patch( "local_deep_research.web.auth.queue_middleware_v2.db_manager" ) as mock_db, patch.dict( "sys.modules", { "local_deep_research.web.queue.processor_v2": MagicMock( queue_processor=mock_processor ) }, ), ): mock_db.is_user_connected.return_value = True from local_deep_research.web.auth.queue_middleware_v2 import ( notify_queue_processor, ) # Must not raise despite RuntimeError in notify_user_activity notify_queue_processor()