LarsHoliday / tests /test_gui_integration.py
PHhTTPS's picture
feat(gui): Integrate HollandVacationAgent with threading
62866be
import unittest
from unittest.mock import MagicMock, patch
import sys
import os
import threading
# Add project root to path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
class TestGUIIntegration(unittest.TestCase):
def test_search_integration(self):
"""
Test that the GUI integrates with the agent and runs search in a thread.
"""
# Mock ALL the things
with patch('tkinter.Tk'), \
patch('tkinter.ttk.Style'), \
patch('tkinter.ttk.Frame'), \
patch('tkinter.ttk.Label'), \
patch('tkinter.ttk.Entry'), \
patch('tkinter.ttk.Checkbutton'), \
patch('tkinter.ttk.Button'), \
patch('tkinter.StringVar', side_effect=lambda value=None: MagicMock(get=MagicMock(return_value=value))) as mock_string_var, \
patch('tkinter.IntVar', side_effect=lambda value=None: MagicMock(get=MagicMock(return_value=value))) as mock_int_var, \
patch('tkinter.BooleanVar', side_effect=lambda value=None: MagicMock(get=MagicMock(return_value=value))), \
patch('tkinter.messagebox.showerror'), \
patch('threading.Thread') as mock_thread, \
patch('holland_agent.HollandVacationAgent') as mock_agent_class:
if 'gui_app' in sys.modules:
del sys.modules['gui_app']
from gui_app import HollandVacationApp
app = HollandVacationApp()
# Setup valid inputs so validation passes
app.cities_var.get.return_value = "Amsterdam"
app.checkin_var.get.return_value = "2026-02-15"
app.checkout_var.get.return_value = "2026-02-22"
app.adults_var.get.return_value = 2
app.budget_var.get.return_value = 200
app.allow_dogs_var.get.return_value = True
# Verify agent initialization
mock_agent_class.assert_called()
# Call start_search
app.start_search()
# Verify it created a thread
mock_thread.assert_called()
# Verify the thread target is the wrapper method
args, kwargs = mock_thread.call_args
target = kwargs.get('target')
thread_args = kwargs.get('args')
self.assertTrue(target, "Thread should have a target")
# Simulate the thread running the target
# We assume the target is app.run_search_thread or similar
# And it should call agent.find_best_deals
# Let's inspect what 'target' is
# It should be a bound method
self.assertTrue(callable(target))
# Execute the target function to verify it calls the agent
# We need to mock asyncio.run inside it probably?
# Or assume agent.find_best_deals is async and we use asyncio.run
with patch('asyncio.run') as mock_asyncio_run:
target(*thread_args)
# Check if agent search was called
# agent instance is mock_agent_class.return_value
agent_instance = mock_agent_class.return_value
# We expect asyncio.run to be called with a coroutine
mock_asyncio_run.assert_called()
# Can't easily check exactly what coroutine was passed to run without more complex mocking,
# but we can verify that finding deals is part of the flow.
if __name__ == '__main__':
unittest.main()