Improve Elgato code quality (#46505)

This commit is contained in:
Franck Nijhof 2021-02-13 23:50:25 +01:00 committed by GitHub
parent eecf07d7df
commit 7148071be8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 153 additions and 234 deletions

View file

@ -1,13 +1,15 @@
"""Config flow to configure the Elgato Key Light integration.""" """Config flow to configure the Elgato Key Light integration."""
from typing import Any, Dict, Optional from __future__ import annotations
from elgato import Elgato, ElgatoError, Info from typing import Any, Dict
from elgato import Elgato, ElgatoError
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import CONN_CLASS_LOCAL_POLL, ConfigFlow from homeassistant.config_entries import CONN_CLASS_LOCAL_POLL, ConfigFlow
from homeassistant.const import CONF_HOST, CONF_PORT from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.typing import ConfigType
from .const import CONF_SERIAL_NUMBER, DOMAIN # pylint: disable=unused-import from .const import CONF_SERIAL_NUMBER, DOMAIN # pylint: disable=unused-import
@ -18,91 +20,54 @@ class ElgatoFlowHandler(ConfigFlow, domain=DOMAIN):
VERSION = 1 VERSION = 1
CONNECTION_CLASS = CONN_CLASS_LOCAL_POLL CONNECTION_CLASS = CONN_CLASS_LOCAL_POLL
host: str
port: int
serial_number: str
async def async_step_user( async def async_step_user(
self, user_input: Optional[ConfigType] = None self, user_input: Dict[str, Any] | None = None
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""Handle a flow initiated by the user.""" """Handle a flow initiated by the user."""
if user_input is None: if user_input is None:
return self._show_setup_form() return self._async_show_setup_form()
self.host = user_input[CONF_HOST]
self.port = user_input[CONF_PORT]
try: try:
info = await self._get_elgato_info( await self._get_elgato_serial_number(raise_on_progress=False)
user_input[CONF_HOST], user_input[CONF_PORT]
)
except ElgatoError: except ElgatoError:
return self._show_setup_form({"base": "cannot_connect"}) return self._async_show_setup_form({"base": "cannot_connect"})
# Check if already configured return self._async_create_entry()
await self.async_set_unique_id(info.serial_number)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=info.serial_number,
data={
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
CONF_SERIAL_NUMBER: info.serial_number,
},
)
async def async_step_zeroconf( async def async_step_zeroconf(
self, user_input: Optional[ConfigType] = None self, discovery_info: Dict[str, Any]
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""Handle zeroconf discovery.""" """Handle zeroconf discovery."""
if user_input is None: self.host = discovery_info[CONF_HOST]
return self.async_abort(reason="cannot_connect") self.port = discovery_info[CONF_PORT]
try: try:
info = await self._get_elgato_info( await self._get_elgato_serial_number()
user_input[CONF_HOST], user_input[CONF_PORT]
)
except ElgatoError: except ElgatoError:
return self.async_abort(reason="cannot_connect") return self.async_abort(reason="cannot_connect")
# Check if already configured return self.async_show_form(
await self.async_set_unique_id(info.serial_number) step_id="zeroconf_confirm",
self._abort_if_unique_id_configured(updates={CONF_HOST: user_input[CONF_HOST]}) description_placeholders={"serial_number": self.serial_number},
self.context.update(
{
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
CONF_SERIAL_NUMBER: info.serial_number,
"title_placeholders": {"serial_number": info.serial_number},
}
) )
# Prepare configuration flow
return self._show_confirm_dialog()
async def async_step_zeroconf_confirm( async def async_step_zeroconf_confirm(
self, user_input: ConfigType = None self, _: Dict[str, Any] | None = None
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""Handle a flow initiated by zeroconf.""" """Handle a flow initiated by zeroconf."""
if user_input is None: return self._async_create_entry()
return self._show_confirm_dialog()
try: @callback
info = await self._get_elgato_info( def _async_show_setup_form(
self.context.get(CONF_HOST), self.context.get(CONF_PORT) self, errors: Dict[str, str] | None = None
) ) -> Dict[str, Any]:
except ElgatoError:
return self.async_abort(reason="cannot_connect")
# Check if already configured
await self.async_set_unique_id(info.serial_number)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=self.context.get(CONF_SERIAL_NUMBER),
data={
CONF_HOST: self.context.get(CONF_HOST),
CONF_PORT: self.context.get(CONF_PORT),
CONF_SERIAL_NUMBER: self.context.get(CONF_SERIAL_NUMBER),
},
)
def _show_setup_form(self, errors: Optional[Dict] = None) -> Dict[str, Any]:
"""Show the setup form to the user.""" """Show the setup form to the user."""
return self.async_show_form( return self.async_show_form(
step_id="user", step_id="user",
@ -115,20 +80,33 @@ class ElgatoFlowHandler(ConfigFlow, domain=DOMAIN):
errors=errors or {}, errors=errors or {},
) )
def _show_confirm_dialog(self) -> Dict[str, Any]: @callback
"""Show the confirm dialog to the user.""" def _async_create_entry(self) -> Dict[str, Any]:
serial_number = self.context.get(CONF_SERIAL_NUMBER) return self.async_create_entry(
return self.async_show_form( title=self.serial_number,
step_id="zeroconf_confirm", data={
description_placeholders={"serial_number": serial_number}, CONF_HOST: self.host,
CONF_PORT: self.port,
CONF_SERIAL_NUMBER: self.serial_number,
},
) )
async def _get_elgato_info(self, host: str, port: int) -> Info: async def _get_elgato_serial_number(self, raise_on_progress: bool = True) -> None:
"""Get device information from an Elgato Key Light device.""" """Get device information from an Elgato Key Light device."""
session = async_get_clientsession(self.hass) session = async_get_clientsession(self.hass)
elgato = Elgato( elgato = Elgato(
host, host=self.host,
port=port, port=self.port,
session=session, session=session,
) )
return await elgato.info() info = await elgato.info()
# Check if already configured
await self.async_set_unique_id(
info.serial_number, raise_on_progress=raise_on_progress
)
self._abort_if_unique_id_configured(
updates={CONF_HOST: self.host, CONF_PORT: self.port}
)
self.serial_number = info.serial_number

View file

@ -1,7 +1,9 @@
"""Support for LED lights.""" """Support for LED lights."""
from __future__ import annotations
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any, Callable, Dict, List, Optional from typing import Any, Callable, Dict, List
from elgato import Elgato, ElgatoError, Info, State from elgato import Elgato, ElgatoError, Info, State
@ -42,7 +44,7 @@ async def async_setup_entry(
"""Set up Elgato Key Light based on a config entry.""" """Set up Elgato Key Light based on a config entry."""
elgato: Elgato = hass.data[DOMAIN][entry.entry_id][DATA_ELGATO_CLIENT] elgato: Elgato = hass.data[DOMAIN][entry.entry_id][DATA_ELGATO_CLIENT]
info = await elgato.info() info = await elgato.info()
async_add_entities([ElgatoLight(entry.entry_id, elgato, info)], True) async_add_entities([ElgatoLight(elgato, info)], True)
class ElgatoLight(LightEntity): class ElgatoLight(LightEntity):
@ -50,15 +52,14 @@ class ElgatoLight(LightEntity):
def __init__( def __init__(
self, self,
entry_id: str,
elgato: Elgato, elgato: Elgato,
info: Info, info: Info,
): ):
"""Initialize Elgato Key Light.""" """Initialize Elgato Key Light."""
self._brightness: Optional[int] = None self._brightness: int | None = None
self._info: Info = info self._info: Info = info
self._state: Optional[bool] = None self._state: bool | None = None
self._temperature: Optional[int] = None self._temperature: int | None = None
self._available = True self._available = True
self.elgato = elgato self.elgato = elgato
@ -81,22 +82,22 @@ class ElgatoLight(LightEntity):
return self._info.serial_number return self._info.serial_number
@property @property
def brightness(self) -> Optional[int]: def brightness(self) -> int | None:
"""Return the brightness of this light between 1..255.""" """Return the brightness of this light between 1..255."""
return self._brightness return self._brightness
@property @property
def color_temp(self): def color_temp(self) -> int | None:
"""Return the CT color value in mireds.""" """Return the CT color value in mireds."""
return self._temperature return self._temperature
@property @property
def min_mireds(self): def min_mireds(self) -> int:
"""Return the coldest color_temp that this light supports.""" """Return the coldest color_temp that this light supports."""
return 143 return 143
@property @property
def max_mireds(self): def max_mireds(self) -> int:
"""Return the warmest color_temp that this light supports.""" """Return the warmest color_temp that this light supports."""
return 344 return 344
@ -116,9 +117,8 @@ class ElgatoLight(LightEntity):
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the light.""" """Turn on the light."""
data = {} data: Dict[str, bool | int] = {ATTR_ON: True}
data[ATTR_ON] = True
if ATTR_ON in kwargs: if ATTR_ON in kwargs:
data[ATTR_ON] = kwargs[ATTR_ON] data[ATTR_ON] = kwargs[ATTR_ON]

View file

@ -14,27 +14,26 @@ async def init_integration(
skip_setup: bool = False, skip_setup: bool = False,
) -> MockConfigEntry: ) -> MockConfigEntry:
"""Set up the Elgato Key Light integration in Home Assistant.""" """Set up the Elgato Key Light integration in Home Assistant."""
aioclient_mock.get( aioclient_mock.get(
"http://1.2.3.4:9123/elgato/accessory-info", "http://127.0.0.1:9123/elgato/accessory-info",
text=load_fixture("elgato/info.json"), text=load_fixture("elgato/info.json"),
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
aioclient_mock.put( aioclient_mock.put(
"http://1.2.3.4:9123/elgato/lights", "http://127.0.0.1:9123/elgato/lights",
text=load_fixture("elgato/state.json"), text=load_fixture("elgato/state.json"),
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
aioclient_mock.get( aioclient_mock.get(
"http://1.2.3.4:9123/elgato/lights", "http://127.0.0.1:9123/elgato/lights",
text=load_fixture("elgato/state.json"), text=load_fixture("elgato/state.json"),
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
aioclient_mock.get( aioclient_mock.get(
"http://5.6.7.8:9123/elgato/accessory-info", "http://127.0.0.2:9123/elgato/accessory-info",
text=load_fixture("elgato/info.json"), text=load_fixture("elgato/info.json"),
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
@ -43,7 +42,7 @@ async def init_integration(
domain=DOMAIN, domain=DOMAIN,
unique_id="CN11A1A00001", unique_id="CN11A1A00001",
data={ data={
CONF_HOST: "1.2.3.4", CONF_HOST: "127.0.0.1",
CONF_PORT: 9123, CONF_PORT: 9123,
CONF_SERIAL_NUMBER: "CN11A1A00001", CONF_SERIAL_NUMBER: "CN11A1A00001",
}, },

View file

@ -2,10 +2,9 @@
import aiohttp import aiohttp
from homeassistant import data_entry_flow from homeassistant import data_entry_flow
from homeassistant.components.elgato import config_flow from homeassistant.components.elgato.const import CONF_SERIAL_NUMBER, DOMAIN
from homeassistant.components.elgato.const import CONF_SERIAL_NUMBER
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, CONTENT_TYPE_JSON from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SOURCE, CONTENT_TYPE_JSON
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from . import init_integration from . import init_integration
@ -14,62 +13,97 @@ from tests.common import load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker
async def test_show_user_form(hass: HomeAssistant) -> None: async def test_full_user_flow_implementation(
"""Test that the user set up form is served.""" hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""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={
"host": "127.0.0.1",
"hostname": "example.local.",
"port": 9123,
"properties": {},
},
)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, DOMAIN,
context={"source": SOURCE_USER}, context={CONF_SOURCE: SOURCE_USER},
) )
assert result["step_id"] == "user" assert result["step_id"] == "user"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={CONF_HOST: "127.0.0.1", CONF_PORT: 9123}
)
async def test_show_zeroconf_confirm_form(hass: HomeAssistant) -> None: assert result["data"][CONF_HOST] == "127.0.0.1"
"""Test that the zeroconf confirmation form is served.""" assert result["data"][CONF_PORT] == 9123
flow = config_flow.ElgatoFlowHandler() assert result["data"][CONF_SERIAL_NUMBER] == "CN11A1A00001"
flow.hass = hass assert result["title"] == "CN11A1A00001"
flow.context = {"source": SOURCE_ZEROCONF, CONF_SERIAL_NUMBER: "12345"} assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
result = await flow.async_step_zeroconf_confirm()
assert result["description_placeholders"] == {CONF_SERIAL_NUMBER: "12345"} entries = hass.config_entries.async_entries(DOMAIN)
assert result["step_id"] == "zeroconf_confirm" assert entries[0].unique_id == "CN11A1A00001"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
async def test_show_zerconf_form( async def test_full_zeroconf_flow_implementation(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None: ) -> None:
"""Test that the zeroconf confirmation form is served.""" """Test the zeroconf flow from start to finish."""
aioclient_mock.get( aioclient_mock.get(
"http://1.2.3.4:9123/elgato/accessory-info", "http://127.0.0.1:9123/elgato/accessory-info",
text=load_fixture("elgato/info.json"), text=load_fixture("elgato/info.json"),
headers={"Content-Type": CONTENT_TYPE_JSON}, headers={"Content-Type": CONTENT_TYPE_JSON},
) )
flow = config_flow.ElgatoFlowHandler() result = await hass.config_entries.flow.async_init(
flow.hass = hass DOMAIN,
flow.context = {"source": SOURCE_ZEROCONF} context={CONF_SOURCE: SOURCE_ZEROCONF},
result = await flow.async_step_zeroconf({"host": "1.2.3.4", "port": 9123}) data={
"host": "127.0.0.1",
"hostname": "example.local.",
"port": 9123,
"properties": {},
},
)
assert flow.context[CONF_HOST] == "1.2.3.4"
assert flow.context[CONF_PORT] == 9123
assert flow.context[CONF_SERIAL_NUMBER] == "CN11A1A00001"
assert result["description_placeholders"] == {CONF_SERIAL_NUMBER: "CN11A1A00001"} assert result["description_placeholders"] == {CONF_SERIAL_NUMBER: "CN11A1A00001"}
assert result["step_id"] == "zeroconf_confirm" assert result["step_id"] == "zeroconf_confirm"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["data"][CONF_HOST] == "127.0.0.1"
assert result["data"][CONF_PORT] == 9123
assert result["data"][CONF_SERIAL_NUMBER] == "CN11A1A00001"
assert result["title"] == "CN11A1A00001"
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
async def test_connection_error( async def test_connection_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> 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("http://1.2.3.4/elgato/accessory-info", exc=aiohttp.ClientError) aioclient_mock.get(
"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(
config_flow.DOMAIN, DOMAIN,
context={"source": SOURCE_USER}, context={CONF_SOURCE: SOURCE_USER},
data={CONF_HOST: "1.2.3.4", CONF_PORT: 9123}, data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
) )
assert result["errors"] == {"base": "cannot_connect"} assert result["errors"] == {"base": "cannot_connect"}
@ -81,51 +115,20 @@ async def test_zeroconf_connection_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> 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("http://1.2.3.4/elgato/accessory-info", exc=aiohttp.ClientError) aioclient_mock.get(
"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(
config_flow.DOMAIN, DOMAIN,
context={"source": SOURCE_ZEROCONF}, context={"source": SOURCE_ZEROCONF},
data={"host": "1.2.3.4", "port": 9123}, data={"host": "127.0.0.1", "port": 9123},
) )
assert result["reason"] == "cannot_connect" assert result["reason"] == "cannot_connect"
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
async def test_zeroconf_confirm_connection_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test we abort zeroconf flow on Elgato Key Light connection error."""
aioclient_mock.get("http://1.2.3.4/elgato/accessory-info", exc=aiohttp.ClientError)
flow = config_flow.ElgatoFlowHandler()
flow.hass = hass
flow.context = {
"source": SOURCE_ZEROCONF,
CONF_HOST: "1.2.3.4",
CONF_PORT: 9123,
}
result = await flow.async_step_zeroconf_confirm(
user_input={CONF_HOST: "1.2.3.4", CONF_PORT: 9123}
)
assert result["reason"] == "cannot_connect"
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
async def test_zeroconf_no_data(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test we abort if zeroconf provides no data."""
flow = config_flow.ElgatoFlowHandler()
flow.hass = hass
result = await flow.async_step_zeroconf()
assert result["reason"] == "cannot_connect"
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
async def test_user_device_exists_abort( async def test_user_device_exists_abort(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None: ) -> None:
@ -133,9 +136,9 @@ async def test_user_device_exists_abort(
await init_integration(hass, aioclient_mock) await init_integration(hass, aioclient_mock)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, DOMAIN,
context={"source": SOURCE_USER}, context={CONF_SOURCE: SOURCE_USER},
data={CONF_HOST: "1.2.3.4", CONF_PORT: 9123}, data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
) )
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
@ -148,84 +151,22 @@ async def test_zeroconf_device_exists_abort(
await init_integration(hass, aioclient_mock) await init_integration(hass, aioclient_mock)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, DOMAIN,
context={"source": SOURCE_ZEROCONF}, context={CONF_SOURCE: SOURCE_ZEROCONF},
data={"host": "1.2.3.4", "port": 9123}, data={"host": "127.0.0.1", "port": 9123},
) )
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, DOMAIN,
context={"source": SOURCE_ZEROCONF, CONF_HOST: "1.2.3.4", "port": 9123}, context={CONF_SOURCE: SOURCE_ZEROCONF},
data={"host": "5.6.7.8", "port": 9123}, data={"host": "127.0.0.2", "port": 9123},
) )
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
entries = hass.config_entries.async_entries(config_flow.DOMAIN) entries = hass.config_entries.async_entries(DOMAIN)
assert entries[0].data[CONF_HOST] == "5.6.7.8" assert entries[0].data[CONF_HOST] == "127.0.0.2"
async def test_full_user_flow_implementation(
hass: HomeAssistant, aioclient_mock
) -> None:
"""Test the full manual user flow from start to finish."""
aioclient_mock.get(
"http://1.2.3.4:9123/elgato/accessory-info",
text=load_fixture("elgato/info.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN,
context={"source": SOURCE_USER},
)
assert result["step_id"] == "user"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={CONF_HOST: "1.2.3.4", CONF_PORT: 9123}
)
assert result["data"][CONF_HOST] == "1.2.3.4"
assert result["data"][CONF_PORT] == 9123
assert result["data"][CONF_SERIAL_NUMBER] == "CN11A1A00001"
assert result["title"] == "CN11A1A00001"
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
entries = hass.config_entries.async_entries(config_flow.DOMAIN)
assert entries[0].unique_id == "CN11A1A00001"
async def test_full_zeroconf_flow_implementation(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test the full manual user flow from start to finish."""
aioclient_mock.get(
"http://1.2.3.4:9123/elgato/accessory-info",
text=load_fixture("elgato/info.json"),
headers={"Content-Type": CONTENT_TYPE_JSON},
)
flow = config_flow.ElgatoFlowHandler()
flow.hass = hass
flow.context = {"source": SOURCE_ZEROCONF}
result = await flow.async_step_zeroconf({"host": "1.2.3.4", "port": 9123})
assert flow.context[CONF_HOST] == "1.2.3.4"
assert flow.context[CONF_PORT] == 9123
assert flow.context[CONF_SERIAL_NUMBER] == "CN11A1A00001"
assert result["description_placeholders"] == {CONF_SERIAL_NUMBER: "CN11A1A00001"}
assert result["step_id"] == "zeroconf_confirm"
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
result = await flow.async_step_zeroconf_confirm(user_input={CONF_HOST: "1.2.3.4"})
assert result["data"][CONF_HOST] == "1.2.3.4"
assert result["data"][CONF_PORT] == 9123
assert result["data"][CONF_SERIAL_NUMBER] == "CN11A1A00001"
assert result["title"] == "CN11A1A00001"
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY

View file

@ -14,7 +14,7 @@ async def test_config_entry_not_ready(
) -> None: ) -> None:
"""Test the Elgato Key Light configuration entry not ready.""" """Test the Elgato Key Light configuration entry not ready."""
aioclient_mock.get( aioclient_mock.get(
"http://1.2.3.4:9123/elgato/accessory-info", exc=aiohttp.ClientError "http://127.0.0.1:9123/elgato/accessory-info", exc=aiohttp.ClientError
) )
entry = await init_integration(hass, aioclient_mock) entry = await init_integration(hass, aioclient_mock)

View file

@ -1,7 +1,8 @@
"""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 patch
from homeassistant.components.elgato.light import ElgatoError from elgato import ElgatoError
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP, ATTR_COLOR_TEMP,