"""Tests for settings dialog.""" from pathlib import Path from unittest.mock import MagicMock, patch import pytest from webdrop_bridge.config import Config, ConfigurationError from webdrop_bridge.ui.settings_dialog import SettingsDialog @pytest.fixture def sample_config(tmp_path): """Create sample configuration.""" return Config( app_name="WebDrop Bridge", app_version="1.0.0", log_level="INFO", log_file=None, allowed_roots=[Path("/home"), Path("/data")], allowed_urls=["http://example.com", "http://*.test.com"], webapp_url="http://localhost:8080", window_width=800, window_height=600, enable_logging=True, ) class TestSettingsDialogInitialization: """Test settings dialog initialization.""" def test_dialog_creation(self, qtbot, sample_config): """Test dialog can be created.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog is not None assert dialog.windowTitle() == "Settings" def test_dialog_has_tabs(self, qtbot, sample_config): """Test dialog has all required tabs.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.tabs is not None assert dialog.tabs.count() == 5 # Paths, URLs, Logging, Window, Profiles def test_dialog_has_paths_tab(self, qtbot, sample_config): """Test Paths tab exists.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.tabs.tabText(0) == "Paths" def test_dialog_has_urls_tab(self, qtbot, sample_config): """Test URLs tab exists.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.tabs.tabText(1) == "URLs" def test_dialog_has_logging_tab(self, qtbot, sample_config): """Test Logging tab exists.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.tabs.tabText(2) == "Logging" def test_dialog_has_window_tab(self, qtbot, sample_config): """Test Window tab exists.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.tabs.tabText(3) == "Window" def test_dialog_has_profiles_tab(self, qtbot, sample_config): """Test Profiles tab exists.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.tabs.tabText(4) == "Profiles" class TestPathsTab: """Test Paths configuration tab.""" def test_paths_loaded_from_config(self, qtbot, sample_config): """Test paths are loaded from configuration.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) items = [dialog.paths_list.item(i).text() for i in range(dialog.paths_list.count())] assert len(items) == 2 # Paths are normalized (backslashes on Windows) assert any("home" in item for item in items) assert any("data" in item for item in items) def test_add_path_button_exists(self, qtbot, sample_config): """Test Add Path button exists.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.tabs.currentWidget() is not None class TestURLsTab: """Test URLs configuration tab.""" def test_urls_loaded_from_config(self, qtbot, sample_config): """Test URLs are loaded from configuration.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) items = [dialog.urls_list.item(i).text() for i in range(dialog.urls_list.count())] assert len(items) == 2 assert "http://example.com" in items assert "http://*.test.com" in items class TestLoggingTab: """Test Logging configuration tab.""" def test_log_level_set_from_config(self, qtbot, sample_config): """Test log level is set from configuration.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.log_level_combo.currentText() == "INFO" def test_log_levels_available(self, qtbot, sample_config): """Test all log levels are available.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) levels = [dialog.log_level_combo.itemText(i) for i in range(dialog.log_level_combo.count())] assert "DEBUG" in levels assert "INFO" in levels assert "WARNING" in levels assert "ERROR" in levels assert "CRITICAL" in levels class TestWindowTab: """Test Window configuration tab.""" def test_window_width_set_from_config(self, qtbot, sample_config): """Test window width is set from configuration.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.width_spin.value() == 800 def test_window_height_set_from_config(self, qtbot, sample_config): """Test window height is set from configuration.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.height_spin.value() == 600 def test_window_width_has_min_max(self, qtbot, sample_config): """Test window width spinbox has min/max.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.width_spin.minimum() == 400 assert dialog.width_spin.maximum() == 5000 def test_window_height_has_min_max(self, qtbot, sample_config): """Test window height spinbox has min/max.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.height_spin.minimum() == 300 assert dialog.height_spin.maximum() == 5000 class TestProfilesTab: """Test Profiles management tab.""" def test_profiles_list_initialized(self, qtbot, sample_config): """Test profiles list is initialized.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) assert dialog.profiles_list is not None class TestConfigDataRetrieval: """Test getting configuration data from dialog.""" def test_get_config_data_from_dialog(self, qtbot, sample_config): """Test retrieving configuration data from dialog.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) config_data = dialog.get_config_data() assert config_data["app_name"] == "WebDrop Bridge" assert config_data["log_level"] == "INFO" assert config_data["window_width"] == 800 assert config_data["window_height"] == 600 def test_get_config_data_validates(self, qtbot, sample_config): """Test get_config_data returns valid configuration data.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) # All default values are valid config_data = dialog.get_config_data() assert config_data is not None assert config_data["window_width"] == 800 def test_get_config_data_with_modified_values(self, qtbot, sample_config): """Test get_config_data returns modified values.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) # Modify values dialog.width_spin.setValue(1024) dialog.height_spin.setValue(768) dialog.log_level_combo.setCurrentText("DEBUG") config_data = dialog.get_config_data() assert config_data["window_width"] == 1024 assert config_data["window_height"] == 768 assert config_data["log_level"] == "DEBUG" class TestApplyConfigData: """Test applying configuration data to dialog.""" def test_apply_config_data_updates_paths(self, qtbot, sample_config): """Test applying config data updates paths.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) new_config = { "app_name": "Test", "app_version": "1.0.0", "log_level": "INFO", "log_file": None, "allowed_roots": ["/new/path", "/another/path"], "allowed_urls": [], "webapp_url": "http://localhost", "window_width": 800, "window_height": 600, "enable_logging": True, } dialog._apply_config_data(new_config) items = [dialog.paths_list.item(i).text() for i in range(dialog.paths_list.count())] assert "/new/path" in items assert "/another/path" in items def test_apply_config_data_updates_urls(self, qtbot, sample_config): """Test applying config data updates URLs.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) new_config = { "app_name": "Test", "app_version": "1.0.0", "log_level": "INFO", "log_file": None, "allowed_roots": [], "allowed_urls": ["http://new.com", "http://test.org"], "webapp_url": "http://localhost", "window_width": 800, "window_height": 600, "enable_logging": True, } dialog._apply_config_data(new_config) items = [dialog.urls_list.item(i).text() for i in range(dialog.urls_list.count())] assert "http://new.com" in items assert "http://test.org" in items def test_apply_config_data_updates_window_size(self, qtbot, sample_config): """Test applying config data updates window size.""" dialog = SettingsDialog(sample_config) qtbot.addWidget(dialog) new_config = { "app_name": "Test", "app_version": "1.0.0", "log_level": "INFO", "log_file": None, "allowed_roots": [], "allowed_urls": [], "webapp_url": "http://localhost", "window_width": 1280, "window_height": 1024, "enable_logging": True, } dialog._apply_config_data(new_config) assert dialog.width_spin.value() == 1280 assert dialog.height_spin.value() == 1024