From: David Bishop Date: Mon, 23 Feb 2026 07:12:34 +0000 (-0800) Subject: Bandcamp: validate login on init when credentials are configured (#3215) X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=cbf3032f1d4ff601c09ce8bd08f726daef171d0d;p=music-assistant-server.git Bandcamp: validate login on init when credentials are configured (#3215) Co-authored-by: David Bishop Co-authored-by: Claude Opus 4.6 --- diff --git a/music_assistant/providers/bandcamp/__init__.py b/music_assistant/providers/bandcamp/__init__.py index 7bfb22a4..e15a0d68 100644 --- a/music_assistant/providers/bandcamp/__init__.py +++ b/music_assistant/providers/bandcamp/__init__.py @@ -124,6 +124,19 @@ class BandcampProvider(MusicProvider): ) self._converters = BandcampConverters(self.domain, self.instance_id) + # The provider can function without login (search-only), + # but if credentials were explicitly configured, validate them now. + # A bad login fails hard so the user can fix it immediately; + # transient errors (rate limits, network) are logged and the provider + # continues since the login may still be valid. + if identity: + try: + await self._client.get_collection_summary() + except BandcampMustBeLoggedInError as error: + raise LoginFailed("Bandcamp login is invalid or expired.") from error + except BandcampAPIError as error: + self.logger.warning("Could not validate Bandcamp login: %s", error) + @property def is_streaming_provider(self) -> bool: """Return True if the provider is a streaming provider.""" diff --git a/tests/providers/bandcamp/test_provider.py b/tests/providers/bandcamp/test_provider.py index 5961d752..f5e85ce4 100644 --- a/tests/providers/bandcamp/test_provider.py +++ b/tests/providers/bandcamp/test_provider.py @@ -59,7 +59,7 @@ async def provider(mass_mock: Mock, manifest_mock: Mock, config_mock: Mock) -> B # Initialize the provider with patch("music_assistant.providers.bandcamp.BandcampAPIClient") as mock_client_class: - mock_client = Mock() + mock_client = AsyncMock() mock_client_class.return_value = mock_client await provider.handle_async_init() @@ -77,7 +77,7 @@ async def test_provider_initialization( # Test that initialization sets the correct values with patch("music_assistant.providers.bandcamp.BandcampAPIClient") as mock_client_class: - mock_client = Mock() + mock_client = AsyncMock() mock_client_class.return_value = mock_client await provider.handle_async_init() @@ -88,7 +88,7 @@ async def test_provider_initialization( async def test_handle_async_init_with_identity(provider: BandcampProvider) -> None: """Test successful async initialization with identity token.""" with patch("music_assistant.providers.bandcamp.BandcampAPIClient") as mock_client_class: - mock_client = Mock() + mock_client = AsyncMock() mock_client_class.return_value = mock_client await provider.handle_async_init() @@ -113,7 +113,7 @@ async def test_handle_async_init_without_identity(mass_mock: Mock, manifest_mock provider = BandcampProvider(mass_mock, manifest_mock, config) with patch("music_assistant.providers.bandcamp.BandcampAPIClient") as mock_client_class: - mock_client = Mock() + mock_client = AsyncMock() mock_client_class.return_value = mock_client await provider.handle_async_init()