Mock dwdwfsapi in all tests that use it (#116414)

* Mock dwdwfsapi in all tests

* Add mocking for config entries

* Fix assertions in init test
This commit is contained in:
andarotajo 2024-04-30 18:08:15 +02:00 committed by GitHub
parent a440783208
commit 1e63665bf2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 164 additions and 107 deletions

View File

@ -1 +1,16 @@
"""Tests for Deutscher Wetterdienst (DWD) Weather Warnings.""" """Tests for Deutscher Wetterdienst (DWD) Weather Warnings."""
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def init_integration(
hass: HomeAssistant, entry: MockConfigEntry
) -> MockConfigEntry:
"""Set up the integration based on the config entry."""
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
return entry

View File

@ -1,10 +1,26 @@
"""Configuration for Deutscher Wetterdienst (DWD) Weather Warnings tests.""" """Configuration for Deutscher Wetterdienst (DWD) Weather Warnings tests."""
from collections.abc import Generator from collections.abc import Generator
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, MagicMock, Mock, patch
import pytest import pytest
from homeassistant.components.dwd_weather_warnings.const import (
ADVANCE_WARNING_SENSOR,
CONF_REGION_DEVICE_TRACKER,
CONF_REGION_IDENTIFIER,
CURRENT_WARNING_SENSOR,
DOMAIN,
)
from homeassistant.const import CONF_MONITORED_CONDITIONS, CONF_NAME
from tests.common import MockConfigEntry
MOCK_NAME = "Unit Test"
MOCK_REGION_IDENTIFIER = "807111000"
MOCK_REGION_DEVICE_TRACKER = "device_tracker.test_gps"
MOCK_CONDITIONS = [CURRENT_WARNING_SENSOR, ADVANCE_WARNING_SENSOR]
@pytest.fixture @pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock, None, None]: def mock_setup_entry() -> Generator[AsyncMock, None, None]:
@ -14,3 +30,58 @@ def mock_setup_entry() -> Generator[AsyncMock, None, None]:
return_value=True, return_value=True,
) as mock_setup_entry: ) as mock_setup_entry:
yield mock_setup_entry yield mock_setup_entry
@pytest.fixture
def mock_identifier_entry() -> MockConfigEntry:
"""Return a mocked config entry with a region identifier."""
return MockConfigEntry(
domain=DOMAIN,
data={
CONF_NAME: MOCK_NAME,
CONF_REGION_IDENTIFIER: MOCK_REGION_IDENTIFIER,
CONF_MONITORED_CONDITIONS: MOCK_CONDITIONS,
},
)
@pytest.fixture
def mock_tracker_entry() -> MockConfigEntry:
"""Return a mocked config entry with a region identifier."""
return MockConfigEntry(
domain=DOMAIN,
data={
CONF_NAME: MOCK_NAME,
CONF_REGION_DEVICE_TRACKER: MOCK_REGION_DEVICE_TRACKER,
CONF_MONITORED_CONDITIONS: MOCK_CONDITIONS,
},
)
@pytest.fixture
def mock_dwdwfsapi() -> Generator[MagicMock, None, None]:
"""Return a mocked dwdwfsapi API client."""
with (
patch(
"homeassistant.components.dwd_weather_warnings.coordinator.DwdWeatherWarningsAPI",
autospec=True,
) as mock_api,
patch(
"homeassistant.components.dwd_weather_warnings.config_flow.DwdWeatherWarningsAPI",
new=mock_api,
),
):
api = mock_api.return_value
api.data_valid = False
api.warncell_id = None
api.warncell_name = None
api.last_update = None
api.current_warning_level = None
api.current_warnings = None
api.expected_warning_level = None
api.expected_warnings = None
api.update = Mock()
api.__bool__ = Mock()
api.__bool__.return_value = True
yield api

View File

