🐛 | Improve test coverage for SonarQube quality gate
Some checks failed
SonarQube Code Quality Scan / SonarQube Scan (push) Failing after 1m20s
Some checks failed
SonarQube Code Quality Scan / SonarQube Scan (push) Failing after 1m20s
- Restructure conftest to try real Qt first, fall back to stubs only if that fails — ensures try/except guards in player.py and gui.py are exercised in CI, improving new_coverage - Add tests for _migrate_legacy error paths (JSONDecodeError, OSError, db migration) — config.py now 100% covered - Add tests for _disconnect, _send_presence exception handlers — discord_rpc.py now 97% covered - Add tests for _cleanup_path and _tmp_dir helpers — player.py coverage bumped to 33%
This commit is contained in:
@@ -59,6 +59,10 @@ class TestLoadConfig:
|
||||
assert loaded["volume"] == 50 # default
|
||||
# The corrupt file is not overwritten, but defaults are returned
|
||||
|
||||
|
||||
class TestMigrateLegacy:
|
||||
"""Tests for the legacy config migration path."""
|
||||
|
||||
def test_legacy_migration(self, _patch_config_paths):
|
||||
"""Legacy config in project dir is migrated to XDG location."""
|
||||
cfg = _patch_config_paths
|
||||
@@ -76,8 +80,63 @@ class TestLoadConfig:
|
||||
assert not cfg._LEGACY_FILE.exists()
|
||||
assert cfg._LEGACY_FILE.with_suffix(".json.migrated").exists()
|
||||
|
||||
def test_legacy_migration_corrupt_json_ignored(self, _patch_config_paths):
|
||||
"""Corrupt legacy JSON is silently ignored (covers JSONDecodeError)."""
|
||||
cfg = _patch_config_paths
|
||||
cfg.CONFIG_FILE.unlink(missing_ok=True)
|
||||
cfg.SETTINGS = dict(cfg.DEFAULT_CONFIG)
|
||||
|
||||
cfg._LEGACY_FILE.write_text("not valid json at all")
|
||||
loaded = cfg.load_config() # should not crash
|
||||
assert loaded["volume"] == 50 # defaults returned
|
||||
|
||||
def test_legacy_oserror_handled_gracefully(self, _patch_config_paths, monkeypatch):
|
||||
"""OSError during migration is silently ignored."""
|
||||
cfg = _patch_config_paths
|
||||
cfg.CONFIG_FILE.unlink(missing_ok=True)
|
||||
cfg.SETTINGS = dict(cfg.DEFAULT_CONFIG)
|
||||
|
||||
cfg._LEGACY_FILE.write_text(json.dumps({"volume": 80}))
|
||||
|
||||
# Make ``os.rename`` fail (used by Path.rename)
|
||||
def _fail_rename(src, dst):
|
||||
raise OSError("Permission denied")
|
||||
|
||||
monkeypatch.setattr(os, "rename", _fail_rename)
|
||||
|
||||
# load_config should catch the OSError
|
||||
loaded = cfg.load_config()
|
||||
# save_config runs BEFORE the failing rename, so the value IS persisted
|
||||
assert loaded["volume"] == 80
|
||||
|
||||
def test_legacy_db_migration(self, _patch_config_paths):
|
||||
"""Database file from legacy project dir is copied to XDG location."""
|
||||
cfg = _patch_config_paths
|
||||
cfg.CONFIG_FILE.unlink(missing_ok=True)
|
||||
cfg.SETTINGS = dict(cfg.DEFAULT_CONFIG)
|
||||
|
||||
# The migration only copies the db if old_db_path.parent matches
|
||||
# the config.py directory. Create the legacy db there.
|
||||
config_dir = Path(cfg.__file__).parent
|
||||
legacy_db = config_dir / "music_history.db"
|
||||
legacy_db.write_text("fake db content")
|
||||
|
||||
legacy = {**cfg.DEFAULT_CONFIG, "db_path": str(legacy_db)}
|
||||
cfg._LEGACY_FILE.write_text(json.dumps(legacy))
|
||||
|
||||
loaded = cfg.load_config()
|
||||
# db_path should point to the new XDG location
|
||||
assert loaded["db_path"] == str(cfg.CONFIG_DIR / "music_history.db")
|
||||
assert cfg.CONFIG_DIR.exists()
|
||||
# Original file should still exist
|
||||
assert legacy_db.exists()
|
||||
|
||||
# Clean up
|
||||
legacy_db.unlink(missing_ok=True)
|
||||
|
||||
|
||||
class TestSaveConfig:
|
||||
|
||||
def test_save_config_persists(self, _patch_config_paths):
|
||||
"""save_config writes merged config to disk."""
|
||||
cfg = _patch_config_paths
|
||||
|
||||
Reference in New Issue
Block a user