mirror of
https://github.com/home-assistant/core.git
synced 2025-09-05 21:01:37 +02:00
NextDNS tests improvements (#150791)
This commit is contained in:
@@ -13,8 +13,6 @@ from nextdns import (
|
|||||||
Settings,
|
Settings,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components.nextdns.const import CONF_PROFILE_ID, DOMAIN
|
|
||||||
from homeassistant.const import CONF_API_KEY
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
@@ -155,20 +153,12 @@ def mock_nextdns():
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
async def init_integration(hass: HomeAssistant) -> MockConfigEntry:
|
async def init_integration(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Set up the NextDNS integration in Home Assistant."""
|
"""Set up the NextDNS integration in Home Assistant."""
|
||||||
entry = MockConfigEntry(
|
mock_config_entry.add_to_hass(hass)
|
||||||
domain=DOMAIN,
|
|
||||||
title="Fake Profile",
|
|
||||||
unique_id="xyz12",
|
|
||||||
data={CONF_API_KEY: "fake_api_key", CONF_PROFILE_ID: "xyz12"},
|
|
||||||
entry_id="d9aa37407ddac7b964a99e86312288d6",
|
|
||||||
)
|
|
||||||
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
with mock_nextdns():
|
with mock_nextdns():
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
return entry
|
|
||||||
|
32
tests/components/nextdns/conftest.py
Normal file
32
tests/components/nextdns/conftest.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
"""Common fixtures for the NextDNS tests."""
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.nextdns.const import CONF_PROFILE_ID, DOMAIN
|
||||||
|
from homeassistant.const import CONF_API_KEY
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_setup_entry() -> Generator[AsyncMock]:
|
||||||
|
"""Override async_setup_entry."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.nextdns.async_setup_entry", return_value=True
|
||||||
|
) as mock_setup_entry:
|
||||||
|
yield mock_setup_entry
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_config_entry() -> MockConfigEntry:
|
||||||
|
"""Return the default mocked config entry."""
|
||||||
|
return MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title="Fake Profile",
|
||||||
|
unique_id="xyz12",
|
||||||
|
data={CONF_API_KEY: "fake_api_key", CONF_PROFILE_ID: "xyz12"},
|
||||||
|
entry_id="d9aa37407ddac7b964a99e86312288d6",
|
||||||
|
)
|
@@ -3,56 +3,65 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from nextdns import ApiError
|
from nextdns import ApiError
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
from homeassistant.const import STATE_ON, STATE_UNAVAILABLE, Platform
|
from homeassistant.const import STATE_UNAVAILABLE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.util.dt import utcnow
|
|
||||||
|
|
||||||
from . import init_integration, mock_nextdns
|
from . import init_integration, mock_nextdns
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed, snapshot_platform
|
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
async def test_binary_sensor(
|
async def test_binary_sensor(
|
||||||
hass: HomeAssistant, entity_registry: er.EntityRegistry, snapshot: SnapshotAssertion
|
hass: HomeAssistant,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test states of the binary sensors."""
|
"""Test states of the binary sensors."""
|
||||||
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.BINARY_SENSOR]):
|
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.BINARY_SENSOR]):
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
async def test_availability(hass: HomeAssistant) -> None:
|
async def test_availability(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
) -> None:
|
||||||
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
|
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
|
||||||
await init_integration(hass)
|
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.BINARY_SENSOR]):
|
||||||
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.fake_profile_device_connection_status")
|
entity_entries = er.async_entries_for_config_entry(
|
||||||
assert state
|
entity_registry, mock_config_entry.entry_id
|
||||||
assert state.state != STATE_UNAVAILABLE
|
)
|
||||||
assert state.state == STATE_ON
|
entity_ids = (entry.entity_id for entry in entity_entries)
|
||||||
|
|
||||||
future = utcnow() + timedelta(minutes=10)
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
freezer.tick(timedelta(minutes=10))
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.nextdns.NextDns.connection_status",
|
"homeassistant.components.nextdns.NextDns.connection_status",
|
||||||
side_effect=ApiError("API Error"),
|
side_effect=ApiError("API Error"),
|
||||||
):
|
):
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done(wait_background_tasks=True)
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.fake_profile_device_connection_status")
|
for entity_id in entity_ids:
|
||||||
assert state
|
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
future = utcnow() + timedelta(minutes=20)
|
freezer.tick(timedelta(minutes=10))
|
||||||
with mock_nextdns():
|
with mock_nextdns():
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done(wait_background_tasks=True)
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.fake_profile_device_connection_status")
|
for entity_id in entity_ids:
|
||||||
assert state
|
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == STATE_ON
|
|
||||||
|
@@ -15,31 +15,34 @@ from homeassistant.const import ATTR_ENTITY_ID, Platform
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.util import dt as dt_util
|
|
||||||
|
|
||||||
from . import init_integration
|
from . import init_integration
|
||||||
|
|
||||||
from tests.common import snapshot_platform
|
from tests.common import MockConfigEntry, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
async def test_button(
|
async def test_button(
|
||||||
hass: HomeAssistant, entity_registry: er.EntityRegistry, snapshot: SnapshotAssertion
|
hass: HomeAssistant,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test states of the button."""
|
"""Test states of the button."""
|
||||||
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.BUTTON]):
|
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.BUTTON]):
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
async def test_button_press(hass: HomeAssistant) -> None:
|
@pytest.mark.freeze_time("2023-10-21")
|
||||||
|
async def test_button_press(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test button press."""
|
"""Test button press."""
|
||||||
await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
now = dt_util.utcnow()
|
|
||||||
with (
|
with (
|
||||||
patch("homeassistant.components.nextdns.NextDns.clear_logs") as mock_clear_logs,
|
patch("homeassistant.components.nextdns.NextDns.clear_logs") as mock_clear_logs,
|
||||||
patch("homeassistant.core.dt_util.utcnow", return_value=now),
|
|
||||||
):
|
):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
BUTTON_DOMAIN,
|
BUTTON_DOMAIN,
|
||||||
@@ -53,7 +56,7 @@ async def test_button_press(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
state = hass.states.get("button.fake_profile_clear_logs")
|
state = hass.states.get("button.fake_profile_clear_logs")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == now.isoformat()
|
assert state.state == "2023-10-21T00:00:00+00:00"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@@ -65,9 +68,11 @@ async def test_button_press(hass: HomeAssistant) -> None:
|
|||||||
ClientError,
|
ClientError,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_button_failure(hass: HomeAssistant, exc: Exception) -> None:
|
async def test_button_failure(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry, exc: Exception
|
||||||
|
) -> None:
|
||||||
"""Tests that the press action throws HomeAssistantError."""
|
"""Tests that the press action throws HomeAssistantError."""
|
||||||
await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
with (
|
with (
|
||||||
patch("homeassistant.components.nextdns.NextDns.clear_logs", side_effect=exc),
|
patch("homeassistant.components.nextdns.NextDns.clear_logs", side_effect=exc),
|
||||||
@@ -84,9 +89,11 @@ async def test_button_failure(hass: HomeAssistant, exc: Exception) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_button_auth_error(hass: HomeAssistant) -> None:
|
async def test_button_auth_error(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Tests that the press action starts re-auth flow."""
|
"""Tests that the press action starts re-auth flow."""
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.nextdns.NextDns.clear_logs",
|
"homeassistant.components.nextdns.NextDns.clear_logs",
|
||||||
@@ -99,7 +106,7 @@ async def test_button_auth_error(hass: HomeAssistant) -> None:
|
|||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.LOADED
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
flows = hass.config_entries.flow.async_progress()
|
flows = hass.config_entries.flow.async_progress()
|
||||||
assert len(flows) == 1
|
assert len(flows) == 1
|
||||||
@@ -110,4 +117,4 @@ async def test_button_auth_error(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
assert "context" in flow
|
assert "context" in flow
|
||||||
assert flow["context"].get("source") == SOURCE_REAUTH
|
assert flow["context"].get("source") == SOURCE_REAUTH
|
||||||
assert flow["context"].get("entry_id") == entry.entry_id
|
assert flow["context"].get("entry_id") == mock_config_entry.entry_id
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
"""Define tests for the NextDNS config flow."""
|
"""Define tests for the NextDNS config flow."""
|
||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
from nextdns import ApiError, InvalidApiKeyError
|
from nextdns import ApiError, InvalidApiKeyError
|
||||||
import pytest
|
import pytest
|
||||||
@@ -14,8 +14,12 @@ from homeassistant.data_entry_flow import FlowResultType
|
|||||||
|
|
||||||
from . import PROFILES, init_integration, mock_nextdns
|
from . import PROFILES, init_integration, mock_nextdns
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
async def test_form_create_entry(hass: HomeAssistant) -> None:
|
|
||||||
|
async def test_form_create_entry(
|
||||||
|
hass: HomeAssistant, mock_setup_entry: AsyncMock
|
||||||
|
) -> None:
|
||||||
"""Test that the user step works."""
|
"""Test that the user step works."""
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
@@ -24,14 +28,9 @@ async def test_form_create_entry(hass: HomeAssistant) -> None:
|
|||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
|
|
||||||
with (
|
with patch(
|
||||||
patch(
|
"homeassistant.components.nextdns.NextDns.get_profiles",
|
||||||
"homeassistant.components.nextdns.NextDns.get_profiles",
|
return_value=PROFILES,
|
||||||
return_value=PROFILES,
|
|
||||||
),
|
|
||||||
patch(
|
|
||||||
"homeassistant.components.nextdns.async_setup_entry", return_value=True
|
|
||||||
) as mock_setup_entry,
|
|
||||||
):
|
):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
@@ -44,12 +43,12 @@ async def test_form_create_entry(hass: HomeAssistant) -> None:
|
|||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"], {CONF_PROFILE_NAME: "Fake Profile"}
|
result["flow_id"], {CONF_PROFILE_NAME: "Fake Profile"}
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
assert result["title"] == "Fake Profile"
|
assert result["title"] == "Fake Profile"
|
||||||
assert result["data"][CONF_API_KEY] == "fake_api_key"
|
assert result["data"][CONF_API_KEY] == "fake_api_key"
|
||||||
assert result["data"][CONF_PROFILE_ID] == "xyz12"
|
assert result["data"][CONF_PROFILE_ID] == "xyz12"
|
||||||
|
assert result["result"].unique_id == "xyz12"
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
@@ -64,24 +63,55 @@ async def test_form_create_entry(hass: HomeAssistant) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_form_errors(
|
async def test_form_errors(
|
||||||
hass: HomeAssistant, exc: Exception, base_error: str
|
hass: HomeAssistant, mock_setup_entry: AsyncMock, exc: Exception, base_error: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we handle errors."""
|
"""Test we handle errors."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
|
)
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["errors"] == {}
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.nextdns.NextDns.get_profiles", side_effect=exc
|
"homeassistant.components.nextdns.NextDns.get_profiles", side_effect=exc
|
||||||
):
|
):
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
DOMAIN,
|
result["flow_id"],
|
||||||
context={"source": SOURCE_USER},
|
{CONF_API_KEY: "fake_api_key"},
|
||||||
data={CONF_API_KEY: "fake_api_key"},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["errors"] == {"base": base_error}
|
assert result["errors"] == {"base": base_error}
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.nextdns.NextDns.get_profiles",
|
||||||
|
return_value=PROFILES,
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{CONF_API_KEY: "fake_api_key"},
|
||||||
|
)
|
||||||
|
|
||||||
async def test_form_already_configured(hass: HomeAssistant) -> None:
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "profiles"
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], {CONF_PROFILE_NAME: "Fake Profile"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["title"] == "Fake Profile"
|
||||||
|
assert result["data"][CONF_API_KEY] == "fake_api_key"
|
||||||
|
assert result["data"][CONF_PROFILE_ID] == "xyz12"
|
||||||
|
assert result["result"].unique_id == "xyz12"
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_form_already_configured(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test that errors are shown when duplicates are added."""
|
"""Test that errors are shown when duplicates are added."""
|
||||||
await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
@@ -103,11 +133,13 @@ async def test_form_already_configured(hass: HomeAssistant) -> None:
|
|||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_reauth_successful(hass: HomeAssistant) -> None:
|
async def test_reauth_successful(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test starting a reauthentication flow."""
|
"""Test starting a reauthentication flow."""
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
result = await entry.start_reauth_flow(hass)
|
result = await mock_config_entry.start_reauth_flow(hass)
|
||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["step_id"] == "reauth_confirm"
|
assert result["step_id"] == "reauth_confirm"
|
||||||
|
|
||||||
@@ -122,7 +154,6 @@ async def test_reauth_successful(hass: HomeAssistant) -> None:
|
|||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={CONF_API_KEY: "new_api_key"},
|
user_input={CONF_API_KEY: "new_api_key"},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == "reauth_successful"
|
assert result["reason"] == "reauth_successful"
|
||||||
@@ -139,12 +170,15 @@ async def test_reauth_successful(hass: HomeAssistant) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_reauth_errors(
|
async def test_reauth_errors(
|
||||||
hass: HomeAssistant, exc: Exception, base_error: str
|
hass: HomeAssistant,
|
||||||
|
exc: Exception,
|
||||||
|
base_error: str,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test reauthentication flow with errors."""
|
"""Test reauthentication flow with errors."""
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
result = await entry.start_reauth_flow(hass)
|
result = await mock_config_entry.start_reauth_flow(hass)
|
||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["step_id"] == "reauth_confirm"
|
assert result["step_id"] == "reauth_confirm"
|
||||||
|
|
||||||
@@ -155,6 +189,20 @@ async def test_reauth_errors(
|
|||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
user_input={CONF_API_KEY: "new_api_key"},
|
user_input={CONF_API_KEY: "new_api_key"},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert result["errors"] == {"base": base_error}
|
assert result["errors"] == {"base": base_error}
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.nextdns.NextDns.get_profiles",
|
||||||
|
return_value=PROFILES,
|
||||||
|
),
|
||||||
|
mock_nextdns(),
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
user_input={CONF_API_KEY: "new_api_key"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "reauth_successful"
|
||||||
|
@@ -12,17 +12,18 @@ from homeassistant.core import HomeAssistant
|
|||||||
|
|
||||||
from . import init_integration
|
from . import init_integration
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||||
|
|
||||||
|
|
||||||
async def test_auth_error(
|
async def test_auth_error(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
freezer: FrozenDateTimeFactory,
|
freezer: FrozenDateTimeFactory,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test authentication error when polling data."""
|
"""Test authentication error when polling data."""
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.LOADED
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
freezer.tick(timedelta(minutes=10))
|
freezer.tick(timedelta(minutes=10))
|
||||||
with (
|
with (
|
||||||
@@ -62,7 +63,7 @@ async def test_auth_error(
|
|||||||
async_fire_time_changed(hass)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.LOADED
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
flows = hass.config_entries.flow.async_progress()
|
flows = hass.config_entries.flow.async_progress()
|
||||||
assert len(flows) == 1
|
assert len(flows) == 1
|
||||||
@@ -73,4 +74,4 @@ async def test_auth_error(
|
|||||||
|
|
||||||
assert "context" in flow
|
assert "context" in flow
|
||||||
assert flow["context"].get("source") == SOURCE_REAUTH
|
assert flow["context"].get("source") == SOURCE_REAUTH
|
||||||
assert flow["context"].get("entry_id") == entry.entry_id
|
assert flow["context"].get("entry_id") == mock_config_entry.entry_id
|
||||||
|
@@ -7,6 +7,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
|
|
||||||
from . import init_integration
|
from . import init_integration
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||||
from tests.typing import ClientSessionGenerator
|
from tests.typing import ClientSessionGenerator
|
||||||
|
|
||||||
@@ -15,10 +16,11 @@ async def test_entry_diagnostics(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
hass_client: ClientSessionGenerator,
|
hass_client: ClientSessionGenerator,
|
||||||
snapshot: SnapshotAssertion,
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test config entry diagnostics."""
|
"""Test config entry diagnostics."""
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
assert await get_diagnostics_for_config_entry(hass, hass_client, entry) == snapshot(
|
assert await get_diagnostics_for_config_entry(
|
||||||
exclude=props("created_at", "modified_at")
|
hass, hass_client, mock_config_entry
|
||||||
)
|
) == snapshot(exclude=props("created_at", "modified_at"))
|
||||||
|
@@ -6,9 +6,9 @@ from nextdns import ApiError, InvalidApiKeyError
|
|||||||
import pytest
|
import pytest
|
||||||
from tenacity import RetryError
|
from tenacity import RetryError
|
||||||
|
|
||||||
from homeassistant.components.nextdns.const import CONF_PROFILE_ID, DOMAIN
|
from homeassistant.components.nextdns.const import DOMAIN
|
||||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
||||||
from homeassistant.const import CONF_API_KEY, STATE_UNAVAILABLE
|
from homeassistant.const import STATE_UNAVAILABLE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import init_integration
|
from . import init_integration
|
||||||
@@ -16,9 +16,11 @@ from . import init_integration
|
|||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
async def test_async_setup_entry(hass: HomeAssistant) -> None:
|
async def test_async_setup_entry(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test a successful setup entry."""
|
"""Test a successful setup entry."""
|
||||||
await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dns_queries_blocked_ratio")
|
state = hass.states.get("sensor.fake_profile_dns_queries_blocked_ratio")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
@@ -29,55 +31,48 @@ async def test_async_setup_entry(hass: HomeAssistant) -> None:
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"exc", [ApiError("API Error"), RetryError("Retry Error"), TimeoutError]
|
"exc", [ApiError("API Error"), RetryError("Retry Error"), TimeoutError]
|
||||||
)
|
)
|
||||||
async def test_config_not_ready(hass: HomeAssistant, exc: Exception) -> None:
|
async def test_config_not_ready(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry, exc: Exception
|
||||||
|
) -> None:
|
||||||
"""Test for setup failure if the connection to the service fails."""
|
"""Test for setup failure if the connection to the service fails."""
|
||||||
entry = MockConfigEntry(
|
|
||||||
domain=DOMAIN,
|
|
||||||
title="Fake Profile",
|
|
||||||
unique_id="xyz12",
|
|
||||||
data={CONF_API_KEY: "fake_api_key", CONF_PROFILE_ID: "xyz12"},
|
|
||||||
)
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.nextdns.NextDns.get_profiles",
|
"homeassistant.components.nextdns.NextDns.get_profiles",
|
||||||
side_effect=exc,
|
side_effect=exc,
|
||||||
):
|
):
|
||||||
entry.add_to_hass(hass)
|
mock_config_entry.add_to_hass(hass)
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
async def test_unload_entry(hass: HomeAssistant) -> None:
|
async def test_unload_entry(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test successful unload of entry."""
|
"""Test successful unload of entry."""
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||||
assert entry.state is ConfigEntryState.LOADED
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
assert await hass.config_entries.async_unload(entry.entry_id)
|
assert await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.NOT_LOADED
|
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||||
assert not hass.data.get(DOMAIN)
|
assert not hass.data.get(DOMAIN)
|
||||||
|
|
||||||
|
|
||||||
async def test_config_auth_failed(hass: HomeAssistant) -> None:
|
async def test_config_auth_failed(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test for setup failure if the auth fails."""
|
"""Test for setup failure if the auth fails."""
|
||||||
entry = MockConfigEntry(
|
mock_config_entry.add_to_hass(hass)
|
||||||
domain=DOMAIN,
|
|
||||||
title="Fake Profile",
|
|
||||||
unique_id="xyz12",
|
|
||||||
data={CONF_API_KEY: "fake_api_key", CONF_PROFILE_ID: "xyz12"},
|
|
||||||
)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.nextdns.NextDns.get_profiles",
|
"homeassistant.components.nextdns.NextDns.get_profiles",
|
||||||
side_effect=InvalidApiKeyError,
|
side_effect=InvalidApiKeyError,
|
||||||
):
|
):
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.SETUP_ERROR
|
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
|
||||||
|
|
||||||
flows = hass.config_entries.flow.async_progress()
|
flows = hass.config_entries.flow.async_progress()
|
||||||
assert len(flows) == 1
|
assert len(flows) == 1
|
||||||
@@ -88,4 +83,4 @@ async def test_config_auth_failed(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
assert "context" in flow
|
assert "context" in flow
|
||||||
assert flow["context"].get("source") == SOURCE_REAUTH
|
assert flow["context"].get("source") == SOURCE_REAUTH
|
||||||
assert flow["context"].get("entry_id") == entry.entry_id
|
assert flow["context"].get("entry_id") == mock_config_entry.entry_id
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from nextdns import ApiError
|
from nextdns import ApiError
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
@@ -10,11 +11,10 @@ from syrupy.assertion import SnapshotAssertion
|
|||||||
from homeassistant.const import STATE_UNAVAILABLE, Platform
|
from homeassistant.const import STATE_UNAVAILABLE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.util.dt import utcnow
|
|
||||||
|
|
||||||
from . import init_integration, mock_nextdns
|
from . import init_integration, mock_nextdns
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed, snapshot_platform
|
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
@@ -22,48 +22,35 @@ async def test_sensor(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
snapshot: SnapshotAssertion,
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test states of sensors."""
|
"""Test states of sensors."""
|
||||||
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.SENSOR]):
|
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.SENSOR]):
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
async def test_availability(
|
async def test_availability(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
|
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
|
||||||
await init_integration(hass)
|
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.SENSOR]):
|
||||||
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dns_queries")
|
entity_entries = er.async_entries_for_config_entry(
|
||||||
assert state
|
entity_registry, mock_config_entry.entry_id
|
||||||
assert state.state != STATE_UNAVAILABLE
|
)
|
||||||
assert state.state == "100"
|
entity_ids = (entry.entity_id for entry in entity_entries)
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dns_over_https_queries")
|
for entity_id in entity_ids:
|
||||||
assert state
|
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "20"
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries")
|
freezer.tick(timedelta(minutes=10))
|
||||||
assert state
|
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "75"
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_encrypted_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "60"
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_ipv4_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "90"
|
|
||||||
|
|
||||||
future = utcnow() + timedelta(minutes=10)
|
|
||||||
with (
|
with (
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.nextdns.NextDns.get_analytics_status",
|
"homeassistant.components.nextdns.NextDns.get_analytics_status",
|
||||||
@@ -86,55 +73,16 @@ async def test_availability(
|
|||||||
side_effect=ApiError("API Error"),
|
side_effect=ApiError("API Error"),
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done(wait_background_tasks=True)
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dns_queries")
|
for entity_id in entity_ids:
|
||||||
assert state
|
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dns_over_https_queries")
|
freezer.tick(timedelta(minutes=10))
|
||||||
assert state
|
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_encrypted_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_ipv4_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
future = utcnow() + timedelta(minutes=20)
|
|
||||||
with mock_nextdns():
|
with mock_nextdns():
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done(wait_background_tasks=True)
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dns_queries")
|
for entity_id in entity_ids:
|
||||||
assert state
|
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "100"
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dns_over_https_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "20"
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_dnssec_validated_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "75"
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_encrypted_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "60"
|
|
||||||
|
|
||||||
state = hass.states.get("sensor.fake_profile_ipv4_queries")
|
|
||||||
assert state
|
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == "90"
|
|
||||||
|
@@ -5,6 +5,7 @@ from unittest.mock import Mock, patch
|
|||||||
|
|
||||||
from aiohttp import ClientError
|
from aiohttp import ClientError
|
||||||
from aiohttp.client_exceptions import ClientConnectorError
|
from aiohttp.client_exceptions import ClientConnectorError
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from nextdns import ApiError, InvalidApiKeyError
|
from nextdns import ApiError, InvalidApiKeyError
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
@@ -25,11 +26,10 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.util.dt import utcnow
|
|
||||||
|
|
||||||
from . import init_integration, mock_nextdns
|
from . import init_integration, mock_nextdns
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed, snapshot_platform
|
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
@@ -37,17 +37,20 @@ async def test_switch(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
snapshot: SnapshotAssertion,
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test states of the switches."""
|
"""Test states of the switches."""
|
||||||
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.SWITCH]):
|
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.SWITCH]):
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
async def test_switch_on(hass: HomeAssistant) -> None:
|
async def test_switch_on(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test the switch can be turned on."""
|
"""Test the switch can be turned on."""
|
||||||
await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
state = hass.states.get("switch.fake_profile_block_page")
|
state = hass.states.get("switch.fake_profile_block_page")
|
||||||
assert state
|
assert state
|
||||||
@@ -71,9 +74,11 @@ async def test_switch_on(hass: HomeAssistant) -> None:
|
|||||||
mock_switch_on.assert_called_once()
|
mock_switch_on.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
async def test_switch_off(hass: HomeAssistant) -> None:
|
async def test_switch_off(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Test the switch can be turned on."""
|
"""Test the switch can be turned on."""
|
||||||
await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
state = hass.states.get("switch.fake_profile_web3")
|
state = hass.states.get("switch.fake_profile_web3")
|
||||||
assert state
|
assert state
|
||||||
@@ -97,6 +102,7 @@ async def test_switch_off(hass: HomeAssistant) -> None:
|
|||||||
mock_switch_on.assert_called_once()
|
mock_switch_on.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"exc",
|
"exc",
|
||||||
[
|
[
|
||||||
@@ -105,36 +111,43 @@ async def test_switch_off(hass: HomeAssistant) -> None:
|
|||||||
TimeoutError,
|
TimeoutError,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_availability(hass: HomeAssistant, exc: Exception) -> None:
|
async def test_availability(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
exc: Exception,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
) -> None:
|
||||||
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
|
"""Ensure that we mark the entities unavailable correctly when service causes an error."""
|
||||||
await init_integration(hass)
|
with patch("homeassistant.components.nextdns.PLATFORMS", [Platform.SWITCH]):
|
||||||
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
state = hass.states.get("switch.fake_profile_web3")
|
entity_entries = er.async_entries_for_config_entry(
|
||||||
assert state
|
entity_registry, mock_config_entry.entry_id
|
||||||
assert state.state != STATE_UNAVAILABLE
|
)
|
||||||
assert state.state == STATE_ON
|
entity_ids = (entry.entity_id for entry in entity_entries)
|
||||||
|
|
||||||
future = utcnow() + timedelta(minutes=10)
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
freezer.tick(timedelta(minutes=10))
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.nextdns.NextDns.get_settings",
|
"homeassistant.components.nextdns.NextDns.get_settings",
|
||||||
side_effect=exc,
|
side_effect=exc,
|
||||||
):
|
):
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done(wait_background_tasks=True)
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
state = hass.states.get("switch.fake_profile_web3")
|
for entity_id in entity_ids:
|
||||||
assert state
|
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
||||||
assert state.state == STATE_UNAVAILABLE
|
|
||||||
|
|
||||||
future = utcnow() + timedelta(minutes=20)
|
freezer.tick(timedelta(minutes=10))
|
||||||
with mock_nextdns():
|
with mock_nextdns():
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done(wait_background_tasks=True)
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
state = hass.states.get("switch.fake_profile_web3")
|
for entity_id in entity_ids:
|
||||||
assert state
|
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE
|
||||||
assert state.state != STATE_UNAVAILABLE
|
|
||||||
assert state.state == STATE_ON
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@@ -146,9 +159,11 @@ async def test_availability(hass: HomeAssistant, exc: Exception) -> None:
|
|||||||
ClientError,
|
ClientError,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_switch_failure(hass: HomeAssistant, exc: Exception) -> None:
|
async def test_switch_failure(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry, exc: Exception
|
||||||
|
) -> None:
|
||||||
"""Tests that the turn on/off service throws HomeAssistantError."""
|
"""Tests that the turn on/off service throws HomeAssistantError."""
|
||||||
await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
with (
|
with (
|
||||||
patch("homeassistant.components.nextdns.NextDns.set_setting", side_effect=exc),
|
patch("homeassistant.components.nextdns.NextDns.set_setting", side_effect=exc),
|
||||||
@@ -162,9 +177,11 @@ async def test_switch_failure(hass: HomeAssistant, exc: Exception) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_switch_auth_error(hass: HomeAssistant) -> None:
|
async def test_switch_auth_error(
|
||||||
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
|
) -> None:
|
||||||
"""Tests that the turn on/off action starts re-auth flow."""
|
"""Tests that the turn on/off action starts re-auth flow."""
|
||||||
entry = await init_integration(hass)
|
await init_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.nextdns.NextDns.set_setting",
|
"homeassistant.components.nextdns.NextDns.set_setting",
|
||||||
@@ -177,7 +194,7 @@ async def test_switch_auth_error(hass: HomeAssistant) -> None:
|
|||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert entry.state is ConfigEntryState.LOADED
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
flows = hass.config_entries.flow.async_progress()
|
flows = hass.config_entries.flow.async_progress()
|
||||||
assert len(flows) == 1
|
assert len(flows) == 1
|
||||||
@@ -188,4 +205,4 @@ async def test_switch_auth_error(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
assert "context" in flow
|
assert "context" in flow
|
||||||
assert flow["context"].get("source") == SOURCE_REAUTH
|
assert flow["context"].get("source") == SOURCE_REAUTH
|
||||||
assert flow["context"].get("entry_id") == entry.entry_id
|
assert flow["context"].get("entry_id") == mock_config_entry.entry_id
|
||||||
|
Reference in New Issue
Block a user