feat: add voice channel cleanup and signal handling during application shutdown
This commit is contained in:
3 files changed
+211
-9
No files matched your search
@@ -0,0 +1,79 @@
|
||||
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.bot = MusicBot(
|
||||
self.settings,
|
||||
self.tracks,
|
||||
self.uploads,
|
||||
self.config,
|
||||
self.history,
|
||||
)
|
||||
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)
|
||||
Reference in new issue
Block a user