mirror of
https://github.com/home-assistant/core
synced 2024-10-05 19:57:25 +00:00
Renovate Airvisual tests (#84892)
* Renovate AirVisual tests * Cleanup * Package scope * Update tests/components/airvisual/test_config_flow.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
9c88dea584
commit
6e9d3bf8e9
|
@ -132,15 +132,14 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
LOGGER.error(err)
|
||||
errors["base"] = "unknown"
|
||||
|
||||
if errors:
|
||||
return self.async_show_form(
|
||||
step_id=error_step, data_schema=error_schema, errors=errors
|
||||
)
|
||||
|
||||
valid_keys.add(user_input[CONF_API_KEY])
|
||||
|
||||
if errors:
|
||||
return self.async_show_form(
|
||||
step_id=error_step, data_schema=error_schema, errors=errors
|
||||
)
|
||||
|
||||
existing_entry = await self.async_set_unique_id(self._geo_id)
|
||||
if existing_entry:
|
||||
if existing_entry := await self.async_set_unique_id(self._geo_id):
|
||||
self.hass.config_entries.async_update_entry(existing_entry, data=user_input)
|
||||
self.hass.async_create_task(
|
||||
self.hass.config_entries.async_reload(existing_entry.entry_id)
|
||||
|
|
|
@ -4,29 +4,64 @@ from unittest.mock import AsyncMock, Mock, patch
|
|||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.airvisual.const import (
|
||||
from homeassistant.components.airvisual import (
|
||||
CONF_CITY,
|
||||
CONF_INTEGRATION_TYPE,
|
||||
DOMAIN,
|
||||
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
|
||||
)
|
||||
from homeassistant.components.airvisual.config_flow import async_get_geography_id
|
||||
from homeassistant.const import (
|
||||
CONF_API_KEY,
|
||||
CONF_COUNTRY,
|
||||
CONF_LATITUDE,
|
||||
CONF_LONGITUDE,
|
||||
CONF_SHOW_ON_MAP,
|
||||
CONF_STATE,
|
||||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
||||
TEST_API_KEY = "abcde12345"
|
||||
TEST_LATITUDE = 51.528308
|
||||
TEST_LONGITUDE = -0.3817765
|
||||
|
||||
COORDS_CONFIG = {
|
||||
CONF_API_KEY: TEST_API_KEY,
|
||||
CONF_LATITUDE: TEST_LATITUDE,
|
||||
CONF_LONGITUDE: TEST_LONGITUDE,
|
||||
}
|
||||
|
||||
TEST_CITY = "Beijing"
|
||||
TEST_STATE = "Beijing"
|
||||
TEST_COUNTRY = "China"
|
||||
|
||||
NAME_CONFIG = {
|
||||
CONF_API_KEY: TEST_API_KEY,
|
||||
CONF_CITY: TEST_CITY,
|
||||
CONF_STATE: TEST_STATE,
|
||||
CONF_COUNTRY: TEST_COUNTRY,
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(name="cloud_api")
|
||||
def cloud_api_fixture(data_cloud):
|
||||
"""Define a mock CloudAPI object."""
|
||||
return Mock(
|
||||
air_quality=Mock(
|
||||
city=AsyncMock(return_value=data_cloud),
|
||||
nearest_city=AsyncMock(return_value=data_cloud),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="config_entry")
|
||||
def config_entry_fixture(hass, config, config_entry_version, unique_id):
|
||||
def config_entry_fixture(hass, config, config_entry_version, integration_type):
|
||||
"""Define a config entry fixture."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=unique_id,
|
||||
data={CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_COORDS, **config},
|
||||
unique_id=async_get_geography_id(config),
|
||||
data={**config, CONF_INTEGRATION_TYPE: integration_type},
|
||||
options={CONF_SHOW_ON_MAP: True},
|
||||
version=config_entry_version,
|
||||
)
|
||||
|
@ -41,49 +76,61 @@ def config_entry_version_fixture():
|
|||
|
||||
|
||||
@pytest.fixture(name="config")
|
||||
def config_fixture(hass):
|
||||
def config_fixture():
|
||||
"""Define a config entry data fixture."""
|
||||
return {
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_LATITUDE: 51.528308,
|
||||
CONF_LONGITUDE: -0.3817765,
|
||||
}
|
||||
return COORDS_CONFIG
|
||||
|
||||
|
||||
@pytest.fixture(name="data", scope="package")
|
||||
def data_fixture():
|
||||
@pytest.fixture(name="data_cloud", scope="package")
|
||||
def data_cloud_fixture():
|
||||
"""Define an update coordinator data example."""
|
||||
return json.loads(load_fixture("data.json", "airvisual"))
|
||||
|
||||
|
||||
@pytest.fixture(name="pro_data", scope="session")
|
||||
def pro_data_fixture():
|
||||
@pytest.fixture(name="data_pro", scope="package")
|
||||
def data_pro_fixture():
|
||||
"""Define an update coordinator data example for the Pro."""
|
||||
return json.loads(load_fixture("data.json", "airvisual_pro"))
|
||||
|
||||
|
||||
@pytest.fixture(name="pro")
|
||||
def pro_fixture(pro_data):
|
||||
"""Define a mocked NodeSamba object."""
|
||||
return Mock(
|
||||
async_connect=AsyncMock(),
|
||||
async_disconnect=AsyncMock(),
|
||||
async_get_latest_measurements=AsyncMock(return_value=pro_data),
|
||||
)
|
||||
@pytest.fixture(name="integration_type")
|
||||
def integration_type_fixture():
|
||||
"""Define an integration type."""
|
||||
return INTEGRATION_TYPE_GEOGRAPHY_COORDS
|
||||
|
||||
|
||||
@pytest.fixture(name="setup_airvisual")
|
||||
async def setup_airvisual_fixture(hass, config, data):
|
||||
"""Define a fixture to set up AirVisual."""
|
||||
with patch("pyairvisual.air_quality.AirQuality.city"), patch(
|
||||
"pyairvisual.air_quality.AirQuality.nearest_city", return_value=data
|
||||
@pytest.fixture(name="mock_pyairvisual")
|
||||
async def mock_pyairvisual_fixture(cloud_api, node_samba):
|
||||
"""Define a fixture to patch pyairvisual."""
|
||||
with patch(
|
||||
"homeassistant.components.airvisual.CloudAPI",
|
||||
return_value=cloud_api,
|
||||
), patch(
|
||||
"homeassistant.components.airvisual.config_flow.CloudAPI",
|
||||
return_value=cloud_api,
|
||||
), patch(
|
||||
"homeassistant.components.airvisual_pro.NodeSamba",
|
||||
return_value=node_samba,
|
||||
), patch(
|
||||
"homeassistant.components.airvisual_pro.config_flow.NodeSamba",
|
||||
return_value=node_samba,
|
||||
):
|
||||
assert await async_setup_component(hass, DOMAIN, config)
|
||||
await hass.async_block_till_done()
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(name="unique_id")
|
||||
def unique_id_fixture(hass):
|
||||
"""Define a config entry unique ID fixture."""
|
||||
return "51.528308, -0.3817765"
|
||||
@pytest.fixture(name="node_samba")
|
||||
def node_samba_fixture(data_pro):
|
||||
"""Define a mock NodeSamba object."""
|
||||
return Mock(
|
||||
async_connect=AsyncMock(),
|
||||
async_disconnect=AsyncMock(),
|
||||
async_get_latest_measurements=AsyncMock(return_value=data_pro),
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="setup_config_entry")
|
||||
async def setup_config_entry_fixture(hass, config_entry, mock_pyairvisual):
|
||||
"""Define a fixture to set up airvisual."""
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
yield
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Define tests for the AirVisual config flow."""
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from pyairvisual.cloud_api import (
|
||||
InvalidKeyError,
|
||||
|
@ -13,307 +13,101 @@ import pytest
|
|||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components.airvisual import (
|
||||
CONF_CITY,
|
||||
CONF_COUNTRY,
|
||||
CONF_GEOGRAPHIES,
|
||||
CONF_INTEGRATION_TYPE,
|
||||
DOMAIN,
|
||||
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
|
||||
INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
INTEGRATION_TYPE_NODE_PRO,
|
||||
)
|
||||
from homeassistant.components.airvisual_pro import DOMAIN as AIRVISUAL_PRO_DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_USER
|
||||
from homeassistant.const import (
|
||||
CONF_API_KEY,
|
||||
CONF_IP_ADDRESS,
|
||||
CONF_LATITUDE,
|
||||
CONF_LONGITUDE,
|
||||
CONF_PASSWORD,
|
||||
CONF_SHOW_ON_MAP,
|
||||
CONF_STATE,
|
||||
from homeassistant.const import CONF_API_KEY, CONF_SHOW_ON_MAP
|
||||
|
||||
from .conftest import (
|
||||
COORDS_CONFIG,
|
||||
NAME_CONFIG,
|
||||
TEST_CITY,
|
||||
TEST_COUNTRY,
|
||||
TEST_LATITUDE,
|
||||
TEST_LONGITUDE,
|
||||
TEST_STATE,
|
||||
)
|
||||
from homeassistant.helpers import device_registry as dr, issue_registry as ir
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_duplicate_error(hass, config, config_entry, data, setup_airvisual):
|
||||
"""Test that errors are shown when duplicate entries are added."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={"type": INTEGRATION_TYPE_GEOGRAPHY_COORDS},
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=config
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"data,exc,errors,integration_type",
|
||||
"integration_type,input_form_step,patched_method,config,entry_title",
|
||||
[
|
||||
(
|
||||
{
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
},
|
||||
InvalidKeyError,
|
||||
{CONF_API_KEY: "invalid_api_key"},
|
||||
INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
|
||||
"geography_by_coords",
|
||||
"nearest_city",
|
||||
COORDS_CONFIG,
|
||||
f"Cloud API ({TEST_LATITUDE}, {TEST_LONGITUDE})",
|
||||
),
|
||||
(
|
||||
{
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
},
|
||||
KeyExpiredError,
|
||||
{CONF_API_KEY: "invalid_api_key"},
|
||||
INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
),
|
||||
(
|
||||
{
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
},
|
||||
UnauthorizedError,
|
||||
{CONF_API_KEY: "invalid_api_key"},
|
||||
INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
),
|
||||
(
|
||||
{
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
},
|
||||
NotFoundError,
|
||||
{CONF_CITY: "location_not_found"},
|
||||
INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
),
|
||||
(
|
||||
{
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
},
|
||||
AirVisualError,
|
||||
{"base": "unknown"},
|
||||
INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
"geography_by_name",
|
||||
"city",
|
||||
NAME_CONFIG,
|
||||
f"Cloud API ({TEST_CITY}, {TEST_STATE}, {TEST_COUNTRY})",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_errors(hass, data, exc, errors, integration_type):
|
||||
"""Test that an exceptions show an error."""
|
||||
with patch("pyairvisual.air_quality.AirQuality.city", side_effect=exc):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}, data={"type": integration_type}
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"response,errors",
|
||||
[
|
||||
(AsyncMock(side_effect=AirVisualError), {"base": "unknown"}),
|
||||
(AsyncMock(side_effect=InvalidKeyError), {CONF_API_KEY: "invalid_api_key"}),
|
||||
(AsyncMock(side_effect=KeyExpiredError), {CONF_API_KEY: "invalid_api_key"}),
|
||||
(AsyncMock(side_effect=NotFoundError), {CONF_CITY: "location_not_found"}),
|
||||
(AsyncMock(side_effect=UnauthorizedError), {CONF_API_KEY: "invalid_api_key"}),
|
||||
],
|
||||
)
|
||||
async def test_create_entry(
|
||||
hass,
|
||||
cloud_api,
|
||||
config,
|
||||
entry_title,
|
||||
errors,
|
||||
input_form_step,
|
||||
integration_type,
|
||||
mock_pyairvisual,
|
||||
patched_method,
|
||||
response,
|
||||
):
|
||||
"""Test creating a config entry."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}, data={"type": integration_type}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == input_form_step
|
||||
|
||||
# Test errors that can arise:
|
||||
with patch.object(cloud_api.air_quality, patched_method, response):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=data
|
||||
result["flow_id"], user_input=config
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["errors"] == errors
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config,config_entry_version,unique_id",
|
||||
[
|
||||
(
|
||||
{
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_GEOGRAPHIES: [
|
||||
{CONF_LATITUDE: 51.528308, CONF_LONGITUDE: -0.3817765},
|
||||
{
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
},
|
||||
],
|
||||
},
|
||||
1,
|
||||
"abcde12345",
|
||||
)
|
||||
],
|
||||
)
|
||||
async def test_migration_1_2(hass, config, config_entry, setup_airvisual, unique_id):
|
||||
"""Test migrating from version 1 to 2."""
|
||||
config_entries = hass.config_entries.async_entries(DOMAIN)
|
||||
assert len(config_entries) == 2
|
||||
|
||||
assert config_entries[0].unique_id == "51.528308, -0.3817765"
|
||||
assert config_entries[0].title == "Cloud API (51.528308, -0.3817765)"
|
||||
assert config_entries[0].data == {
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_LATITUDE: 51.528308,
|
||||
CONF_LONGITUDE: -0.3817765,
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_COORDS,
|
||||
}
|
||||
|
||||
assert config_entries[1].unique_id == "Beijing, Beijing, China"
|
||||
assert config_entries[1].title == "Cloud API (Beijing, Beijing, China)"
|
||||
assert config_entries[1].data == {
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
}
|
||||
|
||||
|
||||
async def test_migration_2_3(hass, pro):
|
||||
"""Test migrating from version 2 to 3."""
|
||||
old_pro_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="192.168.1.100",
|
||||
data={
|
||||
CONF_IP_ADDRESS: "192.168.1.100",
|
||||
CONF_PASSWORD: "abcde12345",
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_NODE_PRO,
|
||||
},
|
||||
version=2,
|
||||
)
|
||||
old_pro_entry.add_to_hass(hass)
|
||||
|
||||
device_registry = dr.async_get(hass)
|
||||
device_registry.async_get_or_create(
|
||||
name="192.168.1.100",
|
||||
config_entry_id=old_pro_entry.entry_id,
|
||||
identifiers={(DOMAIN, "ABCDE12345")},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.airvisual.automation.automations_with_device",
|
||||
return_value=["automation.test_automation"],
|
||||
), patch(
|
||||
"homeassistant.components.airvisual_pro.NodeSamba", return_value=pro
|
||||
), patch(
|
||||
"homeassistant.components.airvisual_pro.config_flow.NodeSamba", return_value=pro
|
||||
):
|
||||
await hass.config_entries.async_setup(old_pro_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
for domain, entry_count in ((DOMAIN, 0), (AIRVISUAL_PRO_DOMAIN, 1)):
|
||||
entries = hass.config_entries.async_entries(domain)
|
||||
assert len(entries) == entry_count
|
||||
|
||||
issue_registry = ir.async_get(hass)
|
||||
assert len(issue_registry.issues) == 1
|
||||
|
||||
|
||||
async def test_options_flow(hass, config_entry):
|
||||
"""Test config flow options."""
|
||||
with patch(
|
||||
"homeassistant.components.airvisual.async_setup_entry", return_value=True
|
||||
):
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={CONF_SHOW_ON_MAP: False}
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||
assert config_entry.options == {CONF_SHOW_ON_MAP: False}
|
||||
|
||||
|
||||
async def test_step_geography_by_coords(hass, config, setup_airvisual):
|
||||
"""Test setting up a geography entry by latitude/longitude."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={"type": INTEGRATION_TYPE_GEOGRAPHY_COORDS},
|
||||
)
|
||||
# Test that we can recover and finish the flow after errors occur:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=config
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "Cloud API (51.528308, -0.3817765)"
|
||||
assert result["data"] == {
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_LATITUDE: 51.528308,
|
||||
CONF_LONGITUDE: -0.3817765,
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_COORDS,
|
||||
}
|
||||
assert result["title"] == entry_title
|
||||
assert result["data"] == {**config, CONF_INTEGRATION_TYPE: integration_type}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config",
|
||||
[
|
||||
{
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
}
|
||||
],
|
||||
)
|
||||
async def test_step_geography_by_name(hass, config, setup_airvisual):
|
||||
"""Test setting up a geography entry by city/state/country."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={"type": INTEGRATION_TYPE_GEOGRAPHY_NAME},
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=config
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "Cloud API (Beijing, Beijing, China)"
|
||||
assert result["data"] == {
|
||||
CONF_API_KEY: "abcde12345",
|
||||
CONF_CITY: "Beijing",
|
||||
CONF_STATE: "Beijing",
|
||||
CONF_COUNTRY: "China",
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
}
|
||||
|
||||
|
||||
async def test_step_reauth(hass, config_entry, setup_airvisual):
|
||||
"""Test that the reauth step works."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_REAUTH}, data=config_entry.data
|
||||
)
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
new_api_key = "defgh67890"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.airvisual.async_setup_entry", return_value=True
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={CONF_API_KEY: new_api_key}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
||||
assert result["reason"] == "reauth_successful"
|
||||
|
||||
assert len(hass.config_entries.async_entries()) == 1
|
||||
assert hass.config_entries.async_entries()[0].data[CONF_API_KEY] == new_api_key
|
||||
|
||||
|
||||
async def test_step_user(hass):
|
||||
"""Test the user ("pick the integration type") step."""
|
||||
async def test_duplicate_error(hass, config, setup_config_entry):
|
||||
"""Test that errors are shown when duplicate entries are added."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
|
@ -322,15 +116,48 @@ async def test_step_user(hass):
|
|||
context={"source": SOURCE_USER},
|
||||
data={"type": INTEGRATION_TYPE_GEOGRAPHY_COORDS},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "geography_by_coords"
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={"type": INTEGRATION_TYPE_GEOGRAPHY_NAME},
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=config
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
async def test_options_flow(hass, config_entry, setup_config_entry):
|
||||
"""Test config flow options."""
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "geography_by_name"
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={CONF_SHOW_ON_MAP: False}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||
assert config_entry.options == {CONF_SHOW_ON_MAP: False}
|
||||
|
||||
|
||||
async def test_step_reauth(hass, config_entry, setup_config_entry):
|
||||
"""Test that the reauth step works."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_REAUTH}, data=config_entry.data
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
new_api_key = "defgh67890"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={CONF_API_KEY: new_api_key}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.ABORT
|
||||
assert result["reason"] == "reauth_successful"
|
||||
|
||||
assert len(hass.config_entries.async_entries()) == 1
|
||||
assert hass.config_entries.async_entries()[0].data[CONF_API_KEY] == new_api_key
|
||||
|
|
|
@ -4,7 +4,7 @@ from homeassistant.components.diagnostics import REDACTED
|
|||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
|
||||
|
||||
async def test_entry_diagnostics(hass, config_entry, hass_client, setup_airvisual):
|
||||
async def test_entry_diagnostics(hass, config_entry, hass_client, setup_config_entry):
|
||||
"""Test config entry diagnostics."""
|
||||
assert await get_diagnostics_for_config_entry(hass, hass_client, config_entry) == {
|
||||
"entry": {
|
||||
|
|
120
tests/components/airvisual/test_init.py
Normal file
120
tests/components/airvisual/test_init.py
Normal file
|
@ -0,0 +1,120 @@
|
|||
"""Define tests for AirVisual init."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components.airvisual import (
|
||||
CONF_CITY,
|
||||
CONF_GEOGRAPHIES,
|
||||
CONF_INTEGRATION_TYPE,
|
||||
DOMAIN,
|
||||
INTEGRATION_TYPE_GEOGRAPHY_COORDS,
|
||||
INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
INTEGRATION_TYPE_NODE_PRO,
|
||||
)
|
||||
from homeassistant.components.airvisual_pro import DOMAIN as AIRVISUAL_PRO_DOMAIN
|
||||
from homeassistant.const import (
|
||||
CONF_API_KEY,
|
||||
CONF_COUNTRY,
|
||||
CONF_IP_ADDRESS,
|
||||
CONF_LATITUDE,
|
||||
CONF_LONGITUDE,
|
||||
CONF_PASSWORD,
|
||||
CONF_STATE,
|
||||
)
|
||||
from homeassistant.helpers import device_registry as dr, issue_registry as ir
|
||||
|
||||
from .conftest import (
|
||||
COORDS_CONFIG,
|
||||
NAME_CONFIG,
|
||||
TEST_API_KEY,
|
||||
TEST_CITY,
|
||||
TEST_COUNTRY,
|
||||
TEST_LATITUDE,
|
||||
TEST_LONGITUDE,
|
||||
TEST_STATE,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_migration_1_2(hass, mock_pyairvisual):
|
||||
"""Test migrating from version 1 to 2."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=TEST_API_KEY,
|
||||
data={
|
||||
CONF_API_KEY: TEST_API_KEY,
|
||||
CONF_GEOGRAPHIES: [
|
||||
{
|
||||
CONF_LATITUDE: TEST_LATITUDE,
|
||||
CONF_LONGITUDE: TEST_LONGITUDE,
|
||||
},
|
||||
{
|
||||
CONF_CITY: TEST_CITY,
|
||||
CONF_STATE: TEST_STATE,
|
||||
CONF_COUNTRY: TEST_COUNTRY,
|
||||
},
|
||||
],
|
||||
},
|
||||
version=1,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
config_entries = hass.config_entries.async_entries(DOMAIN)
|
||||
assert len(config_entries) == 2
|
||||
|
||||
# Ensure that after migration, each configuration has its own config entry:
|
||||
identifier1 = f"{TEST_LATITUDE}, {TEST_LONGITUDE}"
|
||||
assert config_entries[0].unique_id == identifier1
|
||||
assert config_entries[0].title == f"Cloud API ({identifier1})"
|
||||
assert config_entries[0].data == {
|
||||
**COORDS_CONFIG,
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_COORDS,
|
||||
}
|
||||
|
||||
identifier2 = f"{TEST_CITY}, {TEST_STATE}, {TEST_COUNTRY}"
|
||||
assert config_entries[1].unique_id == identifier2
|
||||
assert config_entries[1].title == f"Cloud API ({identifier2})"
|
||||
assert config_entries[1].data == {
|
||||
**NAME_CONFIG,
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_GEOGRAPHY_NAME,
|
||||
}
|
||||
|
||||
|
||||
async def test_migration_2_3(hass, mock_pyairvisual):
|
||||
"""Test migrating from version 2 to 3."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="192.168.1.100",
|
||||
data={
|
||||
CONF_IP_ADDRESS: "192.168.1.100",
|
||||
CONF_PASSWORD: "abcde12345",
|
||||
CONF_INTEGRATION_TYPE: INTEGRATION_TYPE_NODE_PRO,
|
||||
},
|
||||
version=2,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
device_registry = dr.async_get(hass)
|
||||
device_registry.async_get_or_create(
|
||||
name="192.168.1.100",
|
||||
config_entry_id=entry.entry_id,
|
||||
identifiers={(DOMAIN, "SERIAL_NUMBER")},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.airvisual.automation.automations_with_device",
|
||||
return_value=["automation.test_automation"],
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Ensure that after migration, the AirVisual Pro device has been moved to the
|
||||
# `airvisual_pro` domain and an issue has been created:
|
||||
for domain, entry_count in ((DOMAIN, 0), (AIRVISUAL_PRO_DOMAIN, 1)):
|
||||
assert len(hass.config_entries.async_entries(domain)) == entry_count
|
||||
|
||||
issue_registry = ir.async_get(hass)
|
||||
assert len(issue_registry.issues) == 1
|
Loading…
Reference in a new issue