Add remote control platform to Panasonic Viera (#42450)

* Adding remote platform

* Update homeassistant/components/panasonic_viera/remote.py

Simplify entity creation

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>

* Use Pytest fixture

* Use Pytest fixtures and assert service calls

* Adding conftest.py and organizing tests

* Reorganizing tests

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
João Gabriel 2021-02-25 09:40:01 -03:00 committed by GitHub
parent c9d7a2be88
commit 372ed2db91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 386 additions and 323 deletions

View file

@ -8,6 +8,7 @@ from panasonic_viera import EncryptionRequired, Keys, RemoteControl, SOAPError
import voluptuous as vol
from homeassistant.components.media_player.const import DOMAIN as MEDIA_PLAYER_DOMAIN
from homeassistant.components.remote import DOMAIN as REMOTE_DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, STATE_OFF, STATE_ON
import homeassistant.helpers.config_validation as cv
@ -46,7 +47,7 @@ CONFIG_SCHEMA = vol.Schema(
extra=vol.ALLOW_EXTRA,
)
PLATFORMS = [MEDIA_PLAYER_DOMAIN]
PLATFORMS = [MEDIA_PLAYER_DOMAIN, REMOTE_DOMAIN]
async def async_setup(hass, config):
@ -219,6 +220,7 @@ class Remote:
"""Turn off the TV."""
if self.state != STATE_OFF:
await self.async_send_key(Keys.power)
self.state = STATE_OFF
await self.async_update()
async def async_set_mute(self, enable):

View file

@ -0,0 +1,90 @@
"""Remote control support for Panasonic Viera TV."""
import logging
from homeassistant.components.remote import RemoteEntity
from homeassistant.const import CONF_NAME, STATE_ON
from .const import (
ATTR_DEVICE_INFO,
ATTR_MANUFACTURER,
ATTR_MODEL_NUMBER,
ATTR_REMOTE,
ATTR_UDN,
DEFAULT_MANUFACTURER,
DEFAULT_MODEL_NUMBER,
DOMAIN,
)
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up Panasonic Viera TV Remote from a config entry."""
config = config_entry.data
remote = hass.data[DOMAIN][config_entry.entry_id][ATTR_REMOTE]
name = config[CONF_NAME]
device_info = config[ATTR_DEVICE_INFO]
async_add_entities([PanasonicVieraRemoteEntity(remote, name, device_info)])
class PanasonicVieraRemoteEntity(RemoteEntity):
"""Representation of a Panasonic Viera TV Remote."""
def __init__(self, remote, name, device_info):
"""Initialize the entity."""
# Save a reference to the imported class
self._remote = remote
self._name = name
self._device_info = device_info
@property
def unique_id(self):
"""Return the unique ID of the device."""
if self._device_info is None:
return None
return self._device_info[ATTR_UDN]
@property
def device_info(self):
"""Return device specific attributes."""
if self._device_info is None:
return None
return {
"name": self._name,
"identifiers": {(DOMAIN, self._device_info[ATTR_UDN])},
"manufacturer": self._device_info.get(
ATTR_MANUFACTURER, DEFAULT_MANUFACTURER
),
"model": self._device_info.get(ATTR_MODEL_NUMBER, DEFAULT_MODEL_NUMBER),
}
@property
def name(self):
"""Return the name of the device."""
return self._name
@property
def available(self):
"""Return True if the device is available."""
return self._remote.available
@property
def is_on(self):
"""Return true if device is on."""
return self._remote.state == STATE_ON
async def async_turn_on(self, **kwargs):
"""Turn the device on."""
await self._remote.async_turn_on(context=self._context)
async def async_turn_off(self, **kwargs):
"""Turn the device off."""
await self._remote.async_turn_off()
async def async_send_command(self, command, **kwargs):
"""Send a command to one device."""
for cmd in command:
await self._remote.async_send_key(cmd)

View file

@ -0,0 +1,104 @@
"""Test helpers for Panasonic Viera."""
from unittest.mock import Mock, patch
from panasonic_viera import TV_TYPE_ENCRYPTED, TV_TYPE_NONENCRYPTED
import pytest
from homeassistant.components.panasonic_viera.const import (
ATTR_FRIENDLY_NAME,
ATTR_MANUFACTURER,
ATTR_MODEL_NUMBER,
ATTR_UDN,
CONF_APP_ID,
CONF_ENCRYPTION_KEY,
CONF_ON_ACTION,
DEFAULT_MANUFACTURER,
DEFAULT_MODEL_NUMBER,
DEFAULT_NAME,
DEFAULT_PORT,
)
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT
MOCK_BASIC_DATA = {
CONF_HOST: "0.0.0.0",
CONF_NAME: DEFAULT_NAME,
}
MOCK_CONFIG_DATA = {
**MOCK_BASIC_DATA,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: None,
}
MOCK_ENCRYPTION_DATA = {
CONF_APP_ID: "mock-app-id",
CONF_ENCRYPTION_KEY: "mock-encryption-key",
}
MOCK_DEVICE_INFO = {
ATTR_FRIENDLY_NAME: DEFAULT_NAME,
ATTR_MANUFACTURER: DEFAULT_MANUFACTURER,
ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER,
ATTR_UDN: "mock-unique-id",
}
def get_mock_remote(
request_error=None,
authorize_error=None,
encrypted=False,
app_id=None,
encryption_key=None,
device_info=MOCK_DEVICE_INFO,
):
"""Return a mock remote."""
mock_remote = Mock()
mock_remote.type = TV_TYPE_ENCRYPTED if encrypted else TV_TYPE_NONENCRYPTED
mock_remote.app_id = app_id
mock_remote.enc_key = encryption_key
def request_pin_code(name=None):
if request_error is not None:
raise request_error
mock_remote.request_pin_code = request_pin_code
def authorize_pin_code(pincode):
if pincode == "1234":
return
if authorize_error is not None:
raise authorize_error
mock_remote.authorize_pin_code = authorize_pin_code
def get_device_info():
return device_info
mock_remote.get_device_info = get_device_info
def send_key(key):
return
mock_remote.send_key = Mock(send_key)
def get_volume(key):
return 100
mock_remote.get_volume = Mock(get_volume)
return mock_remote
@pytest.fixture(name="mock_remote")
def mock_remote_fixture():
"""Patch the library remote."""
mock_remote = get_mock_remote()
with patch(
"homeassistant.components.panasonic_viera.RemoteControl",
return_value=mock_remote,
):
yield mock_remote

View file

@ -1,90 +1,28 @@
"""Test the Panasonic Viera config flow."""
from unittest.mock import Mock, patch
from unittest.mock import patch
from panasonic_viera import TV_TYPE_ENCRYPTED, TV_TYPE_NONENCRYPTED, SOAPError
import pytest
from panasonic_viera import SOAPError
from homeassistant import config_entries
from homeassistant.components.panasonic_viera.const import (
ATTR_DEVICE_INFO,
ATTR_FRIENDLY_NAME,
ATTR_MANUFACTURER,
ATTR_MODEL_NUMBER,
ATTR_UDN,
CONF_APP_ID,
CONF_ENCRYPTION_KEY,
CONF_ON_ACTION,
DEFAULT_MANUFACTURER,
DEFAULT_MODEL_NUMBER,
DEFAULT_NAME,
DEFAULT_PORT,
DOMAIN,
ERROR_INVALID_PIN_CODE,
)
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PIN, CONF_PORT
from homeassistant.const import CONF_PIN
from .conftest import (
MOCK_BASIC_DATA,
MOCK_CONFIG_DATA,
MOCK_DEVICE_INFO,
MOCK_ENCRYPTION_DATA,
get_mock_remote,
)
from tests.common import MockConfigEntry
@pytest.fixture(name="panasonic_viera_setup", autouse=True)
def panasonic_viera_setup_fixture():
"""Mock panasonic_viera setup."""
with patch(
"homeassistant.components.panasonic_viera.async_setup", return_value=True
), patch(
"homeassistant.components.panasonic_viera.async_setup_entry",
return_value=True,
):
yield
def get_mock_remote(
host="1.2.3.4",
request_error=None,
authorize_error=None,
encrypted=False,
app_id=None,
encryption_key=None,
name=DEFAULT_NAME,
manufacturer=DEFAULT_MANUFACTURER,
model_number=DEFAULT_MODEL_NUMBER,
unique_id="mock-unique-id",
):
"""Return a mock remote."""
mock_remote = Mock()
mock_remote.type = TV_TYPE_ENCRYPTED if encrypted else TV_TYPE_NONENCRYPTED
mock_remote.app_id = app_id
mock_remote.enc_key = encryption_key
def request_pin_code(name=None):
if request_error is not None:
raise request_error
mock_remote.request_pin_code = request_pin_code
def authorize_pin_code(pincode):
if pincode == "1234":
return
if authorize_error is not None:
raise authorize_error
mock_remote.authorize_pin_code = authorize_pin_code
def get_device_info():
return {
ATTR_FRIENDLY_NAME: name,
ATTR_MANUFACTURER: manufacturer,
ATTR_MODEL_NUMBER: model_number,
ATTR_UDN: unique_id,
}
mock_remote.get_device_info = get_device_info
return mock_remote
async def test_flow_non_encrypted(hass):
"""Test flow without encryption."""
@ -103,23 +41,12 @@ async def test_flow_non_encrypted(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "create_entry"
assert result["title"] == DEFAULT_NAME
assert result["data"] == {
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: None,
ATTR_DEVICE_INFO: {
ATTR_FRIENDLY_NAME: DEFAULT_NAME,
ATTR_MANUFACTURER: DEFAULT_MANUFACTURER,
ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER,
ATTR_UDN: "mock-unique-id",
},
}
assert result["data"] == {**MOCK_CONFIG_DATA, ATTR_DEVICE_INFO: MOCK_DEVICE_INFO}
async def test_flow_not_connected_error(hass):
@ -138,7 +65,7 @@ async def test_flow_not_connected_error(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "form"
@ -162,7 +89,7 @@ async def test_flow_unknown_abort(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "abort"
@ -187,7 +114,7 @@ async def test_flow_encrypted_not_connected_pin_code_request(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "abort"
@ -212,7 +139,7 @@ async def test_flow_encrypted_unknown_pin_code_request(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "abort"
@ -231,8 +158,8 @@ async def test_flow_encrypted_valid_pin_code(hass):
mock_remote = get_mock_remote(
encrypted=True,
app_id="test-app-id",
encryption_key="test-encryption-key",
app_id="mock-app-id",
encryption_key="mock-encryption-key",
)
with patch(
@ -241,7 +168,7 @@ async def test_flow_encrypted_valid_pin_code(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "form"
@ -255,18 +182,9 @@ async def test_flow_encrypted_valid_pin_code(hass):
assert result["type"] == "create_entry"
assert result["title"] == DEFAULT_NAME
assert result["data"] == {
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: None,
CONF_APP_ID: "test-app-id",
CONF_ENCRYPTION_KEY: "test-encryption-key",
ATTR_DEVICE_INFO: {
ATTR_FRIENDLY_NAME: DEFAULT_NAME,
ATTR_MANUFACTURER: DEFAULT_MANUFACTURER,
ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER,
ATTR_UDN: "mock-unique-id",
},
**MOCK_CONFIG_DATA,
**MOCK_ENCRYPTION_DATA,
ATTR_DEVICE_INFO: MOCK_DEVICE_INFO,
}
@ -288,7 +206,7 @@ async def test_flow_encrypted_invalid_pin_code_error(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "form"
@ -326,7 +244,7 @@ async def test_flow_encrypted_not_connected_abort(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "form"
@ -359,7 +277,7 @@ async def test_flow_encrypted_unknown_abort(hass):
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
MOCK_BASIC_DATA,
)
assert result["type"] == "form"
@ -379,14 +297,14 @@ async def test_flow_non_encrypted_already_configured_abort(hass):
MockConfigEntry(
domain=DOMAIN,
unique_id="1.2.3.4",
data={CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME, CONF_PORT: DEFAULT_PORT},
unique_id="0.0.0.0",
data=MOCK_CONFIG_DATA,
).add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data={CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
data=MOCK_BASIC_DATA,
)
assert result["type"] == "abort"
@ -398,20 +316,14 @@ async def test_flow_encrypted_already_configured_abort(hass):
MockConfigEntry(
domain=DOMAIN,
unique_id="1.2.3.4",
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_APP_ID: "test-app-id",
CONF_ENCRYPTION_KEY: "test-encryption-key",
},
unique_id="0.0.0.0",
data={**MOCK_CONFIG_DATA, **MOCK_ENCRYPTION_DATA},
).add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data={CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
data=MOCK_BASIC_DATA,
)
assert result["type"] == "abort"
@ -430,28 +342,12 @@ async def test_imported_flow_non_encrypted(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
data=MOCK_CONFIG_DATA,
)
assert result["type"] == "create_entry"
assert result["title"] == DEFAULT_NAME
assert result["data"] == {
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
ATTR_DEVICE_INFO: {
ATTR_FRIENDLY_NAME: DEFAULT_NAME,
ATTR_MANUFACTURER: DEFAULT_MANUFACTURER,
ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER,
ATTR_UDN: "mock-unique-id",
},
}
assert result["data"] == {**MOCK_CONFIG_DATA, ATTR_DEVICE_INFO: MOCK_DEVICE_INFO}
async def test_imported_flow_encrypted_valid_pin_code(hass):
@ -459,8 +355,8 @@ async def test_imported_flow_encrypted_valid_pin_code(hass):
mock_remote = get_mock_remote(
encrypted=True,
app_id="test-app-id",
encryption_key="test-encryption-key",
app_id="mock-app-id",
encryption_key="mock-encryption-key",
)
with patch(
@ -470,12 +366,7 @@ async def test_imported_flow_encrypted_valid_pin_code(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
data=MOCK_CONFIG_DATA,
)
assert result["type"] == "form"
@ -489,18 +380,9 @@ async def test_imported_flow_encrypted_valid_pin_code(hass):
assert result["type"] == "create_entry"
assert result["title"] == DEFAULT_NAME
assert result["data"] == {
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
CONF_APP_ID: "test-app-id",
CONF_ENCRYPTION_KEY: "test-encryption-key",
ATTR_DEVICE_INFO: {
ATTR_FRIENDLY_NAME: DEFAULT_NAME,
ATTR_MANUFACTURER: DEFAULT_MANUFACTURER,
ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER,
ATTR_UDN: "mock-unique-id",
},
**MOCK_CONFIG_DATA,
**MOCK_ENCRYPTION_DATA,
ATTR_DEVICE_INFO: MOCK_DEVICE_INFO,
}
@ -516,12 +398,7 @@ async def test_imported_flow_encrypted_invalid_pin_code_error(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
data=MOCK_CONFIG_DATA,
)
assert result["type"] == "form"
@ -553,12 +430,7 @@ async def test_imported_flow_encrypted_not_connected_abort(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
data=MOCK_CONFIG_DATA,
)
assert result["type"] == "form"
@ -585,12 +457,7 @@ async def test_imported_flow_encrypted_unknown_abort(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
data=MOCK_CONFIG_DATA,
)
assert result["type"] == "form"
@ -615,12 +482,7 @@ async def test_imported_flow_not_connected_error(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
data=MOCK_CONFIG_DATA,
)
assert result["type"] == "form"
@ -638,12 +500,7 @@ async def test_imported_flow_unknown_abort(hass):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
data=MOCK_CONFIG_DATA,
)
assert result["type"] == "abort"
@ -655,19 +512,14 @@ async def test_imported_flow_non_encrypted_already_configured_abort(hass):
MockConfigEntry(
domain=DOMAIN,
unique_id="1.2.3.4",
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
},
unique_id="0.0.0.0",
data=MOCK_CONFIG_DATA,
).add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
data=MOCK_BASIC_DATA,
)
assert result["type"] == "abort"
@ -679,21 +531,14 @@ async def test_imported_flow_encrypted_already_configured_abort(hass):
MockConfigEntry(
domain=DOMAIN,
unique_id="1.2.3.4",
data={
CONF_HOST: "1.2.3.4",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: "test-on-action",
CONF_APP_ID: "test-app-id",
CONF_ENCRYPTION_KEY: "test-encryption-key",
},
unique_id="0.0.0.0",
data={**MOCK_CONFIG_DATA, **MOCK_ENCRYPTION_DATA},
).add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME},
data=MOCK_BASIC_DATA,
)
assert result["type"] == "abort"

View file

@ -1,65 +1,27 @@
"""Test the Panasonic Viera setup process."""
from unittest.mock import Mock, patch
from unittest.mock import patch
from homeassistant.components.panasonic_viera.const import (
ATTR_DEVICE_INFO,
ATTR_FRIENDLY_NAME,
ATTR_MANUFACTURER,
ATTR_MODEL_NUMBER,
ATTR_UDN,
CONF_APP_ID,
CONF_ENCRYPTION_KEY,
CONF_ON_ACTION,
DEFAULT_MANUFACTURER,
DEFAULT_MODEL_NUMBER,
DEFAULT_NAME,
DEFAULT_PORT,
DOMAIN,
)
from homeassistant.config_entries import ENTRY_STATE_NOT_LOADED
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, STATE_UNAVAILABLE
from homeassistant.const import CONF_HOST, STATE_UNAVAILABLE
from homeassistant.setup import async_setup_component
from .conftest import (
MOCK_CONFIG_DATA,
MOCK_DEVICE_INFO,
MOCK_ENCRYPTION_DATA,
get_mock_remote,
)
from tests.common import MockConfigEntry
MOCK_CONFIG_DATA = {
CONF_HOST: "0.0.0.0",
CONF_NAME: DEFAULT_NAME,
CONF_PORT: DEFAULT_PORT,
CONF_ON_ACTION: None,
}
MOCK_ENCRYPTION_DATA = {
CONF_APP_ID: "mock-app-id",
CONF_ENCRYPTION_KEY: "mock-encryption-key",
}
MOCK_DEVICE_INFO = {
ATTR_FRIENDLY_NAME: DEFAULT_NAME,
ATTR_MANUFACTURER: DEFAULT_MANUFACTURER,
ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER,
ATTR_UDN: "mock-unique-id",
}
def get_mock_remote(device_info=MOCK_DEVICE_INFO):
"""Return a mock remote."""
mock_remote = Mock()
async def async_create_remote_control(during_setup=False):
return
mock_remote.async_create_remote_control = async_create_remote_control
async def async_get_device_info():
return device_info
mock_remote.async_get_device_info = async_get_device_info
return mock_remote
async def test_setup_entry_encrypted(hass):
async def test_setup_entry_encrypted(hass, mock_remote):
"""Test setup with encrypted config entry."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
@ -69,22 +31,20 @@ async def test_setup_entry_encrypted(hass):
mock_entry.add_to_hass(hass)
mock_remote = get_mock_remote()
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
with patch(
"homeassistant.components.panasonic_viera.Remote",
return_value=mock_remote,
):
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
state = hass.states.get("media_player.panasonic_viera_tv")
assert state_tv
assert state_tv.name == DEFAULT_NAME
assert state
assert state.name == DEFAULT_NAME
assert state_remote
assert state_remote.name == DEFAULT_NAME
async def test_setup_entry_encrypted_missing_device_info(hass):
async def test_setup_entry_encrypted_missing_device_info(hass, mock_remote):
"""Test setup with encrypted config entry and missing device info."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
@ -94,22 +54,20 @@ async def test_setup_entry_encrypted_missing_device_info(hass):
mock_entry.add_to_hass(hass)
mock_remote = get_mock_remote()
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
with patch(
"homeassistant.components.panasonic_viera.Remote",
return_value=mock_remote,
):
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
assert mock_entry.data[ATTR_DEVICE_INFO] == MOCK_DEVICE_INFO
assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN]
assert mock_entry.data[ATTR_DEVICE_INFO] == MOCK_DEVICE_INFO
assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN]
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
state = hass.states.get("media_player.panasonic_viera_tv")
assert state_tv
assert state_tv.name == DEFAULT_NAME
assert state
assert state.name == DEFAULT_NAME
assert state_remote
assert state_remote.name == DEFAULT_NAME
async def test_setup_entry_encrypted_missing_device_info_none(hass):
@ -125,7 +83,7 @@ async def test_setup_entry_encrypted_missing_device_info_none(hass):
mock_remote = get_mock_remote(device_info=None)
with patch(
"homeassistant.components.panasonic_viera.Remote",
"homeassistant.components.panasonic_viera.RemoteControl",
return_value=mock_remote,
):
await hass.config_entries.async_setup(mock_entry.entry_id)
@ -134,13 +92,17 @@ async def test_setup_entry_encrypted_missing_device_info_none(hass):
assert mock_entry.data[ATTR_DEVICE_INFO] is None
assert mock_entry.unique_id == MOCK_CONFIG_DATA[CONF_HOST]
state = hass.states.get("media_player.panasonic_viera_tv")
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
assert state
assert state.name == DEFAULT_NAME
assert state_tv
assert state_tv.name == DEFAULT_NAME
assert state_remote
assert state_remote.name == DEFAULT_NAME
async def test_setup_entry_unencrypted(hass):
async def test_setup_entry_unencrypted(hass, mock_remote):
"""Test setup with unencrypted config entry."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
@ -150,22 +112,20 @@ async def test_setup_entry_unencrypted(hass):
mock_entry.add_to_hass(hass)
mock_remote = get_mock_remote()
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
with patch(
"homeassistant.components.panasonic_viera.Remote",
return_value=mock_remote,
):
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
state = hass.states.get("media_player.panasonic_viera_tv")
assert state_tv
assert state_tv.name == DEFAULT_NAME
assert state
assert state.name == DEFAULT_NAME
assert state_remote
assert state_remote.name == DEFAULT_NAME
async def test_setup_entry_unencrypted_missing_device_info(hass):
async def test_setup_entry_unencrypted_missing_device_info(hass, mock_remote):
"""Test setup with unencrypted config entry and missing device info."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
@ -175,22 +135,20 @@ async def test_setup_entry_unencrypted_missing_device_info(hass):
mock_entry.add_to_hass(hass)
mock_remote = get_mock_remote()
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
with patch(
"homeassistant.components.panasonic_viera.Remote",
return_value=mock_remote,
):
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
assert mock_entry.data[ATTR_DEVICE_INFO] == MOCK_DEVICE_INFO
assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN]
assert mock_entry.data[ATTR_DEVICE_INFO] == MOCK_DEVICE_INFO
assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN]
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
state = hass.states.get("media_player.panasonic_viera_tv")
assert state_tv
assert state_tv.name == DEFAULT_NAME
assert state
assert state.name == DEFAULT_NAME
assert state_remote
assert state_remote.name == DEFAULT_NAME
async def test_setup_entry_unencrypted_missing_device_info_none(hass):
@ -206,7 +164,7 @@ async def test_setup_entry_unencrypted_missing_device_info_none(hass):
mock_remote = get_mock_remote(device_info=None)
with patch(
"homeassistant.components.panasonic_viera.Remote",
"homeassistant.components.panasonic_viera.RemoteControl",
return_value=mock_remote,
):
await hass.config_entries.async_setup(mock_entry.entry_id)
@ -215,10 +173,14 @@ async def test_setup_entry_unencrypted_missing_device_info_none(hass):
assert mock_entry.data[ATTR_DEVICE_INFO] is None
assert mock_entry.unique_id == MOCK_CONFIG_DATA[CONF_HOST]
state = hass.states.get("media_player.panasonic_viera_tv")
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
assert state
assert state.name == DEFAULT_NAME
assert state_tv
assert state_tv.name == DEFAULT_NAME
assert state_remote
assert state_remote.name == DEFAULT_NAME
async def test_setup_config_flow_initiated(hass):
@ -235,7 +197,7 @@ async def test_setup_config_flow_initiated(hass):
assert len(hass.config_entries.flow.async_progress()) == 1
async def test_setup_unload_entry(hass):
async def test_setup_unload_entry(hass, mock_remote):
"""Test if config entry is unloaded."""
mock_entry = MockConfigEntry(
domain=DOMAIN, unique_id=MOCK_DEVICE_INFO[ATTR_UDN], data=MOCK_CONFIG_DATA
@ -243,21 +205,23 @@ async def test_setup_unload_entry(hass):
mock_entry.add_to_hass(hass)
mock_remote = get_mock_remote()
with patch(
"homeassistant.components.panasonic_viera.Remote",
return_value=mock_remote,
):
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
await hass.config_entries.async_unload(mock_entry.entry_id)
assert mock_entry.state == ENTRY_STATE_NOT_LOADED
state = hass.states.get("media_player.panasonic_viera_tv")
assert state.state == STATE_UNAVAILABLE
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
assert state_tv.state == STATE_UNAVAILABLE
assert state_remote.state == STATE_UNAVAILABLE
await hass.config_entries.async_remove(mock_entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get("media_player.panasonic_viera_tv")
assert state is None
state_tv = hass.states.get("media_player.panasonic_viera_tv")
state_remote = hass.states.get("remote.panasonic_viera_tv")
assert state_tv is None
assert state_remote is None

View file

@ -0,0 +1,58 @@
"""Test the Panasonic Viera remote entity."""
from unittest.mock import call
from panasonic_viera import Keys
from homeassistant.components.panasonic_viera.const import ATTR_UDN, DOMAIN
from homeassistant.components.remote import (
ATTR_COMMAND,
DOMAIN as REMOTE_DOMAIN,
SERVICE_SEND_COMMAND,
)
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON
from .conftest import MOCK_CONFIG_DATA, MOCK_DEVICE_INFO, MOCK_ENCRYPTION_DATA
from tests.common import MockConfigEntry
async def setup_panasonic_viera(hass):
"""Initialize integration for tests."""
mock_entry = MockConfigEntry(
domain=DOMAIN,
unique_id=MOCK_DEVICE_INFO[ATTR_UDN],
data={**MOCK_CONFIG_DATA, **MOCK_ENCRYPTION_DATA, **MOCK_DEVICE_INFO},
)
mock_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_entry.entry_id)
await hass.async_block_till_done()
async def test_onoff(hass, mock_remote):
"""Test the on/off service calls."""
await setup_panasonic_viera(hass)
data = {ATTR_ENTITY_ID: "remote.panasonic_viera_tv"}
await hass.services.async_call(REMOTE_DOMAIN, SERVICE_TURN_OFF, data)
await hass.services.async_call(REMOTE_DOMAIN, SERVICE_TURN_ON, data)
await hass.async_block_till_done()
power = getattr(Keys.power, "value", Keys.power)
assert mock_remote.send_key.call_args_list == [call(power), call(power)]
async def test_send_command(hass, mock_remote):
"""Test the send_command service call."""
await setup_panasonic_viera(hass)
data = {ATTR_ENTITY_ID: "remote.panasonic_viera_tv", ATTR_COMMAND: "command"}
await hass.services.async_call(REMOTE_DOMAIN, SERVICE_SEND_COMMAND, data)
await hass.async_block_till_done()
assert mock_remote.send_key.call_args == call("command")