mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 11:03:59 +00:00
- Refactored install.py and installer package for improved UI and navigation. - Replaced Supabase k8s manifests with a dedicated deployment script and port-wiring logic. - Added new deployment pipeline and finalization scripts in etc/. - Updated initialization scripts for Kerberos, authority, and port forwards. - Updated port mappings and tests.
142 lines
5.6 KiB
Python
142 lines
5.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():
|
|
with patch('install.tk.Tk'), \
|
|
patch('install.tk.Frame'), \
|
|
patch('install.tk.Canvas'), \
|
|
patch('install.tk.Label'), \
|
|
patch('install.tk.Button'), \
|
|
patch('install.ttk.Style'), \
|
|
patch('install.Path.exists', return_value=True):
|
|
|
|
root = MagicMock()
|
|
# Mock winfo methods needed for centering
|
|
root.winfo_screenwidth.return_value = 1920
|
|
root.winfo_screenheight.return_value = 1080
|
|
|
|
app = ProleInstaller(root)
|
|
return app
|
|
|
|
def test_initial_page(mock_installer):
|
|
# Should start at index 0 (welcome)
|
|
assert mock_installer.page_index == 0
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'welcome'
|
|
|
|
def test_show_page_by_id(mock_installer):
|
|
mock_installer.show_page('network_scan')
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'network_scan'
|
|
|
|
def test_show_page_invalid_id(mock_installer):
|
|
# Current page is welcome (0)
|
|
mock_installer.page_index = 0
|
|
|
|
with patch('install.messagebox.showerror') as mock_error:
|
|
mock_installer.show_page('non_existent_page')
|
|
# Should stay at current index and NOT fallback to 0 if it was elsewhere,
|
|
# or just stay at 0 if it was at 0.
|
|
# The key fix was NOT defaulting to 0 when index_or_id is a string and not found.
|
|
assert mock_installer.page_index == 0
|
|
mock_error.assert_called_once()
|
|
|
|
def test_navigation_flow_standard(mock_installer):
|
|
# Welcome -> Dependencies
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'deps_summary'
|
|
|
|
# Mock all dependencies installed to skip dep pages
|
|
with patch.object(mock_installer, 'all_dependencies_installed', return_value=True):
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'network_scan'
|
|
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'env_setup'
|
|
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'init_cluster'
|
|
|
|
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_navigation_flow_missing_deps(mock_installer):
|
|
# Welcome -> Dependencies
|
|
mock_installer.show_page('welcome')
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'deps_summary'
|
|
|
|
# Mock one dependency missing
|
|
mock_dep_id = mock_installer.dependencies[0]['id']
|
|
with patch.object(mock_installer, 'all_dependencies_installed', return_value=False), \
|
|
patch.object(mock_installer, '_dep_navigation_sequence', return_value=[f'dep_{mock_dep_id}']):
|
|
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == f'dep_{mock_dep_id}'
|
|
|
|
# Next from dep page with all installed now
|
|
with patch.object(mock_installer, 'all_dependencies_installed', return_value=True):
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'network_scan'
|
|
|
|
def test_on_prev(mock_installer):
|
|
# network_scan -> deps_summary
|
|
mock_installer.show_page('network_scan')
|
|
with patch.object(mock_installer, 'all_dependencies_installed', return_value=True):
|
|
mock_installer.on_prev()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'deps_summary'
|
|
|
|
# deps_summary -> welcome
|
|
mock_installer.on_prev()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'welcome'
|
|
|
|
def test_infinite_loop_prevention(mock_installer):
|
|
# This specifically tests the scenario that caused the bug:
|
|
# trying to navigate to a missing ID should NOT reset to welcome (0)
|
|
mock_installer.show_page('network_scan')
|
|
current_idx = mock_installer.page_index
|
|
|
|
mock_installer.show_page('invalid_id')
|
|
assert mock_installer.page_index == current_idx
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'network_scan'
|
|
|
|
def test_on_next_finish_loop(mock_installer):
|
|
# From last page, on_next should not crash or loop
|
|
last_idx = len(mock_installer.pages) - 1
|
|
mock_installer.show_page(last_idx)
|
|
mock_installer.on_next()
|
|
assert mock_installer.page_index == last_idx
|
|
|
|
def test_on_prev_first_page(mock_installer):
|
|
# From first page, on_prev should not crash or loop
|
|
mock_installer.show_page(0)
|
|
mock_installer.on_prev()
|
|
assert mock_installer.page_index == 0
|
|
|
|
def test_navigation_to_create_installer(mock_installer):
|
|
# From build page, if successful, next should go to create_installer
|
|
mock_installer.show_page('build')
|
|
mock_installer._built_success = True
|
|
mock_installer.on_next()
|
|
assert mock_installer.pages[mock_installer.page_index][0] == 'create_installer'
|
|
|
|
# Last page Finish label
|
|
mock_installer.update_footer()
|
|
mock_installer.next_button.configure.assert_any_call(text='Finish')
|