/
/
/
1"""Tests for the local_audio tombstone: the retired provider refuses to load."""
2
3from __future__ import annotations
4
5import json
6from pathlib import Path
7from unittest.mock import MagicMock
8
9import pytest
10from music_assistant_models.enums import ProviderStatus
11from music_assistant_models.errors import UnsupportedSystemError
12
13from music_assistant.controllers.config.helpers import _provider_status
14from music_assistant.mass import _provider_error_from_exc
15from music_assistant.providers.local_audio import setup
16from tests.controllers.config.test_provider_status import _conf
17
18MANIFEST = Path("music_assistant/providers/local_audio/manifest.json")
19STRINGS = Path("music_assistant/providers/local_audio/strings.json")
20
21
22async def test_setup_raises_the_retirement_notice() -> None:
23 """Loading the retired provider fails with a localizable retirement error."""
24 with pytest.raises(UnsupportedSystemError) as excinfo:
25 await setup(MagicMock(), MagicMock(), MagicMock())
26 err = excinfo.value
27 assert err.translation_key == "provider_retired"
28 assert err.translation_owner == "provider.local_audio"
29
30
31async def test_a_retired_config_lands_as_incompatible() -> None:
32 """The failure maps to INCOMPATIBLE, which is never retried and offers Remove."""
33 with pytest.raises(UnsupportedSystemError) as excinfo:
34 await setup(MagicMock(), MagicMock(), MagicMock())
35 last_error = _provider_error_from_exc(excinfo.value)
36 assert _provider_status(_conf(last_error=last_error), is_loaded=False) == (
37 ProviderStatus.INCOMPATIBLE
38 )
39 assert "retired" in last_error.message
40
41
42def test_manifest_carries_no_load_bearing_flags() -> None:
43 """The tombstone must not be builtin, depend on sendspin, or pull requirements."""
44 manifest = json.loads(MANIFEST.read_text())
45 assert manifest["stage"] == "deprecated"
46 assert manifest["requirements"] == []
47 # builtin would re-create the config on every boot and block the Remove button;
48 # depends_on would make the load fail silently before setup() ever runs
49 assert "builtin" not in manifest
50 assert "depends_on" not in manifest
51 assert "allow_disable" not in manifest
52
53
54def test_strings_cover_both_surfaces() -> None:
55 """The notice is defined for the failed load and for the add-provider flow."""
56 strings = json.loads(STRINGS.read_text())
57 assert "provider_retired" in strings["errors"]
58 assert "provider_retired" in strings["setup_flow"]["abort"]
59 assert "config_entries" not in strings
60