Add tests

This commit is contained in:
G Johansson 2024-07-12 17:15:18 +00:00
parent 42fe1d6097
commit 22bb68d610
4 changed files with 424 additions and 0 deletions

View File

@ -0,0 +1,81 @@
"""Fixtures for the Compensation integration."""
from __future__ import annotations
from collections.abc import Generator
from typing import Any
from unittest.mock import AsyncMock, patch
import pytest
from homeassistant.components.compensation.const import (
CONF_DATAPOINTS,
CONF_DEGREE,
CONF_LOWER_LIMIT,
CONF_PRECISION,
CONF_UPPER_LIMIT,
DEFAULT_DEGREE,
DEFAULT_NAME,
DOMAIN,
)
from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import CONF_ENTITY_ID, CONF_NAME, CONF_UNIT_OF_MEASUREMENT
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock]:
"""Automatically patch compensation setup_entry."""
with patch(
"homeassistant.components.compensation.async_setup_entry",
return_value=True,
) as mock_setup_entry:
yield mock_setup_entry
@pytest.fixture(name="get_config")
async def get_config_to_integration_load() -> dict[str, Any]:
"""Return configuration.
To override the config, tests can be marked with:
@pytest.mark.parametrize("get_config", [{...}])
"""
return {
CONF_NAME: DEFAULT_NAME,
CONF_ENTITY_ID: "sensor.uncompensated",
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: DEFAULT_DEGREE,
CONF_UNIT_OF_MEASUREMENT: "mm",
}
@pytest.fixture(name="loaded_entry")
async def load_integration(
hass: HomeAssistant, get_config: dict[str, Any]
) -> MockConfigEntry:
"""Set up the Compensation integration in Home Assistant."""
config_entry = MockConfigEntry(
domain=DOMAIN,
title="Compensation sensor",
source=SOURCE_USER,
options=get_config,
entry_id="1",
)
config_entry.add_to_hass(hass)
entity_id = get_config[CONF_ENTITY_ID]
hass.states.async_set(entity_id, 4, {})
await hass.async_block_till_done()
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
return config_entry

View File

