/
/
/
1"""Tests for Soundcloud provider setup and configuration."""
2
3from __future__ import annotations
4
5from unittest.mock import AsyncMock, Mock, patch
6
7import pytest
8from music_assistant_models.errors import LoginFailed
9
10from music_assistant.constants import CONF_ENTRY_UNOFFICIAL_PROVIDER
11from music_assistant.providers.soundcloud import (
12 SUPPORTED_FEATURES,
13 SoundcloudMusicProvider,
14 setup,
15)
16
17
18def _setup_values(provider: SoundcloudMusicProvider, **values: str) -> None:
19 """Make the setup flow answer with the given credentials."""
20 provider.get_setup_value = Mock( # type: ignore[method-assign]
21 side_effect=lambda key, default=None: values.get(key, default)
22 )
23
24
25async def test_setup_returns_provider() -> None:
26 """Setting up returns a provider instance."""
27 manifest = Mock()
28 manifest.domain = "soundcloud"
29 config = Mock()
30 config.get_value.return_value = "GLOBAL"
31
32 provider = await setup(Mock(), manifest, config)
33
34 assert isinstance(provider, SoundcloudMusicProvider)
35 assert provider.supported_features == SUPPORTED_FEATURES
36
37
38async def test_config_entries(provider: SoundcloudMusicProvider) -> None:
39 """The provider warns that it is unofficial."""
40 assert await provider.get_config_entries() == (CONF_ENTRY_UNOFFICIAL_PROVIDER,)
41
42
43async def test_async_init_requires_credentials(provider: SoundcloudMusicProvider) -> None:
44 """Initialization without credentials fails with a login error."""
45 _setup_values(provider)
46
47 with pytest.raises(LoginFailed):
48 await provider.handle_async_init()
49
50
51async def test_async_init_stores_user_id(provider: SoundcloudMusicProvider) -> None:
52 """Initialization logs in and remembers the account id."""
53 _setup_values(provider, client_id="test-client-id", authorization="OAuth test-token")
54 api = AsyncMock()
55 api.get_account_details.return_value = {"id": 42}
56
57 with patch(
58 "music_assistant.providers.soundcloud.SoundcloudAsyncAPI", return_value=api
59 ) as api_cls:
60 await provider.handle_async_init()
61
62 api_cls.assert_called_once()
63 api.login.assert_awaited_once()
64 # the API returns a number, which is stored as the string it is used as
65 assert provider._user_id == "42"
66