Revert "fix: Complete fixes: tests, workflows, coverage"

This reverts commit ed94d40e96.
This commit is contained in:
2025-10-02 12:47:35 +01:00
parent 089e046fd9
commit f4bea6863f
17 changed files with 1756 additions and 1081 deletions

View File

@@ -1,6 +1,7 @@
"""Config flow for AdGuard Control Hub integration."""
import asyncio
import logging
import re
from typing import Any, Dict, Optional
import voluptuous as vol
@@ -32,6 +33,86 @@ STEP_USER_DATA_SCHEMA = vol.Schema({
})
def validate_host(host: str) -> str:
"""Validate and clean host input."""
host = host.strip()
if not host:
raise InvalidHost("Host cannot be empty")
# Remove protocol if present
if host.startswith(("http://", "https://")):
host = host.split("://", 1)[1]
# Remove path if present
if "/" in host:
host = host.split("/", 1)[0]
return host
async def validate_input(hass, data: Dict[str, Any]) -> Dict[str, Any]:
"""Validate the user input allows us to connect."""
# Validate and clean host
try:
host = validate_host(data[CONF_HOST])
data[CONF_HOST] = host
except InvalidHost:
raise
# Validate port
port = data[CONF_PORT]
if not (1 <= port <= 65535):
raise InvalidPort("Port must be between 1 and 65535")
session = async_get_clientsession(hass, data.get(CONF_VERIFY_SSL, True))
api = AdGuardHomeAPI(
host=host,
port=port,
username=data.get(CONF_USERNAME),
password=data.get(CONF_PASSWORD),
ssl=data.get(CONF_SSL, False),
verify_ssl=data.get(CONF_VERIFY_SSL, True),
session=session,
timeout=10,
)
try:
if not await api.test_connection():
raise CannotConnect("Failed to connect to AdGuard Home")
try:
status = await api.get_status()
version = status.get("version", "unknown")
return {
"title": f"AdGuard Control Hub ({host})",
"version": version,
"host": host,
}
except Exception:
# If we can't get status but connection works, still proceed
return {
"title": f"AdGuard Control Hub ({host})",
"version": "unknown",
"host": host,
}
except AdGuardAuthError as err:
raise InvalidAuth from err
except AdGuardTimeoutError as err:
raise Timeout from err
except AdGuardConnectionError as err:
if "timeout" in str(err).lower():
raise Timeout from err
raise CannotConnect from err
except asyncio.TimeoutError as err:
raise Timeout from err
except Exception as err:
_LOGGER.exception("Unexpected error during validation")
raise CannotConnect from err
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for AdGuard Control Hub."""
@@ -46,42 +127,27 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
if user_input is not None:
try:
# Basic validation
host = user_input[CONF_HOST].strip()
if not host:
errors[CONF_HOST] = "invalid_host"
info = await validate_input(self.hass, user_input)
# Test connection
session = async_get_clientsession(self.hass, user_input.get(CONF_VERIFY_SSL, True))
api = AdGuardHomeAPI(
host=host,
port=user_input[CONF_PORT],
username=user_input.get(CONF_USERNAME),
password=user_input.get(CONF_PASSWORD),
ssl=user_input.get(CONF_SSL, False),
verify_ssl=user_input.get(CONF_VERIFY_SSL, True),
session=session,
timeout=10,
unique_id = f"{info['host']}:{user_input[CONF_PORT]}"
await self.async_set_unique_id(unique_id)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=info["title"],
data=user_input,
)
if not await api.test_connection():
errors["base"] = "cannot_connect"
else:
unique_id = f"{host}:{user_input[CONF_PORT]}"
await self.async_set_unique_id(unique_id)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=f"AdGuard Control Hub ({host})",
data=user_input,
)
except AdGuardAuthError:
errors["base"] = "invalid_auth"
except AdGuardTimeoutError:
errors["base"] = "timeout"
except AdGuardConnectionError:
except CannotConnect:
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except InvalidHost:
errors[CONF_HOST] = "invalid_host"
except InvalidPort:
errors[CONF_PORT] = "invalid_port"
except Timeout:
errors["base"] = "timeout"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
@@ -91,3 +157,23 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
data_schema=STEP_USER_DATA_SCHEMA,
errors=errors,
)
class CannotConnect(Exception):
"""Error to indicate we cannot connect."""
class InvalidAuth(Exception):
"""Error to indicate there is invalid auth."""
class InvalidHost(Exception):
"""Error to indicate invalid host."""
class InvalidPort(Exception):
"""Error to indicate invalid port."""
class Timeout(Exception):
"""Error to indicate connection timeout."""