Add a new weather integration - Met Éireann (#39429)

* Added a new weather integration - Met Éireann

* Fix codespell error

* Update met_eireann to use CoordinatorEntity

* Remove deprecated platform setup

* Fix merge conflict

* Remove unnecessary onboarding/home tracking code

* Use common strings for config flow

* Remove unnecessary code

* Switch to using unique IDs in config flow

* Use constants where possible

* Fix failing tests

* Fix isort errors

* Remove unnecessary DataUpdateCoordinator class

* Add device info

* Explicitly define forecast data

* Disable hourly forecast entity by default

* Update config flow to reflect requested changes

* Cleanup code

* Update entity naming to match other similar components

* Convert forecast time to UTC

* Fix test coverage

* Update test coverage

* Remove elevation conversion

* Update translations for additional clarity

* Remove en-GB translation
This commit is contained in:
Dylan Gore
2021-04-05 22:23:57 +01:00
committed by GitHub
parent c28d4e8e01
commit f3399aa8aa
17 changed files with 696 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
"""Tests for Met Éireann."""
from unittest.mock import patch
from homeassistant.components.met_eireann.const import DOMAIN
from homeassistant.const import CONF_ELEVATION, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
from tests.common import MockConfigEntry
async def init_integration(hass) -> MockConfigEntry:
"""Set up the Met Éireann integration in Home Assistant."""
entry_data = {
CONF_NAME: "test",
CONF_LATITUDE: 0,
CONF_LONGITUDE: 0,
CONF_ELEVATION: 0,
}
entry = MockConfigEntry(domain=DOMAIN, data=entry_data)
with patch(
"homeassistant.components.met_eireann.meteireann.WeatherData.fetching_data",
return_value=True,
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
return entry

View File

@@ -0,0 +1,22 @@
"""Fixtures for Met Éireann weather testing."""
from unittest.mock import AsyncMock, patch
import pytest
@pytest.fixture
def mock_weather():
"""Mock weather data."""
with patch("meteireann.WeatherData") as mock_data:
mock_data = mock_data.return_value
mock_data.fetching_data = AsyncMock(return_value=True)
mock_data.get_current_weather.return_value = {
"condition": "Cloud",
"temperature": 15,
"pressure": 100,
"humidity": 50,
"wind_speed": 10,
"wind_bearing": "NE",
}
mock_data.get_forecast.return_value = {}
yield mock_data

View File

@@ -0,0 +1,95 @@
"""Tests for Met Éireann config flow."""
from unittest.mock import patch
import pytest
from homeassistant import config_entries, data_entry_flow
from homeassistant.components.met_eireann.const import DOMAIN, HOME_LOCATION_NAME
from homeassistant.const import CONF_ELEVATION, CONF_LATITUDE, CONF_LONGITUDE
@pytest.fixture(name="met_eireann_setup", autouse=True)
def met_setup_fixture():
"""Patch Met Éireann setup entry."""
with patch(
"homeassistant.components.met_eireann.async_setup_entry", return_value=True
):
yield
async def test_show_config_form(hass):
"""Test show configuration form."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["step_id"] == config_entries.SOURCE_USER
async def test_flow_with_home_location(hass):
"""Test config flow.
Test the flow when a default location is configured.
Then it should return a form with default values.
"""
hass.config.latitude = 1
hass.config.longitude = 2
hass.config.elevation = 3
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["step_id"] == config_entries.SOURCE_USER
default_data = result["data_schema"]({})
assert default_data["name"] == HOME_LOCATION_NAME
assert default_data["latitude"] == 1
assert default_data["longitude"] == 2
assert default_data["elevation"] == 3
async def test_create_entry(hass):
"""Test create entry from user input."""
test_data = {
"name": "test",
CONF_LONGITUDE: 0,
CONF_LATITUDE: 0,
CONF_ELEVATION: 0,
}
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=test_data
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == test_data.get("name")
assert result["data"] == test_data
async def test_flow_entry_already_exists(hass):
"""Test user input for config_entry that already exists.
Test to ensure the config form does not allow duplicate entries.
"""
test_data = {
"name": "test",
CONF_LONGITUDE: 0,
CONF_LATITUDE: 0,
CONF_ELEVATION: 0,
}
# Create the first entry and assert that it is created successfully
result1 = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=test_data
)
assert result1["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
# Create the second entry and assert that it is aborted
result2 = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=test_data
)
assert result2["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result2["reason"] == "already_configured"

View File

@@ -0,0 +1,19 @@
"""Test the Met Éireann integration init."""
from homeassistant.components.met_eireann.const import DOMAIN
from homeassistant.config_entries import ENTRY_STATE_LOADED, ENTRY_STATE_NOT_LOADED
from . import init_integration
async def test_unload_entry(hass):
"""Test successful unload of entry."""
entry = await init_integration(hass)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert entry.state == ENTRY_STATE_LOADED
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
assert entry.state == ENTRY_STATE_NOT_LOADED
assert not hass.data.get(DOMAIN)

View File

@@ -0,0 +1,31 @@
"""Test Met Éireann weather entity."""
from homeassistant.components.met_eireann.const import DOMAIN
from tests.common import MockConfigEntry
async def test_weather(hass, mock_weather):
"""Test weather entity."""
# Create a mock configuration for testing
mock_data = MockConfigEntry(
domain=DOMAIN,
data={"name": "Somewhere", "latitude": 10, "longitude": 20, "elevation": 0},
)
mock_data.add_to_hass(hass)
await hass.config_entries.async_setup(mock_data.entry_id)
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids("weather")) == 1
assert len(mock_weather.mock_calls) == 4
# Test we do not track config
await hass.config.async_update(latitude=10, longitude=20)
await hass.async_block_till_done()
assert len(mock_weather.mock_calls) == 4
entry = hass.config_entries.async_entries()[0]
await hass.config_entries.async_remove(entry.entry_id)
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids("weather")) == 0