Add 100% test coverage for Uptime Robot (#54314)
* Add 100% test coverage for Uptime Robot * Update tests/components/uptimerobot/test_binary_sensor.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Add more typehints Co-authored-by: Martin Hjelmare <marhje52@gmail.com>pull/54411/head
parent
f03b160c46
commit
d1ea38e8f0
|
@ -1115,10 +1115,6 @@ omit =
|
|||
homeassistant/components/upcloud/switch.py
|
||||
homeassistant/components/upnp/*
|
||||
homeassistant/components/upc_connect/*
|
||||
homeassistant/components/uptimerobot/__init__.py
|
||||
homeassistant/components/uptimerobot/binary_sensor.py
|
||||
homeassistant/components/uptimerobot/const.py
|
||||
homeassistant/components/uptimerobot/entity.py
|
||||
homeassistant/components/uscis/sensor.py
|
||||
homeassistant/components/vallox/*
|
||||
homeassistant/components/vasttrafik/sensor.py
|
||||
|
|
|
@ -53,7 +53,7 @@ async def async_setup_entry(
|
|||
name=monitor.friendly_name,
|
||||
device_class=DEVICE_CLASS_CONNECTIVITY,
|
||||
),
|
||||
target=monitor.url,
|
||||
monitor=monitor,
|
||||
)
|
||||
for monitor in coordinator.data
|
||||
],
|
||||
|
|
|
@ -20,11 +20,12 @@ class UptimeRobotEntity(CoordinatorEntity):
|
|||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
description: EntityDescription,
|
||||
target: str,
|
||||
monitor: UptimeRobotMonitor,
|
||||
) -> None:
|
||||
"""Initialize Uptime Robot entities."""
|
||||
super().__init__(coordinator)
|
||||
self.entity_description = description
|
||||
self._monitor = monitor
|
||||
self._attr_device_info = {
|
||||
"identifiers": {(DOMAIN, str(self.monitor.id))},
|
||||
"name": "Uptime Robot",
|
||||
|
@ -34,7 +35,7 @@ class UptimeRobotEntity(CoordinatorEntity):
|
|||
}
|
||||
self._attr_extra_state_attributes = {
|
||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
ATTR_TARGET: target,
|
||||
ATTR_TARGET: self.monitor.url,
|
||||
}
|
||||
self._attr_unique_id = str(self.monitor.id)
|
||||
|
||||
|
@ -47,9 +48,12 @@ class UptimeRobotEntity(CoordinatorEntity):
|
|||
def monitor(self) -> UptimeRobotMonitor:
|
||||
"""Return the monitor for this entity."""
|
||||
return next(
|
||||
monitor
|
||||
for monitor in self._monitors
|
||||
if str(monitor.id) == self.entity_description.key
|
||||
(
|
||||
monitor
|
||||
for monitor in self._monitors
|
||||
if str(monitor.id) == self.entity_description.key
|
||||
),
|
||||
self._monitor,
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
"""Common constants and functions for Uptime Robot tests."""
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
from pyuptimerobot import (
|
||||
APIStatus,
|
||||
UptimeRobotAccount,
|
||||
UptimeRobotApiError,
|
||||
UptimeRobotApiResponse,
|
||||
UptimeRobotMonitor,
|
||||
)
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.uptimerobot.const import DOMAIN
|
||||
from homeassistant.const import STATE_ON
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_UPTIMEROBOT_API_KEY = "1234"
|
||||
MOCK_UPTIMEROBOT_UNIQUE_ID = "1234567890"
|
||||
|
||||
MOCK_UPTIMEROBOT_ACCOUNT = {"email": "test@test.test", "user_id": 1234567890}
|
||||
MOCK_UPTIMEROBOT_ERROR = {"message": "test error from API."}
|
||||
MOCK_UPTIMEROBOT_MONITOR = {
|
||||
"id": 1234,
|
||||
"friendly_name": "Test monitor",
|
||||
"status": 2,
|
||||
"type": 1,
|
||||
"url": "http://example.com",
|
||||
}
|
||||
|
||||
MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA = {
|
||||
"domain": DOMAIN,
|
||||
"title": "test@test.test",
|
||||
"data": {"platform": DOMAIN, "api_key": MOCK_UPTIMEROBOT_API_KEY},
|
||||
"unique_id": MOCK_UPTIMEROBOT_UNIQUE_ID,
|
||||
"source": config_entries.SOURCE_USER,
|
||||
}
|
||||
|
||||
UPTIMEROBOT_TEST_ENTITY = "binary_sensor.test_monitor"
|
||||
|
||||
|
||||
class MockApiResponseKey(str, Enum):
|
||||
"""Mock API response key."""
|
||||
|
||||
ACCOUNT = "account"
|
||||
ERROR = "error"
|
||||
MONITORS = "monitors"
|
||||
|
||||
|
||||
def mock_uptimerobot_api_response(
|
||||
data: dict[str, Any]
|
||||
| None
|
||||
| list[UptimeRobotMonitor]
|
||||
| UptimeRobotAccount
|
||||
| UptimeRobotApiError = None,
|
||||
status: APIStatus = APIStatus.OK,
|
||||
key: MockApiResponseKey = MockApiResponseKey.MONITORS,
|
||||
) -> UptimeRobotApiResponse:
|
||||
"""Mock API response for Uptime Robot."""
|
||||
return UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": {"error": APIStatus.FAIL}.get(key, status),
|
||||
key: data
|
||||
if data is not None
|
||||
else {
|
||||
"account": MOCK_UPTIMEROBOT_ACCOUNT,
|
||||
"error": MOCK_UPTIMEROBOT_ERROR,
|
||||
"monitors": [MOCK_UPTIMEROBOT_MONITOR],
|
||||
}.get(key, {}),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def setup_uptimerobot_integration(hass: HomeAssistant) -> MockConfigEntry:
|
||||
"""Set up the Uptime Robot integration."""
|
||||
mock_entry = MockConfigEntry(**MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA)
|
||||
mock_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=mock_uptimerobot_api_response(data=[MOCK_UPTIMEROBOT_MONITOR]),
|
||||
):
|
||||
|
||||
assert await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_ON
|
||||
assert mock_entry.state == config_entries.ConfigEntryState.LOADED
|
||||
|
||||
return mock_entry
|
|
@ -0,0 +1,82 @@
|
|||
"""Test Uptime Robot binary_sensor."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from pyuptimerobot import UptimeRobotAuthenticationException
|
||||
|
||||
from homeassistant.components.binary_sensor import DEVICE_CLASS_CONNECTIVITY
|
||||
from homeassistant.components.uptimerobot.const import (
|
||||
ATTRIBUTION,
|
||||
COORDINATOR_UPDATE_INTERVAL,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.const import STATE_ON, STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt
|
||||
|
||||
from .common import (
|
||||
MOCK_UPTIMEROBOT_API_KEY,
|
||||
MOCK_UPTIMEROBOT_MONITOR,
|
||||
UPTIMEROBOT_TEST_ENTITY,
|
||||
MockApiResponseKey,
|
||||
mock_uptimerobot_api_response,
|
||||
setup_uptimerobot_integration,
|
||||
)
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_config_import(hass: HomeAssistant) -> None:
|
||||
"""Test importing YAML configuration."""
|
||||
config = {
|
||||
"binary_sensor": {
|
||||
"platform": DOMAIN,
|
||||
"api_key": MOCK_UPTIMEROBOT_API_KEY,
|
||||
}
|
||||
}
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ACCOUNT),
|
||||
), patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=mock_uptimerobot_api_response(),
|
||||
):
|
||||
assert await async_setup_component(hass, "binary_sensor", config)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
config_entries = hass.config_entries.async_entries(DOMAIN)
|
||||
|
||||
assert len(config_entries) == 1
|
||||
config_entry = config_entries[0]
|
||||
assert config_entry.source == "import"
|
||||
|
||||
|
||||
async def test_presentation(hass: HomeAssistant) -> None:
|
||||
"""Test the presenstation of Uptime Robot binary_sensors."""
|
||||
await setup_uptimerobot_integration(hass)
|
||||
|
||||
entity = hass.states.get(UPTIMEROBOT_TEST_ENTITY)
|
||||
|
||||
assert entity.state == STATE_ON
|
||||
assert entity.attributes["device_class"] == DEVICE_CLASS_CONNECTIVITY
|
||||
assert entity.attributes["attribution"] == ATTRIBUTION
|
||||
assert entity.attributes["target"] == MOCK_UPTIMEROBOT_MONITOR["url"]
|
||||
|
||||
|
||||
async def test_unaviable_on_update_failure(hass: HomeAssistant) -> None:
|
||||
"""Test entity unaviable on update failure."""
|
||||
await setup_uptimerobot_integration(hass)
|
||||
|
||||
entity = hass.states.get(UPTIMEROBOT_TEST_ENTITY)
|
||||
assert entity.state == STATE_ON
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
side_effect=UptimeRobotAuthenticationException,
|
||||
):
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity = hass.states.get(UPTIMEROBOT_TEST_ENTITY)
|
||||
assert entity.state == STATE_UNAVAILABLE
|
|
@ -1,15 +1,13 @@
|
|||
"""Test the Uptime Robot config flow."""
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from pytest import LogCaptureFixture
|
||||
from pyuptimerobot import UptimeRobotApiResponse
|
||||
from pyuptimerobot.exceptions import (
|
||||
UptimeRobotAuthenticationException,
|
||||
UptimeRobotException,
|
||||
)
|
||||
from pyuptimerobot import UptimeRobotAuthenticationException, UptimeRobotException
|
||||
|
||||
from homeassistant import config_entries, setup
|
||||
from homeassistant.components.uptimerobot.const import DOMAIN
|
||||
from homeassistant.const import CONF_API_KEY
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import (
|
||||
RESULT_TYPE_ABORT,
|
||||
|
@ -17,6 +15,15 @@ from homeassistant.data_entry_flow import (
|
|||
RESULT_TYPE_FORM,
|
||||
)
|
||||
|
||||
from .common import (
|
||||
MOCK_UPTIMEROBOT_ACCOUNT,
|
||||
MOCK_UPTIMEROBOT_API_KEY,
|
||||
MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA,
|
||||
MOCK_UPTIMEROBOT_UNIQUE_ID,
|
||||
MockApiResponseKey,
|
||||
mock_uptimerobot_api_response,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
|
@ -31,82 +38,49 @@ async def test_form(hass: HomeAssistant) -> None:
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"account": {"email": "test@test.test", "user_id": 1234567890},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ACCOUNT),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
{CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result2["result"].unique_id == "1234567890"
|
||||
assert result2["result"].unique_id == MOCK_UPTIMEROBOT_UNIQUE_ID
|
||||
assert result2["type"] == RESULT_TYPE_CREATE_ENTRY
|
||||
assert result2["title"] == "test@test.test"
|
||||
assert result2["data"] == {"api_key": "1234"}
|
||||
assert result2["title"] == MOCK_UPTIMEROBOT_ACCOUNT["email"]
|
||||
assert result2["data"] == {CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_cannot_connect(hass: HomeAssistant) -> None:
|
||||
"""Test we handle cannot connect error."""
|
||||
@pytest.mark.parametrize(
|
||||
"exception,error_key",
|
||||
[
|
||||
(Exception, "unknown"),
|
||||
(UptimeRobotException, "cannot_connect"),
|
||||
(UptimeRobotAuthenticationException, "invalid_api_key"),
|
||||
],
|
||||
)
|
||||
async def test_form_exception_thrown(hass: HomeAssistant, exception, error_key) -> None:
|
||||
"""Test that we handle exceptions."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
side_effect=UptimeRobotException,
|
||||
side_effect=exception,
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
{CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
|
||||
assert result2["type"] == RESULT_TYPE_FORM
|
||||
assert result2["errors"]["base"] == "cannot_connect"
|
||||
|
||||
|
||||
async def test_form_unexpected_error(hass: HomeAssistant) -> None:
|
||||
"""Test we handle unexpected error."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
side_effect=Exception,
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
)
|
||||
|
||||
assert result2["errors"]["base"] == "unknown"
|
||||
|
||||
|
||||
async def test_form_api_key_error(hass: HomeAssistant) -> None:
|
||||
"""Test we handle unexpected error."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
side_effect=UptimeRobotAuthenticationException,
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
)
|
||||
|
||||
assert result2["errors"]["base"] == "invalid_api_key"
|
||||
assert result2["errors"]["base"] == error_key
|
||||
|
||||
|
||||
async def test_form_api_error(hass: HomeAssistant, caplog: LogCaptureFixture) -> None:
|
||||
|
@ -117,32 +91,24 @@ async def test_form_api_error(hass: HomeAssistant, caplog: LogCaptureFixture) ->
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "fail",
|
||||
"error": {"message": "test error from API."},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ERROR),
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
{CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
|
||||
assert result2["errors"]["base"] == "unknown"
|
||||
assert "test error from API." in caplog.text
|
||||
|
||||
|
||||
async def test_flow_import(hass):
|
||||
async def test_flow_import(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test an import flow."""
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"account": {"email": "test@test.test", "user_id": 1234567890},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ACCOUNT),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
|
@ -150,22 +116,17 @@ async def test_flow_import(hass):
|
|||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
data={"platform": DOMAIN, CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["data"] == {"api_key": "1234"}
|
||||
assert result["data"] == {CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY}
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"account": {"email": "test@test.test", "user_id": 1234567890},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ACCOUNT),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
|
@ -173,7 +134,7 @@ async def test_flow_import(hass):
|
|||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
data={"platform": DOMAIN, CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -183,7 +144,9 @@ async def test_flow_import(hass):
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict({"stat": "ok"}),
|
||||
return_value=mock_uptimerobot_api_response(
|
||||
key=MockApiResponseKey.ACCOUNT, data={}
|
||||
),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
|
@ -191,7 +154,7 @@ async def test_flow_import(hass):
|
|||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={"platform": DOMAIN, "api_key": "12345"},
|
||||
data={"platform": DOMAIN, CONF_API_KEY: "12345"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -199,13 +162,11 @@ async def test_flow_import(hass):
|
|||
assert result["reason"] == "unknown"
|
||||
|
||||
|
||||
async def test_user_unique_id_already_exists(hass):
|
||||
async def test_user_unique_id_already_exists(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test creating an entry where the unique_id already exists."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
unique_id="1234567890",
|
||||
)
|
||||
entry = MockConfigEntry(**MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -216,19 +177,14 @@ async def test_user_unique_id_already_exists(hass):
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"account": {"email": "test@test.test", "user_id": 1234567890},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ACCOUNT),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "12345"},
|
||||
{CONF_API_KEY: "12345"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -237,13 +193,11 @@ async def test_user_unique_id_already_exists(hass):
|
|||
assert result2["reason"] == "already_configured"
|
||||
|
||||
|
||||
async def test_reauthentication(hass):
|
||||
async def test_reauthentication(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test Uptime Robot reauthentication."""
|
||||
old_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
unique_id="1234567890",
|
||||
)
|
||||
old_entry = MockConfigEntry(**MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA)
|
||||
old_entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -262,12 +216,7 @@ async def test_reauthentication(hass):
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"account": {"email": "test@test.test", "user_id": 1234567890},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ACCOUNT),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
|
@ -275,7 +224,7 @@ async def test_reauthentication(hass):
|
|||
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
{CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -283,13 +232,11 @@ async def test_reauthentication(hass):
|
|||
assert result2["reason"] == "reauth_successful"
|
||||
|
||||
|
||||
async def test_reauthentication_failure(hass):
|
||||
async def test_reauthentication_failure(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test Uptime Robot reauthentication failure."""
|
||||
old_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
unique_id="1234567890",
|
||||
)
|
||||
old_entry = MockConfigEntry(**MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA)
|
||||
old_entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -308,12 +255,7 @@ async def test_reauthentication_failure(hass):
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "fail",
|
||||
"error": {"message": "test error from API."},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ERROR),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
|
@ -321,7 +263,7 @@ async def test_reauthentication_failure(hass):
|
|||
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
{CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -330,11 +272,12 @@ async def test_reauthentication_failure(hass):
|
|||
assert result2["errors"]["base"] == "unknown"
|
||||
|
||||
|
||||
async def test_reauthentication_failure_no_existing_entry(hass):
|
||||
async def test_reauthentication_failure_no_existing_entry(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test Uptime Robot reauthentication with no existing entry."""
|
||||
old_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
**{**MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA, "unique_id": None}
|
||||
)
|
||||
old_entry.add_to_hass(hass)
|
||||
|
||||
|
@ -354,12 +297,7 @@ async def test_reauthentication_failure_no_existing_entry(hass):
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"account": {"email": "test@test.test", "user_id": 1234567890},
|
||||
}
|
||||
),
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ACCOUNT),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
return_value=True,
|
||||
|
@ -367,7 +305,7 @@ async def test_reauthentication_failure_no_existing_entry(hass):
|
|||
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
{CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -375,13 +313,11 @@ async def test_reauthentication_failure_no_existing_entry(hass):
|
|||
assert result2["reason"] == "reauth_failed_existing"
|
||||
|
||||
|
||||
async def test_reauthentication_failure_account_not_matching(hass):
|
||||
async def test_reauthentication_failure_account_not_matching(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test Uptime Robot reauthentication failure when using another account."""
|
||||
old_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
unique_id="1234567890",
|
||||
)
|
||||
old_entry = MockConfigEntry(**MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA)
|
||||
old_entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -400,11 +336,9 @@ async def test_reauthentication_failure_account_not_matching(hass):
|
|||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_account_details",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"account": {"email": "test@test.test", "user_id": 1234567891},
|
||||
}
|
||||
return_value=mock_uptimerobot_api_response(
|
||||
key=MockApiResponseKey.ACCOUNT,
|
||||
data={**MOCK_UPTIMEROBOT_ACCOUNT, "user_id": 1234567891},
|
||||
),
|
||||
), patch(
|
||||
"homeassistant.components.uptimerobot.async_setup_entry",
|
||||
|
@ -413,7 +347,7 @@ async def test_reauthentication_failure_account_not_matching(hass):
|
|||
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"api_key": "1234"},
|
||||
{CONF_API_KEY: MOCK_UPTIMEROBOT_API_KEY},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
|
|
@ -1,16 +1,31 @@
|
|||
"""Test the Uptime Robot init."""
|
||||
import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from pytest import LogCaptureFixture
|
||||
from pyuptimerobot import UptimeRobotApiResponse
|
||||
from pyuptimerobot.exceptions import UptimeRobotAuthenticationException
|
||||
from pyuptimerobot import UptimeRobotAuthenticationException, UptimeRobotException
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.uptimerobot.const import DOMAIN
|
||||
from homeassistant.components.uptimerobot.const import (
|
||||
COORDINATOR_UPDATE_INTERVAL,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.const import STATE_ON, STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import (
|
||||
async_entries_for_config_entry,
|
||||
async_get_registry,
|
||||
)
|
||||
from homeassistant.util import dt
|
||||
|
||||
from .common import (
|
||||
MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA,
|
||||
MOCK_UPTIMEROBOT_MONITOR,
|
||||
UPTIMEROBOT_TEST_ENTITY,
|
||||
MockApiResponseKey,
|
||||
mock_uptimerobot_api_response,
|
||||
setup_uptimerobot_integration,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
|
@ -18,13 +33,7 @@ async def test_reauthentication_trigger_in_setup(
|
|||
hass: HomeAssistant, caplog: LogCaptureFixture
|
||||
):
|
||||
"""Test reauthentication trigger."""
|
||||
mock_config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="test@test.test",
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
unique_id="1234567890",
|
||||
source=config_entries.SOURCE_USER,
|
||||
)
|
||||
mock_config_entry = MockConfigEntry(**MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA)
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
|
@ -57,46 +66,23 @@ async def test_reauthentication_trigger_after_setup(
|
|||
hass: HomeAssistant, caplog: LogCaptureFixture
|
||||
):
|
||||
"""Test reauthentication trigger."""
|
||||
mock_config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="test@test.test",
|
||||
data={"platform": DOMAIN, "api_key": "1234"},
|
||||
unique_id="1234567890",
|
||||
source=config_entries.SOURCE_USER,
|
||||
)
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
mock_config_entry = await setup_uptimerobot_integration(hass)
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=UptimeRobotApiResponse.from_dict(
|
||||
{
|
||||
"stat": "ok",
|
||||
"monitors": [
|
||||
{"id": 1234, "friendly_name": "Test monitor", "status": 2}
|
||||
],
|
||||
}
|
||||
),
|
||||
):
|
||||
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
binary_sensor = hass.states.get("binary_sensor.test_monitor")
|
||||
binary_sensor = hass.states.get(UPTIMEROBOT_TEST_ENTITY)
|
||||
assert mock_config_entry.state == config_entries.ConfigEntryState.LOADED
|
||||
assert binary_sensor.state == "on"
|
||||
assert binary_sensor.state == STATE_ON
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
side_effect=UptimeRobotAuthenticationException,
|
||||
):
|
||||
|
||||
async_fire_time_changed(hass, dt.utcnow() + datetime.timedelta(seconds=10))
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
flows = hass.config_entries.flow.async_progress()
|
||||
binary_sensor = hass.states.get("binary_sensor.test_monitor")
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_UNAVAILABLE
|
||||
|
||||
assert binary_sensor.state == "unavailable"
|
||||
assert "Authentication failed while fetching uptimerobot data" in caplog.text
|
||||
|
||||
assert len(flows) == 1
|
||||
|
@ -105,3 +91,96 @@ async def test_reauthentication_trigger_after_setup(
|
|||
assert flow["handler"] == DOMAIN
|
||||
assert flow["context"]["source"] == config_entries.SOURCE_REAUTH
|
||||
assert flow["context"]["entry_id"] == mock_config_entry.entry_id
|
||||
|
||||
|
||||
async def test_integration_reload(hass: HomeAssistant):
|
||||
"""Test integration reload."""
|
||||
mock_entry = await setup_uptimerobot_integration(hass)
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=mock_uptimerobot_api_response(),
|
||||
):
|
||||
assert await hass.config_entries.async_reload(mock_entry.entry_id)
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry = hass.config_entries.async_get_entry(mock_entry.entry_id)
|
||||
assert entry.state == config_entries.ConfigEntryState.LOADED
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_ON
|
||||
|
||||
|
||||
async def test_update_errors(hass: HomeAssistant, caplog: LogCaptureFixture):
|
||||
"""Test errors during updates."""
|
||||
await setup_uptimerobot_integration(hass)
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
side_effect=UptimeRobotException,
|
||||
):
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_UNAVAILABLE
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=mock_uptimerobot_api_response(),
|
||||
):
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_ON
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ERROR),
|
||||
):
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_UNAVAILABLE
|
||||
|
||||
assert "Error fetching uptimerobot data: test error from API" in caplog.text
|
||||
|
||||
|
||||
async def test_device_management(hass: HomeAssistant):
|
||||
"""Test that we are adding and removing devices for monitors returned from the API."""
|
||||
mock_entry = await setup_uptimerobot_integration(hass)
|
||||
dev_reg = await async_get_registry(hass)
|
||||
|
||||
devices = async_entries_for_config_entry(dev_reg, mock_entry.entry_id)
|
||||
assert len(devices) == 1
|
||||
|
||||
assert devices[0].identifiers == {(DOMAIN, "1234")}
|
||||
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_ON
|
||||
assert hass.states.get(f"{UPTIMEROBOT_TEST_ENTITY}_2") is None
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=mock_uptimerobot_api_response(
|
||||
data=[MOCK_UPTIMEROBOT_MONITOR, {**MOCK_UPTIMEROBOT_MONITOR, "id": 12345}]
|
||||
),
|
||||
):
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
devices = async_entries_for_config_entry(dev_reg, mock_entry.entry_id)
|
||||
assert len(devices) == 2
|
||||
assert devices[0].identifiers == {(DOMAIN, "1234")}
|
||||
assert devices[1].identifiers == {(DOMAIN, "12345")}
|
||||
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_ON
|
||||
assert hass.states.get(f"{UPTIMEROBOT_TEST_ENTITY}_2").state == STATE_ON
|
||||
|
||||
with patch(
|
||||
"pyuptimerobot.UptimeRobot.async_get_monitors",
|
||||
return_value=mock_uptimerobot_api_response(),
|
||||
):
|
||||
async_fire_time_changed(hass, dt.utcnow() + COORDINATOR_UPDATE_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
devices = async_entries_for_config_entry(dev_reg, mock_entry.entry_id)
|
||||
assert len(devices) == 1
|
||||
assert devices[0].identifiers == {(DOMAIN, "1234")}
|
||||
|
||||
assert hass.states.get(UPTIMEROBOT_TEST_ENTITY).state == STATE_ON
|
||||
assert hass.states.get(f"{UPTIMEROBOT_TEST_ENTITY}_2") is None
|
||||
|
|
Loading…
Reference in New Issue