diff --git a/src/webdrop_bridge/ui/main_window.py b/src/webdrop_bridge/ui/main_window.py index 039b802..cb4ff5e 100644 --- a/src/webdrop_bridge/ui/main_window.py +++ b/src/webdrop_bridge/ui/main_window.py @@ -3,7 +3,7 @@ from pathlib import Path 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 webdrop_bridge.config import Config @@ -173,6 +173,9 @@ class MainWindow(QMainWindow): integration with the native filesystem. """ + # Signals + check_for_updates = Signal() + def __init__( self, config: Config, @@ -202,6 +205,9 @@ class MainWindow(QMainWindow): # Create navigation toolbar (Kiosk-mode navigation) self._create_navigation_toolbar() + # Create menu bar + self._create_menu_bar() + # Create drag interceptor self.drag_interceptor = DragInterceptor() @@ -341,6 +347,25 @@ class MainWindow(QMainWindow): ) 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: """Navigate to the home (start) URL.""" home_url = self.config.webapp_url diff --git a/tests/unit/test_main_window.py b/tests/unit/test_main_window.py index edc982f..187158a 100644 --- a/tests/unit/test_main_window.py +++ b/tests/unit/test_main_window.py @@ -323,6 +323,38 @@ class TestMainWindowSignals: 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: """Test stylesheet application."""