mirror of
https://github.com/home-assistant/core.git
synced 2026-10-16 03:20:15 -04:00
Add authentication support to Gatus integration (#178663)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from gatus_api import GatusClientError
|
||||
from gatus_api import GatusAuthError, GatusClientError
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
@@ -65,6 +65,7 @@ async def test_form_success_with_path(
|
||||
("side_effect", "error_key"),
|
||||
[
|
||||
(GatusClientError("Cannot connect"), "cannot_connect"),
|
||||
(GatusAuthError("401 Unauthorized"), "invalid_auth"),
|
||||
(Exception("Unexpected backend explosion"), "unknown"),
|
||||
],
|
||||
)
|
||||
@@ -148,6 +149,7 @@ async def test_flow_reconfigure(
|
||||
("side_effect", "error_key"),
|
||||
[
|
||||
(GatusClientError("Cannot connect"), "cannot_connect"),
|
||||
(GatusAuthError("401 Unauthorized"), "invalid_auth"),
|
||||
(Exception("Unexpected backend explosion"), "unknown"),
|
||||
],
|
||||
)
|
||||
@@ -215,3 +217,142 @@ async def test_flow_reconfigure_already_configured(
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_gatus_client")
|
||||
async def test_form_success_with_credentials(
|
||||
hass: HomeAssistant, mock_setup_entry: AsyncMock
|
||||
) -> None:
|
||||
"""Test setup with username, password, and token credentials."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_URL: "http://gatus.example.com:8080",
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"token": "secret_token",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
CONF_URL: "http://gatus.example.com:8080",
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"token": "secret_token",
|
||||
}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_gatus_client")
|
||||
async def test_flow_reconfigure_credentials(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test reconfigure flow updating stored credentials."""
|
||||
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.example.com:8080",
|
||||
"username": "new_user",
|
||||
"password": "new_password",
|
||||
"token": "new_token",
|
||||
},
|
||||
)
|
||||
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.example.com:8080",
|
||||
"username": "new_user",
|
||||
"password": "new_password",
|
||||
"token": "new_token",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_gatus_client")
|
||||
async def test_flow_reauth(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test reauth flow."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
result = await mock_config_entry.start_reauth_flow(hass)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"username": "reauth_user",
|
||||
"password": "reauth_password",
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reauth_successful"
|
||||
assert mock_config_entry.data == {
|
||||
CONF_URL: "http://gatus.example.com:8080",
|
||||
"username": "reauth_user",
|
||||
"password": "reauth_password",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("side_effect", "error_key"),
|
||||
[
|
||||
(GatusClientError("Cannot connect"), "cannot_connect"),
|
||||
(GatusAuthError("401 Unauthorized"), "invalid_auth"),
|
||||
(Exception("Unexpected backend explosion"), "unknown"),
|
||||
],
|
||||
)
|
||||
async def test_flow_reauth_errors(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_gatus_client: AsyncMock,
|
||||
side_effect: Exception,
|
||||
error_key: str,
|
||||
) -> None:
|
||||
"""Test reauth flow errors and recovery."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
result = await mock_config_entry.start_reauth_flow(hass)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
|
||||
mock_gatus_client.get_endpoints_statuses.side_effect = side_effect
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{"username": "user", "password": "wrong_password"},
|
||||
)
|
||||
|
||||
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"],
|
||||
{"username": "user", "password": "correct_password"},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reauth_successful"
|
||||
assert mock_config_entry.data == {
|
||||
CONF_URL: "http://gatus.example.com:8080",
|
||||
"username": "user",
|
||||
"password": "correct_password",
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from gatus_api import GatusClientError
|
||||
from gatus_api import GatusAuthError, GatusClientError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.gatus.coordinator import GatusDataUpdateCoordinator
|
||||
@@ -48,6 +48,21 @@ async def test_setup_failure_retry(
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_setup_failure_auth(
|
||||
hass: HomeAssistant,
|
||||
mock_gatus_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test that an authentication failure places the entry in SETUP_ERROR state."""
|
||||
mock_gatus_client.get_endpoints_statuses.side_effect = GatusAuthError(
|
||||
"401 Unauthorized"
|
||||
)
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_gatus_client")
|
||||
async def test_remove_stale_device_runtime(
|
||||
hass: HomeAssistant,
|
||||
|
||||
Reference in New Issue
Block a user