🐛 | Fix SonarQube issues
All checks were successful
SonarQube Code Quality Scan / SonarQube Scan (push) Successful in 1m42s
All checks were successful
SonarQube Code Quality Scan / SonarQube Scan (push) Successful in 1m42s
- Extract duplicated string literals into constants (S1192)
- Replace dict() with {} literal (S7498)
- Remove duplicate test_zero_ms (S4144)
- Remove/rename unused variables (S1481)
- Replace constant assert True with comment (S5914)
- Mark stub empty methods as intentional (S1186)
- Review 2 security hotspots as safe (S5443)
This commit is contained in:
@@ -27,13 +27,18 @@ from unittest import mock
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
class _StubQObject:
|
||||
"""Minimal replacement for PySide6.QtCore.QObject."""
|
||||
"""Minimal replacement for PySide6.QtCore.QObject.
|
||||
|
||||
Used as a base class so that ``class Foo(QObject)`` produces a real
|
||||
class with the methods defined in its body, not a MagicMock.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class _StubQThread:
|
||||
"""Minimal replacement for PySide6.QtCore.QThread."""
|
||||
def start(self) -> None:
|
||||
"""Stub — no-op; real QThread would start the event loop."""
|
||||
pass
|
||||
def quit(self) -> None:
|
||||
pass
|
||||
@@ -88,56 +93,61 @@ def _install_stubs() -> None:
|
||||
m.__name__ = name
|
||||
return m
|
||||
|
||||
# ── Module-name constants (extracted to avoid S1192 duplicates) ──
|
||||
MOD_QTCORE = "PySide6.QtCore"
|
||||
MOD_QTGUI = "PySide6.QtGui"
|
||||
MOD_QTMULTIMEDIA = "PySide6.QtMultimedia"
|
||||
MOD_QTNETWORK = "PySide6.QtNetwork"
|
||||
MOD_QTWIDGETS = "PySide6.QtWidgets"
|
||||
|
||||
_PYSIDE_STUBS = {
|
||||
("PySide6", "_module"): _stub("PySide6"),
|
||||
# ── QtCore ──────────────────────────────────────────────────
|
||||
("PySide6.QtCore", "QObject"): _StubQObject,
|
||||
("PySide6.QtCore", "QThread"): _StubQThread,
|
||||
("PySide6.QtCore", "Signal"): _stub_signal,
|
||||
("PySide6.QtCore", "Slot"): _stub_slot,
|
||||
("PySide6.QtCore", "QUrl"): _stub("QUrl"),
|
||||
("PySide6.QtCore", "Qt"): _stub("Qt"),
|
||||
("PySide6.QtCore", "QTimer"): _stub("QTimer"),
|
||||
("PySide6.QtCore", "QRectF"): _stub("QRectF"),
|
||||
("PySide6.QtCore", "QPropertyAnimation"): _stub("QPropertyAnimation"),
|
||||
("PySide6.QtCore", "QEasingCurve"): _stub("QEasingCurve"),
|
||||
("PySide6.QtCore", "QLoggingCategory"): _stub("QLoggingCategory"),
|
||||
("PySide6.QtCore", "QEvent"): _stub("QEvent"),
|
||||
(MOD_QTCORE, "QObject"): _StubQObject,
|
||||
(MOD_QTCORE, "QThread"): _StubQThread,
|
||||
(MOD_QTCORE, "Signal"): _stub_signal,
|
||||
(MOD_QTCORE, "Slot"): _stub_slot,
|
||||
(MOD_QTCORE, "QUrl"): _stub("QUrl"),
|
||||
(MOD_QTCORE, "Qt"): _stub("Qt"),
|
||||
(MOD_QTCORE, "QTimer"): _stub("QTimer"),
|
||||
(MOD_QTCORE, "QRectF"): _stub("QRectF"),
|
||||
(MOD_QTCORE, "QPropertyAnimation"): _stub("QPropertyAnimation"),
|
||||
(MOD_QTCORE, "QEasingCurve"): _stub("QEasingCurve"),
|
||||
(MOD_QTCORE, "QLoggingCategory"): _stub("QLoggingCategory"),
|
||||
(MOD_QTCORE, "QEvent"): _stub("QEvent"),
|
||||
# ── QtGui ───────────────────────────────────────────────────
|
||||
("PySide6.QtGui", "QFont"): _stub("QFont"),
|
||||
("PySide6.QtGui", "QPixmap"): _stub("QPixmap"),
|
||||
("PySide6.QtGui", "QPainter"): _stub("QPainter"),
|
||||
("PySide6.QtGui", "QColor"): _stub("QColor"),
|
||||
("PySide6.QtGui", "QBrush"): _stub("QBrush"),
|
||||
(MOD_QTGUI, "QFont"): _stub("QFont"),
|
||||
(MOD_QTGUI, "QPixmap"): _stub("QPixmap"),
|
||||
(MOD_QTGUI, "QPainter"): _stub("QPainter"),
|
||||
(MOD_QTGUI, "QColor"): _stub("QColor"),
|
||||
(MOD_QTGUI, "QBrush"): _stub("QBrush"),
|
||||
# ── QtMultimedia ────────────────────────────────────────────
|
||||
("PySide6.QtMultimedia", "QMediaPlayer"): _stub("QMediaPlayer"),
|
||||
("PySide6.QtMultimedia", "QAudioOutput"): _stub("QAudioOutput"),
|
||||
("PySide6.QtMultimedia", "QAudioBufferOutput"): _stub("QAudioBufferOutput"),
|
||||
(MOD_QTMULTIMEDIA, "QMediaPlayer"): _stub("QMediaPlayer"),
|
||||
(MOD_QTMULTIMEDIA, "QAudioOutput"): _stub("QAudioOutput"),
|
||||
(MOD_QTMULTIMEDIA, "QAudioBufferOutput"): _stub("QAudioBufferOutput"),
|
||||
# ── QtNetwork ───────────────────────────────────────────────
|
||||
("PySide6.QtNetwork", "QNetworkAccessManager"): _stub("QNetworkAccessManager"),
|
||||
("PySide6.QtNetwork", "QNetworkRequest"): _stub("QNetworkRequest"),
|
||||
("PySide6.QtNetwork", "QNetworkReply"): _stub("QNetworkReply"),
|
||||
(MOD_QTNETWORK, "QNetworkAccessManager"): _stub("QNetworkAccessManager"),
|
||||
(MOD_QTNETWORK, "QNetworkRequest"): _stub("QNetworkRequest"),
|
||||
(MOD_QTNETWORK, "QNetworkReply"): _stub("QNetworkReply"),
|
||||
# ── QtWidgets ───────────────────────────────────────────────
|
||||
("PySide6.QtWidgets", "QApplication"): _stub("QApplication"),
|
||||
("PySide6.QtWidgets", "QCheckBox"): _stub("QCheckBox"),
|
||||
("PySide6.QtWidgets", "QDialog"): _stub("QDialog"),
|
||||
("PySide6.QtWidgets", "QHBoxLayout"): _stub("QHBoxLayout"),
|
||||
("PySide6.QtWidgets", "QLabel"): _stub("QLabel"),
|
||||
("PySide6.QtWidgets", "QLineEdit"): _stub("QLineEdit"),
|
||||
("PySide6.QtWidgets", "QListWidget"): _stub("QListWidget"),
|
||||
("PySide6.QtWidgets", "QListWidgetItem"): _stub("QListWidgetItem"),
|
||||
("PySide6.QtWidgets", "QMainWindow"): _stub("QMainWindow"),
|
||||
("PySide6.QtWidgets", "QMenu"): _stub("QMenu"),
|
||||
("PySide6.QtWidgets", "QPushButton"): _stub("QPushButton"),
|
||||
("PySide6.QtWidgets", "QScrollArea"): _stub("QScrollArea"),
|
||||
("PySide6.QtWidgets", "QSlider"): _stub("QSlider"),
|
||||
("PySide6.QtWidgets", "QStackedWidget"): _stub("QStackedWidget"),
|
||||
("PySide6.QtWidgets", "QVBoxLayout"): _stub("QVBoxLayout"),
|
||||
("PySide6.QtWidgets", "QWidget"): _stub("QWidget"),
|
||||
("PySide6.QtWidgets", "QFrame"): _stub("QFrame"),
|
||||
("PySide6.QtWidgets", "QToolButton"): _stub("QToolButton"),
|
||||
("PySide6.QtWidgets", "QButtonGroup"): _stub("QButtonGroup"),
|
||||
("PySide6.QtWidgets", "QSizePolicy"): _stub("QSizePolicy"),
|
||||
(MOD_QTWIDGETS, "QApplication"): _stub("QApplication"),
|
||||
(MOD_QTWIDGETS, "QCheckBox"): _stub("QCheckBox"),
|
||||
(MOD_QTWIDGETS, "QDialog"): _stub("QDialog"),
|
||||
(MOD_QTWIDGETS, "QHBoxLayout"): _stub("QHBoxLayout"),
|
||||
(MOD_QTWIDGETS, "QLabel"): _stub("QLabel"),
|
||||
(MOD_QTWIDGETS, "QLineEdit"): _stub("QLineEdit"),
|
||||
(MOD_QTWIDGETS, "QListWidget"): _stub("QListWidget"),
|
||||
(MOD_QTWIDGETS, "QListWidgetItem"): _stub("QListWidgetItem"),
|
||||
(MOD_QTWIDGETS, "QMainWindow"): _stub("QMainWindow"),
|
||||
(MOD_QTWIDGETS, "QMenu"): _stub("QMenu"),
|
||||
(MOD_QTWIDGETS, "QPushButton"): _stub("QPushButton"),
|
||||
(MOD_QTWIDGETS, "QScrollArea"): _stub("QScrollArea"),
|
||||
(MOD_QTWIDGETS, "QSlider"): _stub("QSlider"),
|
||||
(MOD_QTWIDGETS, "QStackedWidget"): _stub("QStackedWidget"),
|
||||
(MOD_QTWIDGETS, "QVBoxLayout"): _stub("QVBoxLayout"),
|
||||
(MOD_QTWIDGETS, "QWidget"): _stub("QWidget"),
|
||||
(MOD_QTWIDGETS, "QFrame"): _stub("QFrame"),
|
||||
(MOD_QTWIDGETS, "QToolButton"): _stub("QToolButton"),
|
||||
(MOD_QTWIDGETS, "QButtonGroup"): _stub("QButtonGroup"),
|
||||
(MOD_QTWIDGETS, "QSizePolicy"): _stub("QSizePolicy"),
|
||||
}
|
||||
|
||||
for (mod_name, attr_name), stub_value in _PYSIDE_STUBS.items():
|
||||
|
||||
@@ -132,7 +132,6 @@ class TestDiscordRPC:
|
||||
def test_seek_to_adjusts_start_ts(self, rpc):
|
||||
drpc, _ = rpc
|
||||
drpc.update_song({"title": "Test"}, reset_start=True)
|
||||
original_start = drpc._start_ts
|
||||
time.sleep(0.01)
|
||||
drpc.seek_to(position_ms=30_000) # seek to 30s
|
||||
# Now the diff between now and start_ts should be ~30s
|
||||
@@ -140,7 +139,7 @@ class TestDiscordRPC:
|
||||
assert 28 <= diff <= 32 # allow some fuzz
|
||||
|
||||
def test_stop_disconnects_and_joins(self, rpc):
|
||||
drpc, mock_presence = rpc
|
||||
drpc, _ = rpc
|
||||
drpc.start()
|
||||
time.sleep(0.1)
|
||||
drpc.stop()
|
||||
@@ -148,18 +147,18 @@ class TestDiscordRPC:
|
||||
assert drpc._connected is False
|
||||
|
||||
def test_send_presence_clears_when_no_song(self, rpc):
|
||||
drpc, mock_presence = rpc
|
||||
drpc, _mock = rpc
|
||||
drpc.start()
|
||||
time.sleep(0.1)
|
||||
drpc.clear()
|
||||
time.sleep(0.1)
|
||||
mock_presence.clear.assert_called()
|
||||
_mock.clear.assert_called()
|
||||
|
||||
def test_double_start_is_idempotent(self, rpc):
|
||||
drpc, _ = rpc
|
||||
drpc.start()
|
||||
drpc.start() # should not crash
|
||||
assert True
|
||||
# If we get here without exception the test passes
|
||||
|
||||
@mock.patch("discord_rpc.Presence")
|
||||
def test_connect_failure_graceful(self, mock_presence_cls):
|
||||
|
||||
@@ -34,10 +34,6 @@ class TestFmtMs:
|
||||
assert fn(3600_000) == "60:00"
|
||||
assert fn(3661_000) == "61:01"
|
||||
|
||||
def test_zero_ms(self):
|
||||
fn = self._import()
|
||||
assert fn(0) == "0:00"
|
||||
|
||||
def test_large_duration(self):
|
||||
fn = self._import()
|
||||
assert fn(5999_000) == "99:59"
|
||||
|
||||
@@ -24,14 +24,14 @@ def music_db():
|
||||
|
||||
# ── Helper ────────────────────────────────────────────────────────────────────
|
||||
|
||||
_SONG = dict(
|
||||
video_id="test_video_001",
|
||||
title="Test Song",
|
||||
artists=[{"name": "Test Artist", "id": "artist_001"}],
|
||||
album={"name": "Test Album", "id": "album_001"},
|
||||
duration=240,
|
||||
thumbnail="https://example.com/thumb.jpg",
|
||||
)
|
||||
_SONG = {
|
||||
"video_id": "test_video_001",
|
||||
"title": "Test Song",
|
||||
"artists": [{"name": "Test Artist", "id": "artist_001"}],
|
||||
"album": {"name": "Test Album", "id": "album_001"},
|
||||
"duration": 240,
|
||||
"thumbnail": "https://example.com/thumb.jpg",
|
||||
}
|
||||
|
||||
|
||||
def _record_play(db, **overrides):
|
||||
|
||||
@@ -239,8 +239,8 @@ class TestStaleFiles:
|
||||
td = tempfile.mkdtemp(prefix="tunetti_test_")
|
||||
monkeypatch.setattr("player._TUNETTI_TMP", td)
|
||||
|
||||
with open(os.path.join(td, "vid123.mp3"), "w") as f:
|
||||
pass # empty
|
||||
with open(os.path.join(td, "vid123.mp3"), "w") as _f:
|
||||
pass # empty; _f unused intentionally
|
||||
|
||||
result = _stale_files("vid123")
|
||||
assert result == []
|
||||
|
||||
Reference in New Issue
Block a user