""" Tests for the UIManager class. """ import os import pytest import tkinter as tk from tkinter import ttk from unittest.mock import Mock, patch import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) from src.ui_manager import UIManager class TestUIManager: """Test cases for the UIManager class.""" @pytest.fixture def root_window(self): """Create a root window for testing.""" root = tk.Tk() yield root root.destroy() @pytest.fixture def ui_manager(self, root_window, mock_logger): """Create a UIManager instance for testing.""" return UIManager(root_window, mock_logger) def test_init(self, root_window, mock_logger): """Test UIManager initialization.""" ui = UIManager(root_window, mock_logger) assert ui.root == root_window assert ui.logger == mock_logger @patch('os.path.exists') @patch('PIL.Image.open') def test_setup_application_icon_success(self, mock_image_open, mock_exists, ui_manager): """Test successful icon setup.""" mock_exists.return_value = True mock_image = Mock() mock_image.resize.return_value = mock_image mock_image_open.return_value = mock_image with patch('PIL.ImageTk.PhotoImage') as mock_photo: mock_photo_instance = Mock() mock_photo.return_value = mock_photo_instance with patch.object(ui_manager.root, 'iconphoto') as mock_iconphoto, \ patch.object(ui_manager.root, 'wm_iconphoto') as mock_wm_iconphoto: result = ui_manager.setup_application_icon("test_icon.png") assert result is True mock_image_open.assert_called_once_with("test_icon.png") mock_image.resize.assert_called_once() ui_manager.logger.info.assert_called_with("Trying to load icon from: test_icon.png") @patch('os.path.exists') def test_setup_application_icon_file_not_found(self, mock_exists, ui_manager): """Test icon setup when file is not found.""" mock_exists.return_value = False result = ui_manager.setup_application_icon("nonexistent_icon.png") assert result is False ui_manager.logger.warning.assert_called_with("Icon file not found at nonexistent_icon.png") @patch('os.path.exists') @patch('PIL.Image.open') def test_setup_application_icon_exception(self, mock_image_open, mock_exists, ui_manager): """Test icon setup with exception.""" mock_exists.return_value = True mock_image_open.side_effect = Exception("Test error") result = ui_manager.setup_application_icon("test_icon.png") assert result is False ui_manager.logger.error.assert_called_with("Error setting icon: Test error") @patch('sys._MEIPASS', '/test/bundle/path', create=True) @patch('os.path.exists') @patch('PIL.Image.open') def test_setup_application_icon_pyinstaller_bundle(self, mock_image_open, mock_exists, ui_manager): """Test icon setup in PyInstaller bundle.""" # Mock exists to return False for original path, True for bundle path def mock_exists_side_effect(path): if 'test_icon.png' in path and '/test/bundle/path' in path: return True return False mock_exists.side_effect = mock_exists_side_effect mock_image = Mock() mock_image.resize.return_value = mock_image mock_image_open.return_value = mock_image with patch('PIL.ImageTk.PhotoImage') as mock_photo: mock_photo_instance = Mock() mock_photo.return_value = mock_photo_instance with patch.object(ui_manager.root, 'iconphoto') as mock_iconphoto, \ patch.object(ui_manager.root, 'wm_iconphoto') as mock_wm_iconphoto: result = ui_manager.setup_application_icon("test_icon.png") assert result is True ui_manager.logger.info.assert_called_with("Found icon in PyInstaller bundle: /test/bundle/path/test_icon.png") def test_create_graph_frame(self, ui_manager, root_window): """Test creation of graph frame.""" main_frame = ttk.Frame(root_window) graph_frame = ui_manager.create_graph_frame(main_frame) assert isinstance(graph_frame, ttk.LabelFrame) assert graph_frame.winfo_parent() == str(main_frame) def test_create_input_frame(self, ui_manager, root_window): """Test creation of input frame.""" main_frame = ttk.Frame(root_window) input_ui = ui_manager.create_input_frame(main_frame) assert isinstance(input_ui, dict) assert "frame" in input_ui assert "symptom_vars" in input_ui assert "medicine_vars" in input_ui assert "note_var" in input_ui assert "date_var" in input_ui assert isinstance(input_ui["frame"], ttk.LabelFrame) assert isinstance(input_ui["symptom_vars"], dict) assert isinstance(input_ui["medicine_vars"], dict) assert isinstance(input_ui["note_var"], tk.StringVar) assert isinstance(input_ui["date_var"], tk.StringVar) def test_create_input_frame_symptom_vars(self, ui_manager, root_window): """Test that symptom variables are created correctly.""" main_frame = ttk.Frame(root_window) input_ui = ui_manager.create_input_frame(main_frame) symptom_vars = input_ui["symptom_vars"] expected_symptoms = ["depression", "anxiety", "sleep", "appetite"] for symptom in expected_symptoms: assert symptom in symptom_vars assert isinstance(symptom_vars[symptom], tk.IntVar) def test_create_input_frame_medicine_vars(self, ui_manager, root_window): """Test that medicine variables are created correctly.""" main_frame = ttk.Frame(root_window) input_ui = ui_manager.create_input_frame(main_frame) medicine_vars = input_ui["medicine_vars"] expected_medicines = ["bupropion", "hydroxyzine", "gabapentin", "propranolol", "quetiapine"] for medicine in expected_medicines: assert medicine in medicine_vars assert isinstance(medicine_vars[medicine], tuple) assert len(medicine_vars[medicine]) == 2 # IntVar and display text assert isinstance(medicine_vars[medicine][0], tk.IntVar) assert isinstance(medicine_vars[medicine][1], str) @patch('src.ui_manager.datetime') def test_create_input_frame_default_date(self, mock_datetime, ui_manager, root_window): """Test that default date is set to today.""" mock_datetime.now.return_value.strftime.return_value = "07/30/2025" main_frame = ttk.Frame(root_window) input_ui = ui_manager.create_input_frame(main_frame) # The actual date will be today's date, not the mocked value # because the datetime import is within the function assert input_ui["date_var"].get() == "07/30/2025" def test_create_table_frame(self, ui_manager, root_window): """Test creation of table frame.""" main_frame = ttk.Frame(root_window) table_ui = ui_manager.create_table_frame(main_frame) assert isinstance(table_ui, dict) assert "tree" in table_ui assert isinstance(table_ui["tree"], ttk.Treeview) def test_create_table_frame_columns(self, ui_manager, root_window): """Test that table columns are set up correctly.""" main_frame = ttk.Frame(root_window) table_ui = ui_manager.create_table_frame(main_frame) tree = table_ui["tree"] expected_columns = [ "Date", "Depression", "Anxiety", "Sleep", "Appetite", "Bupropion", "Hydroxyzine", "Gabapentin", "Propranolol", "Quetiapine", "Note" ] # Check that columns are configured assert tree["columns"] == tuple(expected_columns) def test_add_buttons(self, ui_manager, root_window): """Test adding buttons to a frame.""" frame = ttk.Frame(root_window) buttons_config = [ {"text": "Test Button 1", "command": lambda: None}, {"text": "Test Button 2", "command": lambda: None, "fill": "x"}, ] ui_manager.add_buttons(frame, buttons_config) # Check that a button frame was added children = frame.winfo_children() assert len(children) >= 1 # At least the button frame should be added def test_create_edit_window(self, ui_manager): """Test creation of edit window.""" values = ("2024-01-01", "3", "2", "4", "3", "1", "0", "2", "1", "Test note") callbacks = { "save": lambda win, *args: None, "delete": lambda win: None } edit_window = ui_manager.create_edit_window(values, callbacks) assert isinstance(edit_window, tk.Toplevel) assert edit_window.title() == "Edit Entry" def test_create_edit_window_widgets(self, ui_manager): """Test that edit window contains expected widgets.""" values = ("2024-01-01", "3", "2", "4", "3", "1", "0", "2", "1", "Test note") callbacks = { "save": lambda win, *args: None, "delete": lambda win: None } edit_window = ui_manager.create_edit_window(values, callbacks) # Check that window has children (widgets) children = edit_window.winfo_children() assert len(children) > 0 def test_create_edit_window_initial_values(self, ui_manager): """Test that edit window is populated with initial values.""" values = ("2024-01-01", "3", "2", "4", "3", "1", "0", "2", "1", "Test note") callbacks = { "save": lambda win, *args: None, "delete": lambda win: None } edit_window = ui_manager.create_edit_window(values, callbacks) # The window should be created successfully assert edit_window is not None # More detailed testing would require examining the internal widgets def test_frame_positioning(self, ui_manager, root_window): """Test that frames are positioned correctly.""" main_frame = ttk.Frame(root_window) # Create multiple frames graph_frame = ui_manager.create_graph_frame(main_frame) input_ui = ui_manager.create_input_frame(main_frame) table_ui = ui_manager.create_table_frame(main_frame) # All frames should be created successfully assert graph_frame is not None assert input_ui["frame"] is not None assert table_ui["tree"] is not None def test_widget_configuration(self, ui_manager, root_window): """Test that widgets are configured with appropriate properties.""" main_frame = ttk.Frame(root_window) input_ui = ui_manager.create_input_frame(main_frame) # Check that variables have default values for var in input_ui["symptom_vars"].values(): assert var.get() == 0 for medicine_data in input_ui["medicine_vars"].values(): assert medicine_data[0].get() == 0 # IntVar should be 0 @patch('tkinter.messagebox.showerror') def test_error_handling_in_setup_application_icon(self, mock_showerror, ui_manager): """Test error handling in setup_application_icon method.""" with patch('PIL.Image.open') as mock_open: mock_open.side_effect = Exception("Image error") result = ui_manager.setup_application_icon("test.png") assert result is False ui_manager.logger.error.assert_called()