mirror of
https://github.com/home-assistant/core.git
synced 2026-08-21 05:41:29 +01:00
178 lines
5.2 KiB
Python
178 lines
5.2 KiB
Python
"""Tests for repairs model.py."""
|
|
|
|
from collections.abc import Iterator
|
|
from contextlib import contextmanager
|
|
|
|
import pytest
|
|
|
|
from homeassistant.components.repairs import (
|
|
DOMAIN,
|
|
FlowType,
|
|
RepairsFlow,
|
|
RepairsFlowResult,
|
|
repairs_flow_manager,
|
|
)
|
|
from homeassistant.config_entries import (
|
|
SOURCE_RECONFIGURE,
|
|
ConfigFlow,
|
|
ConfigSubentryFlow,
|
|
OptionsFlow,
|
|
SubentryFlowResult,
|
|
)
|
|
from homeassistant.core import HomeAssistant, callback
|
|
import homeassistant.helpers.issue_registry as ir
|
|
|
|
from tests.common import (
|
|
AsyncMock,
|
|
Mock,
|
|
MockConfigEntry,
|
|
MockModule,
|
|
async_setup_component,
|
|
mock_config_flow,
|
|
mock_integration,
|
|
mock_platform,
|
|
)
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
async def mock_repairs_integration(hass: HomeAssistant) -> None:
|
|
"""Mock a repairs integration."""
|
|
hass.config.components.add("fake_integration")
|
|
|
|
def async_create_fix_flow(
|
|
hass: HomeAssistant,
|
|
issue_id: str,
|
|
data: dict[str, str | int | float | None] | None,
|
|
) -> RepairsFlow:
|
|
return MockFixFlowNextFlow()
|
|
|
|
mock_platform(
|
|
hass,
|
|
"fake_integration.repairs",
|
|
Mock(async_create_fix_flow=AsyncMock(wraps=async_create_fix_flow)),
|
|
)
|
|
|
|
|
|
@contextmanager
|
|
def mock_core_config_flow() -> Iterator[None]:
|
|
"""Mock a config flow."""
|
|
|
|
class CompConfigSubentryFlowHandler(ConfigSubentryFlow):
|
|
"""Config subentry flow."""
|
|
|
|
async def async_step_reconfigure(self, user_input=None) -> SubentryFlowResult:
|
|
return self.async_show_form(step_id="reconfigure")
|
|
|
|
class CompOptionsFlowHandler(OptionsFlow):
|
|
"""Options flow."""
|
|
|
|
async def async_step_init(self, user_input=None):
|
|
return self.async_show_form(step_id="init")
|
|
|
|
class CompConfigFlow(ConfigFlow):
|
|
"""Config flow with options and subentries flow."""
|
|
|
|
async def async_step_user(self, user_input=None):
|
|
return self.async_show_form(step_id="user")
|
|
|
|
async def async_step_reconfigure(self, user_input=None):
|
|
return self.async_show_form(step_id="reconfigure")
|
|
|
|
@classmethod
|
|
@callback
|
|
def async_get_supported_subentry_types(
|
|
cls, config_entry
|
|
) -> dict[str, type[ConfigSubentryFlow]]:
|
|
return {"fake_subentry": CompConfigSubentryFlowHandler}
|
|
|
|
@staticmethod
|
|
@callback
|
|
def async_get_options_flow(config_entry) -> CompOptionsFlowHandler:
|
|
return CompOptionsFlowHandler()
|
|
|
|
with mock_config_flow("comp", CompConfigFlow):
|
|
yield
|
|
|
|
|
|
class MockFixFlowNextFlow(RepairsFlow):
|
|
"""Mock flow fix supporting `next_flow`."""
|
|
|
|
async def async_step_init(
|
|
self, user_input: dict[str, str] | None = None
|
|
) -> RepairsFlowResult:
|
|
"""Handle the first step of a fix flow."""
|
|
|
|
mock_integration(self.hass, MockModule("comp"))
|
|
mock_platform(self.hass, "comp.config_flow", None)
|
|
|
|
entries = self.hass.config_entries.async_entries("comp")
|
|
assert len(entries) == 1
|
|
mock_entry: MockConfigEntry = entries[0]
|
|
|
|
with mock_core_config_flow():
|
|
if self.issue_id == FlowType.OPTIONS_FLOW:
|
|
next_flow = await self.hass.config_entries.options.async_init(
|
|
mock_entry.entry_id
|
|
)
|
|
return self.async_create_entry(
|
|
next_flow=(FlowType.OPTIONS_FLOW, next_flow["flow_id"]), data={}
|
|
)
|
|
# self.issue_id == "subentry_config_issue"
|
|
assert len(mock_entry.subentries) == 1
|
|
next_flow = await self.hass.config_entries.subentries.async_init(
|
|
(mock_entry.entry_id, "fake_subentry"),
|
|
context={
|
|
"entry_id": mock_entry.entry_id,
|
|
"subentry_id": list(mock_entry.subentries.keys())[0],
|
|
"source": SOURCE_RECONFIGURE,
|
|
},
|
|
)
|
|
return self.async_create_entry(
|
|
next_flow=(FlowType.CONFIG_SUBENTRIES_FLOW, next_flow["flow_id"]),
|
|
data={},
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("flow_type", "ignore_translations_for_mock_domains"),
|
|
[
|
|
(FlowType.OPTIONS_FLOW, ["fake_integration"]),
|
|
(FlowType.CONFIG_SUBENTRIES_FLOW, ["fake_integration"]),
|
|
],
|
|
)
|
|
async def test_fix_issue_next_flow(hass: HomeAssistant, flow_type: FlowType) -> None:
|
|
"""Test that that a repair flow can refer to an options flow."""
|
|
assert await async_setup_component(hass, DOMAIN, {})
|
|
|
|
mock_entry = MockConfigEntry(
|
|
domain="comp",
|
|
data={},
|
|
subentries_data=[
|
|
{
|
|
"unique_id": "test_1",
|
|
"title": "test 1",
|
|
"subentry_type": "fake_subentry",
|
|
"data": {},
|
|
}
|
|
],
|
|
)
|
|
mock_entry.add_to_hass(hass)
|
|
|
|
ir.async_create_issue(
|
|
hass,
|
|
issue_id=flow_type,
|
|
domain="fake_integration",
|
|
is_fixable=True,
|
|
severity="error",
|
|
translation_key="fake_key",
|
|
)
|
|
|
|
assert (repairs := repairs_flow_manager(hass))
|
|
|
|
flow = await repairs.async_init("fake_integration", data={"issue_id": flow_type})
|
|
|
|
next_flow_type, _ = flow["next_flow"]
|
|
|
|
assert next_flow_type is flow_type
|
|
assert mock_entry == flow["result"]
|