@ -0,0 +1,266 @@
"""Test the Compensation config flow."""
from __future__ import annotations
from unittest.mock import AsyncMock
from homeassistant import config_entries
from homeassistant.components.compensation.const import (
CONF_DATAPOINTS,
CONF_DEGREE,
CONF_LOWER_LIMIT,
CONF_PRECISION,
CONF_UPPER_LIMIT,
DEFAULT_NAME,
DOMAIN,
)
from homeassistant.const import CONF_ENTITY_ID, CONF_NAME, CONF_UNIT_OF_MEASUREMENT
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
"""Test we get the form."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["step_id"] == "user"
assert result["type"] is FlowResultType.FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_NAME: DEFAULT_NAME,
CONF_ENTITY_ID: "sensor.test_monitored",
},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 1,
CONF_UNIT_OF_MEASUREMENT: "mm",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["version"] == 1
assert result["options"] == {
CONF_NAME: DEFAULT_NAME,
CONF_ENTITY_ID: "sensor.test_monitored",
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 1,
CONF_UNIT_OF_MEASUREMENT: "mm",
}
assert len(mock_setup_entry.mock_calls) == 1
async def test_options_flow(hass: HomeAssistant, loaded_entry: MockConfigEntry) -> None:
"""Test options flow."""
result = await hass.config_entries.options.async_init(loaded_entry.entry_id)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "init"
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 1,
CONF_UNIT_OF_MEASUREMENT: "km",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"] == {
CONF_NAME: DEFAULT_NAME,
CONF_ENTITY_ID: "sensor.uncompensated",
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 1,
CONF_UNIT_OF_MEASUREMENT: "km",
}
await hass.async_block_till_done()
# Check the entity was updated, no new entity was created
assert len(hass.states.async_all()) == 2
state = hass.states.get("sensor.compensation_sensor")
assert state is not None
async def test_validation_options(
hass: HomeAssistant, mock_setup_entry: AsyncMock
) -> None:
"""Test validation."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["step_id"] == "user"
assert result["type"] is FlowResultType.FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_NAME: DEFAULT_NAME,
CONF_ENTITY_ID: "sensor.test_monitored",
},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 2,
CONF_UNIT_OF_MEASUREMENT: "km",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "not_enough_datapoints"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 1,
CONF_UNIT_OF_MEASUREMENT: "km",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "incorrect_datapoints"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_DATAPOINTS: [
"1.0, 2.0",
"2,0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 1,
CONF_UNIT_OF_MEASUREMENT: "km",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "incorrect_datapoints"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_DATAPOINTS: ["1.0, 2.0", "2.0, 3.0", "3.0, 4.0"],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 2,
CONF_UNIT_OF_MEASUREMENT: "km",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["version"] == 1
assert result["options"] == {
CONF_NAME: DEFAULT_NAME,
CONF_ENTITY_ID: "sensor.test_monitored",
CONF_DATAPOINTS: ["1.0, 2.0", "2.0, 3.0", "3.0, 4.0"],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 2,
CONF_UNIT_OF_MEASUREMENT: "km",
}
assert len(mock_setup_entry.mock_calls) == 1
async def test_entry_already_exist(
hass: HomeAssistant, loaded_entry: MockConfigEntry
) -> None:
"""Test abort when entry already exist."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["step_id"] == "user"
assert result["type"] is FlowResultType.FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_NAME: DEFAULT_NAME,
CONF_ENTITY_ID: "sensor.uncompensated",
},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_DATAPOINTS: [
"1.0, 2.0",
"2.0, 3.0",
],
CONF_UPPER_LIMIT: False,
CONF_LOWER_LIMIT: False,
CONF_PRECISION: 2,
CONF_DEGREE: 1,
CONF_UNIT_OF_MEASUREMENT: "mm",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"

View File

@ -0,0 +1,44 @@
"""Test Statistics component setup process."""
from __future__ import annotations
from typing import Any
from unittest.mock import patch
from homeassistant.components.compensation.const import DOMAIN
from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def test_unload_entry(hass: HomeAssistant, loaded_entry: MockConfigEntry) -> None:
"""Test unload an entry."""
assert loaded_entry.state is ConfigEntryState.LOADED
assert await hass.config_entries.async_unload(loaded_entry.entry_id)
await hass.async_block_till_done()
assert loaded_entry.state is ConfigEntryState.NOT_LOADED
async def test_could_not_setup(hass: HomeAssistant, get_config: dict[str, Any]) -> None:
"""Test exception."""
config_entry = MockConfigEntry(
domain=DOMAIN,
title="Compensation sensor",
source=SOURCE_USER,
options=get_config,
entry_id="1",
)
config_entry.add_to_hass(hass)
with patch(
"homeassistant.components.compensation.np.polyfit",
side_effect=FloatingPointError,
):
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.SETUP_ERROR
assert config_entry.error_reason_translation_key == "setup_error"

View File

@ -1,5 +1,7 @@
"""The tests for the integration sensor platform."""
from typing import Any
import pytest
from homeassistant.components.compensation.const import CONF_PRECISION, DOMAIN
@ -7,6 +9,7 @@ from homeassistant.components.compensation.sensor import ATTR_COEFFICIENTS
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT,
CONF_ENTITY_ID,
EVENT_HOMEASSISTANT_START,
EVENT_STATE_CHANGED,
STATE_UNKNOWN,
@ -14,6 +17,8 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry
async def test_linear_state(hass: HomeAssistant) -> None:
"""Test compensation sensor state."""
@ -60,6 +65,34 @@ async def test_linear_state(hass: HomeAssistant) -> None:
assert state.state == STATE_UNKNOWN
async def test_linear_state_from_config_entry(
hass: HomeAssistant, loaded_entry: MockConfigEntry, get_config: dict[str, Any]
) -> None:
"""Test compensation sensor state loaded from config entry."""
expected_entity_id = "sensor.compensation_sensor"
entity_id = get_config[CONF_ENTITY_ID]
hass.states.async_set(entity_id, 5, {})
await hass.async_block_till_done()
state = hass.states.get(expected_entity_id)
assert state is not None
assert round(float(state.state), get_config[CONF_PRECISION]) == 6.0
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "mm"
coefs = [round(v, 1) for v in state.attributes.get(ATTR_COEFFICIENTS)]
assert coefs == [1.0, 1.0]
hass.states.async_set(entity_id, "foo", {})
await hass.async_block_till_done()
state = hass.states.get(expected_entity_id)
assert state is not None
assert state.state == STATE_UNKNOWN
async def test_linear_state_from_attribute(hass: HomeAssistant) -> None:
"""Test compensation sensor state that pulls from attribute."""
config = {