From 7b60f92a48b4ff54604e8179503488800866ca6f Mon Sep 17 00:00:00 2001 From: Warry Date: Mon, 29 Dec 2025 20:54:26 +0100 Subject: feat: Refactor playlist management, error handling, and testing infrastructure - Improved playlist item handling with pagination, error logging, and dedicated request hooks. - Consolidated reusable helpers for track ID normalization, playlist validation, and removal logic. - Enhanced error handling by introducing `PlaylistNotFound` and `UserNotAuthenticated` exceptions. - Refined Pytest `qapp` fixture for headless CI compatibility and session-scoped reuse. - Replaced redundant fixtures in multiple test files for consistency. - Improved playlist management GUI with detailed debug logging for notifications and operations. - Added `deptry` configuration to handle transitive dependencies and ignored exclusions. - Updated Pytest and Tox configurations for consistent environment setup during CI/CD runs. --- tests/conftest.py | 27 ++++++++++++++++++++------- tests/test_delimiters_category.py | 9 --------- tests/test_dialog_preferences_integration.py | 9 --------- tests/test_settings_dialog_structure.py | 10 ---------- tests/test_settings_ui.py | 10 ---------- 5 files changed, 20 insertions(+), 45 deletions(-) (limited to 'tests') diff --git a/tests/conftest.py b/tests/conftest.py index 1e6cfe3..c85c444 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,6 @@ +import os +import tempfile +from pathlib import Path from unittest.mock import Mock import pytest @@ -6,14 +9,24 @@ from tidalapi import Album, Track, Video from tidalapi.artist import Artist -@pytest.fixture -def qt_app(): - """Create a QApplication instance for testing Qt widgets.""" - app = QtWidgets.QApplication.instance() - if app is None: - app = QtWidgets.QApplication([]) +@pytest.fixture(scope="session") +def qapp(): + """Provide a QApplication configured for headless CI (offscreen/minimal).""" + # Ensure headless backend for CI runners + os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") + # Qt expects XDG_RUNTIME_DIR to exist with correct permissions + runtime_dir = Path(tempfile.mkdtemp(prefix="xdg-runtime-")).resolve() + os.environ.setdefault("XDG_RUNTIME_DIR", str(runtime_dir)) + + # Lower graphical requirements + QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_DisableHighDpiScaling, True) + + app = QtWidgets.QApplication.instance() or QtWidgets.QApplication([]) yield app - # Note: don't quit the app as it may be shared across tests + + +# Backward compatible alias +qt_app = qapp @pytest.fixture diff --git a/tests/test_delimiters_category.py b/tests/test_delimiters_category.py index df5e950..8028e34 100644 --- a/tests/test_delimiters_category.py +++ b/tests/test_delimiters_category.py @@ -9,15 +9,6 @@ from tidal_dl_ng.dialog import DialogPreferences from tidal_dl_ng.ui.dialog_settings import Ui_DialogSettings -@pytest.fixture -def qapp(): - """Create QApplication instance for tests.""" - app = QtWidgets.QApplication.instance() - if app is None: - app = QtWidgets.QApplication([]) - yield app - - class TestDelimitersPage: """Test the Delimiters page specifically.""" diff --git a/tests/test_dialog_preferences_integration.py b/tests/test_dialog_preferences_integration.py index b7df74d..1975a6e 100644 --- a/tests/test_dialog_preferences_integration.py +++ b/tests/test_dialog_preferences_integration.py @@ -9,15 +9,6 @@ from tidal_dl_ng.config import Settings from tidal_dl_ng.dialog import DialogPreferences -@pytest.fixture -def qapp(): - """Create QApplication instance for tests.""" - app = QtWidgets.QApplication.instance() - if app is None: - app = QtWidgets.QApplication([]) - yield app - - @pytest.fixture def mock_settings(): """Create a mock Settings object with all required attributes.""" diff --git a/tests/test_settings_dialog_structure.py b/tests/test_settings_dialog_structure.py index 3c492a5..3c16238 100644 --- a/tests/test_settings_dialog_structure.py +++ b/tests/test_settings_dialog_structure.py @@ -1,20 +1,10 @@ """Tests for the settings dialog category structure and organization.""" -import pytest from PySide6 import QtCore, QtWidgets from tidal_dl_ng.ui.dialog_settings import Ui_DialogSettings -@pytest.fixture -def qapp(): - """Create QApplication instance for tests.""" - app = QtWidgets.QApplication.instance() - if app is None: - app = QtWidgets.QApplication([]) - yield app - - class TestSettingsDialogStructure: """Test the structural integrity of the settings dialog.""" diff --git a/tests/test_settings_ui.py b/tests/test_settings_ui.py index e77a464..67957d5 100644 --- a/tests/test_settings_ui.py +++ b/tests/test_settings_ui.py @@ -10,16 +10,6 @@ from tidal_dl_ng.dialog import DialogPreferences from tidal_dl_ng.ui.dialog_settings import Ui_DialogSettings -@pytest.fixture -def qapp(): - """Create QApplication instance for tests.""" - app = QtWidgets.QApplication.instance() - if app is None: - app = QtWidgets.QApplication([]) - yield app - # Cleanup is handled by pytest-qt if available, otherwise by QApplication - - class TestUiDialogSettings: """Test the generated UI class.""" -- cgit v1.3.1