@ -1,7 +1,7 @@
"""Tests for Deutscher Wetterdienst (DWD) Weather Warnings config flow.""" """Tests for Deutscher Wetterdienst (DWD) Weather Warnings config flow."""
from typing import Final from typing import Final
from unittest.mock import patch from unittest.mock import MagicMock
import pytest import pytest
@ -29,7 +29,9 @@ DEMO_CONFIG_ENTRY_GPS: Final = {
pytestmark = pytest.mark.usefixtures("mock_setup_entry") pytestmark = pytest.mark.usefixtures("mock_setup_entry")
async def test_create_entry_region(hass: HomeAssistant) -> None: async def test_create_entry_region(
hass: HomeAssistant, mock_dwdwfsapi: MagicMock
) -> None:
"""Test that the full config flow works for a region identifier.""" """Test that the full config flow works for a region identifier."""
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}
@ -37,26 +39,20 @@ async def test_create_entry_region(hass: HomeAssistant) -> None:
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
with patch( mock_dwdwfsapi.__bool__.return_value = False
"homeassistant.components.dwd_weather_warnings.config_flow.DwdWeatherWarningsAPI", result = await hass.config_entries.flow.async_configure(
return_value=False, result["flow_id"], user_input=DEMO_CONFIG_ENTRY_REGION
): )
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=DEMO_CONFIG_ENTRY_REGION
)
# Test for invalid region identifier. # Test for invalid region identifier.
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "invalid_identifier"} assert result["errors"] == {"base": "invalid_identifier"}
with patch( mock_dwdwfsapi.__bool__.return_value = True
"homeassistant.components.dwd_weather_warnings.config_flow.DwdWeatherWarningsAPI", result = await hass.config_entries.flow.async_configure(
return_value=True, result["flow_id"], user_input=DEMO_CONFIG_ENTRY_REGION
): )
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=DEMO_CONFIG_ENTRY_REGION
)
# Test for successfully created entry. # Test for successfully created entry.
await hass.async_block_till_done() await hass.async_block_till_done()
@ -68,14 +64,14 @@ async def test_create_entry_region(hass: HomeAssistant) -> None:
async def test_create_entry_gps( async def test_create_entry_gps(
hass: HomeAssistant, entity_registry: er.EntityRegistry hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_dwdwfsapi: MagicMock
) -> None: ) -> None:
"""Test that the full config flow works for a device tracker.""" """Test that the full config flow works for a device tracker."""
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}
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
# Test for missing registry entry error. # Test for missing registry entry error.
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
@ -83,7 +79,7 @@ async def test_create_entry_gps(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "entity_not_found"} assert result["errors"] == {"base": "entity_not_found"}
# Test for missing device tracker error. # Test for missing device tracker error.
@ -96,7 +92,7 @@ async def test_create_entry_gps(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "entity_not_found"} assert result["errors"] == {"base": "entity_not_found"}
# Test for missing attribute error. # Test for missing attribute error.
@ -111,7 +107,7 @@ async def test_create_entry_gps(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "attribute_not_found"} assert result["errors"] == {"base": "attribute_not_found"}
# Test for invalid provided identifier. # Test for invalid provided identifier.
@ -121,36 +117,32 @@ async def test_create_entry_gps(
{ATTR_LATITUDE: "50.180454", ATTR_LONGITUDE: "7.610263"}, {ATTR_LATITUDE: "50.180454", ATTR_LONGITUDE: "7.610263"},
) )
with patch( mock_dwdwfsapi.__bool__.return_value = False
"homeassistant.components.dwd_weather_warnings.config_flow.DwdWeatherWarningsAPI", result = await hass.config_entries.flow.async_configure(
return_value=False, result["flow_id"], user_input=DEMO_CONFIG_ENTRY_GPS
): )
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=DEMO_CONFIG_ENTRY_GPS
)
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "invalid_identifier"} assert result["errors"] == {"base": "invalid_identifier"}
# Test for successfully created entry. # Test for successfully created entry.
with patch( mock_dwdwfsapi.__bool__.return_value = True
"homeassistant.components.dwd_weather_warnings.config_flow.DwdWeatherWarningsAPI", result = await hass.config_entries.flow.async_configure(
return_value=True, result["flow_id"], user_input=DEMO_CONFIG_ENTRY_GPS
): )
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=DEMO_CONFIG_ENTRY_GPS
)
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.CREATE_ENTRY assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "test_gps" assert result["title"] == "test_gps"
assert result["data"] == { assert result["data"] == {
CONF_REGION_DEVICE_TRACKER: registry_entry.id, CONF_REGION_DEVICE_TRACKER: registry_entry.id,
} }
async def test_config_flow_already_configured(hass: HomeAssistant) -> None: async def test_config_flow_already_configured(
hass: HomeAssistant, mock_dwdwfsapi: MagicMock
) -> None:
"""Test aborting, if the warncell ID / name is already configured during the config.""" """Test aborting, if the warncell ID / name is already configured during the config."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
@ -167,13 +159,9 @@ async def test_config_flow_already_configured(hass: HomeAssistant) -> None:
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
with patch( result = await hass.config_entries.flow.async_configure(
"homeassistant.components.dwd_weather_warnings.config_flow.DwdWeatherWarningsAPI", result["flow_id"], user_input=DEMO_CONFIG_ENTRY_REGION
return_value=True, )
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=DEMO_CONFIG_ENTRY_REGION
)
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] is FlowResultType.ABORT assert result["type"] is FlowResultType.ABORT
@ -187,7 +175,7 @@ async def test_config_flow_with_errors(hass: HomeAssistant) -> None:
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
# Test error for empty input data. # Test error for empty input data.
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
@ -195,7 +183,7 @@ async def test_config_flow_with_errors(hass: HomeAssistant) -> None:
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "no_identifier"} assert result["errors"] == {"base": "no_identifier"}
# Test error for setting both options during configuration. # Test error for setting both options during configuration.
@ -207,5 +195,5 @@ async def test_config_flow_with_errors(hass: HomeAssistant) -> None:
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "ambiguous_identifier"} assert result["errors"] == {"base": "ambiguous_identifier"}

View File

@ -1,46 +1,28 @@
"""Tests for Deutscher Wetterdienst (DWD) Weather Warnings integration.""" """Tests for Deutscher Wetterdienst (DWD) Weather Warnings integration."""
from typing import Final from unittest.mock import MagicMock
from homeassistant.components.dwd_weather_warnings.const import ( from homeassistant.components.dwd_weather_warnings.const import (
ADVANCE_WARNING_SENSOR,
CONF_REGION_DEVICE_TRACKER, CONF_REGION_DEVICE_TRACKER,
CONF_REGION_IDENTIFIER,
CURRENT_WARNING_SENSOR,
DOMAIN, DOMAIN,
) )
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import ( from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE, STATE_HOME
ATTR_LATITUDE,
ATTR_LONGITUDE,
CONF_MONITORED_CONDITIONS,
CONF_NAME,
STATE_HOME,
)
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 . import init_integration
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
DEMO_IDENTIFIER_CONFIG_ENTRY: Final = {
CONF_NAME: "Unit Test",
CONF_REGION_IDENTIFIER: "807111000",
CONF_MONITORED_CONDITIONS: [CURRENT_WARNING_SENSOR, ADVANCE_WARNING_SENSOR],
}
DEMO_TRACKER_CONFIG_ENTRY: Final = { async def test_load_unload_entry(
CONF_NAME: "Unit Test", hass: HomeAssistant,
CONF_REGION_DEVICE_TRACKER: "device_tracker.test_gps", mock_identifier_entry: MockConfigEntry,
CONF_MONITORED_CONDITIONS: [CURRENT_WARNING_SENSOR, ADVANCE_WARNING_SENSOR], mock_dwdwfsapi: MagicMock,
} ) -> None:
async def test_load_unload_entry(hass: HomeAssistant) -> None:
"""Test loading and unloading the integration with a region identifier based entry.""" """Test loading and unloading the integration with a region identifier based entry."""
entry = MockConfigEntry(domain=DOMAIN, data=DEMO_IDENTIFIER_CONFIG_ENTRY) entry = await init_integration(hass, mock_identifier_entry)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.LOADED assert entry.state is ConfigEntryState.LOADED
assert entry.entry_id in hass.data[DOMAIN] assert entry.entry_id in hass.data[DOMAIN]
@ -52,66 +34,67 @@ async def test_load_unload_entry(hass: HomeAssistant) -> None:
assert entry.entry_id not in hass.data[DOMAIN] assert entry.entry_id not in hass.data[DOMAIN]
async def test_load_invalid_registry_entry(hass: HomeAssistant) -> None: async def test_load_invalid_registry_entry(
hass: HomeAssistant, mock_tracker_entry: MockConfigEntry
) -> None:
"""Test loading the integration with an invalid registry entry ID.""" """Test loading the integration with an invalid registry entry ID."""
INVALID_DATA = DEMO_TRACKER_CONFIG_ENTRY.copy() INVALID_DATA = mock_tracker_entry.data.copy()
INVALID_DATA[CONF_REGION_DEVICE_TRACKER] = "invalid_registry_id" INVALID_DATA[CONF_REGION_DEVICE_TRACKER] = "invalid_registry_id"
entry = MockConfigEntry(domain=DOMAIN, data=INVALID_DATA)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id) entry = await init_integration(
await hass.async_block_till_done() hass, MockConfigEntry(domain=DOMAIN, data=INVALID_DATA)
assert entry.state == ConfigEntryState.SETUP_RETRY )
assert entry.state is ConfigEntryState.SETUP_RETRY
async def test_load_missing_device_tracker(hass: HomeAssistant) -> None: async def test_load_missing_device_tracker(
hass: HomeAssistant, mock_tracker_entry: MockConfigEntry
) -> None:
"""Test loading the integration with a missing device tracker.""" """Test loading the integration with a missing device tracker."""
entry = MockConfigEntry(domain=DOMAIN, data=DEMO_TRACKER_CONFIG_ENTRY) entry = await init_integration(hass, mock_tracker_entry)
entry.add_to_hass(hass) assert entry.state is ConfigEntryState.SETUP_RETRY
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state == ConfigEntryState.SETUP_RETRY
async def test_load_missing_required_attribute(hass: HomeAssistant) -> None: async def test_load_missing_required_attribute(
hass: HomeAssistant, mock_tracker_entry: MockConfigEntry
) -> None:
"""Test loading the integration with a device tracker missing a required attribute.""" """Test loading the integration with a device tracker missing a required attribute."""
entry = MockConfigEntry(domain=DOMAIN, data=DEMO_TRACKER_CONFIG_ENTRY) mock_tracker_entry.add_to_hass(hass)
entry.add_to_hass(hass)
hass.states.async_set( hass.states.async_set(
DEMO_TRACKER_CONFIG_ENTRY[CONF_REGION_DEVICE_TRACKER], mock_tracker_entry.data[CONF_REGION_DEVICE_TRACKER],
STATE_HOME, STATE_HOME,
{ATTR_LONGITUDE: "7.610263"}, {ATTR_LONGITUDE: "7.610263"},
) )
await hass.config_entries.async_setup(entry.entry_id) await hass.config_entries.async_setup(mock_tracker_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert entry.state == ConfigEntryState.SETUP_RETRY assert mock_tracker_entry.state is ConfigEntryState.SETUP_RETRY
async def test_load_valid_device_tracker( async def test_load_valid_device_tracker(
hass: HomeAssistant, entity_registry: er.EntityRegistry hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_tracker_entry: MockConfigEntry,
mock_dwdwfsapi: MagicMock,
) -> None: ) -> None:
"""Test loading the integration with a valid device tracker based entry.""" """Test loading the integration with a valid device tracker based entry."""
entry = MockConfigEntry(domain=DOMAIN, data=DEMO_TRACKER_CONFIG_ENTRY) mock_tracker_entry.add_to_hass(hass)
entry.add_to_hass(hass)
entity_registry.async_get_or_create( entity_registry.async_get_or_create(
"device_tracker", "device_tracker",
entry.domain, mock_tracker_entry.domain,
"uuid", "uuid",
suggested_object_id="test_gps", suggested_object_id="test_gps",
config_entry=entry, config_entry=mock_tracker_entry,
) )
hass.states.async_set( hass.states.async_set(
DEMO_TRACKER_CONFIG_ENTRY[CONF_REGION_DEVICE_TRACKER], mock_tracker_entry.data[CONF_REGION_DEVICE_TRACKER],
STATE_HOME, STATE_HOME,
{ATTR_LATITUDE: "50.180454", ATTR_LONGITUDE: "7.610263"}, {ATTR_LATITUDE: "50.180454", ATTR_LONGITUDE: "7.610263"},
) )
await hass.config_entries.async_setup(entry.entry_id) await hass.config_entries.async_setup(mock_tracker_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert entry.state == ConfigEntryState.LOADED assert mock_tracker_entry.state is ConfigEntryState.LOADED
assert entry.entry_id in hass.data[DOMAIN] assert mock_tracker_entry.entry_id in hass.data[DOMAIN]