1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
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
|