Move AirNow test fixtures to conftest.py (#79902)

* Move AirNow test fixtures to `conftest.py`

* Unnecessary fixture

* Better

* Linting
This commit is contained in:
Aaron Bach 2022-10-08 16:32:51 -06:00 committed by GitHub
parent 6297a28507
commit 8471a71b60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 124 additions and 127 deletions

View File

@ -0,0 +1,57 @@
"""Define fixtures for AirNow tests."""
import json
from unittest.mock import AsyncMock, patch
import pytest
from homeassistant.components.airnow import DOMAIN
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry, load_fixture
@pytest.fixture(name="config_entry")
def config_entry_fixture(hass, config):
"""Define a config entry fixture."""
entry = MockConfigEntry(
domain=DOMAIN,
unique_id=f"{config[CONF_LATITUDE]}-{config[CONF_LONGITUDE]}",
data=config,
)
entry.add_to_hass(hass)
return entry
@pytest.fixture(name="config")
def config_fixture(hass):
"""Define a config entry data fixture."""
return {
CONF_API_KEY: "abc123",
CONF_LATITUDE: 34.053718,
CONF_LONGITUDE: -118.244842,
CONF_RADIUS: 75,
}
@pytest.fixture(name="data", scope="session")
def data_fixture():
"""Define a fixture for response data."""
return json.loads(load_fixture("response.json", "airnow"))
@pytest.fixture(name="mock_api_get")
def mock_api_get_fixture(data):
"""Define a fixture for a mock "get" coroutine function."""
return AsyncMock(return_value=data)
@pytest.fixture(name="setup_airnow")
async def setup_airnow_fixture(hass, config, mock_api_get):
"""Define a fixture to set up AirNow."""
with patch("pyairnow.WebServiceAPI._get", mock_api_get), patch(
"homeassistant.components.airnow.config_flow.WebServiceAPI._get", mock_api_get
), patch("homeassistant.components.airnow.PLATFORMS", []):
assert await async_setup_component(hass, DOMAIN, config)
await hass.async_block_till_done()
yield

View File

@ -0,0 +1 @@
"""Define AirNow response fixture data."""

View File

@ -0,0 +1,47 @@
[
{
"DateObserved": "2020-12-20",
"HourObserved": 15,
"LocalTimeZone": "PST",
"ReportingArea": "Central LA CO",
"StateCode": "CA",
"Latitude": 34.0663,
"Longitude": -118.2266,
"ParameterName": "O3",
"AQI": 44,
"Category": {
"Number": 1,
"Name": "Good"
}
},
{
"DateObserved": "2020-12-20",
"HourObserved": 15,
"LocalTimeZone": "PST",
"ReportingArea": "Central LA CO",
"StateCode": "CA",
"Latitude": 34.0663,
"Longitude": -118.2266,
"ParameterName": "PM2.5",
"AQI": 37,
"Category": {
"Number": 1,
"Name": "Good"
}
},
{
"DateObserved": "2020-12-20",
"HourObserved": 15,
"LocalTimeZone": "PST",
"ReportingArea": "Central LA CO",
"StateCode": "CA",
"Latitude": 34.0663,
"Longitude": -118.2266,
"ParameterName": "PM10",
"AQI": 11,
"Category": {
"Number": 1,
"Name": "Good"
}
}
]

View File

@ -1,183 +1,75 @@
"""Test the AirNow config flow.""" """Test the AirNow config flow."""
from unittest.mock import patch from unittest.mock import AsyncMock
from pyairnow.errors import AirNowError, InvalidKeyError from pyairnow.errors import AirNowError, InvalidKeyError
import pytest
from homeassistant import config_entries, data_entry_flow from homeassistant import config_entries, data_entry_flow
from homeassistant.components.airnow.const import DOMAIN from homeassistant.components.airnow.const import DOMAIN
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS
from tests.common import MockConfigEntry
CONFIG = {
CONF_API_KEY: "abc123",
CONF_LATITUDE: 34.053718,
CONF_LONGITUDE: -118.244842,
CONF_RADIUS: 75,
}
# Mock AirNow Response
MOCK_RESPONSE = [
{
"DateObserved": "2020-12-20",
"HourObserved": 15,
"LocalTimeZone": "PST",
"ReportingArea": "Central LA CO",
"StateCode": "CA",
"Latitude": 34.0663,
"Longitude": -118.2266,
"ParameterName": "O3",
"AQI": 44,
"Category": {
"Number": 1,
"Name": "Good",
},
},
{
"DateObserved": "2020-12-20",
"HourObserved": 15,
"LocalTimeZone": "PST",
"ReportingArea": "Central LA CO",
"StateCode": "CA",
"Latitude": 34.0663,
"Longitude": -118.2266,
"ParameterName": "PM2.5",
"AQI": 37,
"Category": {
"Number": 1,
"Name": "Good",
},
},
{
"DateObserved": "2020-12-20",
"HourObserved": 15,
"LocalTimeZone": "PST",
"ReportingArea": "Central LA CO",
"StateCode": "CA",
"Latitude": 34.0663,
"Longitude": -118.2266,
"ParameterName": "PM10",
"AQI": 11,
"Category": {
"Number": 1,
"Name": "Good",
},
},
]
async def test_form(hass): async def test_form(hass, config, setup_airnow):
"""Test we get the form.""" """Test we get the form."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["errors"] == {} assert result["errors"] == {}
with patch("pyairnow.WebServiceAPI._get", return_value=MOCK_RESPONSE), patch( result2 = await hass.config_entries.flow.async_configure(result["flow_id"], config)
"homeassistant.components.airnow.async_setup_entry",
return_value=True,
) as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
)
await hass.async_block_till_done()
assert result2["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result2["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert result2["data"] == CONFIG assert result2["data"] == config
assert len(mock_setup_entry.mock_calls) == 1
async def test_form_invalid_auth(hass): @pytest.mark.parametrize("mock_api_get", [AsyncMock(side_effect=InvalidKeyError)])
async def test_form_invalid_auth(hass, config, setup_airnow):
"""Test we handle invalid auth.""" """Test we handle invalid auth."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], config)
with patch(
"pyairnow.WebServiceAPI._get",
side_effect=InvalidKeyError,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
)
assert result2["type"] == "form" assert result2["type"] == "form"
assert result2["errors"] == {"base": "invalid_auth"} assert result2["errors"] == {"base": "invalid_auth"}
async def test_form_invalid_location(hass): @pytest.mark.parametrize("data", [{}])
async def test_form_invalid_location(hass, config, setup_airnow):
"""Test we handle invalid location.""" """Test we handle invalid location."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], config)
with patch("pyairnow.WebServiceAPI._get", return_value={}):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
)
assert result2["type"] == "form" assert result2["type"] == "form"
assert result2["errors"] == {"base": "invalid_location"} assert result2["errors"] == {"base": "invalid_location"}
async def test_form_cannot_connect(hass): @pytest.mark.parametrize("mock_api_get", [AsyncMock(side_effect=AirNowError)])
async def test_form_cannot_connect(hass, config, setup_airnow):
"""Test we handle cannot connect error.""" """Test we handle cannot connect error."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], config)
with patch(
"pyairnow.WebServiceAPI._get",
side_effect=AirNowError,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
)
assert result2["type"] == "form" assert result2["type"] == "form"
assert result2["errors"] == {"base": "cannot_connect"} assert result2["errors"] == {"base": "cannot_connect"}
async def test_form_unexpected(hass): @pytest.mark.parametrize("mock_api_get", [AsyncMock(side_effect=RuntimeError)])
async def test_form_unexpected(hass, config, setup_airnow):
"""Test we handle an unexpected error.""" """Test we handle an unexpected error."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], config)
with patch(
"homeassistant.components.airnow.config_flow.validate_input",
side_effect=RuntimeError,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
)
assert result2["type"] == "form" assert result2["type"] == "form"
assert result2["errors"] == {"base": "unknown"} assert result2["errors"] == {"base": "unknown"}
async def test_entry_already_exists(hass): async def test_entry_already_exists(hass, config, config_entry):
"""Test that the form aborts if the Lat/Lng is already configured.""" """Test that the form aborts if the Lat/Lng is already configured."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], config)
mock_id = f"{CONFIG[CONF_LATITUDE]}-{CONFIG[CONF_LONGITUDE]}"
mock_entry = MockConfigEntry(domain=DOMAIN, unique_id=mock_id)
mock_entry.add_to_hass(hass)
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
)
assert result2["type"] == "abort" assert result2["type"] == "abort"
assert result2["reason"] == "already_configured" assert result2["reason"] == "already_configured"