"""Tests for post-game refractor card render trigger.""" from unittest.mock import AsyncMock, patch import pytest from command_logic.logic_gameplay import _trigger_variant_renders class TestTriggerVariantRenders: """Fire-and-forget card render calls after tier-ups.""" @pytest.mark.asyncio async def test_calls_render_url_for_each_tier_up(self): """Each tier-up with variant_created triggers a card render GET request.""" tier_ups = [ {"player_id": 100, "variant_created": 7, "track_name": "Batter"}, {"player_id": 200, "variant_created": 3, "track_name": "Pitcher"}, ] with patch( "command_logic.logic_gameplay.db_get", new_callable=AsyncMock ) as mock_get: mock_get.return_value = None await _trigger_variant_renders(tier_ups) assert mock_get.call_count == 2 call_args_list = [call.args[0] for call in mock_get.call_args_list] assert any("100" in url and "7" in url for url in call_args_list) assert any("200" in url and "3" in url for url in call_args_list) @pytest.mark.asyncio async def test_skips_tier_ups_without_variant(self): """Tier-ups without variant_created are skipped.""" tier_ups = [ {"player_id": 100, "track_name": "Batter"}, ] with patch( "command_logic.logic_gameplay.db_get", new_callable=AsyncMock ) as mock_get: await _trigger_variant_renders(tier_ups) mock_get.assert_not_called() @pytest.mark.asyncio async def test_api_failure_does_not_raise(self): """Render trigger failures are swallowed — fire-and-forget.""" tier_ups = [ {"player_id": 100, "variant_created": 7, "track_name": "Batter"}, ] with patch( "command_logic.logic_gameplay.db_get", new_callable=AsyncMock ) as mock_get: mock_get.side_effect = Exception("API down") await _trigger_variant_renders(tier_ups) @pytest.mark.asyncio async def test_empty_tier_ups_is_noop(self): """Empty tier_ups list does nothing.""" with patch( "command_logic.logic_gameplay.db_get", new_callable=AsyncMock ) as mock_get: await _trigger_variant_renders([]) mock_get.assert_not_called()