core/tests/components/openweathermap/test_config_flow.py

214 lines
6.7 KiB
Python

"""Define tests for the OpenWeatherMap config flow."""
from unittest.mock import MagicMock, patch
from pyowm.commons.exceptions import APIRequestError, UnauthorizedError
from homeassistant import data_entry_flow
from homeassistant.components.openweathermap.const import (
CONF_LANGUAGE,
DEFAULT_FORECAST_MODE,
DEFAULT_LANGUAGE,
DOMAIN,
)
from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
from homeassistant.const import (
CONF_API_KEY,
CONF_LATITUDE,
CONF_LONGITUDE,
CONF_MODE,
CONF_NAME,
)
from tests.common import MockConfigEntry
CONFIG = {
CONF_NAME: "openweathermap",
CONF_API_KEY: "foo",
CONF_LATITUDE: 50,
CONF_LONGITUDE: 40,
CONF_MODE: DEFAULT_FORECAST_MODE,
CONF_LANGUAGE: DEFAULT_LANGUAGE,
}
VALID_YAML_CONFIG = {CONF_API_KEY: "foo"}
async def test_form(hass):
"""Test that the form is served with valid input."""
mocked_owm = _create_mocked_owm(True)
with patch(
"pyowm.weatherapi25.weather_manager.WeatherManager",
return_value=mocked_owm,
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == SOURCE_USER
assert result["errors"] == {}
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
)
await hass.async_block_till_done()
conf_entries = hass.config_entries.async_entries(DOMAIN)
entry = conf_entries[0]
assert entry.state == ConfigEntryState.LOADED
await hass.config_entries.async_unload(conf_entries[0].entry_id)
await hass.async_block_till_done()
assert entry.state == ConfigEntryState.NOT_LOADED
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == CONFIG[CONF_NAME]
assert result["data"][CONF_LATITUDE] == CONFIG[CONF_LATITUDE]
assert result["data"][CONF_LONGITUDE] == CONFIG[CONF_LONGITUDE]
assert result["data"][CONF_API_KEY] == CONFIG[CONF_API_KEY]
async def test_form_options(hass):
"""Test that the options form."""
mocked_owm = _create_mocked_owm(True)
with patch(
"pyowm.weatherapi25.weather_manager.WeatherManager",
return_value=mocked_owm,
):
config_entry = MockConfigEntry(
domain=DOMAIN, unique_id="openweathermap_unique_id", data=CONFIG
)
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state == ConfigEntryState.LOADED
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input={CONF_MODE: "daily"}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {
CONF_MODE: "daily",
CONF_LANGUAGE: DEFAULT_LANGUAGE,
}
await hass.async_block_till_done()
assert config_entry.state == ConfigEntryState.LOADED
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"
result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input={CONF_MODE: "onecall_daily"}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {
CONF_MODE: "onecall_daily",
CONF_LANGUAGE: DEFAULT_LANGUAGE,
}
await hass.async_block_till_done()
assert config_entry.state == ConfigEntryState.LOADED
async def test_form_invalid_api_key(hass):
"""Test that the form is served with no input."""
mocked_owm = _create_mocked_owm(True)
with patch(
"pyowm.weatherapi25.weather_manager.WeatherManager",
return_value=mocked_owm,
side_effect=UnauthorizedError(""),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
)
assert result["errors"] == {"base": "invalid_api_key"}
async def test_form_api_call_error(hass):
"""Test setting up with api call error."""
mocked_owm = _create_mocked_owm(True)
with patch(
"pyowm.weatherapi25.weather_manager.WeatherManager",
return_value=mocked_owm,
side_effect=APIRequestError(""),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
)
assert result["errors"] == {"base": "cannot_connect"}
async def test_form_api_offline(hass):
"""Test setting up with api call error."""
mocked_owm = _create_mocked_owm(False)
with patch(
"homeassistant.components.openweathermap.config_flow.OWM",
return_value=mocked_owm,
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
)
assert result["errors"] == {"base": "invalid_api_key"}
def _create_mocked_owm(is_api_online: bool):
mocked_owm = MagicMock()
weather = MagicMock()
weather.temperature.return_value.get.return_value = 10
weather.pressure.get.return_value = 10
weather.humidity.return_value = 10
weather.wind.return_value.get.return_value = 0
weather.clouds.return_value = "clouds"
weather.rain.return_value = []
weather.snow.return_value = []
weather.detailed_status.return_value = "status"
weather.weather_code = 803
weather.dewpoint = 10
mocked_owm.weather_at_coords.return_value.weather = weather
one_day_forecast = MagicMock()
one_day_forecast.reference_time.return_value = 10
one_day_forecast.temperature.return_value.get.return_value = 10
one_day_forecast.rain.return_value.get.return_value = 0
one_day_forecast.snow.return_value.get.return_value = 0
one_day_forecast.wind.return_value.get.return_value = 0
one_day_forecast.weather_code = 803
mocked_owm.forecast_at_coords.return_value.forecast.weathers = [one_day_forecast]
one_call = MagicMock()
one_call.current = weather
one_call.forecast_hourly = [one_day_forecast]
one_call.forecast_daily = [one_day_forecast]
mocked_owm.one_call.return_value = one_call
mocked_owm.weather_manager.return_value.one_call.return_value = is_api_online
return mocked_owm