Add tests for goalzero (#59446)
* Add tests for goalzero * tweak * tweak
This commit is contained in:
parent
e9c8de25df
commit
14adcbc07c
13 changed files with 491 additions and 108 deletions
|
@ -386,10 +386,6 @@ omit =
|
||||||
homeassistant/components/glances/sensor.py
|
homeassistant/components/glances/sensor.py
|
||||||
homeassistant/components/gntp/notify.py
|
homeassistant/components/gntp/notify.py
|
||||||
homeassistant/components/goalfeed/*
|
homeassistant/components/goalfeed/*
|
||||||
homeassistant/components/goalzero/__init__.py
|
|
||||||
homeassistant/components/goalzero/binary_sensor.py
|
|
||||||
homeassistant/components/goalzero/sensor.py
|
|
||||||
homeassistant/components/goalzero/switch.py
|
|
||||||
homeassistant/components/google/*
|
homeassistant/components/google/*
|
||||||
homeassistant/components/google_cloud/tts.py
|
homeassistant/components/google_cloud/tts.py
|
||||||
homeassistant/components/google_maps/device_tracker.py
|
homeassistant/components/google_maps/device_tracker.py
|
||||||
|
|
|
@ -12,6 +12,7 @@ from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import ATTR_ATTRIBUTION, ATTR_MODEL, CONF_HOST, CONF_NAME
|
from homeassistant.const import ATTR_ATTRIBUTION, ATTR_MODEL, CONF_HOST, CONF_NAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.update_coordinator import (
|
from homeassistant.helpers.update_coordinator import (
|
||||||
|
@ -25,6 +26,7 @@ from .const import (
|
||||||
DATA_KEY_API,
|
DATA_KEY_API,
|
||||||
DATA_KEY_COORDINATOR,
|
DATA_KEY_COORDINATOR,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
MANUFACTURER,
|
||||||
MIN_TIME_BETWEEN_UPDATES,
|
MIN_TIME_BETWEEN_UPDATES,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -101,8 +103,9 @@ class YetiEntity(CoordinatorEntity):
|
||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return the device information of the entity."""
|
"""Return the device information of the entity."""
|
||||||
return DeviceInfo(
|
return DeviceInfo(
|
||||||
|
connections={(dr.CONNECTION_NETWORK_MAC, self.api.sysdata["macAddress"])},
|
||||||
identifiers={(DOMAIN, self._server_unique_id)},
|
identifiers={(DOMAIN, self._server_unique_id)},
|
||||||
manufacturer="Goal Zero",
|
manufacturer=MANUFACTURER,
|
||||||
model=self.api.sysdata[ATTR_MODEL],
|
model=self.api.sysdata[ATTR_MODEL],
|
||||||
name=self._name,
|
name=self._name,
|
||||||
sw_version=self.api.data["firmwareVersion"],
|
sw_version=self.api.data["firmwareVersion"],
|
||||||
|
|
|
@ -14,7 +14,7 @@ from homeassistant.data_entry_flow import FlowResult
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.device_registry import format_mac
|
from homeassistant.helpers.device_registry import format_mac
|
||||||
|
|
||||||
from .const import DEFAULT_NAME, DOMAIN
|
from .const import DEFAULT_NAME, DOMAIN, MANUFACTURER
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class GoalZeroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
"""Allow the user to confirm adding the device."""
|
"""Allow the user to confirm adding the device."""
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title="Goal Zero",
|
title=MANUFACTURER,
|
||||||
data={
|
data={
|
||||||
CONF_HOST: self.ip_address,
|
CONF_HOST: self.ip_address,
|
||||||
CONF_NAME: DEFAULT_NAME,
|
CONF_NAME: DEFAULT_NAME,
|
||||||
|
|
|
@ -8,5 +8,5 @@ DATA_KEY_COORDINATOR = "coordinator"
|
||||||
DOMAIN = "goalzero"
|
DOMAIN = "goalzero"
|
||||||
DEFAULT_NAME = "Yeti"
|
DEFAULT_NAME = "Yeti"
|
||||||
DATA_KEY_API = "api"
|
DATA_KEY_API = "api"
|
||||||
|
MANUFACTURER = "Goal Zero"
|
||||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)
|
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)
|
||||||
|
|
|
@ -1,42 +1,95 @@
|
||||||
"""Tests for the Goal Zero Yeti integration."""
|
"""Tests for the Goal Zero Yeti integration."""
|
||||||
|
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
from homeassistant.components.dhcp import HOSTNAME, IP_ADDRESS, MAC_ADDRESS
|
from homeassistant.components.dhcp import HOSTNAME, IP_ADDRESS, MAC_ADDRESS
|
||||||
|
from homeassistant.components.goalzero import DOMAIN
|
||||||
|
from homeassistant.components.goalzero.const import DEFAULT_NAME
|
||||||
from homeassistant.const import CONF_HOST, CONF_NAME
|
from homeassistant.const import CONF_HOST, CONF_NAME
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.device_registry import format_mac
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, load_fixture
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
HOST = "1.2.3.4"
|
HOST = "1.2.3.4"
|
||||||
NAME = "Yeti"
|
MAC = "aa:bb:cc:dd:ee:ff"
|
||||||
|
|
||||||
CONF_DATA = {
|
CONF_DATA = {
|
||||||
CONF_HOST: HOST,
|
CONF_HOST: HOST,
|
||||||
CONF_NAME: NAME,
|
CONF_NAME: DEFAULT_NAME,
|
||||||
}
|
|
||||||
|
|
||||||
CONF_CONFIG_FLOW = {
|
|
||||||
CONF_HOST: HOST,
|
|
||||||
CONF_NAME: NAME,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CONF_DHCP_FLOW = {
|
CONF_DHCP_FLOW = {
|
||||||
IP_ADDRESS: "1.1.1.1",
|
IP_ADDRESS: HOST,
|
||||||
MAC_ADDRESS: "AA:BB:CC:DD:EE:FF",
|
MAC_ADDRESS: format_mac("AA:BB:CC:DD:EE:FF"),
|
||||||
HOSTNAME: "any",
|
HOSTNAME: "yeti",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def _create_mocked_yeti(raise_exception=False):
|
def create_entry(hass: HomeAssistant):
|
||||||
|
"""Add config entry in Home Assistant."""
|
||||||
|
entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data=CONF_DATA,
|
||||||
|
unique_id=MAC,
|
||||||
|
)
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
return entry
|
||||||
|
|
||||||
|
|
||||||
|
async def create_mocked_yeti():
|
||||||
|
"""Create mocked yeti device."""
|
||||||
mocked_yeti = AsyncMock()
|
mocked_yeti = AsyncMock()
|
||||||
mocked_yeti.get_state = AsyncMock()
|
mocked_yeti.data = {}
|
||||||
|
mocked_yeti.data["firmwareVersion"] = "1.0.0"
|
||||||
|
mocked_yeti.sysdata = {}
|
||||||
|
mocked_yeti.sysdata["model"] = "test_model"
|
||||||
|
mocked_yeti.sysdata["macAddress"] = MAC
|
||||||
return mocked_yeti
|
return mocked_yeti
|
||||||
|
|
||||||
|
|
||||||
def _patch_init_yeti(mocked_yeti):
|
def patch_config_flow_yeti(mocked_yeti):
|
||||||
return patch("homeassistant.components.goalzero.Yeti", return_value=mocked_yeti)
|
"""Patch Goal Zero config flow."""
|
||||||
|
|
||||||
|
|
||||||
def _patch_config_flow_yeti(mocked_yeti):
|
|
||||||
return patch(
|
return patch(
|
||||||
"homeassistant.components.goalzero.config_flow.Yeti",
|
"homeassistant.components.goalzero.config_flow.Yeti",
|
||||||
return_value=mocked_yeti,
|
return_value=mocked_yeti,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_init_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
skip_setup: bool = False,
|
||||||
|
) -> MockConfigEntry:
|
||||||
|
"""Set up the Goal Zero integration in Home Assistant."""
|
||||||
|
entry = create_entry(hass)
|
||||||
|
base_url = f"http://{HOST}/"
|
||||||
|
aioclient_mock.get(
|
||||||
|
f"{base_url}state",
|
||||||
|
text=load_fixture("goalzero/state_data.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
f"{base_url}sysinfo",
|
||||||
|
text=load_fixture("goalzero/info_data.json"),
|
||||||
|
)
|
||||||
|
|
||||||
|
if not skip_setup:
|
||||||
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return entry
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
platform: str,
|
||||||
|
):
|
||||||
|
"""Set up the platform."""
|
||||||
|
entry = await async_init_integration(hass, aioclient_mock)
|
||||||
|
|
||||||
|
with patch("homeassistant.components.goalzero.PLATFORMS", [platform]):
|
||||||
|
assert await async_setup_component(hass, DOMAIN, {})
|
||||||
|
|
||||||
|
return entry
|
||||||
|
|
7
tests/components/goalzero/fixtures/info_data.json
Normal file
7
tests/components/goalzero/fixtures/info_data.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"name":"yeti123456789012",
|
||||||
|
"model":"Yeti 1400",
|
||||||
|
"firmwareVersion":"1.5.7",
|
||||||
|
"macAddress":"123456789012",
|
||||||
|
"platform":"esp32"
|
||||||
|
}
|
38
tests/components/goalzero/fixtures/state_change.json
Normal file
38
tests/components/goalzero/fixtures/state_change.json
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"thingName":"yeti123456789012",
|
||||||
|
"v12PortStatus":1,
|
||||||
|
"usbPortStatus":0,
|
||||||
|
"acPortStatus":1,
|
||||||
|
"backlight":1,
|
||||||
|
"app_online":0,
|
||||||
|
"wattsIn":0.0,
|
||||||
|
"ampsIn":0.0,
|
||||||
|
"wattsOut":50.5,
|
||||||
|
"ampsOut":2.1,
|
||||||
|
"whOut":5.23,
|
||||||
|
"whStored":1330,
|
||||||
|
"volts":12.0,
|
||||||
|
"socPercent":95,
|
||||||
|
"isCharging":0,
|
||||||
|
"inputDetected":0,
|
||||||
|
"timeToEmptyFull":-1,
|
||||||
|
"temperature":25,
|
||||||
|
"wifiStrength":-62,
|
||||||
|
"ssid":"wifi",
|
||||||
|
"ipAddr":"1.2.3.4",
|
||||||
|
"timestamp":1720984,
|
||||||
|
"firmwareVersion":"1.5.7",
|
||||||
|
"version":3,
|
||||||
|
"ota":{
|
||||||
|
"delay":0,
|
||||||
|
"status":"000-000-100_001-000-100_002-000-100_003-000-100"
|
||||||
|
},
|
||||||
|
"notify":{
|
||||||
|
"enabled":1048575,
|
||||||
|
"trigger":0
|
||||||
|
},
|
||||||
|
"foreignAcsry":{
|
||||||
|
"model":"Yeti MPPT",
|
||||||
|
"firmwareVersion":"1.1.2"
|
||||||
|
}
|
||||||
|
}
|
38
tests/components/goalzero/fixtures/state_data.json
Normal file
38
tests/components/goalzero/fixtures/state_data.json
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"thingName":"yeti123456789012",
|
||||||
|
"v12PortStatus":0,
|
||||||
|
"usbPortStatus":0,
|
||||||
|
"acPortStatus":1,
|
||||||
|
"backlight":1,
|
||||||
|
"app_online":0,
|
||||||
|
"wattsIn":0.0,
|
||||||
|
"ampsIn":0.0,
|
||||||
|
"wattsOut":50.5,
|
||||||
|
"ampsOut":2.1,
|
||||||
|
"whOut":5.23,
|
||||||
|
"whStored":1330,
|
||||||
|
"volts":12.0,
|
||||||
|
"socPercent":95,
|
||||||
|
"isCharging":0,
|
||||||
|
"inputDetected":0,
|
||||||
|
"timeToEmptyFull":-1,
|
||||||
|
"temperature":25,
|
||||||
|
"wifiStrength":-62,
|
||||||
|
"ssid":"wifi",
|
||||||
|
"ipAddr":"1.2.3.4",
|
||||||
|
"timestamp":1720984,
|
||||||
|
"firmwareVersion":"1.5.7",
|
||||||
|
"version":3,
|
||||||
|
"ota":{
|
||||||
|
"delay":0,
|
||||||
|
"status":"000-000-100_001-000-100_002-000-100_003-000-100"
|
||||||
|
},
|
||||||
|
"notify":{
|
||||||
|
"enabled":1048575,
|
||||||
|
"trigger":0
|
||||||
|
},
|
||||||
|
"foreignAcsry":{
|
||||||
|
"model":"Yeti MPPT",
|
||||||
|
"firmwareVersion":"1.1.2"
|
||||||
|
}
|
||||||
|
}
|
36
tests/components/goalzero/test_binary_sensor.py
Normal file
36
tests/components/goalzero/test_binary_sensor.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
"""Binary sensor tests for the Goalzero integration."""
|
||||||
|
from homeassistant.components.binary_sensor import (
|
||||||
|
DEVICE_CLASS_BATTERY_CHARGING,
|
||||||
|
DEVICE_CLASS_CONNECTIVITY,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
from homeassistant.components.goalzero.const import DEFAULT_NAME
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_DEVICE_CLASS,
|
||||||
|
DEVICE_CLASS_POWER,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from . import async_setup_platform
|
||||||
|
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
|
async def test_binary_sensors(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker):
|
||||||
|
"""Test we get sensor data."""
|
||||||
|
await async_setup_platform(hass, aioclient_mock, DOMAIN)
|
||||||
|
|
||||||
|
state = hass.states.get(f"binary_sensor.{DEFAULT_NAME}_backlight")
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) is None
|
||||||
|
state = hass.states.get(f"binary_sensor.{DEFAULT_NAME}_app_online")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_CONNECTIVITY
|
||||||
|
state = hass.states.get(f"binary_sensor.{DEFAULT_NAME}_charging")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_BATTERY_CHARGING
|
||||||
|
state = hass.states.get(f"binary_sensor.{DEFAULT_NAME}_input_detected")
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_POWER
|
|
@ -3,181 +3,150 @@ from unittest.mock import patch
|
||||||
|
|
||||||
from goalzero import exceptions
|
from goalzero import exceptions
|
||||||
|
|
||||||
from homeassistant.components.goalzero.const import DOMAIN
|
from homeassistant import data_entry_flow
|
||||||
|
from homeassistant.components.goalzero.const import DEFAULT_NAME, DOMAIN, MANUFACTURER
|
||||||
from homeassistant.config_entries import SOURCE_DHCP, SOURCE_USER
|
from homeassistant.config_entries import SOURCE_DHCP, SOURCE_USER
|
||||||
from homeassistant.data_entry_flow import (
|
from homeassistant.core import HomeAssistant
|
||||||
RESULT_TYPE_ABORT,
|
|
||||||
RESULT_TYPE_CREATE_ENTRY,
|
|
||||||
RESULT_TYPE_FORM,
|
|
||||||
)
|
|
||||||
|
|
||||||
from . import (
|
from . import (
|
||||||
CONF_CONFIG_FLOW,
|
|
||||||
CONF_DATA,
|
CONF_DATA,
|
||||||
CONF_DHCP_FLOW,
|
CONF_DHCP_FLOW,
|
||||||
CONF_HOST,
|
MAC,
|
||||||
CONF_NAME,
|
create_entry,
|
||||||
NAME,
|
create_mocked_yeti,
|
||||||
_create_mocked_yeti,
|
patch_config_flow_yeti,
|
||||||
_patch_config_flow_yeti,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
|
||||||
|
|
||||||
|
|
||||||
def _flow_next(hass, flow_id):
|
|
||||||
return next(
|
|
||||||
flow
|
|
||||||
for flow in hass.config_entries.flow.async_progress()
|
|
||||||
if flow["flow_id"] == flow_id
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _patch_setup():
|
def _patch_setup():
|
||||||
return patch(
|
return patch("homeassistant.components.goalzero.async_setup_entry")
|
||||||
"homeassistant.components.goalzero.async_setup_entry",
|
|
||||||
return_value=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_flow_user(hass):
|
async def test_flow_user(hass: HomeAssistant):
|
||||||
"""Test user initialized flow."""
|
"""Test user initialized flow."""
|
||||||
mocked_yeti = await _create_mocked_yeti()
|
mocked_yeti = await create_mocked_yeti()
|
||||||
with _patch_config_flow_yeti(mocked_yeti), _patch_setup():
|
with patch_config_flow_yeti(mocked_yeti), _patch_setup():
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_USER},
|
context={"source": SOURCE_USER},
|
||||||
)
|
)
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input=CONF_CONFIG_FLOW,
|
user_input=CONF_DATA,
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["title"] == NAME
|
assert result["title"] == DEFAULT_NAME
|
||||||
assert result["data"] == CONF_DATA
|
assert result["data"] == CONF_DATA
|
||||||
|
assert result["result"].unique_id == MAC
|
||||||
|
|
||||||
|
|
||||||
async def test_flow_user_already_configured(hass):
|
async def test_flow_user_already_configured(hass: HomeAssistant):
|
||||||
"""Test user initialized flow with duplicate server."""
|
"""Test user initialized flow with duplicate server."""
|
||||||
entry = MockConfigEntry(
|
create_entry(hass)
|
||||||
domain=DOMAIN,
|
|
||||||
data={CONF_HOST: "1.2.3.4", CONF_NAME: "Yeti"},
|
|
||||||
)
|
|
||||||
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
service_info = {
|
|
||||||
"host": "1.2.3.4",
|
|
||||||
"name": "Yeti",
|
|
||||||
}
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=service_info
|
DOMAIN, context={"source": SOURCE_USER}, data=CONF_DATA
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_flow_user_cannot_connect(hass):
|
async def test_flow_user_cannot_connect(hass: HomeAssistant):
|
||||||
"""Test user initialized flow with unreachable server."""
|
"""Test user initialized flow with unreachable server."""
|
||||||
mocked_yeti = await _create_mocked_yeti(True)
|
with patch_config_flow_yeti(await create_mocked_yeti()) as yetimock:
|
||||||
with _patch_config_flow_yeti(mocked_yeti) as yetimock:
|
|
||||||
yetimock.side_effect = exceptions.ConnectError
|
yetimock.side_effect = exceptions.ConnectError
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=CONF_CONFIG_FLOW
|
DOMAIN, context={"source": SOURCE_USER}, data=CONF_DATA
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"] == {"base": "cannot_connect"}
|
assert result["errors"]["base"] == "cannot_connect"
|
||||||
|
|
||||||
|
|
||||||
async def test_flow_user_invalid_host(hass):
|
async def test_flow_user_invalid_host(hass: HomeAssistant):
|
||||||
"""Test user initialized flow with invalid server."""
|
"""Test user initialized flow with invalid server."""
|
||||||
mocked_yeti = await _create_mocked_yeti(True)
|
with patch_config_flow_yeti(await create_mocked_yeti()) as yetimock:
|
||||||
with _patch_config_flow_yeti(mocked_yeti) as yetimock:
|
|
||||||
yetimock.side_effect = exceptions.InvalidHost
|
yetimock.side_effect = exceptions.InvalidHost
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=CONF_CONFIG_FLOW
|
DOMAIN, context={"source": SOURCE_USER}, data=CONF_DATA
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"] == {"base": "invalid_host"}
|
assert result["errors"]["base"] == "invalid_host"
|
||||||
|
|
||||||
|
|
||||||
async def test_flow_user_unknown_error(hass):
|
async def test_flow_user_unknown_error(hass: HomeAssistant):
|
||||||
"""Test user initialized flow with unreachable server."""
|
"""Test user initialized flow with unreachable server."""
|
||||||
mocked_yeti = await _create_mocked_yeti(True)
|
with patch_config_flow_yeti(await create_mocked_yeti()) as yetimock:
|
||||||
with _patch_config_flow_yeti(mocked_yeti) as yetimock:
|
|
||||||
yetimock.side_effect = Exception
|
yetimock.side_effect = Exception
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=CONF_CONFIG_FLOW
|
DOMAIN, context={"source": SOURCE_USER}, data=CONF_DATA
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_FORM
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"] == {"base": "unknown"}
|
assert result["errors"]["base"] == "unknown"
|
||||||
|
|
||||||
|
|
||||||
async def test_dhcp_discovery(hass):
|
async def test_dhcp_discovery(hass: HomeAssistant):
|
||||||
"""Test we can process the discovery from dhcp."""
|
"""Test we can process the discovery from dhcp."""
|
||||||
|
|
||||||
mocked_yeti = await _create_mocked_yeti()
|
mocked_yeti = await create_mocked_yeti()
|
||||||
with _patch_config_flow_yeti(mocked_yeti), _patch_setup():
|
with patch_config_flow_yeti(mocked_yeti), _patch_setup():
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_DHCP},
|
context={"source": SOURCE_DHCP},
|
||||||
data=CONF_DHCP_FLOW,
|
data=CONF_DHCP_FLOW,
|
||||||
)
|
)
|
||||||
assert result["type"] == "form"
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
assert result["data"] == {
|
assert result["title"] == MANUFACTURER
|
||||||
CONF_HOST: "1.1.1.1",
|
assert result["data"] == CONF_DATA
|
||||||
CONF_NAME: "Yeti",
|
assert result["result"].unique_id == MAC
|
||||||
}
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_DHCP},
|
context={"source": SOURCE_DHCP},
|
||||||
data=CONF_DHCP_FLOW,
|
data=CONF_DHCP_FLOW,
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_dhcp_discovery_failed(hass):
|
async def test_dhcp_discovery_failed(hass: HomeAssistant):
|
||||||
"""Test failed setup from dhcp."""
|
"""Test failed setup from dhcp."""
|
||||||
mocked_yeti = await _create_mocked_yeti(True)
|
mocked_yeti = await create_mocked_yeti()
|
||||||
with _patch_config_flow_yeti(mocked_yeti) as yetimock:
|
with patch_config_flow_yeti(mocked_yeti) as yetimock:
|
||||||
yetimock.side_effect = exceptions.ConnectError
|
yetimock.side_effect = exceptions.ConnectError
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_DHCP},
|
context={"source": SOURCE_DHCP},
|
||||||
data=CONF_DHCP_FLOW,
|
data=CONF_DHCP_FLOW,
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "cannot_connect"
|
assert result["reason"] == "cannot_connect"
|
||||||
|
|
||||||
with _patch_config_flow_yeti(mocked_yeti) as yetimock:
|
with patch_config_flow_yeti(mocked_yeti) as yetimock:
|
||||||
yetimock.side_effect = exceptions.InvalidHost
|
yetimock.side_effect = exceptions.InvalidHost
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_DHCP},
|
context={"source": SOURCE_DHCP},
|
||||||
data=CONF_DHCP_FLOW,
|
data=CONF_DHCP_FLOW,
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "invalid_host"
|
assert result["reason"] == "invalid_host"
|
||||||
|
|
||||||
with _patch_config_flow_yeti(mocked_yeti) as yetimock:
|
with patch_config_flow_yeti(mocked_yeti) as yetimock:
|
||||||
yetimock.side_effect = Exception
|
yetimock.side_effect = Exception
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_DHCP},
|
context={"source": SOURCE_DHCP},
|
||||||
data=CONF_DHCP_FLOW,
|
data=CONF_DHCP_FLOW,
|
||||||
)
|
)
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "unknown"
|
assert result["reason"] == "unknown"
|
||||||
|
|
80
tests/components/goalzero/test_init.py
Normal file
80
tests/components/goalzero/test_init.py
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
"""Test Goal Zero integration."""
|
||||||
|
from datetime import timedelta
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from goalzero import exceptions
|
||||||
|
|
||||||
|
from homeassistant.components.goalzero.const import DEFAULT_NAME, DOMAIN, MANUFACTURER
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.const import STATE_ON, STATE_UNAVAILABLE
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from . import CONF_DATA, async_init_integration, create_entry, create_mocked_yeti
|
||||||
|
|
||||||
|
from tests.common import async_fire_time_changed
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_config_and_unload(hass: HomeAssistant):
|
||||||
|
"""Test Goal Zero setup and unload."""
|
||||||
|
entry = create_entry(hass)
|
||||||
|
mocked_yeti = await create_mocked_yeti()
|
||||||
|
with patch("homeassistant.components.goalzero.Yeti", return_value=mocked_yeti):
|
||||||
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert entry.state == ConfigEntryState.LOADED
|
||||||
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||||
|
assert entry.data == CONF_DATA
|
||||||
|
|
||||||
|
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert entry.state is ConfigEntryState.NOT_LOADED
|
||||||
|
assert not hass.data.get(DOMAIN)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_async_setup_entry_not_ready(hass: HomeAssistant):
|
||||||
|
"""Test that it throws ConfigEntryNotReady when exception occurs during setup."""
|
||||||
|
entry = create_entry(hass)
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.goalzero.Yeti.init_connect",
|
||||||
|
side_effect=exceptions.ConnectError,
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
|
assert entry.state == ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
|
async def test_update_failed(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
) -> None:
|
||||||
|
"""Test data update failure."""
|
||||||
|
await async_init_integration(hass, aioclient_mock)
|
||||||
|
assert hass.states.get(f"switch.{DEFAULT_NAME}_ac_port_status").state == STATE_ON
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.goalzero.Yeti.get_state",
|
||||||
|
side_effect=exceptions.ConnectError,
|
||||||
|
) as updater:
|
||||||
|
next_update = dt_util.utcnow() + timedelta(seconds=30)
|
||||||
|
async_fire_time_changed(hass, next_update)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
updater.assert_called_once()
|
||||||
|
state = hass.states.get(f"switch.{DEFAULT_NAME}_ac_port_status")
|
||||||
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_info(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker):
|
||||||
|
"""Test device info."""
|
||||||
|
entry = await async_init_integration(hass, aioclient_mock)
|
||||||
|
device_registry = await dr.async_get_registry(hass)
|
||||||
|
|
||||||
|
device = device_registry.async_get_device({(DOMAIN, entry.entry_id)})
|
||||||
|
|
||||||
|
assert device.connections == {("mac", "12:34:56:78:90:12")}
|
||||||
|
assert device.identifiers == {(DOMAIN, entry.entry_id)}
|
||||||
|
assert device.manufacturer == MANUFACTURER
|
||||||
|
assert device.model == "Yeti 1400"
|
||||||
|
assert device.name == DEFAULT_NAME
|
||||||
|
assert device.sw_version == "1.5.7"
|
112
tests/components/goalzero/test_sensor.py
Normal file
112
tests/components/goalzero/test_sensor.py
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
"""Sensor tests for the Goalzero integration."""
|
||||||
|
from homeassistant.components.goalzero.const import DEFAULT_NAME
|
||||||
|
from homeassistant.components.goalzero.sensor import SENSOR_TYPES
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
ATTR_STATE_CLASS,
|
||||||
|
DOMAIN,
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
STATE_CLASS_TOTAL_INCREASING,
|
||||||
|
)
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_DEVICE_CLASS,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
DEVICE_CLASS_BATTERY,
|
||||||
|
DEVICE_CLASS_CURRENT,
|
||||||
|
DEVICE_CLASS_ENERGY,
|
||||||
|
DEVICE_CLASS_POWER,
|
||||||
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
DEVICE_CLASS_TEMPERATURE,
|
||||||
|
DEVICE_CLASS_VOLTAGE,
|
||||||
|
ELECTRIC_CURRENT_AMPERE,
|
||||||
|
ELECTRIC_POTENTIAL_VOLT,
|
||||||
|
ENERGY_WATT_HOUR,
|
||||||
|
PERCENTAGE,
|
||||||
|
POWER_WATT,
|
||||||
|
SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
TEMP_CELSIUS,
|
||||||
|
TIME_MINUTES,
|
||||||
|
TIME_SECONDS,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from . import async_setup_platform
|
||||||
|
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker):
|
||||||
|
"""Test we get sensor data."""
|
||||||
|
for description in SENSOR_TYPES:
|
||||||
|
description.entity_registry_enabled_default = True
|
||||||
|
await async_setup_platform(hass, aioclient_mock, DOMAIN)
|
||||||
|
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_watts_in")
|
||||||
|
assert state.state == "0.0"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_POWER
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == POWER_WATT
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_amps_in")
|
||||||
|
assert state.state == "0.0"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_CURRENT
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ELECTRIC_CURRENT_AMPERE
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_watts_out")
|
||||||
|
assert state.state == "50.5"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_POWER
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == POWER_WATT
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_amps_out")
|
||||||
|
assert state.state == "2.1"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_CURRENT
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ELECTRIC_CURRENT_AMPERE
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_wh_out")
|
||||||
|
assert state.state == "5.23"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_ENERGY
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ENERGY_WATT_HOUR
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_TOTAL_INCREASING
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_wh_stored")
|
||||||
|
assert state.state == "1330"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_ENERGY
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ENERGY_WATT_HOUR
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_volts")
|
||||||
|
assert state.state == "12.0"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_VOLTAGE
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ELECTRIC_POTENTIAL_VOLT
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_state_of_charge_percent")
|
||||||
|
assert state.state == "95"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_BATTERY
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_time_to_empty_full")
|
||||||
|
assert state.state == "-1"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == TIME_MINUTES
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TIME_MINUTES
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_temperature")
|
||||||
|
assert state.state == "25"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TEMPERATURE
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TEMP_CELSIUS
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_wifi_strength")
|
||||||
|
assert state.state == "-62"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_SIGNAL_STRENGTH
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == SIGNAL_STRENGTH_DECIBELS
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_total_run_time")
|
||||||
|
assert state.state == "1720984"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) is None
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == TIME_SECONDS
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_wi_fi_ssid")
|
||||||
|
assert state.state == "wifi"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) is None
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
||||||
|
state = hass.states.get(f"sensor.{DEFAULT_NAME}_ip_address")
|
||||||
|
assert state.state == "1.2.3.4"
|
||||||
|
assert state.attributes.get(ATTR_DEVICE_CLASS) is None
|
||||||
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
|
||||||
|
assert state.attributes.get(ATTR_STATE_CLASS) is None
|
51
tests/components/goalzero/test_switch.py
Normal file
51
tests/components/goalzero/test_switch.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
"""Switch tests for the Goalzero integration."""
|
||||||
|
from homeassistant.components.goalzero.const import DEFAULT_NAME
|
||||||
|
from homeassistant.components.switch import DOMAIN as DOMAIN
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from . import async_setup_platform
|
||||||
|
|
||||||
|
from tests.common import load_fixture
|
||||||
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
|
|
||||||
|
async def test_switches_states(
|
||||||
|
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
||||||
|
):
|
||||||
|
"""Test we get sensor data."""
|
||||||
|
await async_setup_platform(hass, aioclient_mock, DOMAIN)
|
||||||
|
|
||||||
|
assert hass.states.get(f"switch.{DEFAULT_NAME}_usb_port_status").state == STATE_OFF
|
||||||
|
assert hass.states.get(f"switch.{DEFAULT_NAME}_ac_port_status").state == STATE_ON
|
||||||
|
entity_id = f"switch.{DEFAULT_NAME}_12v_port_status"
|
||||||
|
assert hass.states.get(entity_id).state == STATE_OFF
|
||||||
|
aioclient_mock.post(
|
||||||
|
"http://1.2.3.4/state",
|
||||||
|
text=load_fixture("goalzero/state_change.json"),
|
||||||
|
)
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: [entity_id]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert hass.states.get(entity_id).state == STATE_ON
|
||||||
|
aioclient_mock.clear_requests()
|
||||||
|
aioclient_mock.post(
|
||||||
|
"http://1.2.3.4/state",
|
||||||
|
text=load_fixture("goalzero/state_data.json"),
|
||||||
|
)
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
{ATTR_ENTITY_ID: [entity_id]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert hass.states.get(entity_id).state == STATE_OFF
|
Loading…
Add table
Add a link
Reference in a new issue