Add Bang & Olufsen media_player testing (#120580)
This commit is contained in:
parent
2a31774f91
commit
45843a3112
3 changed files with 1354 additions and 3 deletions
|
@ -3,10 +3,26 @@
|
|||
from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from mozart_api.models import BeolinkPeer
|
||||
from mozart_api.models import (
|
||||
Action,
|
||||
BeolinkPeer,
|
||||
ContentItem,
|
||||
PlaybackContentMetadata,
|
||||
PlaybackProgress,
|
||||
PlaybackState,
|
||||
ProductState,
|
||||
RemoteMenuItem,
|
||||
RenderingState,
|
||||
SoftwareUpdateStatus,
|
||||
Source,
|
||||
SourceArray,
|
||||
SourceTypeEnum,
|
||||
VolumeState,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.bang_olufsen.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .const import (
|
||||
TEST_DATA_CREATE_ENTRY,
|
||||
|
@ -30,10 +46,17 @@ def mock_config_entry():
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def mock_media_player(hass: HomeAssistant, mock_config_entry, mock_mozart_client):
|
||||
"""Mock media_player entity."""
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_mozart_client() -> Generator[AsyncMock]:
|
||||
"""Mock MozartClient."""
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.bang_olufsen.MozartClient", autospec=True
|
||||
|
@ -50,6 +73,170 @@ def mock_mozart_client() -> Generator[AsyncMock]:
|
|||
client.get_beolink_self.return_value = BeolinkPeer(
|
||||
friendly_name=TEST_FRIENDLY_NAME, jid=TEST_JID_1
|
||||
)
|
||||
client.get_softwareupdate_status = AsyncMock()
|
||||
client.get_softwareupdate_status.return_value = SoftwareUpdateStatus(
|
||||
software_version="1.0.0", state=""
|
||||
)
|
||||
client.get_product_state = AsyncMock()
|
||||
client.get_product_state.return_value = ProductState(
|
||||
volume=VolumeState(),
|
||||
playback=PlaybackState(
|
||||
metadata=PlaybackContentMetadata(),
|
||||
progress=PlaybackProgress(),
|
||||
source=Source(),
|
||||
state=RenderingState(value="started"),
|
||||
),
|
||||
)
|
||||
client.get_available_sources = AsyncMock()
|
||||
client.get_available_sources.return_value = SourceArray(
|
||||
items=[
|
||||
# Is in the HIDDEN_SOURCE_IDS constant, so should not be user selectable
|
||||
Source(
|
||||
name="AirPlay",
|
||||
id="airPlay",
|
||||
is_enabled=True,
|
||||
is_multiroom_available=False,
|
||||
),
|
||||
# The only available source
|
||||
Source(
|
||||
name="Tidal",
|
||||
id="tidal",
|
||||
is_enabled=True,
|
||||
is_multiroom_available=True,
|
||||
),
|
||||
# Is disabled, so should not be user selectable
|
||||
Source(
|
||||
name="Powerlink",
|
||||
id="pl",
|
||||
is_enabled=False,
|
||||
),
|
||||
]
|
||||
)
|
||||
client.get_remote_menu = AsyncMock()
|
||||
client.get_remote_menu.return_value = {
|
||||
# Music category, so shouldn't be included in video sources
|
||||
"b355888b-2cde-5f94-8592-d47b71d52a27": RemoteMenuItem(
|
||||
action_list=[
|
||||
Action(
|
||||
button_name=None,
|
||||
content_id="netRadio://6629967157728971",
|
||||
deezer_user_id=None,
|
||||
gain_db=None,
|
||||
listening_mode_id=None,
|
||||
preset_key=None,
|
||||
queue_item=None,
|
||||
queue_settings=None,
|
||||
radio_station_id=None,
|
||||
source=None,
|
||||
speaker_group_id=None,
|
||||
stand_position=None,
|
||||
stop_duration=None,
|
||||
tone_name=None,
|
||||
type="triggerContent",
|
||||
volume_level=None,
|
||||
)
|
||||
],
|
||||
scene_list=None,
|
||||
disabled=None,
|
||||
dynamic_list=None,
|
||||
first_child_menu_item_id=None,
|
||||
label="Yle Radio Suomi Helsinki",
|
||||
next_sibling_menu_item_id="0b4552f8-7ac6-5046-9d44-5410a815b8d6",
|
||||
parent_menu_item_id="eee0c2d0-2b3a-4899-a708-658475c38926",
|
||||
available=None,
|
||||
content=ContentItem(
|
||||
categories=["music"],
|
||||
content_uri="netRadio://6629967157728971",
|
||||
label="Yle Radio Suomi Helsinki",
|
||||
source=SourceTypeEnum(value="netRadio"),
|
||||
),
|
||||
fixed=True,
|
||||
id="b355888b-2cde-5f94-8592-d47b71d52a27",
|
||||
),
|
||||
# Has "hdmi" as category, so should be included in video sources
|
||||
"b6591565-80f4-4356-bcd9-c92ca247f0a9": RemoteMenuItem(
|
||||
action_list=[
|
||||
Action(
|
||||
button_name=None,
|
||||
content_id="tv://hdmi_1",
|
||||
deezer_user_id=None,
|
||||
gain_db=None,
|
||||
listening_mode_id=None,
|
||||
preset_key=None,
|
||||
queue_item=None,
|
||||
queue_settings=None,
|
||||
radio_station_id=None,
|
||||
source=None,
|
||||
speaker_group_id=None,
|
||||
stand_position=None,
|
||||
stop_duration=None,
|
||||
tone_name=None,
|
||||
type="triggerContent",
|
||||
volume_level=None,
|
||||
)
|
||||
],
|
||||
scene_list=None,
|
||||
disabled=False,
|
||||
dynamic_list="none",
|
||||
first_child_menu_item_id=None,
|
||||
label="HDMI A",
|
||||
next_sibling_menu_item_id="0ba98974-7b1f-40dc-bc48-fbacbb0f1793",
|
||||
parent_menu_item_id="b66c835b-6b98-4400-8f84-6348043792c7",
|
||||
available=True,
|
||||
content=ContentItem(
|
||||
categories=["hdmi"],
|
||||
content_uri="tv://hdmi_1",
|
||||
label="HDMI A",
|
||||
source=SourceTypeEnum(value="tv"),
|
||||
),
|
||||
fixed=False,
|
||||
id="b6591565-80f4-4356-bcd9-c92ca247f0a9",
|
||||
),
|
||||
# The parent remote menu item. Has the TV label and should therefore not be included in video sources
|
||||
"b66c835b-6b98-4400-8f84-6348043792c7": RemoteMenuItem(
|
||||
action_list=[],
|
||||
scene_list=None,
|
||||
disabled=False,
|
||||
dynamic_list="none",
|
||||
first_child_menu_item_id="b6591565-80f4-4356-bcd9-c92ca247f0a9",
|
||||
label="TV",
|
||||
next_sibling_menu_item_id="0c4547fe-d3cc-4348-a425-473595b8c9fb",
|
||||
parent_menu_item_id=None,
|
||||
available=True,
|
||||
content=None,
|
||||
fixed=True,
|
||||
id="b66c835b-6b98-4400-8f84-6348043792c7",
|
||||
),
|
||||
# Has an empty content, so should not be included
|
||||
"64c9da45-3682-44a4-8030-09ed3ef44160": RemoteMenuItem(
|
||||
action_list=[],
|
||||
scene_list=None,
|
||||
disabled=False,
|
||||
dynamic_list="none",
|
||||
first_child_menu_item_id=None,
|
||||
label="ListeningPosition",
|
||||
next_sibling_menu_item_id=None,
|
||||
parent_menu_item_id="0c4547fe-d3cc-4348-a425-473595b8c9fb",
|
||||
available=True,
|
||||
content=None,
|
||||
fixed=True,
|
||||
id="64c9da45-3682-44a4-8030-09ed3ef44160",
|
||||
),
|
||||
}
|
||||
client.post_standby = AsyncMock()
|
||||
client.set_current_volume_level = AsyncMock()
|
||||
client.set_volume_mute = AsyncMock()
|
||||
client.post_playback_command = AsyncMock()
|
||||
client.seek_to_position = AsyncMock()
|
||||
client.post_clear_queue = AsyncMock()
|
||||
client.post_overlay_play = AsyncMock()
|
||||
client.post_uri_source = AsyncMock()
|
||||
client.run_provided_scene = AsyncMock()
|
||||
client.activate_preset = AsyncMock()
|
||||
client.start_deezer_flow = AsyncMock()
|
||||
client.add_to_queue = AsyncMock()
|
||||
client.post_remote_trigger = AsyncMock()
|
||||
client.set_active_source = AsyncMock()
|
||||
|
||||
# Non-REST API client methods
|
||||
client.check_device_connection = AsyncMock()
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
"""Constants used for testing the bang_olufsen integration."""
|
||||
|
||||
from ipaddress import IPv4Address, IPv6Address
|
||||
from unittest.mock import Mock
|
||||
|
||||
from mozart_api.exceptions import ApiException
|
||||
from mozart_api.models import (
|
||||
Action,
|
||||
OverlayPlayRequest,
|
||||
OverlayPlayRequestTextToSpeechTextToSpeech,
|
||||
PlaybackContentMetadata,
|
||||
PlaybackError,
|
||||
PlaybackProgress,
|
||||
PlayQueueItem,
|
||||
PlayQueueItemType,
|
||||
RenderingState,
|
||||
SceneProperties,
|
||||
UserFlow,
|
||||
VolumeLevel,
|
||||
VolumeMute,
|
||||
VolumeState,
|
||||
)
|
||||
|
||||
from homeassistant.components.bang_olufsen.const import (
|
||||
ATTR_FRIENDLY_NAME,
|
||||
|
@ -8,6 +27,7 @@ from homeassistant.components.bang_olufsen.const import (
|
|||
ATTR_SERIAL_NUMBER,
|
||||
ATTR_TYPE_NUMBER,
|
||||
CONF_BEOLINK_JID,
|
||||
BangOlufsenSource,
|
||||
)
|
||||
from homeassistant.components.zeroconf import ZeroconfServiceInfo
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_NAME
|
||||
|
@ -24,7 +44,7 @@ TEST_FRIENDLY_NAME = "Living room Balance"
|
|||
TEST_TYPE_NUMBER = "1111"
|
||||
TEST_ITEM_NUMBER = "1111111"
|
||||
TEST_JID_1 = f"{TEST_TYPE_NUMBER}.{TEST_ITEM_NUMBER}.{TEST_SERIAL_NUMBER}@products.bang-olufsen.com"
|
||||
|
||||
TEST_MEDIA_PLAYER_ENTITY_ID = "media_player.beosound_balance_11111111"
|
||||
|
||||
TEST_HOSTNAME_ZEROCONF = TEST_NAME.replace(" ", "-") + ".local."
|
||||
TEST_TYPE_ZEROCONF = "_bangolufsen._tcp.local."
|
||||
|
@ -80,3 +100,80 @@ TEST_DATA_ZEROCONF_IPV6 = ZeroconfServiceInfo(
|
|||
ATTR_ITEM_NUMBER: TEST_ITEM_NUMBER,
|
||||
},
|
||||
)
|
||||
|
||||
TEST_AUDIO_SOURCES = [BangOlufsenSource.TIDAL.name]
|
||||
TEST_VIDEO_SOURCES = ["HDMI A"]
|
||||
TEST_SOURCES = TEST_AUDIO_SOURCES + TEST_VIDEO_SOURCES
|
||||
TEST_FALLBACK_SOURCES = [
|
||||
"Audio Streamer",
|
||||
"Spotify Connect",
|
||||
"Line-In",
|
||||
"Optical",
|
||||
"B&O Radio",
|
||||
"Deezer",
|
||||
"Tidal Connect",
|
||||
]
|
||||
TEST_PLAYBACK_METADATA = PlaybackContentMetadata(
|
||||
album_name="Test album",
|
||||
artist_name="Test artist",
|
||||
organization="Test organization",
|
||||
title="Test title",
|
||||
total_duration_seconds=123,
|
||||
track=1,
|
||||
)
|
||||
TEST_PLAYBACK_ERROR = PlaybackError(error="Test error")
|
||||
TEST_PLAYBACK_PROGRESS = PlaybackProgress(progress=123)
|
||||
TEST_PLAYBACK_STATE_PAUSED = RenderingState(value="paused")
|
||||
TEST_PLAYBACK_STATE_PLAYING = RenderingState(value="started")
|
||||
TEST_VOLUME = VolumeState(level=VolumeLevel(level=40))
|
||||
TEST_VOLUME_HOME_ASSISTANT_FORMAT = 0.4
|
||||
TEST_PLAYBACK_STATE_TURN_OFF = RenderingState(value="stopped")
|
||||
TEST_VOLUME_MUTED = VolumeState(
|
||||
muted=VolumeMute(muted=True), level=VolumeLevel(level=40)
|
||||
)
|
||||
TEST_VOLUME_MUTED_HOME_ASSISTANT_FORMAT = True
|
||||
TEST_SEEK_POSITION_HOME_ASSISTANT_FORMAT = 10.0
|
||||
TEST_SEEK_POSITION = 10000
|
||||
TEST_OVERLAY_INVALID_OFFSET_VOLUME_TTS = OverlayPlayRequest(
|
||||
text_to_speech=OverlayPlayRequestTextToSpeechTextToSpeech(
|
||||
lang="da-dk", text="Dette er en test"
|
||||
)
|
||||
)
|
||||
TEST_OVERLAY_OFFSET_VOLUME_TTS = OverlayPlayRequest(
|
||||
text_to_speech=OverlayPlayRequestTextToSpeechTextToSpeech(
|
||||
lang="en-us", text="This is a test"
|
||||
),
|
||||
volume_absolute=60,
|
||||
)
|
||||
TEST_RADIO_STATION = SceneProperties(
|
||||
action_list=[
|
||||
Action(
|
||||
type="radio",
|
||||
radio_station_id="1234567890123456",
|
||||
)
|
||||
]
|
||||
)
|
||||
TEST_DEEZER_FLOW = UserFlow(user_id="123")
|
||||
TEST_DEEZER_PLAYLIST = PlayQueueItem(
|
||||
provider=PlayQueueItemType(value="deezer"),
|
||||
start_now_from_position=123,
|
||||
type="playlist",
|
||||
uri="playlist:1234567890",
|
||||
)
|
||||
TEST_DEEZER_TRACK = PlayQueueItem(
|
||||
provider=PlayQueueItemType(value="deezer"),
|
||||
start_now_from_position=0,
|
||||
type="track",
|
||||
uri="1234567890",
|
||||
)
|
||||
|
||||
# codespell can't see the escaped ', so it thinks the word is misspelled
|
||||
TEST_DEEZER_INVALID_FLOW = ApiException(
|
||||
status=400,
|
||||
reason="Bad Request",
|
||||
http_resp=Mock(
|
||||
status=400,
|
||||
reason="Bad Request",
|
||||
data='{"message": "Couldn\'t start user flow for me"}', # codespell:ignore
|
||||
),
|
||||
)
|
||||
|
|
1067
tests/components/bang_olufsen/test_media_player.py
Normal file
1067
tests/components/bang_olufsen/test_media_player.py
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue