"""Tests for server configuration editing and removal.""" from pathlib import Path import sys ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) import pytest from PySide6.QtCore import Qt from PySide6.QtWidgets import QApplication, QDialog, QMessageBox from src.config.settings import Settings from src.widgets.server_dialog import ServerDialog from src.widgets.server_management_dialog import ServerManagementDialog import src.widgets.server_management_dialog as server_management_dialog_module import src.widgets.server_dialog as server_dialog_module @pytest.fixture(autouse=True) def qt_offscreen_env(monkeypatch, tmp_path): monkeypatch.setenv("QT_QPA_PLATFORM", "offscreen") monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path / "config")) monkeypatch.setenv("XDG_DATA_HOME", str(tmp_path / "data")) monkeypatch.setenv("XDG_CACHE_HOME", str(tmp_path / "cache")) @pytest.fixture() def qt_app(): app = QApplication.instance() if app: return app return QApplication([]) def make_settings() -> Settings: settings = Settings() settings.addServer("Primary", "https://primary.example", "Username", "password1") settings.addServer("Backup", "https://backup.example", "Username", "password2") settings.setDefaultServer("Primary") return settings def test_remove_server_clears_deleted_default(tmp_path: Path): settings = make_settings() settings.removeServer("Primary") assert settings.getDefaultServer() is None assert list(settings.getServers()) == ["Backup"] with open(settings.serversFile, "r", encoding="utf-8") as serversFile: assert "Primary" not in serversFile.read() def test_edit_server_can_clear_default(qt_app): settings = make_settings() dialog = ServerDialog(settings, "Primary") dialog.urlEdit.setText("https://changed.example") dialog.usernameEdit.setText("NewUsername") dialog.passwordEdit.setText("new-password") dialog.defaultCheckbox.setChecked(False) dialog.saveServer() assert dialog.result() == QDialog.Accepted server = settings.getServer("Primary") assert server["url"] == "https://changed.example" assert server["username"] == "NewUsername" assert server["password"] == "new-password" assert settings.getDefaultServer() is None def test_server_dialog_rejects_invalid_url(qt_app, monkeypatch): settings = Settings() dialog = ServerDialog(settings) monkeypatch.setattr(QMessageBox, "warning", lambda *args, **kwargs: None) dialog.nameEdit.setText("Primary") dialog.urlEdit.setText("music.example.com") dialog.usernameEdit.setText("Username") dialog.passwordEdit.setText("password") dialog.saveServer() assert dialog.result() != QDialog.Accepted assert settings.getServers() == {} assert dialog.focusWidget() is dialog.urlEdit def test_server_dialog_test_rejects_invalid_url_without_network(qt_app, monkeypatch): settings = Settings() dialog = ServerDialog(settings) def unexpected_client(*args, **kwargs): raise AssertionError("Connection test should validate before creating a client") monkeypatch.setattr(server_dialog_module, "SubsonicClient", unexpected_client) dialog.urlEdit.setText("ftp://music.example.com") dialog.usernameEdit.setText("Username") dialog.passwordEdit.setText("password") dialog.testConnection() assert dialog.testButton.isEnabled() assert dialog.statusLabel.text() == "Enter a valid server URL beginning with http:// or https://" assert dialog.focusWidget() is dialog.urlEdit def test_management_dialog_lists_default_and_selection_actions(qt_app): settings = make_settings() dialog = ServerManagementDialog(settings) assert dialog.serverList.count() == 2 assert dialog.serverList.item(0).text() == "Primary (default)" assert dialog.serverList.item(1).text() == "Backup" assert dialog.connectButton.isEnabled() assert dialog.editButton.isEnabled() assert dialog.removeButton.isEnabled() def test_management_dialog_with_no_servers_focuses_add(qt_app): settings = Settings() dialog = ServerManagementDialog(settings) assert dialog.serverList.count() == 0 assert dialog.focusWidget() is dialog.addButton assert not dialog.connectButton.isEnabled() assert not dialog.editButton.isEnabled() assert not dialog.removeButton.isEnabled() def test_management_dialog_remove_confirmed_server(qt_app, monkeypatch): settings = make_settings() dialog = ServerManagementDialog(settings) monkeypatch.setattr(QMessageBox, "question", lambda *args, **kwargs: QMessageBox.Yes) dialog.removeSelected() assert dialog.removedServerNames == {"Primary"} assert "Primary" not in settings.getServers() assert dialog.serverList.count() == 1 assert dialog.serverList.currentItem().data(Qt.UserRole) == "Backup" def test_management_dialog_remove_discards_edit_state(qt_app, monkeypatch): settings = make_settings() dialog = ServerManagementDialog(settings) dialog.editedServerNames.add("Primary") monkeypatch.setattr(QMessageBox, "question", lambda *args, **kwargs: QMessageBox.Yes) dialog.removeSelected() assert dialog.removedServerNames == {"Primary"} assert dialog.editedServerNames == set() def test_management_dialog_remove_canceled_server(qt_app, monkeypatch): settings = make_settings() dialog = ServerManagementDialog(settings) monkeypatch.setattr(QMessageBox, "question", lambda *args, **kwargs: QMessageBox.No) dialog.removeSelected() assert dialog.removedServerNames == set() assert list(settings.getServers()) == ["Primary", "Backup"] def test_management_dialog_edit_uses_selected_server(qt_app, monkeypatch): settings = make_settings() dialog = ServerManagementDialog(settings) calls = [] class FakeServerDialog: def __init__(self, settings, serverName=None, parent=None): calls.append((settings, serverName, parent)) def exec(self): return True monkeypatch.setattr(server_management_dialog_module, "ServerDialog", FakeServerDialog) dialog.editSelected() assert calls == [(settings, "Primary", dialog)] assert dialog.editedServerNames == {"Primary"}