import pytest from unittest.mock import MagicMock, patch from src.gui_2 import App from src.events import UserRequestEvent @pytest.fixture def mock_gui() -> App: with ( patch('src.app_controller.AppController.load_config', return_value={ "ai": {"provider": "gemini", "model": "model-1"}, "projects": {"paths": [], "active": ""}, "gui": {"show_windows": {}} }), patch('src.project_manager.load_project', return_value={}), patch('src.project_manager.migrate_from_legacy_config', return_value={}), patch('src.project_manager.save_project'), patch('src.session_logger.open_session'), patch('src.session_logger.reset_session'), patch('src.app_controller.AppController._init_ai_and_hooks'), patch('src.app_controller.AppController._fetch_models') ): gui = App() return gui def test_handle_generate_send_pushes_event(mock_gui: App) -> None: mock_gui.controller._do_generate = MagicMock(return_value=( "full_md", "path", [], "stable_md", "disc_text" )) mock_gui.controller.ui_ai_input = "test prompt" mock_gui.controller.ui_files_base_dir = "." # Mock event_queue.put mock_gui.controller.event_queue.put = MagicMock() # No need to mock asyncio.run_coroutine_threadsafe now, it's a standard thread # Production code: self._io_pool.submit_io(worker) (see # src/app_controller.py:_handle_generate_send). Patch submit_io # to capture the worker function instead of the io_pool's # background thread, so we can run the worker synchronously. with patch.object(mock_gui.controller, 'submit_io') as mock_submit: # Verify a job was submitted to the io_pool mock_gui.controller._handle_generate_send() mock_gui.controller._handle_generate_send() print(f"[DBG] mock_submit.called: {mock_submit.called}", file=__import__('sys').stderr) target_worker = mock_submit.call_args[0][0] target_worker() # Verify the call to event_queue.put occurred. mock_gui.controller.event_queue.put.assert_called_once() args, kwargs = mock_gui.controller.event_queue.put.call_args assert args[0] == "user_request" event = args[1] assert isinstance(event, UserRequestEvent) assert event.prompt == "test prompt" assert event.stable_md == "stable_md" assert event.disc_text == "disc_text" assert event.base_dir == "." def test_user_request_event_payload() -> None: payload = UserRequestEvent( prompt="hello", stable_md="md", file_items=[], disc_text="disc", base_dir="." ) d = payload.to_dict() assert d["prompt"] == "hello" assert d["stable_md"] == "md" assert d["file_items"] == [] assert d["disc_text"] == "disc" assert d["base_dir"] == "." def test_sync_event_queue() -> None: from src.events import SyncEventQueue q = SyncEventQueue() q.put("test_event", {"data": 123}) name, payload = q.get() assert name == "test_event" assert payload["data"] == 123