Modernize Elgato tests (#64060)
This commit is contained in:
parent
b17860a7dd
commit
b1848cd2f4
10 changed files with 343 additions and 367 deletions
|
@ -1,72 +1 @@
|
||||||
"""Tests for the Elgato Key Light integration."""
|
"""Tests for the Elgato Key Light integration."""
|
||||||
|
|
||||||
from homeassistant.components.elgato.const import DOMAIN
|
|
||||||
from homeassistant.const import CONF_HOST, CONF_PORT, CONTENT_TYPE_JSON
|
|
||||||
from homeassistant.core import HomeAssistant
|
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, load_fixture
|
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
|
||||||
|
|
||||||
|
|
||||||
async def init_integration(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
aioclient_mock: AiohttpClientMocker,
|
|
||||||
skip_setup: bool = False,
|
|
||||||
color: bool = False,
|
|
||||||
mode_color: bool = False,
|
|
||||||
) -> MockConfigEntry:
|
|
||||||
"""Set up the Elgato Key Light integration in Home Assistant."""
|
|
||||||
aioclient_mock.get(
|
|
||||||
"http://127.0.0.1:9123/elgato/accessory-info",
|
|
||||||
text=load_fixture("elgato/info.json"),
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
aioclient_mock.get(
|
|
||||||
"http://127.0.0.2:9123/elgato/accessory-info",
|
|
||||||
text=load_fixture("elgato/info.json"),
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
settings = "elgato/settings.json"
|
|
||||||
if color:
|
|
||||||
settings = "elgato/settings-color.json"
|
|
||||||
|
|
||||||
aioclient_mock.get(
|
|
||||||
"http://127.0.0.1:9123/elgato/lights/settings",
|
|
||||||
text=load_fixture(settings),
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
state = "elgato/state.json"
|
|
||||||
if mode_color:
|
|
||||||
state = "elgato/state-color.json"
|
|
||||||
|
|
||||||
aioclient_mock.get(
|
|
||||||
"http://127.0.0.1:9123/elgato/lights",
|
|
||||||
text=load_fixture(state),
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
aioclient_mock.put(
|
|
||||||
"http://127.0.0.1:9123/elgato/lights",
|
|
||||||
text=load_fixture("elgato/state.json"),
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
entry = MockConfigEntry(
|
|
||||||
domain=DOMAIN,
|
|
||||||
unique_id="CN11A1A00001",
|
|
||||||
data={
|
|
||||||
CONF_HOST: "127.0.0.1",
|
|
||||||
CONF_PORT: 9123,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
if not skip_setup:
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
return entry
|
|
||||||
|
|
|
@ -1,2 +1,76 @@
|
||||||
"""elgato conftest."""
|
"""Fixtures for Elgato integration tests."""
|
||||||
|
from collections.abc import Generator
|
||||||
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
|
from elgato import Info, Settings, State
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.elgato.const import DOMAIN
|
||||||
|
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, load_fixture
|
||||||
from tests.components.light.conftest import mock_light_profiles # noqa: F401
|
from tests.components.light.conftest import mock_light_profiles # noqa: F401
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_config_entry() -> MockConfigEntry:
|
||||||
|
"""Return the default mocked config entry."""
|
||||||
|
return MockConfigEntry(
|
||||||
|
title="CN11A1A00001",
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
|
||||||
|
unique_id="CN11A1A00001",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
|
||||||
|
"""Mock setting up a config entry."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.elgato.async_setup_entry", return_value=True
|
||||||
|
) as mock_setup:
|
||||||
|
yield mock_setup
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_elgato_config_flow() -> Generator[None, MagicMock, None]:
|
||||||
|
"""Return a mocked Elgato client."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.elgato.config_flow.Elgato", autospec=True
|
||||||
|
) as elgato_mock:
|
||||||
|
elgato = elgato_mock.return_value
|
||||||
|
elgato.info.return_value = Info.parse_raw(load_fixture("info.json", DOMAIN))
|
||||||
|
yield elgato
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_elgato(request: pytest.FixtureRequest) -> Generator[None, MagicMock, None]:
|
||||||
|
"""Return a mocked Elgato client."""
|
||||||
|
variant = {"state": "temperature", "settings": "temperature"}
|
||||||
|
if hasattr(request, "param") and request.param:
|
||||||
|
variant = request.param
|
||||||
|
|
||||||
|
with patch("homeassistant.components.elgato.Elgato", autospec=True) as elgato_mock:
|
||||||
|
elgato = elgato_mock.return_value
|
||||||
|
elgato.info.return_value = Info.parse_raw(load_fixture("info.json", DOMAIN))
|
||||||
|
elgato.state.return_value = State.parse_raw(
|
||||||
|
load_fixture(f"state-{variant['state']}.json", DOMAIN)
|
||||||
|
)
|
||||||
|
elgato.settings.return_value = Settings.parse_raw(
|
||||||
|
load_fixture(f"settings-{variant['settings']}.json", DOMAIN)
|
||||||
|
)
|
||||||
|
yield elgato
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def init_integration(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_elgato: MagicMock
|
||||||
|
) -> MockConfigEntry:
|
||||||
|
"""Set up the Elgato integration for testing."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return mock_config_entry
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
{
|
{
|
||||||
"numberOfLights": 1,
|
"on": 1,
|
||||||
"lights": [
|
"hue": 358.0,
|
||||||
{
|
"saturation": 6.0,
|
||||||
"on": 1,
|
"brightness": 50
|
||||||
"hue": 358.0,
|
|
||||||
"saturation": 6.0,
|
|
||||||
"brightness": 50
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
5
tests/components/elgato/fixtures/state-temperature.json
Normal file
5
tests/components/elgato/fixtures/state-temperature.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"on": 1,
|
||||||
|
"brightness": 21,
|
||||||
|
"temperature": 297
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"numberOfLights": 1,
|
|
||||||
"lights": [
|
|
||||||
{
|
|
||||||
"on": 1,
|
|
||||||
"brightness": 21,
|
|
||||||
"temperature": 297
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""Tests for the Elgato Light button platform."""
|
"""Tests for the Elgato Light button platform."""
|
||||||
from unittest.mock import patch
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from elgato import ElgatoError
|
from elgato import ElgatoError
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -10,17 +10,16 @@ from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.helpers.entity import EntityCategory
|
from homeassistant.helpers.entity import EntityCategory
|
||||||
|
|
||||||
from tests.components.elgato import init_integration
|
from tests.common import MockConfigEntry
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.freeze_time("2021-11-13 11:48:00")
|
@pytest.mark.freeze_time("2021-11-13 11:48:00")
|
||||||
async def test_button_identify(
|
async def test_button_identify(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the Elgato identify button."""
|
"""Test the Elgato identify button."""
|
||||||
await init_integration(hass, aioclient_mock)
|
|
||||||
|
|
||||||
entity_registry = er.async_get(hass)
|
entity_registry = er.async_get(hass)
|
||||||
|
|
||||||
state = hass.states.get("button.identify")
|
state = hass.states.get("button.identify")
|
||||||
|
@ -33,18 +32,15 @@ async def test_button_identify(
|
||||||
assert entry.unique_id == "CN11A1A00001_identify"
|
assert entry.unique_id == "CN11A1A00001_identify"
|
||||||
assert entry.entity_category == EntityCategory.CONFIG
|
assert entry.entity_category == EntityCategory.CONFIG
|
||||||
|
|
||||||
with patch(
|
await hass.services.async_call(
|
||||||
"homeassistant.components.elgato.light.Elgato.identify"
|
BUTTON_DOMAIN,
|
||||||
) as mock_identify:
|
SERVICE_PRESS,
|
||||||
await hass.services.async_call(
|
{ATTR_ENTITY_ID: "button.identify"},
|
||||||
BUTTON_DOMAIN,
|
blocking=True,
|
||||||
SERVICE_PRESS,
|
)
|
||||||
{ATTR_ENTITY_ID: "button.identify"},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert len(mock_identify.mock_calls) == 1
|
assert len(mock_elgato.identify.mock_calls) == 1
|
||||||
mock_identify.assert_called_with()
|
mock_elgato.identify.assert_called_with()
|
||||||
|
|
||||||
state = hass.states.get("button.identify")
|
state = hass.states.get("button.identify")
|
||||||
assert state
|
assert state
|
||||||
|
@ -52,22 +48,20 @@ async def test_button_identify(
|
||||||
|
|
||||||
|
|
||||||
async def test_button_identify_error(
|
async def test_button_identify_error(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test an error occurs with the Elgato identify button."""
|
"""Test an error occurs with the Elgato identify button."""
|
||||||
await init_integration(hass, aioclient_mock)
|
mock_elgato.identify.side_effect = ElgatoError
|
||||||
|
await hass.services.async_call(
|
||||||
with patch(
|
BUTTON_DOMAIN,
|
||||||
"homeassistant.components.elgato.light.Elgato.identify",
|
SERVICE_PRESS,
|
||||||
side_effect=ElgatoError,
|
{ATTR_ENTITY_ID: "button.identify"},
|
||||||
) as mock_identify:
|
blocking=True,
|
||||||
await hass.services.async_call(
|
)
|
||||||
BUTTON_DOMAIN,
|
|
||||||
SERVICE_PRESS,
|
|
||||||
{ATTR_ENTITY_ID: "button.identify"},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_identify.mock_calls) == 1
|
|
||||||
|
assert len(mock_elgato.identify.mock_calls) == 1
|
||||||
assert "An error occurred while identifying the Elgato Light" in caplog.text
|
assert "An error occurred while identifying the Elgato Light" in caplog.text
|
||||||
|
|
|
@ -1,77 +1,63 @@
|
||||||
"""Tests for the Elgato Key Light config flow."""
|
"""Tests for the Elgato Key Light config flow."""
|
||||||
import aiohttp
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
|
|
||||||
|
from elgato import ElgatoConnectionError
|
||||||
|
|
||||||
from homeassistant import data_entry_flow
|
|
||||||
from homeassistant.components import zeroconf
|
from homeassistant.components import zeroconf
|
||||||
from homeassistant.components.elgato.const import DOMAIN
|
from homeassistant.components.elgato.const import DOMAIN
|
||||||
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
||||||
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SOURCE, CONTENT_TYPE_JSON
|
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SOURCE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.data_entry_flow import (
|
||||||
|
RESULT_TYPE_ABORT,
|
||||||
|
RESULT_TYPE_CREATE_ENTRY,
|
||||||
|
RESULT_TYPE_FORM,
|
||||||
|
)
|
||||||
|
|
||||||
from . import init_integration
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
from tests.common import load_fixture
|
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
|
||||||
|
|
||||||
|
|
||||||
async def test_full_user_flow_implementation(
|
async def test_full_user_flow_implementation(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_elgato_config_flow: MagicMock,
|
||||||
|
mock_setup_entry: AsyncMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the full manual user flow from start to finish."""
|
"""Test the full manual user flow from start to finish."""
|
||||||
aioclient_mock.get(
|
|
||||||
"http://127.0.0.1:9123/elgato/accessory-info",
|
|
||||||
text=load_fixture("elgato/info.json"),
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
# Start a discovered configuration flow, to guarantee a user flow doesn't abort
|
|
||||||
await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={CONF_SOURCE: SOURCE_ZEROCONF},
|
|
||||||
data=zeroconf.ZeroconfServiceInfo(
|
|
||||||
host="127.0.0.1",
|
|
||||||
hostname="example.local.",
|
|
||||||
name="mock_name",
|
|
||||||
port=9123,
|
|
||||||
properties={},
|
|
||||||
type="mock_type",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={CONF_SOURCE: SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["step_id"] == "user"
|
assert result.get("type") == RESULT_TYPE_FORM
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result.get("step_id") == SOURCE_USER
|
||||||
|
assert "flow_id" in result
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input={CONF_HOST: "127.0.0.1", CONF_PORT: 9123}
|
result["flow_id"], user_input={CONF_HOST: "127.0.0.1", CONF_PORT: 9123}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["data"][CONF_HOST] == "127.0.0.1"
|
assert result2.get("type") == RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["data"][CONF_PORT] == 9123
|
assert result2.get("title") == "CN11A1A00001"
|
||||||
assert result["title"] == "CN11A1A00001"
|
assert result2.get("data") == {
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
CONF_HOST: "127.0.0.1",
|
||||||
|
CONF_PORT: 9123,
|
||||||
|
}
|
||||||
|
assert "result" in result2
|
||||||
|
assert result2["result"].unique_id == "CN11A1A00001"
|
||||||
|
|
||||||
entries = hass.config_entries.async_entries(DOMAIN)
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
assert entries[0].unique_id == "CN11A1A00001"
|
assert len(mock_elgato_config_flow.info.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_full_zeroconf_flow_implementation(
|
async def test_full_zeroconf_flow_implementation(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_elgato_config_flow: MagicMock,
|
||||||
|
mock_setup_entry: AsyncMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the zeroconf flow from start to finish."""
|
"""Test the zeroconf flow from start to finish."""
|
||||||
aioclient_mock.get(
|
|
||||||
"http://127.0.0.1:9123/elgato/accessory-info",
|
|
||||||
text=load_fixture("elgato/info.json"),
|
|
||||||
headers={"Content-Type": CONTENT_TYPE_JSON},
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={CONF_SOURCE: SOURCE_ZEROCONF},
|
context={"source": SOURCE_ZEROCONF},
|
||||||
data=zeroconf.ZeroconfServiceInfo(
|
data=zeroconf.ZeroconfServiceInfo(
|
||||||
host="127.0.0.1",
|
host="127.0.0.1",
|
||||||
hostname="example.local.",
|
hostname="example.local.",
|
||||||
|
@ -82,51 +68,57 @@ async def test_full_zeroconf_flow_implementation(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["description_placeholders"] == {"serial_number": "CN11A1A00001"}
|
assert result.get("description_placeholders") == {"serial_number": "CN11A1A00001"}
|
||||||
assert result["step_id"] == "zeroconf_confirm"
|
assert result.get("step_id") == "zeroconf_confirm"
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result.get("type") == RESULT_TYPE_FORM
|
||||||
|
assert "flow_id" in result
|
||||||
|
|
||||||
progress = hass.config_entries.flow.async_progress()
|
progress = hass.config_entries.flow.async_progress()
|
||||||
assert len(progress) == 1
|
assert len(progress) == 1
|
||||||
assert progress[0]["flow_id"] == result["flow_id"]
|
assert progress[0].get("flow_id") == result["flow_id"]
|
||||||
assert progress[0]["context"]["confirm_only"] is True
|
assert "context" in progress[0]
|
||||||
|
assert progress[0]["context"].get("confirm_only") is True
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], user_input={}
|
result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
assert result["data"][CONF_HOST] == "127.0.0.1"
|
|
||||||
assert result["data"][CONF_PORT] == 9123
|
assert result2.get("type") == RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["title"] == "CN11A1A00001"
|
assert result2.get("title") == "CN11A1A00001"
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
assert result2.get("data") == {
|
||||||
|
CONF_HOST: "127.0.0.1",
|
||||||
|
CONF_PORT: 9123,
|
||||||
|
}
|
||||||
|
assert "result" in result2
|
||||||
|
assert result2["result"].unique_id == "CN11A1A00001"
|
||||||
|
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
assert len(mock_elgato_config_flow.info.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_connection_error(
|
async def test_connection_error(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_elgato_config_flow: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we show user form on Elgato Key Light connection error."""
|
"""Test we show user form on Elgato Key Light connection error."""
|
||||||
aioclient_mock.get(
|
mock_elgato_config_flow.info.side_effect = ElgatoConnectionError
|
||||||
"http://127.0.0.1/elgato/accessory-info", exc=aiohttp.ClientError
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={CONF_SOURCE: SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
|
data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["errors"] == {"base": "cannot_connect"}
|
assert result.get("type") == RESULT_TYPE_FORM
|
||||||
assert result["step_id"] == "user"
|
assert result.get("errors") == {"base": "cannot_connect"}
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
assert result.get("step_id") == "user"
|
||||||
|
|
||||||
|
|
||||||
async def test_zeroconf_connection_error(
|
async def test_zeroconf_connection_error(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_elgato_config_flow: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we abort zeroconf flow on Elgato Key Light connection error."""
|
"""Test we abort zeroconf flow on Elgato Key Light connection error."""
|
||||||
aioclient_mock.get(
|
mock_elgato_config_flow.info.side_effect = ElgatoConnectionError
|
||||||
"http://127.0.0.1/elgato/accessory-info", exc=aiohttp.ClientError
|
|
||||||
)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_ZEROCONF},
|
context={"source": SOURCE_ZEROCONF},
|
||||||
|
@ -140,31 +132,34 @@ async def test_zeroconf_connection_error(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["reason"] == "cannot_connect"
|
assert result.get("reason") == "cannot_connect"
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result.get("type") == RESULT_TYPE_ABORT
|
||||||
|
|
||||||
|
|
||||||
async def test_user_device_exists_abort(
|
async def test_user_device_exists_abort(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_elgato_config_flow: MagicMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we abort zeroconf flow if Elgato Key Light device already configured."""
|
"""Test we abort zeroconf flow if Elgato Key Light device already configured."""
|
||||||
await init_integration(hass, aioclient_mock)
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={CONF_SOURCE: SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
|
data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result.get("type") == RESULT_TYPE_ABORT
|
||||||
|
assert result.get("reason") == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_zeroconf_device_exists_abort(
|
async def test_zeroconf_device_exists_abort(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_elgato_config_flow: MagicMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we abort zeroconf flow if Elgato Key Light device already configured."""
|
"""Test we abort zeroconf flow if Elgato Key Light device already configured."""
|
||||||
await init_integration(hass, aioclient_mock)
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={CONF_SOURCE: SOURCE_ZEROCONF},
|
context={CONF_SOURCE: SOURCE_ZEROCONF},
|
||||||
|
@ -178,9 +173,13 @@ async def test_zeroconf_device_exists_abort(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["reason"] == "already_configured"
|
assert result.get("type") == RESULT_TYPE_ABORT
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result.get("reason") == "already_configured"
|
||||||
|
|
||||||
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
|
assert entries[0].data[CONF_HOST] == "127.0.0.1"
|
||||||
|
|
||||||
|
# Check the host updates on discovery
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={CONF_SOURCE: SOURCE_ZEROCONF},
|
context={CONF_SOURCE: SOURCE_ZEROCONF},
|
||||||
|
@ -194,8 +193,8 @@ async def test_zeroconf_device_exists_abort(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["reason"] == "already_configured"
|
assert result.get("type") == RESULT_TYPE_ABORT
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result.get("reason") == "already_configured"
|
||||||
|
|
||||||
entries = hass.config_entries.async_entries(DOMAIN)
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
assert entries[0].data[CONF_HOST] == "127.0.0.2"
|
assert entries[0].data[CONF_HOST] == "127.0.0.2"
|
||||||
|
|
|
@ -1,33 +1,46 @@
|
||||||
"""Tests for the Elgato Key Light integration."""
|
"""Tests for the Elgato Key Light integration."""
|
||||||
import aiohttp
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from elgato import ElgatoConnectionError
|
||||||
|
|
||||||
from homeassistant.components.elgato.const import DOMAIN
|
from homeassistant.components.elgato.const import DOMAIN
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from tests.components.elgato import init_integration
|
from tests.common import MockConfigEntry
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
|
||||||
|
|
||||||
|
async def test_load_unload_config_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test the Elgato configuration entry loading/unloading."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
assert len(mock_elgato.info.mock_calls) == 1
|
||||||
|
|
||||||
|
await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert not hass.data.get(DOMAIN)
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||||
|
|
||||||
|
|
||||||
async def test_config_entry_not_ready(
|
async def test_config_entry_not_ready(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the Elgato Key Light configuration entry not ready."""
|
"""Test the Elgato configuration entry not ready."""
|
||||||
aioclient_mock.get(
|
mock_elgato.info.side_effect = ElgatoConnectionError
|
||||||
"http://127.0.0.1:9123/elgato/accessory-info", exc=aiohttp.ClientError
|
|
||||||
)
|
|
||||||
|
|
||||||
entry = await init_integration(hass, aioclient_mock)
|
mock_config_entry.add_to_hass(hass)
|
||||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
async def test_unload_config_entry(
|
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
|
||||||
) -> None:
|
|
||||||
"""Test the Elgato Key Light configuration entry unloading."""
|
|
||||||
entry = await init_integration(hass, aioclient_mock)
|
|
||||||
assert hass.data[DOMAIN]
|
|
||||||
|
|
||||||
await hass.config_entries.async_unload(entry.entry_id)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert not hass.data.get(DOMAIN)
|
|
||||||
|
assert len(mock_elgato.info.mock_calls) == 1
|
||||||
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
"""Tests for the Elgato Key Light light platform."""
|
"""Tests for the Elgato Key Light light platform."""
|
||||||
from unittest.mock import patch
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from elgato import ElgatoError
|
from elgato import ElgatoError
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -27,17 +27,15 @@ from homeassistant.const import (
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
from tests.common import mock_coro
|
from tests.common import MockConfigEntry
|
||||||
from tests.components.elgato import init_integration
|
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
|
||||||
|
|
||||||
|
|
||||||
async def test_light_state_temperature(
|
async def test_light_state_temperature(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the creation and values of the Elgato Lights in temperature mode."""
|
"""Test the creation and values of the Elgato Lights in temperature mode."""
|
||||||
await init_integration(hass, aioclient_mock)
|
|
||||||
|
|
||||||
entity_registry = er.async_get(hass)
|
entity_registry = er.async_get(hass)
|
||||||
|
|
||||||
# First segment of the strip
|
# First segment of the strip
|
||||||
|
@ -57,12 +55,15 @@ async def test_light_state_temperature(
|
||||||
assert entry.unique_id == "CN11A1A00001"
|
assert entry.unique_id == "CN11A1A00001"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"mock_elgato", [{"settings": "color", "state": "color"}], indirect=True
|
||||||
|
)
|
||||||
async def test_light_state_color(
|
async def test_light_state_color(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the creation and values of the Elgato Lights in temperature mode."""
|
"""Test the creation and values of the Elgato Lights in temperature mode."""
|
||||||
await init_integration(hass, aioclient_mock, color=True, mode_color=True)
|
|
||||||
|
|
||||||
entity_registry = er.async_get(hass)
|
entity_registry = er.async_get(hass)
|
||||||
|
|
||||||
# First segment of the strip
|
# First segment of the strip
|
||||||
|
@ -85,159 +86,135 @@ async def test_light_state_color(
|
||||||
assert entry.unique_id == "CN11A1A00001"
|
assert entry.unique_id == "CN11A1A00001"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"mock_elgato", [{"settings": "color", "state": "temperature"}], indirect=True
|
||||||
|
)
|
||||||
async def test_light_change_state_temperature(
|
async def test_light_change_state_temperature(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the change of state of a Elgato Key Light device."""
|
"""Test the change of state of a Elgato Key Light device."""
|
||||||
await init_integration(hass, aioclient_mock, color=True, mode_color=False)
|
|
||||||
|
|
||||||
state = hass.states.get("light.frenck")
|
state = hass.states.get("light.frenck")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
|
||||||
with patch(
|
await hass.services.async_call(
|
||||||
"homeassistant.components.elgato.light.Elgato.light",
|
LIGHT_DOMAIN,
|
||||||
return_value=mock_coro(),
|
SERVICE_TURN_ON,
|
||||||
) as mock_light:
|
{
|
||||||
await hass.services.async_call(
|
ATTR_ENTITY_ID: "light.frenck",
|
||||||
LIGHT_DOMAIN,
|
ATTR_BRIGHTNESS: 255,
|
||||||
SERVICE_TURN_ON,
|
ATTR_COLOR_TEMP: 100,
|
||||||
{
|
},
|
||||||
ATTR_ENTITY_ID: "light.frenck",
|
blocking=True,
|
||||||
ATTR_BRIGHTNESS: 255,
|
)
|
||||||
ATTR_COLOR_TEMP: 100,
|
await hass.async_block_till_done()
|
||||||
},
|
assert len(mock_elgato.light.mock_calls) == 1
|
||||||
blocking=True,
|
mock_elgato.light.assert_called_with(
|
||||||
)
|
on=True, brightness=100, temperature=100, hue=None, saturation=None
|
||||||
await hass.async_block_till_done()
|
)
|
||||||
assert len(mock_light.mock_calls) == 1
|
|
||||||
mock_light.assert_called_with(
|
|
||||||
on=True, brightness=100, temperature=100, hue=None, saturation=None
|
|
||||||
)
|
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
LIGHT_DOMAIN,
|
LIGHT_DOMAIN,
|
||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
{
|
{
|
||||||
ATTR_ENTITY_ID: "light.frenck",
|
ATTR_ENTITY_ID: "light.frenck",
|
||||||
ATTR_BRIGHTNESS: 255,
|
ATTR_BRIGHTNESS: 255,
|
||||||
},
|
},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_light.mock_calls) == 2
|
assert len(mock_elgato.light.mock_calls) == 2
|
||||||
mock_light.assert_called_with(
|
mock_elgato.light.assert_called_with(
|
||||||
on=True, brightness=100, temperature=297, hue=None, saturation=None
|
on=True, brightness=100, temperature=297, hue=None, saturation=None
|
||||||
)
|
)
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
LIGHT_DOMAIN,
|
LIGHT_DOMAIN,
|
||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
{ATTR_ENTITY_ID: "light.frenck"},
|
{ATTR_ENTITY_ID: "light.frenck"},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_light.mock_calls) == 3
|
assert len(mock_elgato.light.mock_calls) == 3
|
||||||
mock_light.assert_called_with(on=False)
|
mock_elgato.light.assert_called_with(on=False)
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
async def test_light_change_state_color(
|
LIGHT_DOMAIN,
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
SERVICE_TURN_ON,
|
||||||
) -> None:
|
{
|
||||||
"""Test the color state state of a Elgato Light device."""
|
ATTR_ENTITY_ID: "light.frenck",
|
||||||
await init_integration(hass, aioclient_mock, color=True)
|
ATTR_BRIGHTNESS: 255,
|
||||||
|
ATTR_HS_COLOR: (10.1, 20.2),
|
||||||
state = hass.states.get("light.frenck")
|
},
|
||||||
assert state
|
blocking=True,
|
||||||
assert state.state == STATE_ON
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
with patch(
|
assert len(mock_elgato.light.mock_calls) == 4
|
||||||
"homeassistant.components.elgato.light.Elgato.light",
|
mock_elgato.light.assert_called_with(
|
||||||
return_value=mock_coro(),
|
on=True, brightness=100, temperature=None, hue=10.1, saturation=20.2
|
||||||
) as mock_light:
|
)
|
||||||
await hass.services.async_call(
|
|
||||||
LIGHT_DOMAIN,
|
|
||||||
SERVICE_TURN_ON,
|
|
||||||
{
|
|
||||||
ATTR_ENTITY_ID: "light.frenck",
|
|
||||||
ATTR_BRIGHTNESS: 255,
|
|
||||||
ATTR_HS_COLOR: (10.1, 20.2),
|
|
||||||
},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert len(mock_light.mock_calls) == 1
|
|
||||||
mock_light.assert_called_with(
|
|
||||||
on=True, brightness=100, temperature=None, hue=10.1, saturation=20.2
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("service", [SERVICE_TURN_ON, SERVICE_TURN_OFF])
|
@pytest.mark.parametrize("service", [SERVICE_TURN_ON, SERVICE_TURN_OFF])
|
||||||
async def test_light_unavailable(
|
async def test_light_unavailable(
|
||||||
service: str, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
|
service: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test error/unavailable handling of an Elgato Light."""
|
"""Test error/unavailable handling of an Elgato Light."""
|
||||||
await init_integration(hass, aioclient_mock)
|
mock_elgato.state.side_effect = ElgatoError
|
||||||
with patch(
|
mock_elgato.light.side_effect = ElgatoError
|
||||||
"homeassistant.components.elgato.light.Elgato.light",
|
|
||||||
side_effect=ElgatoError,
|
await hass.services.async_call(
|
||||||
), patch(
|
LIGHT_DOMAIN,
|
||||||
"homeassistant.components.elgato.light.Elgato.state",
|
service,
|
||||||
side_effect=ElgatoError,
|
{ATTR_ENTITY_ID: "light.frenck"},
|
||||||
):
|
blocking=True,
|
||||||
await hass.services.async_call(
|
)
|
||||||
LIGHT_DOMAIN,
|
await hass.async_block_till_done()
|
||||||
service,
|
state = hass.states.get("light.frenck")
|
||||||
{ATTR_ENTITY_ID: "light.frenck"},
|
assert state
|
||||||
blocking=True,
|
assert state.state == STATE_UNAVAILABLE
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
state = hass.states.get("light.frenck")
|
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
|
|
||||||
async def test_light_identify(
|
async def test_light_identify(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test identifying an Elgato Light."""
|
"""Test identifying an Elgato Light."""
|
||||||
await init_integration(hass, aioclient_mock)
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
with patch(
|
SERVICE_IDENTIFY,
|
||||||
"homeassistant.components.elgato.light.Elgato.identify",
|
{
|
||||||
return_value=mock_coro(),
|
ATTR_ENTITY_ID: "light.frenck",
|
||||||
) as mock_identify:
|
},
|
||||||
await hass.services.async_call(
|
blocking=True,
|
||||||
DOMAIN,
|
)
|
||||||
SERVICE_IDENTIFY,
|
await hass.async_block_till_done()
|
||||||
{
|
assert len(mock_elgato.identify.mock_calls) == 1
|
||||||
ATTR_ENTITY_ID: "light.frenck",
|
mock_elgato.identify.assert_called_with()
|
||||||
},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert len(mock_identify.mock_calls) == 1
|
|
||||||
mock_identify.assert_called_with()
|
|
||||||
|
|
||||||
|
|
||||||
async def test_light_identify_error(
|
async def test_light_identify_error(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog
|
hass: HomeAssistant,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
mock_elgato: MagicMock,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test error occurred during identifying an Elgato Light."""
|
"""Test error occurred during identifying an Elgato Light."""
|
||||||
await init_integration(hass, aioclient_mock)
|
mock_elgato.identify.side_effect = ElgatoError
|
||||||
|
await hass.services.async_call(
|
||||||
with patch(
|
DOMAIN,
|
||||||
"homeassistant.components.elgato.light.Elgato.identify",
|
SERVICE_IDENTIFY,
|
||||||
side_effect=ElgatoError,
|
{
|
||||||
) as mock_identify:
|
ATTR_ENTITY_ID: "light.frenck",
|
||||||
await hass.services.async_call(
|
},
|
||||||
DOMAIN,
|
blocking=True,
|
||||||
SERVICE_IDENTIFY,
|
)
|
||||||
{
|
await hass.async_block_till_done()
|
||||||
ATTR_ENTITY_ID: "light.frenck",
|
assert len(mock_elgato.identify.mock_calls) == 1
|
||||||
},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
assert len(mock_identify.mock_calls) == 1
|
|
||||||
|
|
||||||
assert "An error occurred while identifying the Elgato Light" in caplog.text
|
assert "An error occurred while identifying the Elgato Light" in caplog.text
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue