core/tests/components/sonos/test_sensor.py

178 lines
6.4 KiB
Python

"""Tests for the Sonos battery sensor platform."""
from unittest.mock import PropertyMock
from soco.exceptions import NotSupportedException
from homeassistant.components.sensor import SCAN_INTERVAL
from homeassistant.components.sonos.binary_sensor import ATTR_BATTERY_POWER_SOURCE
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.helpers import entity_registry as ent_reg
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed
async def test_entity_registry_unsupported(hass, async_setup_sonos, soco):
"""Test sonos device without battery registered in the device registry."""
soco.get_battery_info.side_effect = NotSupportedException
await async_setup_sonos()
entity_registry = ent_reg.async_get(hass)
assert "media_player.zone_a" in entity_registry.entities
assert "sensor.zone_a_battery" not in entity_registry.entities
assert "binary_sensor.zone_a_power" not in entity_registry.entities
async def test_entity_registry_supported(hass, async_autosetup_sonos, soco):
"""Test sonos device with battery registered in the device registry."""
entity_registry = ent_reg.async_get(hass)
assert "media_player.zone_a" in entity_registry.entities
assert "sensor.zone_a_battery" in entity_registry.entities
assert "binary_sensor.zone_a_power" in entity_registry.entities
async def test_battery_attributes(hass, async_autosetup_sonos, soco):
"""Test sonos device with battery state."""
entity_registry = ent_reg.async_get(hass)
battery = entity_registry.entities["sensor.zone_a_battery"]
battery_state = hass.states.get(battery.entity_id)
assert battery_state.state == "100"
assert battery_state.attributes.get("unit_of_measurement") == "%"
power = entity_registry.entities["binary_sensor.zone_a_power"]
power_state = hass.states.get(power.entity_id)
assert power_state.state == STATE_ON
assert (
power_state.attributes.get(ATTR_BATTERY_POWER_SOURCE) == "SONOS_CHARGING_RING"
)
async def test_battery_on_s1(hass, async_setup_sonos, soco, device_properties_event):
"""Test battery state updates on a Sonos S1 device."""
soco.get_battery_info.return_value = {}
await async_setup_sonos()
subscription = soco.deviceProperties.subscribe.return_value
sub_callback = subscription.callback
entity_registry = ent_reg.async_get(hass)
assert "sensor.zone_a_battery" not in entity_registry.entities
assert "binary_sensor.zone_a_power" not in entity_registry.entities
# Update the speaker with a callback event
sub_callback(device_properties_event)
await hass.async_block_till_done()
battery = entity_registry.entities["sensor.zone_a_battery"]
battery_state = hass.states.get(battery.entity_id)
assert battery_state.state == "100"
power = entity_registry.entities["binary_sensor.zone_a_power"]
power_state = hass.states.get(power.entity_id)
assert power_state.state == STATE_OFF
assert power_state.attributes.get(ATTR_BATTERY_POWER_SOURCE) == "BATTERY"
async def test_device_payload_without_battery(
hass, async_setup_sonos, soco, device_properties_event, caplog
):
"""Test device properties event update without battery info."""
soco.get_battery_info.return_value = None
await async_setup_sonos()
subscription = soco.deviceProperties.subscribe.return_value
sub_callback = subscription.callback
bad_payload = "BadKey:BadValue"
device_properties_event.variables["more_info"] = bad_payload
sub_callback(device_properties_event)
await hass.async_block_till_done()
assert bad_payload in caplog.text
async def test_device_payload_without_battery_and_ignored_keys(
hass, async_setup_sonos, soco, device_properties_event, caplog
):
"""Test device properties event update without battery info and ignored keys."""
soco.get_battery_info.return_value = None
await async_setup_sonos()
subscription = soco.deviceProperties.subscribe.return_value
sub_callback = subscription.callback
ignored_payload = "SPID:InCeiling,TargetRoomName:Bouncy House"
device_properties_event.variables["more_info"] = ignored_payload
sub_callback(device_properties_event)
await hass.async_block_till_done()
assert ignored_payload not in caplog.text
async def test_audio_input_sensor(
hass, async_autosetup_sonos, soco, tv_event, no_media_event
):
"""Test audio input sensor."""
entity_registry = ent_reg.async_get(hass)
subscription = soco.avTransport.subscribe.return_value
sub_callback = subscription.callback
sub_callback(tv_event)
await hass.async_block_till_done()
audio_input_sensor = entity_registry.entities["sensor.zone_a_audio_input_format"]
audio_input_state = hass.states.get(audio_input_sensor.entity_id)
assert audio_input_state.state == "Dolby 5.1"
# Set mocked input format to new value and ensure poll success
no_input_mock = PropertyMock(return_value="No input")
type(soco).soundbar_audio_input_format = no_input_mock
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
no_input_mock.assert_called_once()
audio_input_state = hass.states.get(audio_input_sensor.entity_id)
assert audio_input_state.state == "No input"
# Ensure state is not polled when source is not TV and state is already "No input"
sub_callback(no_media_event)
await hass.async_block_till_done()
unpolled_mock = PropertyMock(return_value="Will not be polled")
type(soco).soundbar_audio_input_format = unpolled_mock
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
await hass.async_block_till_done()
unpolled_mock.assert_not_called()
audio_input_state = hass.states.get(audio_input_sensor.entity_id)
assert audio_input_state.state == "No input"
async def test_microphone_binary_sensor(
hass, async_autosetup_sonos, soco, device_properties_event
):
"""Test microphone binary sensor."""
entity_registry = ent_reg.async_get(hass)
assert "binary_sensor.zone_a_microphone" not in entity_registry.entities
# Update the speaker with a callback event
subscription = soco.deviceProperties.subscribe.return_value
subscription.callback(device_properties_event)
await hass.async_block_till_done()
mic_binary_sensor = entity_registry.entities["binary_sensor.zone_a_microphone"]
mic_binary_sensor_state = hass.states.get(mic_binary_sensor.entity_id)
assert mic_binary_sensor_state.state == STATE_ON