import pytest import asyncio from unittest.mock import MagicMock, AsyncMock, patch @pytest.fixture def vclogs_cog(bot): from cogs.vclogs import VcLogs cog = VcLogs(bot) return cog @pytest.mark.slow @pytest.mark.asyncio async def test_full_voice_session_tracking(vclogs_cog, monkeypatch): """Test complete voice session with AFK transitions using real time sleeps.""" cog = vclogs_cog # Set up environment monkeypatch.setenv("STATUS_CHANNEL_ID", "123456") member = MagicMock() member.id = 123 member.guild.id = 456 member.bot = False member.display_name = "TestUser" member.guild.get_member.return_value = member # Create a mock log channel log_channel = MagicMock() log_channel.send = AsyncMock(return_value=MagicMock()) # Mock bot.get_channel to return our log channel with patch.object(vclogs_cog.bot, 'get_channel', return_value=log_channel): # Join voice before = MagicMock() before.channel = None after_join = MagicMock() after_join.channel = MagicMock() after_join.channel.id = 789 after_join.channel.name = "Test Voice" after_join.self_deaf = False after_join.self_mute = False after_join.deaf = False after_join.mute = False await cog.on_voice_state_update(member, before, after_join) await asyncio.sleep(2) # Simulate 2s active # Go AFK (self_deaf) before_afk = after_join after_afk = MagicMock() after_afk.channel = before_afk.channel after_afk.self_deaf = True after_afk.self_mute = False after_afk.deaf = True after_afk.mute = False await cog.on_voice_state_update(member, before_afk, after_afk) await asyncio.sleep(3) # Simulate 3s AFK # Return from AFK before_back = after_afk after_back = MagicMock() after_back.channel = before_back.channel after_back.self_deaf = False after_back.self_mute = False after_back.deaf = False after_back.mute = False await cog.on_voice_state_update(member, before_back, after_back) await asyncio.sleep(1) # Simulate 1s active # Leave voice before_leave = after_back after_leave = MagicMock() after_leave.channel = None after_leave.self_deaf = False after_leave.self_mute = False await cog.on_voice_state_update(member, before_leave, after_leave) # Verify activity was saved (check DB) from cogs.vclogs import load_activity_data activity_data = load_activity_data() # After leaving, data should be deleted, so check the log channel was called assert log_channel.send.called