feat: Add Help menu with Check for Updates action
Menu implementation: - Added menu bar to MainWindow - Help menu with 'Check for Updates...' action - Signal-based architecture for async update check - Action triggers check_for_updates signal Test coverage: - 3 new tests for menu bar functionality - Test menu bar creation - Test signal exists and is callable - Test callback method exists - All 146 tests passing, 86% coverage Design: - Decoupled menu from update logic - Emits signal that main app listens to - Allows async update check without blocking UI
This commit is contained in:
parent
af8e417197
commit
2896f6ba5c
2 changed files with 58 additions and 1 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from PySide6.QtCore import QSize, Qt, QUrl
|
from PySide6.QtCore import QSize, Qt, QUrl, Signal
|
||||||
from PySide6.QtWidgets import QMainWindow, QToolBar, QVBoxLayout, QWidget
|
from PySide6.QtWidgets import QMainWindow, QToolBar, QVBoxLayout, QWidget
|
||||||
|
|
||||||
from webdrop_bridge.config import Config
|
from webdrop_bridge.config import Config
|
||||||
|
|
@ -173,6 +173,9 @@ class MainWindow(QMainWindow):
|
||||||
integration with the native filesystem.
|
integration with the native filesystem.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
check_for_updates = Signal()
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
config: Config,
|
config: Config,
|
||||||
|
|
@ -202,6 +205,9 @@ class MainWindow(QMainWindow):
|
||||||
# Create navigation toolbar (Kiosk-mode navigation)
|
# Create navigation toolbar (Kiosk-mode navigation)
|
||||||
self._create_navigation_toolbar()
|
self._create_navigation_toolbar()
|
||||||
|
|
||||||
|
# Create menu bar
|
||||||
|
self._create_menu_bar()
|
||||||
|
|
||||||
# Create drag interceptor
|
# Create drag interceptor
|
||||||
self.drag_interceptor = DragInterceptor()
|
self.drag_interceptor = DragInterceptor()
|
||||||
|
|
||||||
|
|
@ -341,6 +347,25 @@ class MainWindow(QMainWindow):
|
||||||
)
|
)
|
||||||
toolbar.addAction(refresh_action)
|
toolbar.addAction(refresh_action)
|
||||||
|
|
||||||
|
def _create_menu_bar(self) -> None:
|
||||||
|
"""Create menu bar with Help menu and update check action."""
|
||||||
|
menu_bar = self.menuBar()
|
||||||
|
|
||||||
|
# Help menu
|
||||||
|
help_menu = menu_bar.addMenu("Help")
|
||||||
|
|
||||||
|
# Check for Updates action
|
||||||
|
check_updates_action = help_menu.addAction("Check for Updates...")
|
||||||
|
check_updates_action.triggered.connect(self._on_check_for_updates)
|
||||||
|
|
||||||
|
def _on_check_for_updates(self) -> None:
|
||||||
|
"""Handle check for updates menu action.
|
||||||
|
|
||||||
|
Emits the check_for_updates signal to allow the main application
|
||||||
|
to perform the update check asynchronously.
|
||||||
|
"""
|
||||||
|
self.check_for_updates.emit()
|
||||||
|
|
||||||
def _navigate_home(self) -> None:
|
def _navigate_home(self) -> None:
|
||||||
"""Navigate to the home (start) URL."""
|
"""Navigate to the home (start) URL."""
|
||||||
home_url = self.config.webapp_url
|
home_url = self.config.webapp_url
|
||||||
|
|
|
||||||
|
|
@ -323,6 +323,38 @@ class TestMainWindowSignals:
|
||||||
mock_handler.assert_called_once()
|
mock_handler.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
class TestMainWindowMenuBar:
|
||||||
|
"""Test menu bar and menu actions."""
|
||||||
|
|
||||||
|
def test_menu_bar_created(self, qtbot, sample_config):
|
||||||
|
"""Test menu bar is created."""
|
||||||
|
window = MainWindow(sample_config)
|
||||||
|
qtbot.addWidget(window)
|
||||||
|
|
||||||
|
menu_bar = window.menuBar()
|
||||||
|
assert menu_bar is not None
|
||||||
|
|
||||||
|
def test_window_has_check_for_updates_signal(self, qtbot, sample_config):
|
||||||
|
"""Test window has check_for_updates signal."""
|
||||||
|
window = MainWindow(sample_config)
|
||||||
|
qtbot.addWidget(window)
|
||||||
|
|
||||||
|
# Test that signal exists
|
||||||
|
assert hasattr(window, "check_for_updates")
|
||||||
|
|
||||||
|
# Test that signal is callable (can be emitted)
|
||||||
|
assert callable(window.check_for_updates.emit)
|
||||||
|
|
||||||
|
def test_on_check_for_updates_method_exists(self, qtbot, sample_config):
|
||||||
|
"""Test _on_check_for_updates method exists."""
|
||||||
|
window = MainWindow(sample_config)
|
||||||
|
qtbot.addWidget(window)
|
||||||
|
|
||||||
|
# Test that the method exists
|
||||||
|
assert hasattr(window, "_on_check_for_updates")
|
||||||
|
assert callable(window._on_check_for_updates)
|
||||||
|
|
||||||
|
|
||||||
class TestMainWindowStylesheet:
|
class TestMainWindowStylesheet:
|
||||||
"""Test stylesheet application."""
|
"""Test stylesheet application."""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue