fix: add websockets dependency and apply ruff formatting to tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Krzysztof kuhy Rudnicki 2026-05-28 21:00:49 +02:00
parent b8bd8459e4
commit 06c61f08bc
9 changed files with 37 additions and 108 deletions

View File

@ -16,4 +16,5 @@ pytest-timeout>=2.2.0
pytest-xdist>=3.5.0
requests>=2.0
ruff>=0.8.0
websockets>=12.0
types-requests>=2.31.0

View File

@ -105,9 +105,7 @@ class TestEnforceAllowedGame:
"steam_backlog_enforcer.enforcer.get_running_steam_game_pids",
return_value={100: 570, 200: 440},
),
patch(
"steam_backlog_enforcer.enforcer.kill_process"
) as mock_kill,
patch("steam_backlog_enforcer.enforcer.kill_process") as mock_kill,
):
result = enforce_allowed_game(440, kill_unauthorized=True)
assert result == [(100, 570)]
@ -144,9 +142,7 @@ class TestEnforceAllowedGame:
"steam_backlog_enforcer.enforcer.is_protected_app",
side_effect=lambda aid: aid == 1331550,
),
patch(
"steam_backlog_enforcer.enforcer.kill_process"
) as mock_kill,
patch("steam_backlog_enforcer.enforcer.kill_process") as mock_kill,
):
result = enforce_allowed_game(440, kill_unauthorized=True)
assert result == []
@ -180,9 +176,7 @@ class TestSendNotification:
"""Tests for send_notification."""
def test_sends(self) -> None:
with patch(
"steam_backlog_enforcer.enforcer.subprocess.run"
) as mock_run:
with patch("steam_backlog_enforcer.enforcer.subprocess.run") as mock_run:
send_notification("Title", "Body")
mock_run.assert_called_once()

View File

