""" Tests for the UIManager class. """ import os import pytest import tkinter as tk from tkinter import ttk from unittest.mock import Mock, patch, MagicMock from datetime import datetime 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_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 result = ui_manager.setup_icon("test_icon.png") assert result is True mock_image_open.assert_called_once_with("test_icon.png") mock_image.resize.assert_called_once_with(size=(32, 32), resample=Mock()) ui_manager.logger.info.assert_called_with("Trying to load icon from: test_icon.png") @patch('os.path.exists') def test_setup_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_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_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_icon("test_icon.png") assert result is False ui_manager.logger.error.assert_called_with("Error setting up icon: Test error") @patch('sys._MEIPASS', '/test/bundle/path', create=True) @patch('os.path.exists') @patch('PIL.Image.open') def test_setup_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 result = ui_manager.setup_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"] for medicine in expected_medicines: assert medicine in medicine_vars assert isinstance(medicine_vars[medicine], list) assert len(medicine_vars[medicine]) == 2 # IntVar and Spinbox assert isinstance(medicine_vars[medicine][0], tk.IntVar) assert isinstance(medicine_vars[medicine][1], ttk.Spinbox) @patch('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 = "2024-01-15" main_frame = ttk.Frame(root_window) input_ui = ui_manager.create_input_frame(main_frame) assert input_ui["date_var"].get() == "2024-01-15" 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", "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 buttons were added (basic structure test) children = frame.winfo_children() assert len(children) >= 2 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_create_scale_with_var(self, ui_manager, root_window): """Test creation of scale widget with variable.""" frame = ttk.Frame(root_window) var = tk.IntVar() scale = ui_manager._create_scale_with_var(frame, var, "Test Label", 0, 0) assert isinstance(scale, ttk.Scale) def test_create_spinbox_with_var(self, ui_manager, root_window): """Test creation of spinbox widget with variable.""" frame = ttk.Frame(root_window) var = tk.IntVar() result = ui_manager._create_spinbox_with_var(frame, var, "Test Label", 0, 0) assert isinstance(result, list) assert len(result) == 2 assert isinstance(result[0], tk.IntVar) assert isinstance(result[1], ttk.Spinbox) 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 @patch('tkinter.messagebox.showerror') def test_error_handling_in_setup_icon(self, mock_showerror, ui_manager): """Test error handling in setup_icon method.""" with patch('PIL.Image.open') as mock_open: mock_open.side_effect = Exception("Image error") result = ui_manager.setup_icon("test.png") assert result is False ui_manager.logger.error.assert_called()