prole/tests/test_service_layer_navigation.py

94 lines
3.6 KiB
Python

import sys
from unittest.mock import patch, MagicMock
import pytest
from pathlib import Path
# Mock tkinter and other GUI/macOS specific imports
sys.modules['tkinter'] = MagicMock()
sys.modules['tkinter.ttk'] = MagicMock()
sys.modules['tkinter.scrolledtext'] = MagicMock()
sys.modules['tkinter.messagebox'] = MagicMock()
sys.modules['Foundation'] = MagicMock()
sys.modules['AppKit'] = MagicMock()
sys.modules['PIL'] = MagicMock()
sys.modules['PIL.Image'] = MagicMock()
sys.modules['PIL.ImageTk'] = MagicMock()
import install
from install import ProleInstaller
@pytest.fixture
def mock_installer(tmp_path):
test_cfg_src = Path(__file__).parent / "fixtures" / "test-prole.cfg"
cfg_path = tmp_path / "prole.cfg"
cfg_path.write_text(test_cfg_src.read_text())
with patch('install.tk.Tk'), \
patch('install.tk.Frame'), \
patch('install.tk.Canvas'), \
patch('install.tk.Label'), \
patch('install.tk.Button'), \
patch('install.tk.StringVar'), \
patch('install.tk.BooleanVar'), \
patch('install.tk.IntVar'), \
patch('install.ttk.Style'), \
patch('install.Path.exists', return_value=True):
root = MagicMock()
root.winfo_screenwidth.return_value = 1920
root.winfo_screenheight.return_value = 1080
app = ProleInstaller(root, config_path=str(cfg_path))
app.bg_canvas.winfo_width.return_value = 1000
return app
def test_service_layer_navigation_pause(mock_installer):
# Go to init_cluster
mock_installer.show_page('init_cluster')
# Mock cluster ready
with patch.object(mock_installer, '_cluster_ready_for_navigation', return_value=True):
# Click Next - should NOT go to init_password yet, but show overlay
with patch.object(mock_installer, '_run_service_layer_overlay') as mock_overlay:
mock_installer.on_next()
mock_overlay.assert_called_once()
assert mock_installer.pages[mock_installer.page_index][0] == 'init_cluster'
def test_service_layer_overlay_behavior(mock_installer):
mock_installer.show_page('init_cluster')
# Trigger overlay
with patch.object(mock_installer, '_cluster_ready_for_navigation', return_value=True), \
patch.object(mock_installer, '_create_console_output'):
mock_installer.on_next()
assert mock_installer._showing_service_overlay is True
assert mock_installer._common_services_success is False
# Next button should be disabled via update_footer
mock_installer.update_footer()
mock_installer.next_button.configure.assert_any_call(state='disabled')
# Simulate success
mock_installer._common_services_success = True
mock_installer.update_footer()
mock_installer.next_button.configure.assert_any_call(state='normal')
# Now Next should proceed
with patch.object(mock_installer, '_cluster_ready_for_navigation', return_value=True):
mock_installer.on_next()
assert mock_installer.pages[mock_installer.page_index][0] == 'init_password'
def test_service_layer_prev_behavior(mock_installer):
mock_installer.show_page('init_cluster')
with patch.object(mock_installer, '_cluster_ready_for_navigation', return_value=True), \
patch.object(mock_installer, '_create_console_output'):
mock_installer.on_next()
assert mock_installer._showing_service_overlay is True
# Prev from overlay should go back to init_cluster and reset overlay flag
mock_installer.on_prev()
assert mock_installer._showing_service_overlay is False
assert mock_installer.pages[mock_installer.page_index][0] == 'init_cluster'