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.
This commit is contained in:
+20
-7
@@ -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
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user