First config flow testu
This commit is contained in:
@@ -331,7 +331,7 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
async def validate_input(self, data: dict) -> dict[str]:
|
async def validate_input(self, data: dict) -> None:
|
||||||
"""Validate the user input allows us to connect.
|
"""Validate the user input allows us to connect.
|
||||||
|
|
||||||
Data has the keys from STEP_*_DATA_SCHEMA with values provided by the user.
|
Data has the keys from STEP_*_DATA_SCHEMA with values provided by the user.
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
homeassistant
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# -r requirements_dev.txt
|
||||||
|
# aiodiscover
|
||||||
|
pytest-homeassistant-custom-component
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
""" To make this repo a module """
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
"""Global fixtures for integration_blueprint integration."""
|
||||||
|
# Fixtures allow you to replace functions with a Mock object. You can perform
|
||||||
|
# many options via the Mock to reflect a particular behavior from the original
|
||||||
|
# function that you want to see without going through the function's actual logic.
|
||||||
|
# Fixtures can either be passed into tests as parameters, or if autouse=True, they
|
||||||
|
# will automatically be used across all tests.
|
||||||
|
#
|
||||||
|
# Fixtures that are defined in conftest.py are available across all tests. You can also
|
||||||
|
# define fixtures within a particular test file to scope them locally.
|
||||||
|
#
|
||||||
|
# pytest_homeassistant_custom_component provides some fixtures that are provided by
|
||||||
|
# Home Assistant core. You can find those fixture definitions here:
|
||||||
|
# https://github.com/MatthewFlamm/pytest-homeassistant-custom-component/blob/master/pytest_homeassistant_custom_component/common.py
|
||||||
|
#
|
||||||
|
# See here for more info: https://docs.pytest.org/en/latest/fixture.html (note that
|
||||||
|
# pytest includes fixtures OOB which you can use as defined on this page)
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from custom_components.versatile_thermostat.config_flow import (
|
||||||
|
VersatileThermostatBaseConfigFlow,
|
||||||
|
)
|
||||||
|
|
||||||
|
pytest_plugins = "pytest_homeassistant_custom_component"
|
||||||
|
|
||||||
|
|
||||||
|
# This fixture enables loading custom integrations in all tests.
|
||||||
|
# Remove to enable selective use of this fixture
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def auto_enable_custom_integrations(enable_custom_integrations):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
# This fixture is used to prevent HomeAssistant from attempting to create and dismiss persistent
|
||||||
|
# notifications. These calls would fail without this fixture since the persistent_notification
|
||||||
|
# integration is never loaded during a test.
|
||||||
|
@pytest.fixture(name="skip_notifications", autouse=True)
|
||||||
|
def skip_notifications_fixture():
|
||||||
|
"""Skip notification calls."""
|
||||||
|
with patch("homeassistant.components.persistent_notification.async_create"), patch(
|
||||||
|
"homeassistant.components.persistent_notification.async_dismiss"
|
||||||
|
):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
# This fixture is used to bypass the validate_input function in config_flow
|
||||||
|
@pytest.fixture(name="skip_validate_input")
|
||||||
|
def skip_validate_input_fixture():
|
||||||
|
"""Skip the validate_input in config flow"""
|
||||||
|
with patch.object(VersatileThermostatBaseConfigFlow, "validate_input"):
|
||||||
|
yield
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
from homeassistant.components.climate.const import (
|
||||||
|
PRESET_BOOST,
|
||||||
|
PRESET_COMFORT,
|
||||||
|
PRESET_ECO,
|
||||||
|
)
|
||||||
|
from custom_components.versatile_thermostat.const import (
|
||||||
|
CONF_NAME,
|
||||||
|
CONF_HEATER,
|
||||||
|
CONF_THERMOSTAT_CLIMATE,
|
||||||
|
CONF_THERMOSTAT_SWITCH,
|
||||||
|
CONF_THERMOSTAT_TYPE,
|
||||||
|
CONF_TEMP_SENSOR,
|
||||||
|
CONF_EXTERNAL_TEMP_SENSOR,
|
||||||
|
CONF_CYCLE_MIN,
|
||||||
|
CONF_TEMP_MAX,
|
||||||
|
CONF_TEMP_MIN,
|
||||||
|
CONF_PROP_FUNCTION,
|
||||||
|
PROPORTIONAL_FUNCTION_TPI,
|
||||||
|
CONF_TPI_COEF_INT,
|
||||||
|
CONF_TPI_COEF_EXT,
|
||||||
|
CONF_MINIMAL_ACTIVATION_DELAY,
|
||||||
|
CONF_SECURITY_DELAY_MIN,
|
||||||
|
CONF_SECURITY_MIN_ON_PERCENT,
|
||||||
|
CONF_SECURITY_DEFAULT_ON_PERCENT,
|
||||||
|
CONF_USE_WINDOW_FEATURE,
|
||||||
|
CONF_USE_MOTION_FEATURE,
|
||||||
|
CONF_USE_POWER_FEATURE,
|
||||||
|
CONF_USE_PRESENCE_FEATURE,
|
||||||
|
)
|
||||||
|
|
||||||
|
MOCK_TH_OVER_SWITCH_USER_CONFIG = {
|
||||||
|
CONF_NAME: "TheOverSwitchMockName",
|
||||||
|
CONF_THERMOSTAT_TYPE: CONF_THERMOSTAT_SWITCH,
|
||||||
|
CONF_TEMP_SENSOR: "sensor.mock_temp_sensor",
|
||||||
|
CONF_EXTERNAL_TEMP_SENSOR: "sensor.mock_ext_temp_sensor",
|
||||||
|
CONF_CYCLE_MIN: 5,
|
||||||
|
CONF_TEMP_MIN: 15,
|
||||||
|
CONF_TEMP_MAX: 30,
|
||||||
|
# Keep all additional optional features to false
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_TH_OVER_SWITCH_TYPE_CONFIG = {
|
||||||
|
CONF_HEATER: "switch.mock_switch",
|
||||||
|
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_TH_OVER_SWITCH_TPI_CONFIG = {
|
||||||
|
CONF_TPI_COEF_INT: 0.3,
|
||||||
|
CONF_TPI_COEF_EXT: 0.1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MOCK_PRESETS_CONFIG = {
|
||||||
|
PRESET_ECO + "_temp": 16,
|
||||||
|
PRESET_COMFORT + "_temp": 17,
|
||||||
|
PRESET_BOOST + "_temp": 18,
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_ADVANCED_CONFIG = {
|
||||||
|
CONF_MINIMAL_ACTIVATION_DELAY: 10,
|
||||||
|
CONF_SECURITY_DELAY_MIN: 5,
|
||||||
|
CONF_SECURITY_MIN_ON_PERCENT: 0.4,
|
||||||
|
CONF_SECURITY_DEFAULT_ON_PERCENT: 0.3,
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_DEFAULT_FEATURE_CONFIG = {
|
||||||
|
CONF_USE_WINDOW_FEATURE: False,
|
||||||
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
|
CONF_USE_POWER_FEATURE: False,
|
||||||
|
CONF_USE_PRESENCE_FEATURE: False,
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
""" Test the Versatile Thermostat config flow """
|
||||||
|
|
||||||
|
from homeassistant import data_entry_flow
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.config_entries import SOURCE_USER, ConfigEntry
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pytest_homeassistant_custom_component.common import MockConfigEntry, load_fixture
|
||||||
|
|
||||||
|
from custom_components.versatile_thermostat.const import DOMAIN
|
||||||
|
from custom_components.versatile_thermostat import VersatileThermostatAPI
|
||||||
|
|
||||||
|
from custom_components.versatile_thermostat.tests.const import (
|
||||||
|
MOCK_TH_OVER_SWITCH_USER_CONFIG,
|
||||||
|
MOCK_TH_OVER_SWITCH_TYPE_CONFIG,
|
||||||
|
MOCK_TH_OVER_SWITCH_TPI_CONFIG,
|
||||||
|
MOCK_PRESETS_CONFIG,
|
||||||
|
MOCK_ADVANCED_CONFIG,
|
||||||
|
MOCK_DEFAULT_FEATURE_CONFIG,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_show_form(hass: HomeAssistant) -> None:
|
||||||
|
"""Test that the form is served with no input"""
|
||||||
|
# Init the API
|
||||||
|
# hass.data["custom_components"] = None
|
||||||
|
# loader.async_get_custom_components(hass)
|
||||||
|
# VersatileThermostatAPI(hass)
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == SOURCE_USER
|
||||||
|
|
||||||
|
|
||||||
|
async def test_user_config_flow_over_switch(hass, skip_validate_input):
|
||||||
|
"""Test the config flow with thermostat_over_switch features"""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == SOURCE_USER
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input=MOCK_TH_OVER_SWITCH_USER_CONFIG
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "type"
|
||||||
|
assert result["errors"] == {}
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input=MOCK_TH_OVER_SWITCH_TYPE_CONFIG
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "tpi"
|
||||||
|
assert result["errors"] == {}
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input=MOCK_TH_OVER_SWITCH_TPI_CONFIG
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "presets"
|
||||||
|
assert result["errors"] == {}
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input=MOCK_PRESETS_CONFIG
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result["step_id"] == "advanced"
|
||||||
|
assert result["errors"] == {}
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"], user_input=MOCK_ADVANCED_CONFIG
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert (
|
||||||
|
result["data"]
|
||||||
|
== MOCK_TH_OVER_SWITCH_USER_CONFIG
|
||||||
|
| MOCK_TH_OVER_SWITCH_TYPE_CONFIG
|
||||||
|
| MOCK_TH_OVER_SWITCH_TPI_CONFIG
|
||||||
|
| MOCK_PRESETS_CONFIG
|
||||||
|
| MOCK_ADVANCED_CONFIG
|
||||||
|
| MOCK_DEFAULT_FEATURE_CONFIG
|
||||||
|
)
|
||||||
|
assert result["result"]
|
||||||
|
assert result["result"].domain == DOMAIN
|
||||||
|
assert result["result"].version == 1
|
||||||
|
assert result["result"].title == "TheOverSwitchMockName"
|
||||||
|
assert isinstance(result["result"], ConfigEntry)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import unittest # The test framework
|
||||||
|
|
||||||
|
|
||||||
|
class Test_TestIncrementDecrement(unittest.TestCase):
|
||||||
|
def test_increment(self):
|
||||||
|
self.assertEqual(4, 4)
|
||||||
|
|
||||||
|
# This test is designed to fail for demonstration purposes.
|
||||||
|
def test_decrement(self):
|
||||||
|
self.assertEqual(3, 3)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user