82 lines
3.3 KiB
Python
82 lines
3.3 KiB
Python
"""Tests for the DevToolsCog /dev refractor-test command."""
|
|
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import discord
|
|
import pytest
|
|
|
|
|
|
class TestCleanupView:
|
|
"""Test the cleanup button view for the refractor integration test.
|
|
|
|
The view presents two buttons after a test run: 'Clean Up Test Data'
|
|
deletes the synthetic game/plays/decisions; 'Keep Test Data' dismisses
|
|
the buttons. Only the command invoker can press them.
|
|
"""
|
|
|
|
@pytest.fixture
|
|
def owner_interaction(self):
|
|
"""Interaction from the user who ran the command."""
|
|
interaction = AsyncMock(spec=discord.Interaction)
|
|
interaction.user = MagicMock()
|
|
interaction.user.id = 12345
|
|
interaction.response = AsyncMock()
|
|
return interaction
|
|
|
|
@pytest.fixture
|
|
def other_interaction(self):
|
|
"""Interaction from a different user — should be rejected."""
|
|
interaction = AsyncMock(spec=discord.Interaction)
|
|
interaction.user = MagicMock()
|
|
interaction.user.id = 99999
|
|
interaction.response = AsyncMock()
|
|
return interaction
|
|
|
|
async def test_view_has_two_buttons(self):
|
|
"""View should have exactly two buttons: cleanup and keep.
|
|
|
|
Must be async because discord.ui.View.__init__ calls
|
|
asyncio.get_running_loop() internally and requires an event loop.
|
|
"""
|
|
from cogs.dev_tools import CleanupView
|
|
|
|
view = CleanupView(owner_id=12345, game_id=1, embed=discord.Embed())
|
|
buttons = [
|
|
child for child in view.children if isinstance(child, discord.ui.Button)
|
|
]
|
|
assert len(buttons) == 2
|
|
|
|
async def test_unauthorized_user_ignored(self, other_interaction):
|
|
"""Non-owner clicks should be silently ignored."""
|
|
from cogs.dev_tools import CleanupView
|
|
|
|
view = CleanupView(owner_id=12345, game_id=1, embed=discord.Embed())
|
|
with patch("cogs.dev_tools.db_delete", new_callable=AsyncMock) as mock_delete:
|
|
await view.cleanup_btn.callback(other_interaction)
|
|
mock_delete.assert_not_called()
|
|
other_interaction.response.edit_message.assert_not_called()
|
|
|
|
async def test_cleanup_calls_delete_endpoints(self, owner_interaction):
|
|
"""Cleanup button deletes decisions, plays, then game in order."""
|
|
from cogs.dev_tools import CleanupView
|
|
|
|
embed = discord.Embed(description="test")
|
|
view = CleanupView(owner_id=12345, game_id=42, embed=embed)
|
|
with patch("cogs.dev_tools.db_delete", new_callable=AsyncMock) as mock_delete:
|
|
await view.cleanup_btn.callback(owner_interaction)
|
|
assert mock_delete.call_count == 3
|
|
# Verify correct endpoints and order
|
|
calls = mock_delete.call_args_list
|
|
assert "decisions/game" in str(calls[0])
|
|
assert "plays/game" in str(calls[1])
|
|
assert "games" in str(calls[2])
|
|
|
|
async def test_keep_removes_buttons(self, owner_interaction):
|
|
"""Keep button removes buttons and updates embed."""
|
|
from cogs.dev_tools import CleanupView
|
|
|
|
embed = discord.Embed(description="test")
|
|
view = CleanupView(owner_id=12345, game_id=42, embed=embed)
|
|
await view.keep_btn.callback(owner_interaction)
|
|
owner_interaction.response.edit_message.assert_called_once()
|