Add button entity to Music Assistant to add currently playing item to favorites (#145626)

* Add action to Music Assistant to add currently playing item to favorites

* add test

* Convert to button entity

* review comments

* Update test_button.ambr

* Fix

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Robert Resch <robert@resch.dev>
This commit is contained in:
Marcel van der Veldt
2025-06-23 20:39:46 +02:00
committed by GitHub
parent e494f66c02
commit 673a2e35ad
8 changed files with 331 additions and 51 deletions

View File

@@ -0,0 +1,145 @@
# serializer version: 1
# name: test_button_entities[button.my_super_test_player_2_favorite_current_song-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.my_super_test_player_2_favorite_current_song',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Favorite current song',
'platform': 'music_assistant',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'favorite_now_playing',
'unique_id': '00:00:00:00:00:02_favorite_now_playing',
'unit_of_measurement': None,
})
# ---
# name: test_button_entities[button.my_super_test_player_2_favorite_current_song-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'My Super Test Player 2 Favorite current song',
}),
'context': <ANY>,
'entity_id': 'button.my_super_test_player_2_favorite_current_song',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_button_entities[button.test_group_player_1_favorite_current_song-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.test_group_player_1_favorite_current_song',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Favorite current song',
'platform': 'music_assistant',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'favorite_now_playing',
'unique_id': 'test_group_player_1_favorite_now_playing',
'unit_of_measurement': None,
})
# ---
# name: test_button_entities[button.test_group_player_1_favorite_current_song-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Group Player 1 Favorite current song',
}),
'context': <ANY>,
'entity_id': 'button.test_group_player_1_favorite_current_song',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_button_entities[button.test_player_1_favorite_current_song-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.test_player_1_favorite_current_song',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Favorite current song',
'platform': 'music_assistant',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'favorite_now_playing',
'unique_id': '00:00:00:00:00:01_favorite_now_playing',
'unit_of_measurement': None,
})
# ---
# name: test_button_entities[button.test_player_1_favorite_current_song-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Player 1 Favorite current song',
}),
'context': <ANY>,
'entity_id': 'button.test_player_1_favorite_current_song',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unavailable',
})
# ---

View File

@@ -0,0 +1,48 @@
"""Test Music Assistant button entities."""
from unittest.mock import MagicMock, call
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .common import setup_integration_from_fixtures, snapshot_music_assistant_entities
async def test_button_entities(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
music_assistant_client: MagicMock,
) -> None:
"""Test media player."""
await setup_integration_from_fixtures(hass, music_assistant_client)
snapshot_music_assistant_entities(hass, entity_registry, snapshot, Platform.BUTTON)
async def test_button_press_action(
hass: HomeAssistant,
music_assistant_client: MagicMock,
) -> None:
"""Test button press action."""
await setup_integration_from_fixtures(hass, music_assistant_client)
entity_id = "button.my_super_test_player_2_favorite_current_song"
state = hass.states.get(entity_id)
assert state
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{
ATTR_ENTITY_ID: entity_id,
},
blocking=True,
)
assert music_assistant_client.send_command.call_count == 1
assert music_assistant_client.send_command.call_args == call(
"music/favorites/add_item",
item="spotify://track/5d95dc5be77e4f7eb4939f62cfef527b",
)