steam-backlog-enforcer/steam_backlog_enforcer/tests/test_main_misc.py
2026-10-03 13:43:32 +02:00

131 lines
4.3 KiB
Python

"""Tests for the main CLI: store, reset, setup, exception and block-gaming commands."""
from datetime import UTC, datetime
from unittest.mock import patch
import pytest
from steam_backlog_enforcer._store_window import DEFAULT_WINDOW_MINUTES
from steam_backlog_enforcer.config import Config, State
from steam_backlog_enforcer.main import (
cmd_buy_dlc,
cmd_reset,
cmd_setup,
cmd_unblock,
)
PKG = "steam_backlog_enforcer.main.misc"
_UNTIL = datetime(2026, 10, 3, 12, 0, tzinfo=UTC)
_FIVE_MINUTES = 5
class TestCmdUnblock:
"""Tests for cmd_unblock: it opens a timed store window."""
def test_default_window(self) -> None:
with (
patch(f"{PKG}.open_store_window", return_value=_UNTIL) as mock_open,
patch(f"{PKG}._echo") as mock_echo,
):
cmd_unblock(Config(), State())
assert mock_open.call_args.args[1] == DEFAULT_WINDOW_MINUTES
assert any("UNBLOCKED until" in str(c) for c in mock_echo.call_args_list)
def test_explicit_minutes(self) -> None:
with (
patch(f"{PKG}.open_store_window", return_value=_UNTIL) as mock_open,
patch(f"{PKG}._echo"),
):
cmd_unblock(Config(), State(), ["5"])
assert mock_open.call_args.args[1] == _FIVE_MINUTES
@pytest.mark.parametrize("raw", ["abc", "0", "31"])
def test_bad_minutes_exits(self, raw: str) -> None:
with (
patch(f"{PKG}._echo") as mock_echo,
pytest.raises(SystemExit),
):
cmd_unblock(Config(), State(), [raw])
assert any("Usage" in str(c) for c in mock_echo.call_args_list)
def test_unblock_failure_exits(self) -> None:
with (
patch(f"{PKG}.open_store_window", side_effect=RuntimeError("sudo?")),
patch(f"{PKG}._echo") as mock_echo,
pytest.raises(SystemExit),
):
cmd_unblock(Config(), State())
assert any("Failed" in str(c) for c in mock_echo.call_args_list)
class TestCmdBuyDlc:
"""cmd_buy_dlc is the default-length window, assigned game or not."""
def test_opens_default_window(self) -> None:
with (
patch(f"{PKG}.open_store_window", return_value=_UNTIL) as mock_open,
patch(f"{PKG}._echo"),
):
cmd_buy_dlc(Config(), State())
assert mock_open.call_args.args[1] == DEFAULT_WINDOW_MINUTES
class TestCmdReset:
"""Tests for cmd_reset."""
def test_normal_reset(self) -> None:
state = State(current_app_id=1, current_game_name="G", finished_app_ids=[1])
with (
patch(f"{PKG}.unblock_store"),
patch(f"{PKG}.get_all_owned_app_ids", return_value=[1, 2]),
patch(f"{PKG}.unhide_all_games", return_value=2),
patch(f"{PKG}._echo"),
patch.object(State, "save"),
):
cmd_reset(Config(), state)
assert state.current_app_id is None
assert state.finished_app_ids == []
def test_unhide_fails(self) -> None:
state = State(current_app_id=1)
with (
patch(f"{PKG}.unblock_store"),
patch(
f"{PKG}.get_all_owned_app_ids",
side_effect=OSError("fail"),
),
patch(f"{PKG}._echo"),
patch.object(State, "save"),
):
cmd_reset(Config(), state)
def test_unhide_returns_zero(self) -> None:
state = State(current_app_id=1)
with (
patch(f"{PKG}.unblock_store"),
patch(f"{PKG}.get_all_owned_app_ids", return_value=[1, 2]),
patch(f"{PKG}.unhide_all_games", return_value=0),
patch(f"{PKG}._echo"),
patch.object(State, "save"),
):
cmd_reset(Config(), state)
def test_no_owned_ids(self) -> None:
state = State(current_app_id=1)
with (
patch(f"{PKG}.unblock_store"),
patch(f"{PKG}.get_all_owned_app_ids", return_value=[]),
patch(f"{PKG}._echo"),
patch.object(State, "save"),
):
cmd_reset(Config(), state)
class TestCmdSetup:
"""Tests for cmd_setup."""
def test_calls_interactive(self) -> None:
with patch(f"{PKG}.interactive_setup") as mock_setup:
cmd_setup(Config(), State())
mock_setup.assert_called_once()