@ -98,9 +98,7 @@ class TestTriggerSteamInstall:
"""Tests for _trigger_steam_install."""
def test_success(self) -> None:
with patch(
"steam_backlog_enforcer.game_install.subprocess.run"
) as mock_run:
with patch("steam_backlog_enforcer.game_install.subprocess.run") as mock_run:
result = _trigger_steam_install(440, "TF2")
assert result is True
mock_run.assert_called_once()
@ -174,15 +172,11 @@ class TestIsGameInstalled:
def test_installed(self, tmp_path: Path) -> None:
manifest = tmp_path / "appmanifest_440.acf"
manifest.touch()
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
assert is_game_installed(440) is True
def test_not_installed(self, tmp_path: Path) -> None:
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
assert is_game_installed(440) is False
@ -204,9 +198,7 @@ class TestEnsureSteamRunning:
"steam_backlog_enforcer.game_install.subprocess.run",
return_value=mock_result,
),
patch(
"steam_backlog_enforcer.game_install.subprocess.Popen"
) as mock_popen,
patch("steam_backlog_enforcer.game_install.subprocess.Popen") as mock_popen,
patch(
"steam_backlog_enforcer.game_install.os.geteuid",
return_value=1000,
@ -226,9 +218,7 @@ class TestEnsureSteamRunning:
"steam_backlog_enforcer.game_install.subprocess.run",
return_value=mock_result,
),
patch(
"steam_backlog_enforcer.game_install.subprocess.Popen"
) as mock_popen,
patch("steam_backlog_enforcer.game_install.subprocess.Popen") as mock_popen,
patch(
"steam_backlog_enforcer.game_install.os.geteuid",
return_value=0,

View File

@ -25,9 +25,7 @@ class TestInstallGame:
def test_already_installed(self, tmp_path: Path) -> None:
manifest = tmp_path / "appmanifest_440.acf"
manifest.touch()
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
assert install_game(440, "TF2", "steam123") is True
def test_use_steam_protocol_success(self, tmp_path: Path) -> None:
@ -36,9 +34,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH",
tmp_path,
),
patch(
"steam_backlog_enforcer.game_install._ensure_steam_running"
),
patch("steam_backlog_enforcer.game_install._ensure_steam_running"),
patch(
"steam_backlog_enforcer.game_install._trigger_steam_install",
return_value=True,
@ -52,9 +48,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH",
tmp_path,
),
patch(
"steam_backlog_enforcer.game_install._ensure_steam_running"
),
patch("steam_backlog_enforcer.game_install._ensure_steam_running"),
patch(
"steam_backlog_enforcer.game_install._trigger_steam_install",
return_value=False,
@ -73,9 +67,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH",
tmp_path,
),
patch(
"steam_backlog_enforcer.game_install._ensure_steam_running"
),
patch("steam_backlog_enforcer.game_install._ensure_steam_running"),
patch(
"steam_backlog_enforcer.game_install.os.geteuid",
return_value=0,
@ -88,9 +80,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install._get_uid_gid_for_user",
return_value=(1001, 1001),
),
patch(
"steam_backlog_enforcer.game_install.os.chown"
) as mock_chown,
patch("steam_backlog_enforcer.game_install.os.chown") as mock_chown,
):
assert install_game(440, "TF2", "s1") is True
mock_chown.assert_called_once()
@ -102,9 +92,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH",
tmp_path / "nonexistent" / "deep",
),
patch(
"steam_backlog_enforcer.game_install._ensure_steam_running"
),
patch("steam_backlog_enforcer.game_install._ensure_steam_running"),
patch(
"steam_backlog_enforcer.game_install.os.geteuid",
return_value=1000,
@ -118,9 +106,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH",
tmp_path,
),
patch(
"steam_backlog_enforcer.game_install._ensure_steam_running"
),
patch("steam_backlog_enforcer.game_install._ensure_steam_running"),
patch(
"steam_backlog_enforcer.game_install.os.geteuid",
return_value=1000,
@ -134,16 +120,12 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH",
tmp_path,
),
patch(
"steam_backlog_enforcer.game_install._ensure_steam_running"
),
patch("steam_backlog_enforcer.game_install._ensure_steam_running"),
patch(
"steam_backlog_enforcer.game_install.os.geteuid",
return_value=1000,
),
patch(
"steam_backlog_enforcer.game_install.os.chown"
) as mock_chown,
patch("steam_backlog_enforcer.game_install.os.chown") as mock_chown,
):
assert install_game(440, "TF2", "s1") is True
mock_chown.assert_not_called()
@ -155,9 +137,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH",
tmp_path,
),
patch(
"steam_backlog_enforcer.game_install._ensure_steam_running"
),
patch("steam_backlog_enforcer.game_install._ensure_steam_running"),
patch(
"steam_backlog_enforcer.game_install.os.geteuid",
return_value=0,
@ -166,9 +146,7 @@ class TestInstallGame:
"steam_backlog_enforcer.game_install._get_real_user",
return_value="root",
),
patch(
"steam_backlog_enforcer.game_install.os.chown"
) as mock_chown,
patch("steam_backlog_enforcer.game_install.os.chown") as mock_chown,
):
assert install_game(440, "TF2", "s1") is True
mock_chown.assert_not_called()
@ -180,34 +158,26 @@ class TestGetInstalledGames:
def test_parses_manifests(self, tmp_path: Path) -> None:
manifest = tmp_path / "appmanifest_440.acf"
manifest.write_text('"appid"\t\t"440"\n"name"\t\t"Team Fortress 2"\n')
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
result = get_installed_games()
assert result == [(440, "Team Fortress 2")]
def test_no_name(self, tmp_path: Path) -> None:
manifest = tmp_path / "appmanifest_440.acf"
manifest.write_text('"appid"\t\t"440"\n')
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
result = get_installed_games()
assert result == [(440, "Unknown (440)")]
def test_empty_dir(self, tmp_path: Path) -> None:
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
result = get_installed_games()
assert result == []
def test_no_appid_match(self, tmp_path: Path) -> None:
manifest = tmp_path / "appmanifest_440.acf"
manifest.write_text('"name"\t\t"NoAppId"\n')
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
result = get_installed_games()
assert result == []
@ -218,18 +188,14 @@ class TestReadInstallDir:
def test_reads_dir(self, tmp_path: Path) -> None:
manifest = tmp_path / "appmanifest_440.acf"
manifest.write_text('"installdir"\t\t"Team Fortress 2"\n')
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
result = _read_install_dir(manifest)
assert result == tmp_path / "common" / "Team Fortress 2"
def test_no_match(self, tmp_path: Path) -> None:
manifest = tmp_path / "appmanifest_440.acf"
manifest.write_text('"appid"\t\t"440"\n')
with patch(
"steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path
):
with patch("steam_backlog_enforcer.game_install.STEAMAPPS_PATH", tmp_path):
assert _read_install_dir(manifest) is None
def test_missing_file(self, tmp_path: Path) -> None:

View File

