mirror of
https://github.com/home-assistant/core.git
synced 2025-11-10 11:29:46 +00:00
382 lines
11 KiB
Python
382 lines
11 KiB
Python
"""Test the World Air Quality Index (WAQI) config flow."""
|
|
|
|
from unittest.mock import AsyncMock
|
|
|
|
from aiowaqi import WAQIAuthenticationError, WAQIConnectionError
|
|
import pytest
|
|
|
|
from homeassistant.components.waqi.const import CONF_STATION_NUMBER, DOMAIN
|
|
from homeassistant.config_entries import SOURCE_USER, ConfigSubentryData
|
|
from homeassistant.const import (
|
|
ATTR_LATITUDE,
|
|
ATTR_LOCATION,
|
|
ATTR_LONGITUDE,
|
|
CONF_API_KEY,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.data_entry_flow import FlowResultType
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
|
|
@pytest.fixture
|
|
def second_mock_config_entry() -> MockConfigEntry:
|
|
"""Mock config entry."""
|
|
return MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="WAQI",
|
|
data={CONF_API_KEY: "asdf"},
|
|
version=2,
|
|
subentries_data=[
|
|
ConfigSubentryData(
|
|
data={CONF_STATION_NUMBER: 4584},
|
|
subentry_id="ABCDEF",
|
|
subentry_type="station",
|
|
title="de Jongweg, Utrecht",
|
|
unique_id="4584",
|
|
)
|
|
],
|
|
)
|
|
|
|
|
|
async def test_full_flow(
|
|
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_waqi: AsyncMock
|
|
) -> None:
|
|
"""Test full flow."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "user"
|
|
assert not result["errors"]
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"], {CONF_API_KEY: "asd"}
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "World Air Quality Index"
|
|
assert result["data"] == {CONF_API_KEY: "asd"}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("exception", "error"),
|
|
[
|
|
(WAQIAuthenticationError("Test error"), "invalid_auth"),
|
|
(WAQIConnectionError("Test error"), "cannot_connect"),
|
|
(Exception("Test error"), "unknown"),
|
|
],
|
|
)
|
|
async def test_entry_errors(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
exception: Exception,
|
|
error: str,
|
|
) -> None:
|
|
"""Test full flow."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "user"
|
|
assert not result["errors"]
|
|
|
|
mock_waqi.get_by_ip.side_effect = exception
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"], {CONF_API_KEY: "asd"}
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["errors"] == {"base": error}
|
|
assert result["step_id"] == "user"
|
|
|
|
mock_waqi.get_by_ip.side_effect = None
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"], {CONF_API_KEY: "asd"}
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
|
|
|
|
async def test_duplicate_entry(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test duplicate entry handling."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "user"
|
|
assert not result["errors"]
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"], {CONF_API_KEY: "asd"}
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "already_configured"
|
|
|
|
|
|
async def test_full_map_flow(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test we get the form."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.subentries.async_init(
|
|
(mock_config_entry.entry_id, "station"),
|
|
context={"source": SOURCE_USER},
|
|
)
|
|
assert result["type"] is FlowResultType.MENU
|
|
assert result["step_id"] == "user"
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{"next_step_id": "map"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "map"
|
|
assert not result["errors"]
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
ATTR_LOCATION: {ATTR_LATITUDE: 50.0, ATTR_LONGITUDE: 10.0},
|
|
},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "de Jongweg, Utrecht"
|
|
assert result["data"] == {CONF_STATION_NUMBER: 4584}
|
|
assert list(mock_config_entry.subentries.values())[1].unique_id == "4584"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("exception", "error"),
|
|
[
|
|
(WAQIConnectionError("Test error"), "cannot_connect"),
|
|
(Exception("Test error"), "unknown"),
|
|
],
|
|
)
|
|
async def test_map_flow_errors(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
exception: Exception,
|
|
error: str,
|
|
) -> None:
|
|
"""Test we get the form."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.subentries.async_init(
|
|
(mock_config_entry.entry_id, "station"),
|
|
context={"source": SOURCE_USER},
|
|
)
|
|
assert result["type"] is FlowResultType.MENU
|
|
assert result["step_id"] == "user"
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{"next_step_id": "map"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "map"
|
|
assert not result["errors"]
|
|
|
|
mock_waqi.get_by_coordinates.side_effect = exception
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
ATTR_LOCATION: {ATTR_LATITUDE: 50.0, ATTR_LONGITUDE: 10.0},
|
|
},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "map"
|
|
assert result["errors"] == {"base": error}
|
|
|
|
mock_waqi.get_by_coordinates.side_effect = None
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
ATTR_LOCATION: {ATTR_LATITUDE: 50.0, ATTR_LONGITUDE: 10.0},
|
|
},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
|
|
|
|
async def test_map_duplicate(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
second_mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test duplicate location handling."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
second_mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.subentries.async_init(
|
|
(mock_config_entry.entry_id, "station"),
|
|
context={"source": SOURCE_USER},
|
|
)
|
|
assert result["type"] is FlowResultType.MENU
|
|
assert result["step_id"] == "user"
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{"next_step_id": "map"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "map"
|
|
assert not result["errors"]
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{
|
|
ATTR_LOCATION: {ATTR_LATITUDE: 50.0, ATTR_LONGITUDE: 10.0},
|
|
},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "already_configured"
|
|
|
|
|
|
async def test_full_station_number_flow(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test the station number flow."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.subentries.async_init(
|
|
(mock_config_entry.entry_id, "station"),
|
|
context={"source": SOURCE_USER},
|
|
)
|
|
assert result["type"] is FlowResultType.MENU
|
|
assert result["step_id"] == "user"
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{"next_step_id": "station_number"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "station_number"
|
|
assert not result["errors"]
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{CONF_STATION_NUMBER: 4584},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "de Jongweg, Utrecht"
|
|
assert result["data"] == {CONF_STATION_NUMBER: 4584}
|
|
assert list(mock_config_entry.subentries.values())[1].unique_id == "4584"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("exception", "error"),
|
|
[
|
|
(WAQIConnectionError("Test error"), "cannot_connect"),
|
|
(Exception("Test error"), "unknown"),
|
|
],
|
|
)
|
|
async def test_station_number_flow_errors(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
exception: Exception,
|
|
error: str,
|
|
) -> None:
|
|
"""Test we get the form."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.subentries.async_init(
|
|
(mock_config_entry.entry_id, "station"),
|
|
context={"source": SOURCE_USER},
|
|
)
|
|
assert result["type"] is FlowResultType.MENU
|
|
assert result["step_id"] == "user"
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{"next_step_id": "station_number"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "station_number"
|
|
assert not result["errors"]
|
|
|
|
mock_waqi.get_by_station_number.side_effect = exception
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{CONF_STATION_NUMBER: 4584},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "station_number"
|
|
assert result["errors"] == {"base": error}
|
|
|
|
mock_waqi.get_by_station_number.side_effect = None
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{CONF_STATION_NUMBER: 4584},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
|
|
|
|
async def test_station_number_duplicate(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_waqi: AsyncMock,
|
|
mock_config_entry: MockConfigEntry,
|
|
second_mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test duplicate station number handling."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
second_mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.subentries.async_init(
|
|
(mock_config_entry.entry_id, "station"),
|
|
context={"source": SOURCE_USER},
|
|
)
|
|
assert result["type"] is FlowResultType.MENU
|
|
assert result["step_id"] == "user"
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{"next_step_id": "station_number"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "station_number"
|
|
assert not result["errors"]
|
|
|
|
result = await hass.config_entries.subentries.async_configure(
|
|
result["flow_id"],
|
|
{CONF_STATION_NUMBER: 4584},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "already_configured"
|