steam-backlog-enforcer/steam_backlog_enforcer/tests/test_protondb.py
Krzysztof kuhy Rudnicki 9a2dd4fb73 Bring every test file under the 250-line cap
The pre-push ci-mirror runs the file-length gate over the whole tree, not
the diff, so ~30 files left it red and no push could land. This clears the
test half: 18 modules split into 60, plus the docstrings pylint wants on
every class and test method.

Splits are by responsibility, never mechanical partN names -- files are
named for the first class or test they contain (test_stats_sum_hours,
test_store_blocker_unblock_store, ...). Where a file was a single oversized
class, its test methods are partitioned into sibling classes instead, with
fixtures and helper classes copied into every part: a method-level split
that drops an autouse fixture fails at runtime, not at import, so it is easy
to miss.

test_polls_tracking_part2 keeps its name only because it still holds one
indivisible class; the rest of the partN files are gone.

1347 tests pass, unchanged in count and name from before the split -- the
splitter was checked by diffing test-function names, since a test silently
lost in a partition looks identical to one that never existed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016A1EYiv7e7HGhET84oa9M3
2026-08-24 14:16:08 +02:00

197 lines
6.5 KiB
Python

"""Tests for protondb module."""
from __future__ import annotations
import json
from typing import TYPE_CHECKING, Any
from unittest.mock import patch
from steam_backlog_enforcer.protondb import (
ProtonDBRating,
_load_cache,
_rating_from_cache,
_rating_to_dict,
_save_cache,
)
if TYPE_CHECKING:
from pathlib import Path
class TestProtonDBRating:
"""Tests for ProtonDBRating."""
def test_playable_native(self) -> None:
"""Test playable native."""
r = ProtonDBRating(app_id=1, tier="native")
assert r.is_playable is True
def test_playable_platinum(self) -> None:
"""Test playable platinum."""
r = ProtonDBRating(app_id=1, tier="platinum")
assert r.is_playable is True
def test_playable_gold(self) -> None:
"""Test playable gold."""
r = ProtonDBRating(app_id=1, tier="gold")
assert r.is_playable is True
def test_not_playable_silver(self) -> None:
"""Test not playable silver."""
r = ProtonDBRating(app_id=1, tier="silver")
assert r.is_playable is False
def test_not_playable_bronze(self) -> None:
"""Test not playable bronze."""
r = ProtonDBRating(app_id=1, tier="bronze")
assert r.is_playable is False
def test_not_playable_borked(self) -> None:
"""Test not playable borked."""
r = ProtonDBRating(app_id=1, tier="borked")
assert r.is_playable is False
def test_playable_no_data(self) -> None:
"""Test playable no data."""
r = ProtonDBRating(app_id=1, tier="")
assert r.is_playable is True
def test_playable_pending(self) -> None:
"""Test playable pending."""
r = ProtonDBRating(app_id=1, tier="pending")
assert r.is_playable is True
def test_gold_trending_silver(self) -> None:
"""Test gold trending silver."""
r = ProtonDBRating(app_id=1, tier="gold", trending_tier="silver")
assert r.is_playable is True
def test_gold_trending_gold(self) -> None:
"""Test gold trending gold."""
r = ProtonDBRating(app_id=1, tier="gold", trending_tier="gold")
assert r.is_playable is True
def test_silver_trending_gold(self) -> None:
"""Test silver trending gold."""
r = ProtonDBRating(app_id=1, tier="silver", trending_tier="gold")
assert r.is_playable is True
def test_gold_no_trending(self) -> None:
"""Test gold no trending."""
r = ProtonDBRating(app_id=1, tier="gold", trending_tier="")
assert r.is_playable is True
def test_gold_trending_platinum(self) -> None:
"""Test gold trending platinum."""
r = ProtonDBRating(app_id=1, tier="gold", trending_tier="platinum")
assert r.is_playable is True
def test_gold_trending_unknown(self) -> None:
"""Test gold trending unknown."""
r = ProtonDBRating(app_id=1, tier="gold", trending_tier="unknown")
assert r.is_playable is False
def test_gold_trending_bronze(self) -> None:
"""Test gold trending bronze."""
r = ProtonDBRating(app_id=1, tier="gold", trending_tier="bronze")
assert r.is_playable is False
def test_unknown_tier(self) -> None:
"""Test unknown tier."""
r = ProtonDBRating(app_id=1, tier="unknown_tier")
assert r.is_playable is False
def test_unplayable_reason_no_trending_tier(self) -> None:
"""Test unplayable reason no trending tier."""
r = ProtonDBRating(app_id=1, tier="borked")
assert "tier<" in r.unplayable_reason
def test_unplayable_reason_for_silver_silver(self) -> None:
"""Test unplayable reason for silver silver."""
r = ProtonDBRating(app_id=1, tier="silver", trending_tier="silver")
assert "no gold tier" in r.unplayable_reason
def test_unplayable_reason_for_gold_bronze(self) -> None:
"""Test unplayable reason for gold bronze."""
r = ProtonDBRating(app_id=1, tier="gold", trending_tier="bronze")
assert "below silver" in r.unplayable_reason
def test_unplayable_reason_empty_when_playable(self) -> None:
"""Test unplayable reason empty when playable."""
r = ProtonDBRating(app_id=1, tier="gold")
assert r.unplayable_reason == ""
class TestProtonDBCache:
"""Tests for cache I/O."""
def test_load_cache_exists(self, tmp_path: Path) -> None:
"""Test load cache exists."""
cache_file = tmp_path / "protondb_cache.json"
cache_file.write_text(json.dumps({"440": {"tier": "gold"}}), encoding="utf-8")
with patch(
"steam_backlog_enforcer.protondb.PROTONDB_CACHE_FILE",
cache_file,
):
result = _load_cache()
assert result == {"440": {"tier": "gold"}}
def test_load_cache_missing(self, tmp_path: Path) -> None:
"""Test load cache missing."""
cache_file = tmp_path / "nonexistent.json"
with patch(
"steam_backlog_enforcer.protondb.PROTONDB_CACHE_FILE",
cache_file,
):
assert _load_cache() == {}
def test_save_cache(self, tmp_path: Path) -> None:
"""Test save cache."""
cache_file = tmp_path / "protondb_cache.json"
config_dir = tmp_path
with (
patch(
"steam_backlog_enforcer.protondb.PROTONDB_CACHE_FILE",
cache_file,
),
patch("steam_backlog_enforcer.protondb.CONFIG_DIR", config_dir),
):
_save_cache({"440": {"tier": "gold"}})
assert cache_file.exists()
class TestRatingConversion:
"""Tests for rating serialization."""
def test_to_dict(self) -> None:
"""Test to dict."""
r = ProtonDBRating(
app_id=1,
tier="gold",
trending_tier="platinum",
score=0.9,
confidence="high",
total_reports=100,
)
d = _rating_to_dict(r)
assert d["tier"] == "gold"
assert d["total_reports"] == 100
def test_from_cache(self) -> None:
"""Test from cache."""
data: dict[str, Any] = {
"tier": "silver",
"trending_tier": "bronze",
"score": 0.5,
}
r = _rating_from_cache(440, data)
assert r.app_id == 440
assert r.tier == "silver"
assert r.trending_tier == "bronze"
def test_from_cache_defaults(self) -> None:
"""Test from cache defaults."""
r = _rating_from_cache(440, {})
assert r.tier == ""
assert r.total_reports == 0