83 lines
2.9 KiB
Python
83 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import discord
|
|
|
|
from zyrarbot.settings import Settings
|
|
from zyrarbot.ui.bot.client import MusicBot
|
|
|
|
|
|
class ShutdownVoiceCleanupTests(unittest.IsolatedAsyncioTestCase):
|
|
def setUp(self):
|
|
self.settings = Settings(discord_token="fake_token")
|
|
self.tracks = MagicMock()
|
|
self.uploads = MagicMock()
|
|
self.config = MagicMock()
|
|
self.history = MagicMock()
|
|
self.migration = MagicMock()
|
|
|
|
self.bot = MusicBot(
|
|
self.settings,
|
|
self.tracks,
|
|
self.uploads,
|
|
self.config,
|
|
self.history,
|
|
self.migration,
|
|
)
|
|
self.player = MagicMock()
|
|
self.bot.player = self.player
|
|
|
|
async def test_disconnect_all_voice_disconnects_vcs_and_cleans_guild_state(self):
|
|
mock_vc = MagicMock()
|
|
mock_vc.guild.id = 12345
|
|
mock_vc.channel.name = "Test Channel"
|
|
mock_vc.is_connected.return_value = True
|
|
mock_vc.disconnect = AsyncMock()
|
|
|
|
mock_guild = MagicMock(spec=discord.Guild)
|
|
mock_guild.id = 12345
|
|
mock_guild.name = "Test Guild"
|
|
mock_guild.me.voice.channel = MagicMock()
|
|
mock_guild.change_voice_state = AsyncMock()
|
|
|
|
with (
|
|
patch.object(type(self.bot), "voice_clients", [mock_vc]),
|
|
patch.object(type(self.bot), "guilds", [mock_guild]),
|
|
):
|
|
await self.bot.disconnect_all_voice()
|
|
|
|
self.player.save_queue.assert_called_once_with(12345)
|
|
self.player.clear.assert_called_once_with(12345)
|
|
mock_vc.disconnect.assert_awaited_once_with(force=False)
|
|
mock_guild.change_voice_state.assert_awaited_once_with(channel=None)
|
|
|
|
async def test_close_calls_disconnect_all_voice_before_super_close(self):
|
|
disconnect_mock = AsyncMock()
|
|
self.bot.disconnect_all_voice = disconnect_mock
|
|
|
|
with patch("discord.ext.commands.Bot.close", new_callable=AsyncMock) as super_close_mock:
|
|
await self.bot.close()
|
|
|
|
disconnect_mock.assert_awaited_once()
|
|
super_close_mock.assert_awaited_once()
|
|
|
|
# Calling close again should be a no-op due to _is_closing guard
|
|
await self.bot.close()
|
|
self.assertEqual(disconnect_mock.await_count, 1)
|
|
|
|
async def test_on_ready_cleans_dangling_voice_connection(self):
|
|
mock_guild = MagicMock(spec=discord.Guild)
|
|
mock_guild.id = 12345
|
|
mock_guild.name = "Test Guild"
|
|
mock_guild.me.voice.channel.name = "Ghost Channel"
|
|
mock_guild.voice_client = MagicMock(spec=discord.VoiceClient)
|
|
mock_guild.voice_client.disconnect = AsyncMock()
|
|
mock_guild.change_voice_state = AsyncMock()
|
|
|
|
with patch.object(type(self.bot), "guilds", [mock_guild]):
|
|
await self.bot.on_ready()
|
|
|
|
mock_guild.voice_client.disconnect.assert_awaited_once_with(force=True)
|