mirror of
https://github.com/home-assistant/core.git
synced 2025-11-08 18:39:30 +00:00
230 lines
6.9 KiB
Python
230 lines
6.9 KiB
Python
"""Test the snapcast media player implementation."""
|
|
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
import pytest
|
|
from syrupy.assertion import SnapshotAssertion
|
|
|
|
from homeassistant.components.media_player import (
|
|
ATTR_GROUP_MEMBERS,
|
|
ATTR_MEDIA_VOLUME_LEVEL,
|
|
DOMAIN as MEDIA_PLAYER_DOMAIN,
|
|
SERVICE_JOIN,
|
|
SERVICE_UNJOIN,
|
|
SERVICE_VOLUME_SET,
|
|
)
|
|
from homeassistant.components.snapcast.const import ATTR_MASTER, DOMAIN
|
|
from homeassistant.config_entries import ConfigEntryState
|
|
from homeassistant.const import ATTR_ENTITY_ID
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ServiceValidationError
|
|
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
|
|
|
from . import setup_integration
|
|
|
|
from tests.common import MockConfigEntry, snapshot_platform
|
|
|
|
|
|
async def test_state(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_create_server: AsyncMock,
|
|
entity_registry: er.EntityRegistry,
|
|
snapshot: SnapshotAssertion,
|
|
) -> None:
|
|
"""Test basic state information."""
|
|
|
|
# Setup and verify the integration is loaded
|
|
with patch("secrets.token_hex", return_value="mock_token"):
|
|
await setup_integration(hass, mock_config_entry)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("members"),
|
|
[
|
|
["media_player.test_client_2_snapcast_client"],
|
|
[
|
|
"media_player.test_client_1_snapcast_client",
|
|
"media_player.test_client_2_snapcast_client",
|
|
],
|
|
],
|
|
)
|
|
async def test_join(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_create_server: AsyncMock,
|
|
mock_group_1: AsyncMock,
|
|
mock_client_2: AsyncMock,
|
|
members: list[str],
|
|
) -> None:
|
|
"""Test grouping of media players through the join service."""
|
|
|
|
# Setup and verify the integration is loaded
|
|
with patch("secrets.token_hex", return_value="mock_token"):
|
|
await setup_integration(hass, mock_config_entry)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
await hass.services.async_call(
|
|
MEDIA_PLAYER_DOMAIN,
|
|
SERVICE_JOIN,
|
|
{
|
|
ATTR_ENTITY_ID: "media_player.test_client_1_snapcast_client",
|
|
ATTR_GROUP_MEMBERS: members,
|
|
},
|
|
blocking=True,
|
|
)
|
|
mock_group_1.add_client.assert_awaited_once_with(mock_client_2.identifier)
|
|
|
|
|
|
async def test_unjoin(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_create_server: AsyncMock,
|
|
mock_client_1: AsyncMock,
|
|
mock_group_1: AsyncMock,
|
|
) -> None:
|
|
"""Test the unjoin service removes the client from the group."""
|
|
|
|
# Setup and verify the integration is loaded
|
|
with patch("secrets.token_hex", return_value="mock_token"):
|
|
await setup_integration(hass, mock_config_entry)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
await hass.services.async_call(
|
|
MEDIA_PLAYER_DOMAIN,
|
|
SERVICE_UNJOIN,
|
|
{
|
|
ATTR_ENTITY_ID: "media_player.test_client_1_snapcast_client",
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
mock_group_1.remove_client.assert_awaited_once_with(mock_client_1.identifier)
|
|
|
|
|
|
async def test_join_exception(
|
|
hass: HomeAssistant,
|
|
entity_registry: er.EntityRegistry,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_create_server: AsyncMock,
|
|
mock_group_1: AsyncMock,
|
|
) -> None:
|
|
"""Test join service throws an exception when trying to add a non-Snapcast client."""
|
|
|
|
# Create a dummy media player entity
|
|
entity_registry.async_get_or_create(
|
|
MEDIA_PLAYER_DOMAIN,
|
|
"dummy",
|
|
"media_player_1",
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Setup and verify the integration is loaded
|
|
with patch("secrets.token_hex", return_value="mock_token"):
|
|
await setup_integration(hass, mock_config_entry)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
with pytest.raises(ServiceValidationError):
|
|
await hass.services.async_call(
|
|
MEDIA_PLAYER_DOMAIN,
|
|
SERVICE_JOIN,
|
|
{
|
|
ATTR_ENTITY_ID: "media_player.test_client_1_snapcast_client",
|
|
ATTR_GROUP_MEMBERS: ["media_player.dummy_media_player_1"],
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
# Ensure that the group did not attempt to add a non-Snapcast client
|
|
mock_group_1.add_client.assert_not_awaited()
|
|
|
|
|
|
async def test_legacy_join_issue(
|
|
hass: HomeAssistant,
|
|
issue_registry: ir.IssueRegistry,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_create_server: AsyncMock,
|
|
) -> None:
|
|
"""Test the legacy grouping services create issues when used."""
|
|
|
|
# Setup and verify the integration is loaded
|
|
with patch("secrets.token_hex", return_value="mock_token"):
|
|
await setup_integration(hass, mock_config_entry)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
# Call the legacy join service
|
|
await hass.services.async_call(
|
|
DOMAIN,
|
|
SERVICE_JOIN,
|
|
{
|
|
ATTR_ENTITY_ID: "media_player.test_client_2_snapcast_client",
|
|
ATTR_MASTER: "media_player.test_client_1_snapcast_client",
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
# Verify the issue is created
|
|
issue = issue_registry.async_get_issue(
|
|
domain=DOMAIN,
|
|
issue_id="deprecated_grouping_actions",
|
|
)
|
|
assert issue is not None
|
|
|
|
# Clear existing issue
|
|
issue_registry.async_delete(
|
|
domain=DOMAIN,
|
|
issue_id="deprecated_grouping_actions",
|
|
)
|
|
|
|
# Call legacy unjoin service
|
|
await hass.services.async_call(
|
|
DOMAIN,
|
|
SERVICE_UNJOIN,
|
|
{
|
|
ATTR_ENTITY_ID: "media_player.test_client_2_snapcast_client",
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
# Verify the issue is created again
|
|
issue = issue_registry.async_get_issue(
|
|
domain=DOMAIN,
|
|
issue_id="deprecated_grouping_actions",
|
|
)
|
|
assert issue is not None
|
|
|
|
|
|
async def test_deprecated_group_entity_issue(
|
|
hass: HomeAssistant,
|
|
issue_registry: ir.IssueRegistry,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_create_server: AsyncMock,
|
|
) -> None:
|
|
"""Test the legacy group entities create issues when used."""
|
|
|
|
# Setup and verify the integration is loaded
|
|
with patch("secrets.token_hex", return_value="mock_token"):
|
|
await setup_integration(hass, mock_config_entry)
|
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
|
|
|
# Call a servuce that uses a group entity
|
|
await hass.services.async_call(
|
|
MEDIA_PLAYER_DOMAIN,
|
|
SERVICE_VOLUME_SET,
|
|
service_data={
|
|
ATTR_ENTITY_ID: "media_player.test_group_1_snapcast_group",
|
|
ATTR_MEDIA_VOLUME_LEVEL: 0.5,
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
# Verify the issue is created
|
|
issue = issue_registry.async_get_issue(
|
|
domain=DOMAIN,
|
|
issue_id="deprecated_group_entities",
|
|
)
|
|
assert issue is not None
|