core/tests/components/bsblan/test_init.py

114 lines
3.8 KiB
Python

"""Tests for the BSBLan integration."""
from unittest.mock import MagicMock
from bsblan import BSBLANAuthError, BSBLANConnectionError, BSBLANError
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.bsblan.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry, async_fire_time_changed
async def test_load_unload_config_entry(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_bsblan: MagicMock,
) -> None:
"""Test the BSBLAN configuration entry loading/unloading."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.LOADED
assert len(mock_bsblan.device.mock_calls) == 1
await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert not hass.data.get(DOMAIN)
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
async def test_config_entry_not_ready(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_bsblan: MagicMock,
) -> None:
"""Test the bsblan configuration entry not ready."""
mock_bsblan.state.side_effect = BSBLANConnectionError
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert len(mock_bsblan.state.mock_calls) == 1
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
async def test_config_entry_auth_failed_triggers_reauth(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_bsblan: MagicMock,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test that BSBLANAuthError during coordinator update triggers reauth flow."""
# First, set up the integration successfully
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.LOADED
# Mock BSBLANAuthError during next update
mock_bsblan.initialize.side_effect = BSBLANAuthError("Authentication failed")
# Advance time by the coordinator's update interval to trigger update
freezer.tick(delta=20) # Advance beyond the 12 second scan interval + random offset
async_fire_time_changed(hass)
await hass.async_block_till_done()
# Check that a reauth flow has been started
flows = hass.config_entries.flow.async_progress()
assert len(flows) == 1
assert flows[0]["context"]["source"] == "reauth"
assert flows[0]["context"]["entry_id"] == mock_config_entry.entry_id
@pytest.mark.parametrize(
("method", "exception", "expected_state"),
[
(
"device",
BSBLANConnectionError("Connection failed"),
ConfigEntryState.SETUP_RETRY,
),
(
"info",
BSBLANAuthError("Authentication failed"),
ConfigEntryState.SETUP_ERROR,
),
("static_values", BSBLANError("General error"), ConfigEntryState.SETUP_ERROR),
],
)
async def test_config_entry_static_data_errors(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_bsblan: MagicMock,
method: str,
exception: Exception,
expected_state: ConfigEntryState,
) -> None:
"""Test various errors during static data fetching trigger appropriate config entry states."""
# Mock the specified method to raise the exception
getattr(mock_bsblan, method).side_effect = exception
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is expected_state