294 lines
11 KiB
Python
294 lines
11 KiB
Python
"""
|
|
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()
|