mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Improve fyta tests (#117661)
* Add test for init * update tests * split common.py into const.py and __init__.py * Update tests/components/fyta/__init__.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * add autospec, tidy up * adjust len-test --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
e8f544d216
commit
6682244abf
@ -471,7 +471,6 @@ omit =
|
||||
homeassistant/components/frontier_silicon/browse_media.py
|
||||
homeassistant/components/frontier_silicon/media_player.py
|
||||
homeassistant/components/futurenow/light.py
|
||||
homeassistant/components/fyta/__init__.py
|
||||
homeassistant/components/fyta/coordinator.py
|
||||
homeassistant/components/fyta/entity.py
|
||||
homeassistant/components/fyta/sensor.py
|
||||
|
@ -1 +1,19 @@
|
||||
"""Tests for the Fyta integration."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def setup_platform(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry, platforms: list[Platform]
|
||||
) -> MockConfigEntry:
|
||||
"""Set up the Fyta platform."""
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch("homeassistant.components.fyta.PLATFORMS", platforms):
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -1,50 +1,63 @@
|
||||
"""Test helpers."""
|
||||
"""Test helpers for FYTA."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from datetime import UTC, datetime
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.fyta.const import CONF_EXPIRATION
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||
from homeassistant.components.fyta.const import CONF_EXPIRATION, DOMAIN as FYTA_DOMAIN
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_PASSWORD, CONF_USERNAME
|
||||
|
||||
from .test_config_flow import ACCESS_TOKEN, EXPIRATION
|
||||
from .const import ACCESS_TOKEN, EXPIRATION, PASSWORD, USERNAME
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_fyta():
|
||||
"""Build a fixture for the Fyta API that connects successfully and returns one device."""
|
||||
|
||||
mock_fyta_api = AsyncMock()
|
||||
with patch(
|
||||
"homeassistant.components.fyta.config_flow.FytaConnector",
|
||||
return_value=mock_fyta_api,
|
||||
) as mock_fyta_api:
|
||||
mock_fyta_api.return_value.login.return_value = {
|
||||
def mock_config_entry() -> MockConfigEntry:
|
||||
"""Mock a config entry."""
|
||||
return MockConfigEntry(
|
||||
domain=FYTA_DOMAIN,
|
||||
title="fyta_user",
|
||||
data={
|
||||
CONF_USERNAME: USERNAME,
|
||||
CONF_PASSWORD: PASSWORD,
|
||||
CONF_ACCESS_TOKEN: ACCESS_TOKEN,
|
||||
CONF_EXPIRATION: EXPIRATION,
|
||||
}
|
||||
yield mock_fyta_api
|
||||
},
|
||||
minor_version=2,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_fyta_init():
|
||||
def mock_fyta_connector():
|
||||
"""Build a fixture for the Fyta API that connects successfully and returns one device."""
|
||||
|
||||
mock_fyta_api = AsyncMock()
|
||||
mock_fyta_api.expiration = datetime.now(tz=UTC) + timedelta(days=1)
|
||||
mock_fyta_api.login = AsyncMock(
|
||||
mock_fyta_connector = AsyncMock()
|
||||
mock_fyta_connector.expiration = datetime.fromisoformat(EXPIRATION).replace(
|
||||
tzinfo=UTC
|
||||
)
|
||||
mock_fyta_connector.client = AsyncMock(autospec=True)
|
||||
mock_fyta_connector.login = AsyncMock(
|
||||
return_value={
|
||||
CONF_ACCESS_TOKEN: ACCESS_TOKEN,
|
||||
CONF_EXPIRATION: EXPIRATION,
|
||||
CONF_EXPIRATION: datetime.fromisoformat(EXPIRATION).replace(tzinfo=UTC),
|
||||
}
|
||||
)
|
||||
with patch(
|
||||
"homeassistant.components.fyta.FytaConnector.__new__",
|
||||
return_value=mock_fyta_api,
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.fyta.FytaConnector",
|
||||
autospec=True,
|
||||
return_value=mock_fyta_connector,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.fyta.config_flow.FytaConnector",
|
||||
autospec=True,
|
||||
return_value=mock_fyta_connector,
|
||||
),
|
||||
):
|
||||
yield mock_fyta_api
|
||||
yield mock_fyta_connector
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
7
tests/components/fyta/const.py
Normal file
7
tests/components/fyta/const.py
Normal file
@ -0,0 +1,7 @@
|
||||
"""Common methods and const used across tests for FYTA."""
|
||||
|
||||
USERNAME = "fyta_user"
|
||||
PASSWORD = "fyta_pass"
|
||||
ACCESS_TOKEN = "123xyz"
|
||||
EXPIRATION = "2030-12-31T10:00:00+00:00"
|
||||
EXPIRATION_OLD = "2020-01-01T00:00:00+00:00"
|
@ -1,6 +1,5 @@
|
||||
"""Test the fyta config flow."""
|
||||
|
||||
from datetime import UTC, datetime
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from fyta_cli.fyta_exceptions import (
|
||||
@ -16,16 +15,13 @@ from homeassistant.const import CONF_ACCESS_TOKEN, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from .const import ACCESS_TOKEN, EXPIRATION, PASSWORD, USERNAME
|
||||
|
||||
USERNAME = "fyta_user"
|
||||
PASSWORD = "fyta_pass"
|
||||
ACCESS_TOKEN = "123xyz"
|
||||
EXPIRATION = datetime.fromisoformat("2024-12-31T10:00:00").replace(tzinfo=UTC)
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_user_flow(
|
||||
hass: HomeAssistant, mock_fyta: AsyncMock, mock_setup_entry: AsyncMock
|
||||
hass: HomeAssistant, mock_fyta_connector: AsyncMock, mock_setup_entry: AsyncMock
|
||||
) -> None:
|
||||
"""Test we get the form."""
|
||||
|
||||
@ -46,7 +42,7 @@ async def test_user_flow(
|
||||
CONF_USERNAME: USERNAME,
|
||||
CONF_PASSWORD: PASSWORD,
|
||||
CONF_ACCESS_TOKEN: ACCESS_TOKEN,
|
||||
CONF_EXPIRATION: "2024-12-31T10:00:00+00:00",
|
||||
CONF_EXPIRATION: EXPIRATION,
|
||||
}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
@ -64,7 +60,7 @@ async def test_form_exceptions(
|
||||
hass: HomeAssistant,
|
||||
exception: Exception,
|
||||
error: dict[str, str],
|
||||
mock_fyta: AsyncMock,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
mock_setup_entry: AsyncMock,
|
||||
) -> None:
|
||||
"""Test we can handle Form exceptions."""
|
||||
@ -73,7 +69,7 @@ async def test_form_exceptions(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
mock_fyta.return_value.login.side_effect = exception
|
||||
mock_fyta_connector.login.side_effect = exception
|
||||
|
||||
# tests with connection error
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
@ -85,7 +81,7 @@ async def test_form_exceptions(
|
||||
assert result["step_id"] == "user"
|
||||
assert result["errors"] == error
|
||||
|
||||
mock_fyta.return_value.login.side_effect = None
|
||||
mock_fyta_connector.login.side_effect = None
|
||||
|
||||
# tests with all information provided
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
@ -98,12 +94,14 @@ async def test_form_exceptions(
|
||||
assert result["data"][CONF_USERNAME] == USERNAME
|
||||
assert result["data"][CONF_PASSWORD] == PASSWORD
|
||||
assert result["data"][CONF_ACCESS_TOKEN] == ACCESS_TOKEN
|
||||
assert result["data"][CONF_EXPIRATION] == "2024-12-31T10:00:00+00:00"
|
||||
assert result["data"][CONF_EXPIRATION] == EXPIRATION
|
||||
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_duplicate_entry(hass: HomeAssistant, mock_fyta: AsyncMock) -> None:
|
||||
async def test_duplicate_entry(
|
||||
hass: HomeAssistant, mock_fyta_connector: AsyncMock
|
||||
) -> None:
|
||||
"""Test duplicate setup handling."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
@ -143,7 +141,7 @@ async def test_reauth(
|
||||
hass: HomeAssistant,
|
||||
exception: Exception,
|
||||
error: dict[str, str],
|
||||
mock_fyta: AsyncMock,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
mock_setup_entry: AsyncMock,
|
||||
) -> None:
|
||||
"""Test reauth-flow works."""
|
||||
@ -155,7 +153,7 @@ async def test_reauth(
|
||||
CONF_USERNAME: USERNAME,
|
||||
CONF_PASSWORD: PASSWORD,
|
||||
CONF_ACCESS_TOKEN: ACCESS_TOKEN,
|
||||
CONF_EXPIRATION: "2024-06-30T10:00:00+00:00",
|
||||
CONF_EXPIRATION: EXPIRATION,
|
||||
},
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
@ -168,7 +166,7 @@ async def test_reauth(
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
mock_fyta.return_value.login.side_effect = exception
|
||||
mock_fyta_connector.login.side_effect = exception
|
||||
|
||||
# tests with connection error
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
@ -181,7 +179,7 @@ async def test_reauth(
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
assert result["errors"] == error
|
||||
|
||||
mock_fyta.return_value.login.side_effect = None
|
||||
mock_fyta_connector.login.side_effect = None
|
||||
|
||||
# tests with all information provided
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
@ -195,4 +193,4 @@ async def test_reauth(
|
||||
assert entry.data[CONF_USERNAME] == "other_username"
|
||||
assert entry.data[CONF_PASSWORD] == "other_password"
|
||||
assert entry.data[CONF_ACCESS_TOKEN] == ACCESS_TOKEN
|
||||
assert entry.data[CONF_EXPIRATION] == "2024-12-31T10:00:00+00:00"
|
||||
assert entry.data[CONF_EXPIRATION] == EXPIRATION
|
||||
|
@ -1,23 +1,96 @@
|
||||
"""Test the initialization."""
|
||||
|
||||
from datetime import UTC, datetime
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from homeassistant.components.fyta.const import CONF_EXPIRATION, DOMAIN
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_PASSWORD, CONF_USERNAME
|
||||
from fyta_cli.fyta_exceptions import (
|
||||
FytaAuthentificationError,
|
||||
FytaConnectionError,
|
||||
FytaPasswordError,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.fyta.const import CONF_EXPIRATION, DOMAIN as FYTA_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
CONF_ACCESS_TOKEN,
|
||||
CONF_PASSWORD,
|
||||
CONF_USERNAME,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .test_config_flow import ACCESS_TOKEN, PASSWORD, USERNAME
|
||||
from . import setup_platform
|
||||
from .const import ACCESS_TOKEN, EXPIRATION, EXPIRATION_OLD, PASSWORD, USERNAME
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_load_unload(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
) -> None:
|
||||
"""Test load and unload."""
|
||||
|
||||
await setup_platform(hass, mock_config_entry, [Platform.SENSOR])
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
assert await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
[
|
||||
FytaAuthentificationError,
|
||||
FytaPasswordError,
|
||||
],
|
||||
)
|
||||
async def test_invalid_credentials(
|
||||
hass: HomeAssistant,
|
||||
exception: Exception,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
) -> None:
|
||||
"""Test FYTA credentials changing."""
|
||||
|
||||
mock_fyta_connector.expiration = datetime.fromisoformat(EXPIRATION_OLD).replace(
|
||||
tzinfo=UTC
|
||||
)
|
||||
mock_fyta_connector.login.side_effect = exception
|
||||
|
||||
await setup_platform(hass, mock_config_entry, [Platform.SENSOR])
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
|
||||
|
||||
|
||||
async def test_raise_config_entry_not_ready_when_offline(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
) -> None:
|
||||
"""Config entry state is SETUP_RETRY when FYTA is offline."""
|
||||
|
||||
mock_fyta_connector.update_all_plants.side_effect = FytaConnectionError
|
||||
|
||||
await setup_platform(hass, mock_config_entry, [Platform.SENSOR])
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
assert len(hass.config_entries.flow.async_progress()) == 0
|
||||
|
||||
|
||||
async def test_migrate_config_entry(
|
||||
hass: HomeAssistant,
|
||||
mock_fyta_init: AsyncMock,
|
||||
mock_fyta_connector: AsyncMock,
|
||||
) -> None:
|
||||
"""Test successful migration of entry data."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
domain=FYTA_DOMAIN,
|
||||
title=USERNAME,
|
||||
data={
|
||||
CONF_USERNAME: USERNAME,
|
||||
@ -39,4 +112,4 @@ async def test_migrate_config_entry(
|
||||
assert entry.data[CONF_USERNAME] == USERNAME
|
||||
assert entry.data[CONF_PASSWORD] == PASSWORD
|
||||
assert entry.data[CONF_ACCESS_TOKEN] == ACCESS_TOKEN
|
||||
assert entry.data[CONF_EXPIRATION] == "2024-12-31T10:00:00+00:00"
|
||||
assert entry.data[CONF_EXPIRATION] == EXPIRATION
|
||||
|
Loading…
x
Reference in New Issue
Block a user