IPMA Code quality improvement (#77771)
* merge upstream/dev * remove comment * coverage increase * merge upstream/dev * refactor * wait for another PR * remove left overs * wait for next PR * only remove on successful unload Co-authored-by: Shay Levy <levyshay1@gmail.com> Co-authored-by: Shay Levy <levyshay1@gmail.com>pull/79669/head^2
parent
e721d8ed02
commit
180b296426
|
@ -57,4 +57,11 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
|
||||
if not hass.data[DOMAIN]:
|
||||
hass.data.pop(DOMAIN)
|
||||
|
||||
return unload_ok
|
||||
|
|
|
@ -5,7 +5,7 @@ DOMAIN = "ipma"
|
|||
|
||||
HOME_LOCATION_NAME = "Home"
|
||||
|
||||
ENTITY_ID_SENSOR_FORMAT_HOME = f"{WEATHER_DOMAIN}.ipma_{HOME_LOCATION_NAME}"
|
||||
|
||||
DATA_LOCATION = "location"
|
||||
DATA_API = "api"
|
||||
DATA_LOCATION = "location"
|
||||
|
||||
ENTITY_ID_SENSOR_FORMAT_HOME = f"{WEATHER_DOMAIN}.ipma_{HOME_LOCATION_NAME}"
|
||||
|
|
|
@ -8,7 +8,6 @@ import async_timeout
|
|||
from pyipma.api import IPMA_API
|
||||
from pyipma.forecast import Forecast
|
||||
from pyipma.location import Location
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.weather import (
|
||||
ATTR_CONDITION_CLEAR_NIGHT,
|
||||
|
@ -33,13 +32,10 @@ from homeassistant.components.weather import (
|
|||
ATTR_FORECAST_PRECIPITATION_PROBABILITY,
|
||||
ATTR_FORECAST_TIME,
|
||||
ATTR_FORECAST_WIND_BEARING,
|
||||
PLATFORM_SCHEMA,
|
||||
WeatherEntity,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_LATITUDE,
|
||||
CONF_LONGITUDE,
|
||||
CONF_MODE,
|
||||
CONF_NAME,
|
||||
PRESSURE_HPA,
|
||||
|
@ -47,7 +43,7 @@ from homeassistant.const import (
|
|||
TEMP_CELSIUS,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import config_validation as cv, entity_registry
|
||||
from homeassistant.helpers import entity_registry
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.sun import is_up
|
||||
from homeassistant.util import Throttle
|
||||
|
@ -80,15 +76,6 @@ CONDITION_CLASSES = {
|
|||
|
||||
FORECAST_MODE = ["hourly", "daily"]
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Optional(CONF_NAME): cv.string,
|
||||
vol.Optional(CONF_LATITUDE): cv.latitude,
|
||||
vol.Optional(CONF_LONGITUDE): cv.longitude,
|
||||
vol.Optional(CONF_MODE, default="daily"): vol.In(FORECAST_MODE),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
|
|
|
@ -1 +1,111 @@
|
|||
"""Tests for the IPMA component."""
|
||||
from collections import namedtuple
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE, CONF_NAME
|
||||
|
||||
ENTRY_CONFIG = {
|
||||
CONF_NAME: "Home Town",
|
||||
CONF_LATITUDE: "1",
|
||||
CONF_LONGITUDE: "2",
|
||||
CONF_MODE: "hourly",
|
||||
}
|
||||
|
||||
|
||||
class MockLocation:
|
||||
"""Mock Location from pyipma."""
|
||||
|
||||
async def observation(self, api):
|
||||
"""Mock Observation."""
|
||||
Observation = namedtuple(
|
||||
"Observation",
|
||||
[
|
||||
"accumulated_precipitation",
|
||||
"humidity",
|
||||
"pressure",
|
||||
"radiation",
|
||||
"temperature",
|
||||
"wind_direction",
|
||||
"wind_intensity_km",
|
||||
],
|
||||
)
|
||||
|
||||
return Observation(0.0, 71.0, 1000.0, 0.0, 18.0, "NW", 3.94)
|
||||
|
||||
async def forecast(self, api, period):
|
||||
"""Mock Forecast."""
|
||||
Forecast = namedtuple(
|
||||
"Forecast",
|
||||
[
|
||||
"feels_like_temperature",
|
||||
"forecast_date",
|
||||
"forecasted_hours",
|
||||
"humidity",
|
||||
"max_temperature",
|
||||
"min_temperature",
|
||||
"precipitation_probability",
|
||||
"temperature",
|
||||
"update_date",
|
||||
"weather_type",
|
||||
"wind_direction",
|
||||
"wind_strength",
|
||||
],
|
||||
)
|
||||
|
||||
WeatherType = namedtuple("WeatherType", ["id", "en", "pt"])
|
||||
|
||||
if period == 24:
|
||||
return [
|
||||
Forecast(
|
||||
None,
|
||||
datetime(2020, 1, 16, 0, 0, 0),
|
||||
24,
|
||||
None,
|
||||
16.2,
|
||||
10.6,
|
||||
"100.0",
|
||||
13.4,
|
||||
"2020-01-15T07:51:00",
|
||||
WeatherType(9, "Rain/showers", "Chuva/aguaceiros"),
|
||||
"S",
|
||||
"10",
|
||||
),
|
||||
]
|
||||
if period == 1:
|
||||
return [
|
||||
Forecast(
|
||||
"7.7",
|
||||
datetime(2020, 1, 15, 1, 0, 0, tzinfo=timezone.utc),
|
||||
1,
|
||||
"86.9",
|
||||
12.0,
|
||||
None,
|
||||
80.0,
|
||||
10.6,
|
||||
"2020-01-15T02:51:00",
|
||||
WeatherType(10, "Light rain", "Chuva fraca ou chuvisco"),
|
||||
"S",
|
||||
"32.7",
|
||||
),
|
||||
Forecast(
|
||||
"5.7",
|
||||
datetime(2020, 1, 15, 2, 0, 0, tzinfo=timezone.utc),
|
||||
1,
|
||||
"86.9",
|
||||
12.0,
|
||||
None,
|
||||
80.0,
|
||||
10.6,
|
||||
"2020-01-15T02:51:00",
|
||||
WeatherType(1, "Clear sky", "C\u00e9u limpo"),
|
||||
"S",
|
||||
"32.7",
|
||||
),
|
||||
]
|
||||
|
||||
name = "HomeTown"
|
||||
station = "HomeTown Station"
|
||||
station_latitude = 0
|
||||
station_longitude = 0
|
||||
global_id_local = 1130600
|
||||
id_station = 1200545
|
||||
|
|
|
@ -3,21 +3,14 @@
|
|||
from unittest.mock import Mock, patch
|
||||
|
||||
from homeassistant.components.ipma import DOMAIN, config_flow
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE, CONF_NAME
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .test_weather import MockLocation
|
||||
from . import MockLocation
|
||||
|
||||
from tests.common import MockConfigEntry, mock_registry
|
||||
|
||||
ENTRY_CONFIG = {
|
||||
CONF_NAME: "Home Town",
|
||||
CONF_LATITUDE: "1",
|
||||
CONF_LONGITUDE: "2",
|
||||
CONF_MODE: "hourly",
|
||||
}
|
||||
|
||||
|
||||
async def test_show_config_form():
|
||||
"""Test show configuration form."""
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
"""Test the IPMA integration."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from pyipma import IPMAException
|
||||
|
||||
from homeassistant.components.ipma import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE
|
||||
|
||||
from .test_weather import MockLocation
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_async_setup_raises_entry_not_ready(hass):
|
||||
"""Test that it throws ConfigEntryNotReady when exception occurs during setup."""
|
||||
|
||||
with patch(
|
||||
"pyipma.location.Location.get", side_effect=IPMAException("API unavailable")
|
||||
):
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home",
|
||||
data={CONF_LATITUDE: 0, CONF_LONGITUDE: 0, CONF_MODE: "daily"},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
||||
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_unload_config_entry(hass):
|
||||
"""Test entry unloading."""
|
||||
|
||||
with patch(
|
||||
"pyipma.location.Location.get",
|
||||
return_value=MockLocation(),
|
||||
):
|
||||
config_entry = MockConfigEntry(
|
||||
domain="ipma",
|
||||
data={CONF_LATITUDE: 0, CONF_LONGITUDE: 0, CONF_MODE: "daily"},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.NOT_LOADED
|
|
@ -1,6 +1,5 @@
|
|||
"""The tests for the IPMA weather component."""
|
||||
from collections import namedtuple
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from freezegun import freeze_time
|
||||
|
@ -22,6 +21,8 @@ from homeassistant.components.weather import (
|
|||
)
|
||||
from homeassistant.const import STATE_UNKNOWN
|
||||
|
||||
from . import MockLocation
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
TEST_CONFIG = {
|
||||
|
@ -39,128 +40,6 @@ TEST_CONFIG_HOURLY = {
|
|||
}
|
||||
|
||||
|
||||
class MockLocation:
|
||||
"""Mock Location from pyipma."""
|
||||
|
||||
async def observation(self, api):
|
||||
"""Mock Observation."""
|
||||
Observation = namedtuple(
|
||||
"Observation",
|
||||
[
|
||||
"accumulated_precipitation",
|
||||
"humidity",
|
||||
"pressure",
|
||||
"radiation",
|
||||
"temperature",
|
||||
"wind_direction",
|
||||
"wind_intensity_km",
|
||||
],
|
||||
)
|
||||
|
||||
return Observation(0.0, 71.0, 1000.0, 0.0, 18.0, "NW", 3.94)
|
||||
|
||||
async def forecast(self, api, period):
|
||||
"""Mock Forecast."""
|
||||
Forecast = namedtuple(
|
||||
"Forecast",
|
||||
[
|
||||
"feels_like_temperature",
|
||||
"forecast_date",
|
||||
"forecasted_hours",
|
||||
"humidity",
|
||||
"max_temperature",
|
||||
"min_temperature",
|
||||
"precipitation_probability",
|
||||
"temperature",
|
||||
"update_date",
|
||||
"weather_type",
|
||||
"wind_direction",
|
||||
"wind_strength",
|
||||
],
|
||||
)
|
||||
|
||||
WeatherType = namedtuple("WeatherType", ["id", "en", "pt"])
|
||||
|
||||
if period == 24:
|
||||
return [
|
||||
Forecast(
|
||||
None,
|
||||
datetime(2020, 1, 16, 0, 0, 0),
|
||||
24,
|
||||
None,
|
||||
16.2,
|
||||
10.6,
|
||||
"100.0",
|
||||
13.4,
|
||||
"2020-01-15T07:51:00",
|
||||
WeatherType(9, "Rain/showers", "Chuva/aguaceiros"),
|
||||
"S",
|
||||
"10",
|
||||
),
|
||||
]
|
||||
if period == 1:
|
||||
return [
|
||||
Forecast(
|
||||
"7.7",
|
||||
datetime(2020, 1, 15, 1, 0, 0, tzinfo=timezone.utc),
|
||||
1,
|
||||
"86.9",
|
||||
12.0,
|
||||
None,
|
||||
80.0,
|
||||
10.6,
|
||||
"2020-01-15T02:51:00",
|
||||
WeatherType(10, "Light rain", "Chuva fraca ou chuvisco"),
|
||||
"S",
|
||||
"32.7",
|
||||
),
|
||||
Forecast(
|
||||
"5.7",
|
||||
datetime(2020, 1, 15, 2, 0, 0, tzinfo=timezone.utc),
|
||||
1,
|
||||
"86.9",
|
||||
12.0,
|
||||
None,
|
||||
80.0,
|
||||
10.6,
|
||||
"2020-01-15T02:51:00",
|
||||
WeatherType(1, "Clear sky", "C\u00e9u limpo"),
|
||||
"S",
|
||||
"32.7",
|
||||
),
|
||||
]
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Mock location."""
|
||||
return "HomeTown"
|
||||
|
||||
@property
|
||||
def station(self):
|
||||
"""Mock station."""
|
||||
return "HomeTown Station"
|
||||
|
||||
@property
|
||||
def station_latitude(self):
|
||||
"""Mock latitude."""
|
||||
return 0
|
||||
|
||||
@property
|
||||
def global_id_local(self):
|
||||
"""Mock global identifier of the location."""
|
||||
return 1130600
|
||||
|
||||
@property
|
||||
def id_station(self):
|
||||
"""Mock identifier of the station."""
|
||||
return 1200545
|
||||
|
||||
@property
|
||||
def station_longitude(self):
|
||||
"""Mock longitude."""
|
||||
return 0
|
||||
|
||||
|
||||
class MockBadLocation(MockLocation):
|
||||
"""Mock Location with unresponsive api."""
|
||||
|
||||
|
|
Loading…
Reference in New Issue