@ -32,25 +32,19 @@ class TestHltbCache:
def test_load_cache_exists(self, tmp_path: Path) -> None:
cache_file = tmp_path / "hltb_cache.json"
cache_file.write_text(json.dumps({"440": 10.5}), encoding="utf-8")
with patch(
"steam_backlog_enforcer._hltb_types.HLTB_CACHE_FILE", cache_file
):
with patch("steam_backlog_enforcer._hltb_types.HLTB_CACHE_FILE", cache_file):
result = load_hltb_cache()
assert result == {440: 10.5}
def test_load_cache_missing(self, tmp_path: Path) -> None:
cache_file = tmp_path / "nonexistent.json"
with patch(
"steam_backlog_enforcer._hltb_types.HLTB_CACHE_FILE", cache_file
):
with patch("steam_backlog_enforcer._hltb_types.HLTB_CACHE_FILE", cache_file):
assert load_hltb_cache() == {}
def test_load_cache_corrupt(self, tmp_path: Path) -> None:
cache_file = tmp_path / "hltb_cache.json"
cache_file.write_text("not json", encoding="utf-8")
with patch(
"steam_backlog_enforcer._hltb_types.HLTB_CACHE_FILE", cache_file
):
with patch("steam_backlog_enforcer._hltb_types.HLTB_CACHE_FILE", cache_file):
assert load_hltb_cache() == {}
def test_save_cache(self, tmp_path: Path) -> None:
@ -79,18 +73,14 @@ class TestGetHltbSearchUrl:
def test_discovers_url(self) -> None:
mock_info = MagicMock()
mock_info.search_url = "/api/search/abc"
with patch(
"steam_backlog_enforcer._hltb_search.HTMLRequests"
) as mock_html:
with patch("steam_backlog_enforcer._hltb_search.HTMLRequests") as mock_html:
mock_html.send_website_request_getcode.return_value = mock_info
mock_html.BASE_URL = "https://howlongtobeat.com"
url = _get_hltb_search_url()
assert url == "https://howlongtobeat.com/api/search/abc"
def test_fallback_url(self) -> None:
with patch(
"steam_backlog_enforcer._hltb_search.HTMLRequests"
) as mock_html:
with patch("steam_backlog_enforcer._hltb_search.HTMLRequests") as mock_html:
mock_html.send_website_request_getcode.return_value = None
url = _get_hltb_search_url()
assert url == "https://howlongtobeat.com/api/finder"
@ -98,18 +88,14 @@ class TestGetHltbSearchUrl:
def test_first_returns_none_second_returns_info(self) -> None:
mock_info = MagicMock()
mock_info.search_url = "/api/search/xyz"
with patch(
"steam_backlog_enforcer._hltb_search.HTMLRequests"
) as mock_html:
with patch("steam_backlog_enforcer._hltb_search.HTMLRequests") as mock_html:
mock_html.send_website_request_getcode.side_effect = [None, mock_info]
mock_html.BASE_URL = "https://howlongtobeat.com"
url = _get_hltb_search_url()
assert url == "https://howlongtobeat.com/api/search/xyz"
def test_exception_fallback(self) -> None:
with patch(
"steam_backlog_enforcer._hltb_search.HTMLRequests"
) as mock_html:
with patch("steam_backlog_enforcer._hltb_search.HTMLRequests") as mock_html:
mock_html.send_website_request_getcode.side_effect = RuntimeError
url = _get_hltb_search_url()
assert url == "https://howlongtobeat.com/api/finder"

View File

@ -454,9 +454,7 @@ class TestFetchLeisureTimes:
new_callable=AsyncMock,
return_value=game_data,
),
patch(
"steam_backlog_enforcer._hltb_detail.save_hltb_cache"
) as mock_save,
patch("steam_backlog_enforcer._hltb_detail.save_hltb_cache") as mock_save,
):
asyncio.run(_fetch_leisure_times(results, cache, {}, None))
mock_save.assert_called_once()

View File

@ -322,9 +322,7 @@ class TestPickNextGame:
"steam_backlog_enforcer.scanning.is_game_installed",
return_value=False,
),
patch(
"steam_backlog_enforcer.scanning.install_game"
) as mock_install,
patch("steam_backlog_enforcer.scanning.install_game") as mock_install,
patch("builtins.input", return_value="1"),
):
pick_next_game([g1], state, config)

View File

@ -311,9 +311,7 @@ class TestPickNextGameSequential:
return_value=0,
)
)
stack.enter_context(
patch("steam_backlog_enforcer.config._atomic_write")
)
stack.enter_context(patch("steam_backlog_enforcer.config._atomic_write"))
return stack
def test_on_select_accepts_pick(self) -> None:

View File

@ -172,9 +172,7 @@ class TestConfidenceHelpers:
patch(
"steam_backlog_enforcer._scanning_confidence._refresh_candidate_confidence_batch",
),
patch(
"steam_backlog_enforcer._scanning_confidence._echo"
) as mock_echo,
patch("steam_backlog_enforcer._scanning_confidence._echo") as mock_echo,
):
result = _filter_hltb_confident_candidates([low])
assert result == []