From ba7ad1029ca6ef7e650404e948ce546a7e02c046 Mon Sep 17 00:00:00 2001 From: jjlawren Date: Thu, 7 Jul 2022 05:17:13 -0500 Subject: [PATCH] Remove legacy Sonos grouping services (#74476) --- .../components/sonos/media_player.py | 35 +-------------- homeassistant/components/sonos/services.yaml | 29 ------------- tests/components/sonos/test_media_player.py | 17 -------- tests/components/sonos/test_services.py | 43 +++++++++++++++++++ 4 files changed, 44 insertions(+), 80 deletions(-) create mode 100644 tests/components/sonos/test_services.py diff --git a/homeassistant/components/sonos/media_player.py b/homeassistant/components/sonos/media_player.py index 470386c341d..4e7998c8e4e 100644 --- a/homeassistant/components/sonos/media_player.py +++ b/homeassistant/components/sonos/media_player.py @@ -82,8 +82,6 @@ SONOS_TO_REPEAT = {meaning: mode for mode, meaning in REPEAT_TO_SONOS.items()} UPNP_ERRORS_TO_IGNORE = ["701", "711", "712"] -SERVICE_JOIN = "join" -SERVICE_UNJOIN = "unjoin" SERVICE_SNAPSHOT = "snapshot" SERVICE_RESTORE = "restore" SERVICE_SET_TIMER = "set_sleep_timer" @@ -130,24 +128,7 @@ async def async_setup_entry( assert isinstance(entity, SonosMediaPlayerEntity) speakers.append(entity.speaker) - if service_call.service == SERVICE_JOIN: - _LOGGER.warning( - "Service 'sonos.join' is deprecated and will be removed in 2022.8, please use 'media_player.join'" - ) - master = platform.entities.get(service_call.data[ATTR_MASTER]) - if master: - await SonosSpeaker.join_multi(hass, master.speaker, speakers) # type: ignore[arg-type] - else: - _LOGGER.error( - "Invalid master specified for join service: %s", - service_call.data[ATTR_MASTER], - ) - elif service_call.service == SERVICE_UNJOIN: - _LOGGER.warning( - "Service 'sonos.unjoin' is deprecated and will be removed in 2022.8, please use 'media_player.unjoin'" - ) - await SonosSpeaker.unjoin_multi(hass, speakers) # type: ignore[arg-type] - elif service_call.service == SERVICE_SNAPSHOT: + if service_call.service == SERVICE_SNAPSHOT: await SonosSpeaker.snapshot_multi( hass, speakers, service_call.data[ATTR_WITH_GROUP] # type: ignore[arg-type] ) @@ -160,20 +141,6 @@ async def async_setup_entry( async_dispatcher_connect(hass, SONOS_CREATE_MEDIA_PLAYER, async_create_entities) ) - hass.services.async_register( - SONOS_DOMAIN, - SERVICE_JOIN, - async_service_handle, - cv.make_entity_service_schema({vol.Required(ATTR_MASTER): cv.entity_id}), - ) - - hass.services.async_register( - SONOS_DOMAIN, - SERVICE_UNJOIN, - async_service_handle, - cv.make_entity_service_schema({}), - ) - join_unjoin_schema = cv.make_entity_service_schema( {vol.Optional(ATTR_WITH_GROUP, default=True): cv.boolean} ) diff --git a/homeassistant/components/sonos/services.yaml b/homeassistant/components/sonos/services.yaml index a172b45ecd9..9d61c20f7cb 100644 --- a/homeassistant/components/sonos/services.yaml +++ b/homeassistant/components/sonos/services.yaml @@ -1,32 +1,3 @@ -join: - name: Join group - description: Group player together. - fields: - master: - name: Master - description: Entity ID of the player that should become the coordinator of the group. - required: true - selector: - entity: - integration: sonos - domain: media_player - entity_id: - name: Entity - description: Name of entity that will join the master. - required: true - selector: - entity: - integration: sonos - domain: media_player - -unjoin: - name: Unjoin group - description: Unjoin the player from a group. - target: - entity: - integration: sonos - domain: media_player - snapshot: name: Snapshot description: Take a snapshot of the media player. diff --git a/tests/components/sonos/test_media_player.py b/tests/components/sonos/test_media_player.py index 425b11fc35c..9c2119c8331 100644 --- a/tests/components/sonos/test_media_player.py +++ b/tests/components/sonos/test_media_player.py @@ -1,25 +1,8 @@ """Tests for the Sonos Media Player platform.""" -import pytest - -from homeassistant.components.sonos import DOMAIN, media_player from homeassistant.const import STATE_IDLE -from homeassistant.core import Context -from homeassistant.exceptions import Unauthorized from homeassistant.helpers import device_registry as dr -async def test_services(hass, async_autosetup_sonos, hass_read_only_user): - """Test join/unjoin requires control access.""" - with pytest.raises(Unauthorized): - await hass.services.async_call( - DOMAIN, - media_player.SERVICE_JOIN, - {"master": "media_player.bla", "entity_id": "media_player.blub"}, - blocking=True, - context=Context(user_id=hass_read_only_user.id), - ) - - async def test_device_registry(hass, async_autosetup_sonos, soco): """Test sonos device registered in the device registry.""" device_registry = dr.async_get(hass) diff --git a/tests/components/sonos/test_services.py b/tests/components/sonos/test_services.py new file mode 100644 index 00000000000..d0bf3bf3a06 --- /dev/null +++ b/tests/components/sonos/test_services.py @@ -0,0 +1,43 @@ +"""Tests for Sonos services.""" +from unittest.mock import Mock, patch + +import pytest + +from homeassistant.components.media_player import DOMAIN as MP_DOMAIN +from homeassistant.components.media_player.const import SERVICE_JOIN +from homeassistant.components.sonos.const import DATA_SONOS +from homeassistant.exceptions import HomeAssistantError + + +async def test_media_player_join(hass, async_autosetup_sonos): + """Test join service.""" + valid_entity_id = "media_player.zone_a" + mocked_entity_id = "media_player.mocked" + + # Ensure an error is raised if the entity is unknown + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + MP_DOMAIN, + SERVICE_JOIN, + {"entity_id": valid_entity_id, "group_members": mocked_entity_id}, + blocking=True, + ) + + # Ensure SonosSpeaker.join_multi is called if entity is found + mocked_speaker = Mock() + mock_entity_id_mappings = {mocked_entity_id: mocked_speaker} + + with patch.dict( + hass.data[DATA_SONOS].entity_id_mappings, mock_entity_id_mappings + ), patch( + "homeassistant.components.sonos.speaker.SonosSpeaker.join_multi" + ) as mock_join_multi: + await hass.services.async_call( + MP_DOMAIN, + SERVICE_JOIN, + {"entity_id": valid_entity_id, "group_members": mocked_entity_id}, + blocking=True, + ) + + found_speaker = hass.data[DATA_SONOS].entity_id_mappings[valid_entity_id] + mock_join_multi.assert_called_with(hass, found_speaker, [mocked_speaker])