test_discord_model_picker.py
1 """Regression tests for the Discord /model picker. 2 3 Uses the shared discord mock from tests/gateway/conftest.py (installed 4 at collection time via _ensure_discord_mock()). Previously this file 5 installed its own mock at module-import time and clobbered sys.modules, 6 breaking other gateway tests under pytest-xdist. 7 """ 8 9 from types import SimpleNamespace 10 from unittest.mock import AsyncMock 11 12 import pytest 13 14 from gateway.platforms.discord import ModelPickerView 15 16 17 @pytest.mark.asyncio 18 async def test_model_picker_clears_controls_before_running_switch_callback(): 19 events: list[object] = [] 20 21 async def on_model_selected(chat_id: str, model_id: str, provider_slug: str) -> str: 22 events.append(("switch", chat_id, model_id, provider_slug)) 23 return "Model switched" 24 25 async def edit_message(**kwargs): 26 events.append( 27 ( 28 "initial-edit", 29 kwargs["embed"].title, 30 kwargs["embed"].description, 31 kwargs["view"], 32 ) 33 ) 34 35 async def edit_original_response(**kwargs): 36 events.append(( 37 "final-edit", 38 kwargs["embed"].title, 39 kwargs["embed"].description, 40 kwargs["view"], 41 )) 42 43 view = ModelPickerView( 44 providers=[ 45 { 46 "slug": "copilot", 47 "name": "GitHub Copilot", 48 "models": ["gpt-5.4"], 49 "total_models": 1, 50 "is_current": True, 51 } 52 ], 53 current_model="gpt-5-mini", 54 current_provider="copilot", 55 session_key="session-1", 56 on_model_selected=on_model_selected, 57 allowed_user_ids=set(), 58 ) 59 view._selected_provider = "copilot" 60 61 interaction = SimpleNamespace( 62 user=SimpleNamespace(id=123), 63 channel_id=456, 64 data={"values": ["gpt-5.4"]}, 65 response=SimpleNamespace( 66 defer=AsyncMock(), 67 send_message=AsyncMock(), 68 edit_message=AsyncMock(side_effect=edit_message), 69 ), 70 edit_original_response=AsyncMock(side_effect=edit_original_response), 71 ) 72 73 await view._on_model_selected(interaction) 74 75 assert events == [ 76 ("initial-edit", "⚙ Switching Model", "Switching to `gpt-5.4`...", None), 77 ("switch", "456", "gpt-5.4", "copilot"), 78 ("final-edit", "⚙ Model Switched", "Model switched", None), 79 ] 80 interaction.response.edit_message.assert_awaited_once() 81 interaction.response.defer.assert_not_called() 82 interaction.edit_original_response.assert_awaited_once()