Rewrite SoundTouch tests to use mocked payloads (#72984)

This commit is contained in:
Stefan Rado 2022-06-28 23:02:39 +02:00 committed by GitHub
parent 389f1f4eda
commit efbd47c828
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 846 additions and 759 deletions

View file

@ -523,7 +523,7 @@ class SoundTouchDevice(MediaPlayerEntity):
for slave in zone_slaves:
slave_instance = self._get_instance_by_ip(slave.device_ip)
if slave_instance:
if slave_instance and slave_instance.entity_id != master:
slaves.append(slave_instance.entity_id)
attributes = {

View file

@ -0,0 +1,286 @@
"""Fixtures for Bose SoundTouch integration tests."""
import pytest
from requests_mock import Mocker
from homeassistant.components.media_player.const import DOMAIN as MEDIA_PLAYER_DOMAIN
from homeassistant.components.soundtouch.const import DOMAIN
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PLATFORM
from tests.common import load_fixture
DEVICE_1_ID = "020000000001"
DEVICE_2_ID = "020000000002"
DEVICE_1_IP = "192.168.42.1"
DEVICE_2_IP = "192.168.42.2"
DEVICE_1_URL = f"http://{DEVICE_1_IP}:8090"
DEVICE_2_URL = f"http://{DEVICE_2_IP}:8090"
DEVICE_1_NAME = "My Soundtouch 1"
DEVICE_2_NAME = "My Soundtouch 2"
DEVICE_1_ENTITY_ID = f"{MEDIA_PLAYER_DOMAIN}.my_soundtouch_1"
DEVICE_2_ENTITY_ID = f"{MEDIA_PLAYER_DOMAIN}.my_soundtouch_2"
# pylint: disable=redefined-outer-name
@pytest.fixture
def device1_config() -> dict[str, str]:
"""Mock SoundTouch device 1 config."""
yield {CONF_PLATFORM: DOMAIN, CONF_HOST: DEVICE_1_IP, CONF_NAME: DEVICE_1_NAME}
@pytest.fixture
def device2_config() -> dict[str, str]:
"""Mock SoundTouch device 2 config."""
yield {CONF_PLATFORM: DOMAIN, CONF_HOST: DEVICE_2_IP, CONF_NAME: DEVICE_2_NAME}
@pytest.fixture(scope="session")
def device1_info() -> str:
"""Load SoundTouch device 1 info response and return it."""
return load_fixture("soundtouch/device1_info.xml")
@pytest.fixture(scope="session")
def device1_now_playing_aux() -> str:
"""Load SoundTouch device 1 now_playing response and return it."""
return load_fixture("soundtouch/device1_now_playing_aux.xml")
@pytest.fixture(scope="session")
def device1_now_playing_bluetooth() -> str:
"""Load SoundTouch device 1 now_playing response and return it."""
return load_fixture("soundtouch/device1_now_playing_bluetooth.xml")
@pytest.fixture(scope="session")
def device1_now_playing_radio() -> str:
"""Load SoundTouch device 1 now_playing response and return it."""
return load_fixture("soundtouch/device1_now_playing_radio.xml")
@pytest.fixture(scope="session")
def device1_now_playing_standby() -> str:
"""Load SoundTouch device 1 now_playing response and return it."""
return load_fixture("soundtouch/device1_now_playing_standby.xml")
@pytest.fixture(scope="session")
def device1_now_playing_upnp() -> str:
"""Load SoundTouch device 1 now_playing response and return it."""
return load_fixture("soundtouch/device1_now_playing_upnp.xml")
@pytest.fixture(scope="session")
def device1_now_playing_upnp_paused() -> str:
"""Load SoundTouch device 1 now_playing response and return it."""
return load_fixture("soundtouch/device1_now_playing_upnp_paused.xml")
@pytest.fixture(scope="session")
def device1_presets() -> str:
"""Load SoundTouch device 1 presets response and return it."""
return load_fixture("soundtouch/device1_presets.xml")
@pytest.fixture(scope="session")
def device1_volume() -> str:
"""Load SoundTouch device 1 volume response and return it."""
return load_fixture("soundtouch/device1_volume.xml")
@pytest.fixture(scope="session")
def device1_volume_muted() -> str:
"""Load SoundTouch device 1 volume response and return it."""
return load_fixture("soundtouch/device1_volume_muted.xml")
@pytest.fixture(scope="session")
def device1_zone_master() -> str:
"""Load SoundTouch device 1 getZone response and return it."""
return load_fixture("soundtouch/device1_getZone_master.xml")
@pytest.fixture(scope="session")
def device2_info() -> str:
"""Load SoundTouch device 2 info response and return it."""
return load_fixture("soundtouch/device2_info.xml")
@pytest.fixture(scope="session")
def device2_volume() -> str:
"""Load SoundTouch device 2 volume response and return it."""
return load_fixture("soundtouch/device2_volume.xml")
@pytest.fixture(scope="session")
def device2_now_playing_standby() -> str:
"""Load SoundTouch device 2 now_playing response and return it."""
return load_fixture("soundtouch/device2_now_playing_standby.xml")
@pytest.fixture(scope="session")
def device2_zone_slave() -> str:
"""Load SoundTouch device 2 getZone response and return it."""
return load_fixture("soundtouch/device2_getZone_slave.xml")
@pytest.fixture(scope="session")
def zone_empty() -> str:
"""Load empty SoundTouch getZone response and return it."""
return load_fixture("soundtouch/getZone_empty.xml")
@pytest.fixture
def device1_requests_mock(
requests_mock: Mocker,
device1_info: str,
device1_volume: str,
device1_presets: str,
device1_zone_master: str,
) -> Mocker:
"""Mock SoundTouch device 1 API - base URLs."""
requests_mock.get(f"{DEVICE_1_URL}/info", text=device1_info)
requests_mock.get(f"{DEVICE_1_URL}/volume", text=device1_volume)
requests_mock.get(f"{DEVICE_1_URL}/presets", text=device1_presets)
requests_mock.get(f"{DEVICE_1_URL}/getZone", text=device1_zone_master)
yield requests_mock
@pytest.fixture
def device1_requests_mock_standby(
device1_requests_mock: Mocker,
device1_now_playing_standby: str,
):
"""Mock SoundTouch device 1 API - standby."""
device1_requests_mock.get(
f"{DEVICE_1_URL}/now_playing", text=device1_now_playing_standby
)
@pytest.fixture
def device1_requests_mock_aux(
device1_requests_mock: Mocker,
device1_now_playing_aux: str,
):
"""Mock SoundTouch device 1 API - playing AUX."""
device1_requests_mock.get(
f"{DEVICE_1_URL}/now_playing", text=device1_now_playing_aux
)
@pytest.fixture
def device1_requests_mock_bluetooth(
device1_requests_mock: Mocker,
device1_now_playing_bluetooth: str,
):
"""Mock SoundTouch device 1 API - playing bluetooth."""
device1_requests_mock.get(
f"{DEVICE_1_URL}/now_playing", text=device1_now_playing_bluetooth
)
@pytest.fixture
def device1_requests_mock_radio(
device1_requests_mock: Mocker,
device1_now_playing_radio: str,
):
"""Mock SoundTouch device 1 API - playing radio."""
device1_requests_mock.get(
f"{DEVICE_1_URL}/now_playing", text=device1_now_playing_radio
)
@pytest.fixture
def device1_requests_mock_upnp(
device1_requests_mock: Mocker,
device1_now_playing_upnp: str,
):
"""Mock SoundTouch device 1 API - playing UPNP."""
device1_requests_mock.get(
f"{DEVICE_1_URL}/now_playing", text=device1_now_playing_upnp
)
@pytest.fixture
def device1_requests_mock_upnp_paused(
device1_requests_mock: Mocker,
device1_now_playing_upnp_paused: str,
):
"""Mock SoundTouch device 1 API - playing UPNP (paused)."""
device1_requests_mock.get(
f"{DEVICE_1_URL}/now_playing", text=device1_now_playing_upnp_paused
)
@pytest.fixture
def device1_requests_mock_key(
device1_requests_mock: Mocker,
):
"""Mock SoundTouch device 1 API - key endpoint."""
yield device1_requests_mock.post(f"{DEVICE_1_URL}/key")
@pytest.fixture
def device1_requests_mock_volume(
device1_requests_mock: Mocker,
):
"""Mock SoundTouch device 1 API - volume endpoint."""
yield device1_requests_mock.post(f"{DEVICE_1_URL}/volume")
@pytest.fixture
def device1_requests_mock_select(
device1_requests_mock: Mocker,
):
"""Mock SoundTouch device 1 API - select endpoint."""
yield device1_requests_mock.post(f"{DEVICE_1_URL}/select")
@pytest.fixture
def device1_requests_mock_set_zone(
device1_requests_mock: Mocker,
):
"""Mock SoundTouch device 1 API - setZone endpoint."""
yield device1_requests_mock.post(f"{DEVICE_1_URL}/setZone")
@pytest.fixture
def device1_requests_mock_add_zone_slave(
device1_requests_mock: Mocker,
):
"""Mock SoundTouch device 1 API - addZoneSlave endpoint."""
yield device1_requests_mock.post(f"{DEVICE_1_URL}/addZoneSlave")
@pytest.fixture
def device1_requests_mock_remove_zone_slave(
device1_requests_mock: Mocker,
):
"""Mock SoundTouch device 1 API - removeZoneSlave endpoint."""
yield device1_requests_mock.post(f"{DEVICE_1_URL}/removeZoneSlave")
@pytest.fixture
def device1_requests_mock_dlna(
device1_requests_mock: Mocker,
):
"""Mock SoundTouch device 1 API - DLNA endpoint."""
yield device1_requests_mock.post(f"http://{DEVICE_1_IP}:8091/AVTransport/Control")
@pytest.fixture
def device2_requests_mock_standby(
requests_mock: Mocker,
device2_info: str,
device2_volume: str,
device2_now_playing_standby: str,
device2_zone_slave: str,
) -> Mocker:
"""Mock SoundTouch device 2 API."""
requests_mock.get(f"{DEVICE_2_URL}/info", text=device2_info)
requests_mock.get(f"{DEVICE_2_URL}/volume", text=device2_volume)
requests_mock.get(f"{DEVICE_2_URL}/now_playing", text=device2_now_playing_standby)
requests_mock.get(f"{DEVICE_2_URL}/getZone", text=device2_zone_slave)
yield requests_mock

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<zone master="020000000001">
<member ipaddress="192.168.42.1">020000000001</member>
<member ipaddress="192.168.42.2">020000000002</member>
<member ipaddress="192.168.42.3">020000000003</member>
</zone>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<info deviceID="020000000001">
<name>My SoundTouch 1</name>
<type>SoundTouch 10</type>
<margeAccountUUID>0</margeAccountUUID>
<components>
<component>
<componentCategory>SCM</componentCategory>
<softwareVersion>27.0.3.46298.4608935 epdbuild.trunk.hepdswbld04.2021-10-06T16:35:02</softwareVersion>
<serialNumber>P0000000000000000000001</serialNumber>
</component>
<component>
<componentCategory>PackagedProduct</componentCategory>
<softwareVersion>27.0.3.46298.4608935 epdbuild.trunk.hepdswbld04.2021-10-06T16:35:02</softwareVersion>
<serialNumber>000000P00000001AE</serialNumber>
</component>
</components>
<margeURL>https://streaming.bose.com</margeURL>
<networkInfo type="SCM">
<macAddress>020000000001</macAddress>
<ipAddress>192.168.42.1</ipAddress>
</networkInfo>
<networkInfo type="SMSC">
<macAddress>060000000001</macAddress>
<ipAddress>192.168.42.1</ipAddress>
</networkInfo>
<moduleType>sm2</moduleType>
<variant>rhino</variant>
<variantMode>normal</variantMode>
<countryCode>US</countryCode>
<regionCode>US</regionCode>
</info>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nowPlaying deviceID="020000000001" source="AUX">
<ContentItem source="AUX" sourceAccount="AUX" isPresetable="true">
<itemName>AUX IN</itemName>
</ContentItem>
<playStatus>PLAY_STATE</playStatus>
</nowPlaying>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nowPlaying deviceID="020000000001" source="BLUETOOTH" sourceAccount="">
<ContentItem source="BLUETOOTH" location="" sourceAccount="" isPresetable="false">
<itemName>MockPairedBluetoothDevice</itemName>
</ContentItem>
<track>MockTrack</track>
<artist>MockArtist</artist>
<album>MockAlbum</album>
<stationName>MockPairedBluetoothDevice</stationName>
<art artImageStatus="SHOW_DEFAULT_IMAGE" />
<skipEnabled />
<playStatus>PLAY_STATE</playStatus>
<skipPreviousEnabled />
<genre></genre>
<connectionStatusInfo status="CONNECTED" deviceName="MockPairedBluetoothDevice" />
</nowPlaying>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nowPlaying deviceID="020000000001" source="TUNEIN" sourceAccount="">
<ContentItem source="TUNEIN" type="stationurl" location="/v1/playback/station/sXXXXX" sourceAccount="" isPresetable="true">
<itemName>MockStation</itemName>
<containerArt>http://cdn-profiles.tunein.com/sXXXXX/images/logoq.png</containerArt>
</ContentItem>
<track>MockTrack</track>
<artist>MockArtist</artist>
<album>MockAlbum</album>
<stationName>MockStation</stationName>
<art artImageStatus="IMAGE_PRESENT">http://cdn-profiles.tunein.com/sXXXXX/images/logoq.png</art>
<favoriteEnabled />
<playStatus>PLAY_STATE</playStatus>
<streamType>RADIO_STREAMING</streamType>
<isFavorite />
</nowPlaying>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nowPlaying deviceID="020000000001" source="STANDBY">
<ContentItem source="STANDBY" isPresetable="false" />
</nowPlaying>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nowPlaying deviceID="020000000001" source="UPNP" sourceAccount="UPnPUserName">
<ContentItem source="UPNP" location="http://homeassistant:8123/media/local/test.mp3" sourceAccount="UPnPUserName" isPresetable="true" />
<track>MockTrack</track>
<artist>MockArtist</artist>
<album>MockAlbum</album>
<stationName></stationName>
<art artImageStatus="SHOW_DEFAULT_IMAGE" />
<time total="42">7</time>
<playStatus>PLAY_STATE</playStatus>
<skipPreviousEnabled />
<streamType>TRACK_ONDEMAND</streamType>
</nowPlaying>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nowPlaying deviceID="020000000001" source="UPNP" sourceAccount="UPnPUserName">
<ContentItem source="UPNP" location="http://homeassistant:8123/media/local/test.mp3" sourceAccount="UPnPUserName" isPresetable="true" />
<track>MockTrack</track>
<artist>MockArtist</artist>
<album>MockAlbum</album>
<stationName></stationName>
<art artImageStatus="SHOW_DEFAULT_IMAGE" />
<time total="42">7</time>
<playStatus>PAUSE_STATE</playStatus>
<skipPreviousEnabled />
<streamType>TRACK_ONDEMAND</streamType>
</nowPlaying>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<presets>
<preset id="1">
<ContentItem source="UPNP" location="http://homeassistant:8123/media/local/test.mp3" sourceAccount="UPnPUserName" isPresetable="true"/>
</preset>
<preset id="2">
<ContentItem source="TUNEIN" type="stationurl" location="/v1/playback/station/sXXXXX" sourceAccount="" isPresetable="true">
<itemName>MockStation</itemName>
<containerArt>http://cdn-profiles.tunein.com/sXXXXX/images/logoq.png</containerArt>
</ContentItem>
</preset>
</presets>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<volume deviceID="020000000001">
<targetvolume>12</targetvolume>
<actualvolume>12</actualvolume>
<muteenabled>false</muteenabled>
</volume>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<volume deviceID="020000000001">
<targetvolume>12</targetvolume>
<actualvolume>12</actualvolume>
<muteenabled>true</muteenabled>
</volume>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<zone master="020000000001" senderIPAddress="192.168.42.1" senderIsMaster="true">
<member ipaddress="192.168.42.2">020000000002</member>
</zone>

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<info deviceID="020000000002">
<name>My SoundTouch 2</name>
<type>SoundTouch 10</type>
<margeAccountUUID>0</margeAccountUUID>
<components>
<component>
<componentCategory>SCM</componentCategory>
<softwareVersion>27.0.3.46298.4608935 epdbuild.trunk.hepdswbld04.2021-10-06T16:35:02</softwareVersion>
<serialNumber>P0000000000000000000002</serialNumber>
</component>
<component>
<componentCategory>PackagedProduct</componentCategory>
<softwareVersion>27.0.3.46298.4608935 epdbuild.trunk.hepdswbld04.2021-10-06T16:35:02</softwareVersion>
<serialNumber>000000P00000002AE</serialNumber>
</component>
</components>
<margeURL>https://streaming.bose.com</margeURL>
<networkInfo type="SCM">
<macAddress>020000000002</macAddress>
<ipAddress>192.168.42.2</ipAddress>
</networkInfo>
<networkInfo type="SMSC">
<macAddress>060000000002</macAddress>
<ipAddress>192.168.42.2</ipAddress>
</networkInfo>
<moduleType>sm2</moduleType>
<variant>rhino</variant>
<variantMode>normal</variantMode>
<countryCode>US</countryCode>
<regionCode>US</regionCode>
</info>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nowPlaying deviceID="020000000002" source="STANDBY">
<ContentItem source="STANDBY" isPresetable="false" />
</nowPlaying>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<volume deviceID="020000000002">
<targetvolume>10</targetvolume>
<actualvolume>10</actualvolume>
<muteenabled>false</muteenabled>
</volume>

File diff suppressed because it is too large Load diff