core/tests/components/soundtouch/test_media_player.py

861 lines
26 KiB
Python
Raw Normal View History

"""Test the Soundtouch component."""
from unittest.mock import call
from asynctest import patch
from libsoundtouch.device import (
Config,
Preset,
SoundTouchDevice as STD,
Status,
Volume,
ZoneSlave,
ZoneStatus,
)
import pytest
from homeassistant.components.media_player.const import (
ATTR_MEDIA_CONTENT_ID,
ATTR_MEDIA_CONTENT_TYPE,
)
Consolidate all platforms that have tests (#22109) * Moved climate components with tests into platform dirs. * Updated tests from climate component. * Moved binary_sensor components with tests into platform dirs. * Updated tests from binary_sensor component. * Moved calendar components with tests into platform dirs. * Updated tests from calendar component. * Moved camera components with tests into platform dirs. * Updated tests from camera component. * Moved cover components with tests into platform dirs. * Updated tests from cover component. * Moved device_tracker components with tests into platform dirs. * Updated tests from device_tracker component. * Moved fan components with tests into platform dirs. * Updated tests from fan component. * Moved geo_location components with tests into platform dirs. * Updated tests from geo_location component. * Moved image_processing components with tests into platform dirs. * Updated tests from image_processing component. * Moved light components with tests into platform dirs. * Updated tests from light component. * Moved lock components with tests into platform dirs. * Moved media_player components with tests into platform dirs. * Updated tests from media_player component. * Moved scene components with tests into platform dirs. * Moved sensor components with tests into platform dirs. * Updated tests from sensor component. * Moved switch components with tests into platform dirs. * Updated tests from sensor component. * Moved vacuum components with tests into platform dirs. * Updated tests from vacuum component. * Moved weather components with tests into platform dirs. * Fixed __init__.py files * Fixes for stuff moved as part of this branch. * Fix stuff needed to merge with balloob's branch. * Formatting issues. * Missing __init__.py files. * Fix-ups * Fixup * Regenerated requirements. * Linting errors fixed. * Fixed more broken tests. * Missing init files. * Fix broken tests. * More broken tests * There seems to be a thread race condition. I suspect the logger stuff is running in another thread, which means waiting until the aio loop is done is missing the log messages. Used sleep instead because that allows the logger thread to run. I think the api_streams sensor might not be thread safe. * Disabled tests, will remove sensor in #22147 * Updated coverage and codeowners.
2019-03-19 06:07:39 +00:00
from homeassistant.components.soundtouch import media_player as soundtouch
from homeassistant.components.soundtouch.const import DOMAIN
from homeassistant.components.soundtouch.media_player import DATA_SOUNDTOUCH
2019-07-31 19:25:30 +00:00
from homeassistant.const import STATE_OFF, STATE_PAUSED, STATE_PLAYING
from homeassistant.helpers.discovery import async_load_platform
from homeassistant.setup import async_setup_component
# pylint: disable=super-init-not-called
DEVICE_1_IP = "192.168.0.1"
DEVICE_2_IP = "192.168.0.2"
def get_config(host=DEVICE_1_IP, port=8090, name="soundtouch"):
"""Return a default component."""
return {"platform": DOMAIN, "host": host, "port": port, "name": name}
DEVICE_1_CONFIG = {**get_config(), "name": "soundtouch_1"}
DEVICE_2_CONFIG = {**get_config(), "host": DEVICE_2_IP, "name": "soundtouch_2"}
@pytest.fixture(name="one_device")
def one_device_fixture():
"""Mock one master device."""
device_1 = MockDevice()
device_patch = patch(
"homeassistant.components.soundtouch.media_player.soundtouch_device",
return_value=device_1,
)
with device_patch as device:
yield device
@pytest.fixture(name="two_zones")
def two_zones_fixture():
"""Mock one master and one slave."""
device_1 = MockDevice(
MockZoneStatus(
is_master=True,
master_id=1,
master_ip=DEVICE_1_IP,
slaves=[MockZoneSlave(DEVICE_2_IP)],
)
)
device_2 = MockDevice(
MockZoneStatus(
is_master=False,
master_id=1,
master_ip=DEVICE_1_IP,
slaves=[MockZoneSlave(DEVICE_2_IP)],
)
)
devices = {DEVICE_1_IP: device_1, DEVICE_2_IP: device_2}
device_patch = patch(
"homeassistant.components.soundtouch.media_player.soundtouch_device",
side_effect=lambda host, _: devices[host],
)
with device_patch as device:
yield device
@pytest.fixture(name="mocked_status")
def status_fixture():
"""Mock the device status."""
status_patch = patch(
"libsoundtouch.device.SoundTouchDevice.status", side_effect=MockStatusPlaying
)
with status_patch as status:
yield status
@pytest.fixture(name="mocked_volume")
def volume_fixture():
"""Mock the device volume."""
volume_patch = patch("libsoundtouch.device.SoundTouchDevice.volume")
with volume_patch as volume:
yield volume
async def setup_soundtouch(hass, config):
"""Set up soundtouch integration."""
assert await async_setup_component(hass, "media_player", {"media_player": config})
await hass.async_block_till_done()
await hass.async_start()
class MockDevice(STD):
"""Mock device."""
def __init__(self, zone_status=None):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._config = MockConfig()
self._zone_status = zone_status or MockZoneStatus()
def zone_status(self, refresh=True):
"""Zone status mock object."""
return self._zone_status
class MockConfig(Config):
"""Mock config."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init class."""
self._name = "name"
class MockZoneStatus(ZoneStatus):
"""Mock zone status."""
def __init__(self, is_master=True, master_id=None, master_ip=None, slaves=None):
"""Init the class."""
self._is_master = is_master
self._master_id = master_id
self._master_ip = master_ip
self._slaves = slaves or []
class MockZoneSlave(ZoneSlave):
"""Mock zone slave."""
def __init__(self, device_ip=None, role=None):
"""Init the class."""
self._ip = device_ip
self._role = role
def _mocked_presets(*args, **kwargs):
"""Return a list of mocked presets."""
return [MockPreset("1")]
class MockPreset(Preset):
"""Mock preset."""
def __init__(self, id):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._id = id
self._name = "preset"
class MockVolume(Volume):
"""Mock volume with value."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init class."""
self._actual = 12
self._muted = False
class MockVolumeMuted(Volume):
"""Mock volume muted."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._actual = 12
self._muted = True
class MockStatusStandby(Status):
"""Mock status standby."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._source = "STANDBY"
class MockStatusPlaying(Status):
"""Mock status playing media."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._source = ""
self._play_status = "PLAY_STATE"
self._image = "image.url"
self._artist = "artist"
self._track = "track"
self._album = "album"
self._duration = 1
self._station_name = None
class MockStatusPlayingRadio(Status):
"""Mock status radio."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._source = ""
self._play_status = "PLAY_STATE"
self._image = "image.url"
self._artist = None
self._track = None
self._album = None
self._duration = None
self._station_name = "station"
class MockStatusUnknown(Status):
"""Mock status unknown media."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._source = ""
self._play_status = "PLAY_STATE"
self._image = "image.url"
self._artist = None
self._track = None
self._album = None
self._duration = None
self._station_name = None
class MockStatusPause(Status):
"""Mock status pause."""
def __init__(self):
2016-12-28 18:04:59 +00:00
"""Init the class."""
self._source = ""
self._play_status = "PAUSE_STATE"
self._image = "image.url"
self._artist = None
self._track = None
self._album = None
self._duration = None
self._station_name = None
async def test_ensure_setup_config(mocked_status, mocked_volume, hass, one_device):
"""Test setup OK with custom config."""
await setup_soundtouch(
hass, get_config(host="192.168.1.44", port=8888, name="custom_sound")
)
assert one_device.call_count == 1
assert one_device.call_args == call("192.168.1.44", 8888)
assert len(hass.states.async_all()) == 1
state = hass.states.get("media_player.custom_sound")
assert state.name == "custom_sound"
async def test_ensure_setup_discovery(mocked_status, mocked_volume, hass, one_device):
"""Test setup with discovery."""
new_device = {
"port": "8090",
"host": "192.168.1.1",
"properties": {},
"hostname": "hostname.local",
}
await async_load_platform(
hass, "media_player", DOMAIN, new_device, {"media_player": {}}
)
await hass.async_block_till_done()
assert one_device.call_count == 1
assert one_device.call_args == call("192.168.1.1", 8090)
assert len(hass.states.async_all()) == 1
async def test_ensure_setup_discovery_no_duplicate(
mocked_status, mocked_volume, hass, one_device
):
"""Test setup OK if device already exists."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert len(hass.states.async_all()) == 1
new_device = {
"port": "8090",
"host": "192.168.1.1",
"properties": {},
"hostname": "hostname.local",
}
await async_load_platform(
hass, "media_player", DOMAIN, new_device, {"media_player": DEVICE_1_CONFIG}
2019-07-31 19:25:30 +00:00
)
await hass.async_block_till_done()
assert one_device.call_count == 2
assert len(hass.states.async_all()) == 2
existing_device = {
"port": "8090",
"host": "192.168.0.1",
"properties": {},
"hostname": "hostname.local",
}
await async_load_platform(
hass, "media_player", DOMAIN, existing_device, {"media_player": DEVICE_1_CONFIG}
)
await hass.async_block_till_done()
assert one_device.call_count == 2
assert len(hass.states.async_all()) == 2
async def test_playing_media(mocked_status, mocked_volume, hass, one_device):
"""Test playing media info."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.state == STATE_PLAYING
assert entity_1_state.attributes["media_title"] == "artist - track"
assert entity_1_state.attributes["media_track"] == "track"
assert entity_1_state.attributes["media_artist"] == "artist"
assert entity_1_state.attributes["media_album_name"] == "album"
assert entity_1_state.attributes["media_duration"] == 1
async def test_playing_unknown_media(mocked_status, mocked_volume, hass, one_device):
"""Test playing media info."""
mocked_status.side_effect = MockStatusUnknown
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.state == STATE_PLAYING
async def test_playing_radio(mocked_status, mocked_volume, hass, one_device):
"""Test playing radio info."""
mocked_status.side_effect = MockStatusPlayingRadio
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.state == STATE_PLAYING
assert entity_1_state.attributes["media_title"] == "station"
async def test_get_volume_level(mocked_status, mocked_volume, hass, one_device):
"""Test volume level."""
mocked_volume.side_effect = MockVolume
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.attributes["volume_level"] == 0.12
async def test_get_state_off(mocked_status, mocked_volume, hass, one_device):
"""Test state device is off."""
mocked_status.side_effect = MockStatusStandby
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.state == STATE_OFF
async def test_get_state_pause(mocked_status, mocked_volume, hass, one_device):
"""Test state device is paused."""
mocked_status.side_effect = MockStatusPause
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.state == STATE_PAUSED
async def test_is_muted(mocked_status, mocked_volume, hass, one_device):
"""Test device volume is muted."""
mocked_volume.side_effect = MockVolumeMuted
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.attributes["is_volume_muted"]
async def test_media_commands(mocked_status, mocked_volume, hass, one_device):
"""Test supported media commands."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
entity_1_state = hass.states.get("media_player.soundtouch_1")
assert entity_1_state.attributes["supported_features"] == 18365
@patch("libsoundtouch.device.SoundTouchDevice.power_off")
async def test_should_turn_off(
mocked_power_off, mocked_status, mocked_volume, hass, one_device
):
"""Test device is turned off."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player", "turn_off", {"entity_id": "media_player.soundtouch_1"}, True,
)
assert mocked_status.call_count == 2
assert mocked_power_off.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.power_on")
async def test_should_turn_on(
mocked_power_on, mocked_status, mocked_volume, hass, one_device
):
"""Test device is turned on."""
mocked_status.side_effect = MockStatusStandby
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player", "turn_on", {"entity_id": "media_player.soundtouch_1"}, True,
)
assert mocked_status.call_count == 2
assert mocked_power_on.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.volume_up")
async def test_volume_up(
mocked_volume_up, mocked_status, mocked_volume, hass, one_device
):
"""Test volume up."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player", "volume_up", {"entity_id": "media_player.soundtouch_1"}, True,
)
assert mocked_volume.call_count == 2
assert mocked_volume_up.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.volume_down")
async def test_volume_down(
mocked_volume_down, mocked_status, mocked_volume, hass, one_device
):
"""Test volume down."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player", "volume_down", {"entity_id": "media_player.soundtouch_1"}, True,
)
assert mocked_volume.call_count == 2
assert mocked_volume_down.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.set_volume")
async def test_set_volume_level(
mocked_set_volume, mocked_status, mocked_volume, hass, one_device
):
"""Test set volume level."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player",
"volume_set",
{"entity_id": "media_player.soundtouch_1", "volume_level": 0.17},
True,
)
assert mocked_volume.call_count == 2
mocked_set_volume.assert_called_with(17)
@patch("libsoundtouch.device.SoundTouchDevice.mute")
async def test_mute(mocked_mute, mocked_status, mocked_volume, hass, one_device):
"""Test mute volume."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player",
"volume_mute",
{"entity_id": "media_player.soundtouch_1", "is_volume_muted": True},
True,
)
assert mocked_volume.call_count == 2
assert mocked_mute.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.play")
async def test_play(mocked_play, mocked_status, mocked_volume, hass, one_device):
"""Test play command."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player", "media_play", {"entity_id": "media_player.soundtouch_1"}, True,
)
assert mocked_status.call_count == 2
assert mocked_play.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.pause")
async def test_pause(mocked_pause, mocked_status, mocked_volume, hass, one_device):
"""Test pause command."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player", "media_pause", {"entity_id": "media_player.soundtouch_1"}, True,
)
assert mocked_status.call_count == 2
assert mocked_pause.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.play_pause")
async def test_play_pause(
mocked_play_pause, mocked_status, mocked_volume, hass, one_device
):
"""Test play/pause."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player",
"media_play_pause",
{"entity_id": "media_player.soundtouch_1"},
True,
)
assert mocked_status.call_count == 2
assert mocked_play_pause.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.previous_track")
@patch("libsoundtouch.device.SoundTouchDevice.next_track")
async def test_next_previous_track(
mocked_next_track,
mocked_previous_track,
mocked_status,
mocked_volume,
hass,
one_device,
):
"""Test next/previous track."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player",
"media_next_track",
{"entity_id": "media_player.soundtouch_1"},
True,
)
assert mocked_status.call_count == 2
assert mocked_next_track.call_count == 1
await hass.services.async_call(
"media_player",
"media_previous_track",
{"entity_id": "media_player.soundtouch_1"},
True,
)
assert mocked_status.call_count == 3
assert mocked_previous_track.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.select_preset")
@patch("libsoundtouch.device.SoundTouchDevice.presets", side_effect=_mocked_presets)
async def test_play_media(
mocked_presets, mocked_select_preset, mocked_status, mocked_volume, hass, one_device
):
"""Test play preset 1."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player",
"play_media",
{
"entity_id": "media_player.soundtouch_1",
ATTR_MEDIA_CONTENT_TYPE: "PLAYLIST",
ATTR_MEDIA_CONTENT_ID: 1,
},
True,
)
assert mocked_presets.call_count == 1
assert mocked_select_preset.call_count == 1
await hass.services.async_call(
"media_player",
"play_media",
{
"entity_id": "media_player.soundtouch_1",
ATTR_MEDIA_CONTENT_TYPE: "PLAYLIST",
ATTR_MEDIA_CONTENT_ID: 2,
},
True,
)
assert mocked_presets.call_count == 2
assert mocked_select_preset.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.play_url")
async def test_play_media_url(
mocked_play_url, mocked_status, mocked_volume, hass, one_device
):
"""Test play preset 1."""
await setup_soundtouch(hass, DEVICE_1_CONFIG)
assert one_device.call_count == 1
assert mocked_status.call_count == 1
assert mocked_volume.call_count == 1
await hass.services.async_call(
"media_player",
"play_media",
{
"entity_id": "media_player.soundtouch_1",
ATTR_MEDIA_CONTENT_TYPE: "MUSIC",
ATTR_MEDIA_CONTENT_ID: "http://fqdn/file.mp3",
},
True,
)
mocked_play_url.assert_called_with("http://fqdn/file.mp3")
@patch("libsoundtouch.device.SoundTouchDevice.create_zone")
async def test_play_everywhere(
mocked_create_zone, mocked_status, mocked_volume, hass, two_zones
):
"""Test play everywhere."""
mocked_device = two_zones
await setup_soundtouch(hass, [DEVICE_1_CONFIG, DEVICE_2_CONFIG])
assert mocked_device.call_count == 2
assert mocked_status.call_count == 2
assert mocked_volume.call_count == 2
# one master, one slave => create zone
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_PLAY_EVERYWHERE,
{"master": "media_player.soundtouch_1"},
True,
)
assert mocked_create_zone.call_count == 1
# unknown master, create zone must not be called
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_PLAY_EVERYWHERE,
{"master": "media_player.entity_X"},
True,
)
assert mocked_create_zone.call_count == 1
# no slaves, create zone must not be called
for entity in list(hass.data[DATA_SOUNDTOUCH]):
if entity.entity_id == "media_player.soundtouch_1":
continue
hass.data[DATA_SOUNDTOUCH].remove(entity)
await entity.async_remove()
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_PLAY_EVERYWHERE,
{"master": "media_player.soundtouch_1"},
True,
)
assert mocked_create_zone.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.create_zone")
async def test_create_zone(
mocked_create_zone, mocked_status, mocked_volume, hass, two_zones
):
"""Test creating a zone."""
mocked_device = two_zones
await setup_soundtouch(hass, [DEVICE_1_CONFIG, DEVICE_2_CONFIG])
assert mocked_device.call_count == 2
assert mocked_status.call_count == 2
assert mocked_volume.call_count == 2
# one master, one slave => create zone
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_CREATE_ZONE,
{
"master": "media_player.soundtouch_1",
"slaves": ["media_player.soundtouch_2"],
},
True,
)
assert mocked_create_zone.call_count == 1
# unknown master, create zone must not be called
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_CREATE_ZONE,
{"master": "media_player.entity_X", "slaves": ["media_player.soundtouch_2"]},
True,
)
assert mocked_create_zone.call_count == 1
# no slaves, create zone must not be called
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_CREATE_ZONE,
{"master": "media_player.soundtouch_1", "slaves": []},
True,
)
assert mocked_create_zone.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.remove_zone_slave")
async def test_remove_zone_slave(
mocked_remove_zone_slave, mocked_status, mocked_volume, hass, two_zones
):
"""Test adding a slave to an existing zone."""
mocked_device = two_zones
await setup_soundtouch(hass, [DEVICE_1_CONFIG, DEVICE_2_CONFIG])
assert mocked_device.call_count == 2
assert mocked_status.call_count == 2
assert mocked_volume.call_count == 2
# remove one slave
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_REMOVE_ZONE_SLAVE,
{
"master": "media_player.soundtouch_1",
"slaves": ["media_player.soundtouch_2"],
},
True,
)
assert mocked_remove_zone_slave.call_count == 1
# unknown master. add zone slave is not called
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_REMOVE_ZONE_SLAVE,
{"master": "media_player.entity_X", "slaves": ["media_player.soundtouch_2"]},
True,
)
assert mocked_remove_zone_slave.call_count == 1
# no slave to add, add zone slave is not called
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_REMOVE_ZONE_SLAVE,
{"master": "media_player.soundtouch_1", "slaves": []},
True,
)
assert mocked_remove_zone_slave.call_count == 1
@patch("libsoundtouch.device.SoundTouchDevice.add_zone_slave")
async def test_add_zone_slave(
mocked_add_zone_slave, mocked_status, mocked_volume, hass, two_zones,
):
"""Test removing a slave from a zone."""
mocked_device = two_zones
await setup_soundtouch(hass, [DEVICE_1_CONFIG, DEVICE_2_CONFIG])
assert mocked_device.call_count == 2
assert mocked_status.call_count == 2
assert mocked_volume.call_count == 2
# add one slave
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_ADD_ZONE_SLAVE,
{
"master": "media_player.soundtouch_1",
"slaves": ["media_player.soundtouch_2"],
},
True,
)
assert mocked_add_zone_slave.call_count == 1
# unknown master, add zone slave is not called
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_ADD_ZONE_SLAVE,
{"master": "media_player.entity_X", "slaves": ["media_player.soundtouch_2"]},
True,
)
assert mocked_add_zone_slave.call_count == 1
# no slave to add, add zone slave is not called
await hass.services.async_call(
soundtouch.DOMAIN,
soundtouch.SERVICE_ADD_ZONE_SLAVE,
{"master": "media_player.soundtouch_1", "slaves": ["media_player.entity_X"]},
True,
)
assert mocked_add_zone_slave.call_count == 1