aboutsummaryrefslogtreecommitdiffstats
path: root/tests/cogs/test_music_external_play.py
blob: 25c14e0f4804f149cebc9fb69f1fce0830eba431 (plain) (blame)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import pytest
import os
import asyncio
import tempfile
from unittest.mock import AsyncMock, patch, MagicMock
from tests.conftest import MockApplicationContext


@pytest.fixture
def play_commands_cog(bot):
    with patch('cogs.utils.temp.get_temp_dir', return_value="/tmp"):
        from cogs.music.play_commands import PlayCommands
        cog = PlayCommands(bot)
    return cog


@pytest.fixture
def temp_mp3_file():
    with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as f:
        f.write(b'fake mp3 content')
        temp_path = f.name
    yield temp_path
    if os.path.exists(temp_path):
        os.remove(temp_path)


@pytest.mark.asyncio
async def test_external_url_pattern_matches_youtube(play_commands_cog):
    from cogs.music.play_commands import EXTERNAL_URL_PATTERN

    assert EXTERNAL_URL_PATTERN.match("https://youtube.com/watch?v=test")
    assert EXTERNAL_URL_PATTERN.match("https://youtu.be/test")
    assert EXTERNAL_URL_PATTERN.match("https://www.youtube.com/watch?v=test")


@pytest.mark.asyncio
async def test_external_url_pattern_matches_soundcloud(play_commands_cog):
    from cogs.music.play_commands import EXTERNAL_URL_PATTERN

    assert EXTERNAL_URL_PATTERN.match("https://soundcloud.com/artist/track")
    assert EXTERNAL_URL_PATTERN.match("https://api.soundcloud.com/tracks")


@pytest.mark.asyncio
async def test_external_url_pattern_matches_bandcamp(play_commands_cog):
    from cogs.music.play_commands import EXTERNAL_URL_PATTERN

    assert EXTERNAL_URL_PATTERN.match("https://artist.bandcamp.com/track")


@pytest.mark.asyncio
async def test_external_url_pattern_rejects_copyparty(play_commands_cog):
    from cogs.music.play_commands import EXTERNAL_URL_PATTERN

    assert not EXTERNAL_URL_PATTERN.match("https://catbox.2137697.xyz/sperma/file.mp3")
    assert not EXTERNAL_URL_PATTERN.match("some search query")


@pytest.mark.asyncio
async def test_play_command_calls_external_handler(play_commands_cog, mock_channel, mock_guild, bot):
    ctx = MockApplicationContext(bot=bot, channel=mock_channel, guild=mock_guild)

    with patch.object(play_commands_cog, '_handle_external_url_play', new_callable=AsyncMock) as mock_handler:
        mock_handler.return_value = None
        mock_defer = AsyncMock()
        ctx.defer = mock_defer
        ctx.respond = AsyncMock()

        await play_commands_cog.play.callback(
            play_commands_cog, ctx,
            melodia="https://youtube.com/watch?v=test",
            file=None, compressed=False
        )

        mock_handler.assert_called_once_with(ctx, "https://youtube.com/watch?v=test")


@pytest.mark.asyncio
async def test_play_command_calls_local_handler(play_commands_cog, mock_channel, mock_guild, bot):
    ctx = MockApplicationContext(bot=bot, channel=mock_channel, guild=mock_guild)

    with patch.object(play_commands_cog, '_handle_local_file_play', new_callable=AsyncMock) as mock_handler:
        mock_handler.return_value = None
        mock_defer = AsyncMock()
        ctx.defer = mock_defer
        ctx.respond = AsyncMock()

        await play_commands_cog.play.callback(
            play_commands_cog, ctx,
            melodia="some search query",
            file=None, compressed=False
        )

        mock_handler.assert_called_once_with(ctx, "some search query", False)


@pytest.mark.asyncio
async def test_upload_to_copyparty_async(play_commands_cog, temp_mp3_file, monkeypatch):
    monkeypatch.setenv("COPYPARTY_URL_UPLOAD", "https://catbox.2137697.xyz/sperma/")
    monkeypatch.setenv("COPYPARTY_PASSWORD", "testpassword")

    mock_post = AsyncMock()
    mock_response = AsyncMock()
    mock_response.status = 200
    mock_response.json = AsyncMock(return_value={"fileurl": "https://example.com/file.mp3"})
    mock_post.return_value.__aenter__ = AsyncMock(return_value=mock_response)
    mock_post.return_value.__aexit__ = AsyncMock()

    with patch('aiohttp.ClientSession.post', mock_post):
        await play_commands_cog._upload_to_copyparty_async(temp_mp3_file)
        mock_post.assert_called_once()