diff options
| author | salmonik <raisersoft@proton.me> | 2026-04-19 17:41:05 +0200 |
|---|---|---|
| committer | salmonik <raisersoft@proton.me> | 2026-04-19 17:41:05 +0200 |
| commit | 920d4b18e253f5642b895a1205d9826d54570db8 (patch) | |
| tree | 8539d6e633bee7e2a2f74e5bd725d6a49e7268d1 /tests/cogs | |
| parent | readd main.py (diff) | |
| download | senator-sperma-920d4b18e253f5642b895a1205d9826d54570db8.tar.gz senator-sperma-920d4b18e253f5642b895a1205d9826d54570db8.zip | |
feat: add external URL playback support, fix vclogs audio handling
Diffstat (limited to '')
| -rw-r--r-- | tests/cogs/test_music_external_play.py | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/tests/cogs/test_music_external_play.py b/tests/cogs/test_music_external_play.py new file mode 100644 index 0000000..76debc9 --- /dev/null +++ b/tests/cogs/test_music_external_play.py | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | import pytest | ||
| 2 | import os | ||
| 3 | import asyncio | ||
| 4 | import tempfile | ||
| 5 | from unittest.mock import AsyncMock, patch, MagicMock | ||
| 6 | from tests.conftest import MockApplicationContext | ||
| 7 | |||
| 8 | |||
| 9 | @pytest.fixture | ||
| 10 | def play_commands_cog(bot): | ||
| 11 | with patch('cogs.utils.temp.get_temp_dir', return_value="/tmp"): | ||
| 12 | from cogs.music.play_commands import PlayCommands | ||
| 13 | cog = PlayCommands(bot) | ||
| 14 | return cog | ||
| 15 | |||
| 16 | |||
| 17 | @pytest.fixture | ||
| 18 | def temp_mp3_file(): | ||
| 19 | with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as f: | ||
| 20 | f.write(b'fake mp3 content') | ||
| 21 | temp_path = f.name | ||
| 22 | yield temp_path | ||
| 23 | if os.path.exists(temp_path): | ||
| 24 | os.remove(temp_path) | ||
| 25 | |||
| 26 | |||
| 27 | @pytest.mark.asyncio | ||
| 28 | async def test_external_url_pattern_matches_youtube(play_commands_cog): | ||
| 29 | from cogs.music.play_commands import EXTERNAL_URL_PATTERN | ||
| 30 | |||
| 31 | assert EXTERNAL_URL_PATTERN.match("https://youtube.com/watch?v=test") | ||
| 32 | assert EXTERNAL_URL_PATTERN.match("https://youtu.be/test") | ||
| 33 | assert EXTERNAL_URL_PATTERN.match("https://www.youtube.com/watch?v=test") | ||
| 34 | |||
| 35 | |||
| 36 | @pytest.mark.asyncio | ||
| 37 | async def test_external_url_pattern_matches_soundcloud(play_commands_cog): | ||
| 38 | from cogs.music.play_commands import EXTERNAL_URL_PATTERN | ||
| 39 | |||
| 40 | assert EXTERNAL_URL_PATTERN.match("https://soundcloud.com/artist/track") | ||
| 41 | assert EXTERNAL_URL_PATTERN.match("https://api.soundcloud.com/tracks") | ||
| 42 | |||
| 43 | |||
| 44 | @pytest.mark.asyncio | ||
| 45 | async def test_external_url_pattern_matches_bandcamp(play_commands_cog): | ||
| 46 | from cogs.music.play_commands import EXTERNAL_URL_PATTERN | ||
| 47 | |||
| 48 | assert EXTERNAL_URL_PATTERN.match("https://artist.bandcamp.com/track") | ||
| 49 | |||
| 50 | |||
| 51 | @pytest.mark.asyncio | ||
| 52 | async def test_external_url_pattern_rejects_copyparty(play_commands_cog): | ||
| 53 | from cogs.music.play_commands import EXTERNAL_URL_PATTERN | ||
| 54 | |||
| 55 | assert not EXTERNAL_URL_PATTERN.match("https://catbox.2137697.xyz/sperma/file.mp3") | ||
| 56 | assert not EXTERNAL_URL_PATTERN.match("some search query") | ||
| 57 | |||
| 58 | |||
| 59 | @pytest.mark.asyncio | ||
| 60 | async def test_play_command_calls_external_handler(play_commands_cog, mock_channel, mock_guild, bot): | ||
| 61 | ctx = MockApplicationContext(bot=bot, channel=mock_channel, guild=mock_guild) | ||
| 62 | |||
| 63 | with patch.object(play_commands_cog, '_handle_external_url_play', new_callable=AsyncMock) as mock_handler: | ||
| 64 | mock_handler.return_value = None | ||
| 65 | mock_defer = AsyncMock() | ||
| 66 | ctx.defer = mock_defer | ||
| 67 | ctx.respond = AsyncMock() | ||
| 68 | |||
| 69 | await play_commands_cog.play.callback( | ||
| 70 | play_commands_cog, ctx, | ||
| 71 | melodia="https://youtube.com/watch?v=test", | ||
| 72 | file=None, compressed=False | ||
| 73 | ) | ||
| 74 | |||
| 75 | mock_handler.assert_called_once_with(ctx, "https://youtube.com/watch?v=test") | ||
| 76 | |||
| 77 | |||
| 78 | @pytest.mark.asyncio | ||
| 79 | async def test_play_command_calls_local_handler(play_commands_cog, mock_channel, mock_guild, bot): | ||
| 80 | ctx = MockApplicationContext(bot=bot, channel=mock_channel, guild=mock_guild) | ||
| 81 | |||
| 82 | with patch.object(play_commands_cog, '_handle_local_file_play', new_callable=AsyncMock) as mock_handler: | ||
| 83 | mock_handler.return_value = None | ||
| 84 | mock_defer = AsyncMock() | ||
| 85 | ctx.defer = mock_defer | ||
| 86 | ctx.respond = AsyncMock() | ||
| 87 | |||
| 88 | await play_commands_cog.play.callback( | ||
| 89 | play_commands_cog, ctx, | ||
| 90 | melodia="some search query", | ||
| 91 | file=None, compressed=False | ||
| 92 | ) | ||
| 93 | |||
| 94 | mock_handler.assert_called_once_with(ctx, "some search query", False) | ||
| 95 | |||
| 96 | |||
| 97 | @pytest.mark.asyncio | ||
| 98 | async def test_upload_to_copyparty_async(play_commands_cog, temp_mp3_file, monkeypatch): | ||
| 99 | mock_response = MagicMock() | ||
| 100 | mock_response.status_code = 200 | ||
| 101 | mock_response.json.return_value = {"fileurl": "https://example.com/file.mp3"} | ||
| 102 | |||
| 103 | monkeypatch.setenv("COPYPARTY_URL_UPLOAD", "https://catbox.2137697.xyz/sperma/") | ||
| 104 | monkeypatch.setenv("COPYPARTY_PASSWORD", "testpassword") | ||
| 105 | |||
| 106 | with patch('cogs.music.play_commands.requests.post', return_value=mock_response) as mock_post: | ||
| 107 | await play_commands_cog._upload_to_copyparty_async(temp_mp3_file) | ||
| 108 | mock_post.assert_called_once() | ||
