mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Test connection in config flow for Husqvarna Automower (#131557)
This commit is contained in:
parent
5f7c7b323e
commit
5da7b1dd05
@ -7,6 +7,7 @@ from aioautomower.auth import AbstractAuth
|
||||
from aioautomower.const import API_BASE_URL
|
||||
from aiohttp import ClientSession
|
||||
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -28,3 +29,16 @@ class AsyncConfigEntryAuth(AbstractAuth):
|
||||
"""Return a valid access token."""
|
||||
await self._oauth_session.async_ensure_token_valid()
|
||||
return cast(str, self._oauth_session.token["access_token"])
|
||||
|
||||
|
||||
class AsyncConfigFlowAuth(AbstractAuth):
|
||||
"""Provide Automower AbstractAuth for the config flow."""
|
||||
|
||||
def __init__(self, websession: ClientSession, token: dict) -> None:
|
||||
"""Initialize Husqvarna Automower auth."""
|
||||
super().__init__(websession, API_BASE_URL)
|
||||
self.token: dict = token
|
||||
|
||||
async def async_get_access_token(self) -> str:
|
||||
"""Return a valid access token."""
|
||||
return cast(str, self.token[CONF_ACCESS_TOKEN])
|
||||
|
@ -4,12 +4,15 @@ from collections.abc import Mapping
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from aioautomower.session import AutomowerSession
|
||||
from aioautomower.utils import structure_token
|
||||
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlowResult
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_NAME, CONF_TOKEN
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
from homeassistant.helpers import aiohttp_client, config_entry_oauth2_flow
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .api import AsyncConfigFlowAuth
|
||||
from .const import DOMAIN, NAME
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -46,9 +49,20 @@ class HusqvarnaConfigFlowHandler(
|
||||
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
websession = aiohttp_client.async_get_clientsession(self.hass)
|
||||
tz = await dt_util.async_get_time_zone(str(dt_util.DEFAULT_TIME_ZONE))
|
||||
automower_api = AutomowerSession(AsyncConfigFlowAuth(websession, token), tz)
|
||||
try:
|
||||
data = await automower_api.get_status()
|
||||
except Exception: # noqa: BLE001
|
||||
return self.async_abort(reason="unknown")
|
||||
if data == {}:
|
||||
return self.async_abort(reason="no_mower_connected")
|
||||
|
||||
structured_token = structure_token(token[CONF_ACCESS_TOKEN])
|
||||
first_name = structured_token.user.first_name
|
||||
last_name = structured_token.user.last_name
|
||||
|
||||
return self.async_create_entry(
|
||||
title=f"{NAME} of {first_name} {last_name}",
|
||||
data=data,
|
||||
|
@ -27,7 +27,9 @@
|
||||
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"wrong_account": "You can only reauthenticate this entry with the same Husqvarna account.",
|
||||
"missing_amc_scope": "The `Authentication API` and the `Automower Connect API` are not connected to your application in the Husqvarna Developer Portal."
|
||||
"no_mower_connected": "No mowers connected to this account.",
|
||||
"missing_amc_scope": "The `Authentication API` and the `Automower Connect API` are not connected to your application in the Husqvarna Developer Portal.",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"create_entry": {
|
||||
"default": "[%key:common::config_flow::create_entry::authenticated%]"
|
||||
|
1
tests/components/husqvarna_automower/fixtures/empty.json
Normal file
1
tests/components/husqvarna_automower/fixtures/empty.json
Normal file
@ -0,0 +1 @@
|
||||
{ "data": [] }
|
@ -2,6 +2,8 @@
|
||||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from aioautomower.const import API_BASE_URL
|
||||
from aioautomower.session import AutomowerEndpoint
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
@ -18,16 +20,18 @@ from homeassistant.helpers import config_entry_oauth2_flow
|
||||
from . import setup_integration
|
||||
from .const import CLIENT_ID, USER_ID
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("new_scope", "amount"),
|
||||
("new_scope", "fixture", "exception", "amount"),
|
||||
[
|
||||
("iam:read amc:api", 1),
|
||||
("iam:read", 0),
|
||||
("iam:read amc:api", "mower.json", None, 1),
|
||||
("iam:read amc:api", "mower.json", Exception, 0),
|
||||
("iam:read", "mower.json", None, 0),
|
||||
("iam:read amc:api", "empty.json", None, 0),
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("current_request_with_host")
|
||||
@ -38,6 +42,8 @@ async def test_full_flow(
|
||||
jwt: str,
|
||||
new_scope: str,
|
||||
amount: int,
|
||||
fixture: str,
|
||||
exception: Exception | None,
|
||||
) -> None:
|
||||
"""Check full flow."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -76,11 +82,17 @@ async def test_full_flow(
|
||||
"expires_at": 1697753347,
|
||||
},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.husqvarna_automower.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup:
|
||||
aioclient_mock.get(
|
||||
f"{API_BASE_URL}/{AutomowerEndpoint.mowers}",
|
||||
text=load_fixture(fixture, DOMAIN),
|
||||
exc=exception,
|
||||
)
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.husqvarna_automower.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup,
|
||||
):
|
||||
await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert len(hass.config_entries.async_entries(DOMAIN)) == amount
|
||||
|
Loading…
x
Reference in New Issue
Block a user