mirror of
https://github.com/home-assistant/core.git
synced 2026-08-19 12:48:57 +01:00
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Erwin Douna <e.douna@gmail.com>
218 lines
7.0 KiB
Python
218 lines
7.0 KiB
Python
"""Test the Gatus Config flow."""
|
|
|
|
from unittest.mock import AsyncMock
|
|
|
|
from gatus_api import GatusClientError
|
|
import pytest
|
|
|
|
from homeassistant import config_entries
|
|
from homeassistant.components.gatus.const import DOMAIN
|
|
from homeassistant.const import CONF_URL
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.data_entry_flow import FlowResultType
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_gatus_client")
|
|
async def test_form_success(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
|
"""Test we get the form, validate the client, and create a successful entry."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["errors"] == {}
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example.com:8080"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "Gatus"
|
|
assert result["data"] == {
|
|
CONF_URL: "http://gatus.example.com:8080",
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_gatus_client")
|
|
async def test_form_success_with_path(
|
|
hass: HomeAssistant, mock_setup_entry: AsyncMock
|
|
) -> None:
|
|
"""Test we get the form, validate the client, and create a successful entry with a sub-path."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["errors"] == {}
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example.com:8080/gatus-instance/"},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert result["title"] == "Gatus"
|
|
assert result["data"] == {
|
|
CONF_URL: "http://gatus.example.com:8080/gatus-instance",
|
|
}
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("side_effect", "error_key"),
|
|
[
|
|
(GatusClientError("Cannot connect"), "cannot_connect"),
|
|
(Exception("Unexpected backend explosion"), "unknown"),
|
|
],
|
|
)
|
|
async def test_form_failures_and_recovery(
|
|
hass: HomeAssistant,
|
|
mock_setup_entry: AsyncMock,
|
|
mock_gatus_client: AsyncMock,
|
|
side_effect: Exception,
|
|
error_key: str,
|
|
) -> None:
|
|
"""Test handling validation failures and ensuring the flow can completely recover."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
|
|
mock_gatus_client.get_endpoints_statuses.side_effect = side_effect
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example.com:8080"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["errors"] == {"base": error_key}
|
|
|
|
mock_gatus_client.get_endpoints_statuses.side_effect = None
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example.com:8080"},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
|
assert len(mock_setup_entry.mock_calls) == 1
|
|
|
|
|
|
async def test_form_already_configured(
|
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test that duplicate configurations for the same base URL abort early."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example.com:8080"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "already_configured"
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_gatus_client")
|
|
async def test_flow_reconfigure(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test reconfigure flow."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await mock_config_entry.start_reconfigure_flow(hass)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "reconfigure"
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example2.com:8080/"},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "reconfigure_successful"
|
|
assert mock_config_entry.data == {
|
|
CONF_URL: "http://gatus.example2.com:8080",
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("side_effect", "error_key"),
|
|
[
|
|
(GatusClientError("Cannot connect"), "cannot_connect"),
|
|
(Exception("Unexpected backend explosion"), "unknown"),
|
|
],
|
|
)
|
|
async def test_flow_reconfigure_errors(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_gatus_client: AsyncMock,
|
|
side_effect: Exception,
|
|
error_key: str,
|
|
) -> None:
|
|
"""Test reconfigure flow errors and recover."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
result = await mock_config_entry.start_reconfigure_flow(hass)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "reconfigure"
|
|
|
|
mock_gatus_client.get_endpoints_statuses.side_effect = side_effect
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example2.com:8080"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["errors"] == {"base": error_key}
|
|
|
|
mock_gatus_client.get_endpoints_statuses.side_effect = None
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example2.com:8080"},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "reconfigure_successful"
|
|
assert mock_config_entry.data == {
|
|
CONF_URL: "http://gatus.example2.com:8080",
|
|
}
|
|
|
|
|
|
@pytest.mark.usefixtures("mock_gatus_client")
|
|
async def test_flow_reconfigure_already_configured(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test reconfigure flow aborts if the new URL is already configured."""
|
|
mock_config_entry.add_to_hass(hass)
|
|
|
|
other_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={CONF_URL: "http://gatus.example3.com:8080"},
|
|
entry_id="other_id",
|
|
)
|
|
other_entry.add_to_hass(hass)
|
|
|
|
result = await mock_config_entry.start_reconfigure_flow(hass)
|
|
assert result["type"] is FlowResultType.FORM
|
|
assert result["step_id"] == "reconfigure"
|
|
|
|
result = await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_URL: "http://gatus.example3.com:8080"},
|
|
)
|
|
|
|
assert result["type"] is FlowResultType.ABORT
|
|
assert result["reason"] == "already_configured"
|