Use aiohasupervisor for store APIs (#126780)

* Use aiohasupervosor for store addon info

* Use aiohasupervisor install addon

* Use aiohasupervisor for store info API

* Fix onboarding test

* Changes from feedback

* Move get_supervisor_client out of constructor

* Mock supervisor_client in tests

* Make property private
pull/128087/head
Mike Degatano 2024-10-10 04:27:20 -04:00 committed by GitHub
parent f504c27972
commit a9aa5ad229
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 234 additions and 354 deletions

View File

@ -93,7 +93,6 @@ from .coordinator import (
get_info, # noqa: F401
get_issues_info, # noqa: F401
get_os_info,
get_store, # noqa: F401
get_supervisor_info, # noqa: F401
get_supervisor_stats, # noqa: F401
)
@ -103,10 +102,8 @@ from .handler import ( # noqa: F401
HassioAPIError,
async_create_backup,
async_get_addon_discovery_info,
async_get_addon_store_info,
async_get_green_settings,
async_get_yellow_settings,
async_install_addon,
async_reboot_host,
async_set_addon_options,
async_set_green_settings,
@ -440,7 +437,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
(
hass.data[DATA_INFO],
hass.data[DATA_HOST_INFO],
hass.data[DATA_STORE],
store_info,
hass.data[DATA_CORE_INFO],
hass.data[DATA_SUPERVISOR_INFO],
hass.data[DATA_OS_INFO],
@ -448,7 +445,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
) = await asyncio.gather(
create_eager_task(hassio.get_info()),
create_eager_task(hassio.get_host_info()),
create_eager_task(hassio.get_store()),
create_eager_task(hassio.client.store.info()),
create_eager_task(hassio.get_core_info()),
create_eager_task(hassio.get_supervisor_info()),
create_eager_task(hassio.get_os_info()),
@ -457,6 +454,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
except HassioAPIError as err:
_LOGGER.warning("Can't read Supervisor data: %s", err)
else:
hass.data[DATA_STORE] = store_info.to_dict()
async_call_later(
hass,

View File

@ -10,7 +10,7 @@ from functools import partial, wraps
import logging
from typing import Any, Concatenate
from aiohasupervisor import SupervisorError
from aiohasupervisor import SupervisorClient, SupervisorError
from aiohasupervisor.models import (
AddonState as SupervisorAddonState,
InstalledAddonComplete,
@ -23,8 +23,6 @@ from .handler import (
HassioAPIError,
async_create_backup,
async_get_addon_discovery_info,
async_get_addon_store_info,
async_install_addon,
async_set_addon_options,
async_update_addon,
get_supervisor_client,
@ -113,6 +111,14 @@ class AddonManager:
self._restart_task: asyncio.Task | None = None
self._start_task: asyncio.Task | None = None
self._update_task: asyncio.Task | None = None
self._client: SupervisorClient | None = None
@property
def _supervisor_client(self) -> SupervisorClient:
"""Get supervisor client."""
if not self._client:
self._client = get_supervisor_client(self._hass)
return self._client
def task_in_progress(self) -> bool:
"""Return True if any of the add-on tasks are in progress."""
@ -142,12 +148,13 @@ class AddonManager:
@api_error("Failed to get the {addon_name} add-on info")
async def async_get_addon_info(self) -> AddonInfo:
"""Return and cache manager add-on info."""
supervisor_client = get_supervisor_client(self._hass)
addon_store_info = await async_get_addon_store_info(self._hass, self.addon_slug)
self._logger.debug("Add-on store info: %s", addon_store_info)
if not addon_store_info["installed"]:
addon_store_info = await self._supervisor_client.store.addon_info(
self.addon_slug
)
self._logger.debug("Add-on store info: %s", addon_store_info.to_dict())
if not addon_store_info.installed:
return AddonInfo(
available=addon_store_info["available"],
available=addon_store_info.available,
hostname=None,
options={},
state=AddonState.NOT_INSTALLED,
@ -155,7 +162,7 @@ class AddonManager:
version=None,
)
addon_info = await supervisor_client.addons.addon_info(self.addon_slug)
addon_info = await self._supervisor_client.addons.addon_info(self.addon_slug)
addon_state = self.async_get_addon_state(addon_info)
return AddonInfo(
available=addon_info.available,
@ -199,12 +206,12 @@ class AddonManager:
self._check_addon_available(addon_info)
await async_install_addon(self._hass, self.addon_slug)
await self._supervisor_client.store.install_addon(self.addon_slug)
@api_error("Failed to uninstall the {addon_name} add-on")
async def async_uninstall_addon(self) -> None:
"""Uninstall the managed add-on."""
await get_supervisor_client(self._hass).addons.uninstall_addon(self.addon_slug)
await self._supervisor_client.addons.uninstall_addon(self.addon_slug)
@api_error("Failed to update the {addon_name} add-on")
async def async_update_addon(self) -> None:
@ -225,17 +232,17 @@ class AddonManager:
@api_error("Failed to start the {addon_name} add-on")
async def async_start_addon(self) -> None:
"""Start the managed add-on."""
await get_supervisor_client(self._hass).addons.start_addon(self.addon_slug)
await self._supervisor_client.addons.start_addon(self.addon_slug)
@api_error("Failed to restart the {addon_name} add-on")
async def async_restart_addon(self) -> None:
"""Restart the managed add-on."""
await get_supervisor_client(self._hass).addons.restart_addon(self.addon_slug)
await self._supervisor_client.addons.restart_addon(self.addon_slug)
@api_error("Failed to stop the {addon_name} add-on")
async def async_stop_addon(self) -> None:
"""Stop the managed add-on."""
await get_supervisor_client(self._hass).addons.stop_addon(self.addon_slug)
await self._supervisor_client.addons.stop_addon(self.addon_slug)
@api_error("Failed to create a backup of the {addon_name} add-on")
async def async_create_backup(self) -> None:

View File

@ -8,6 +8,7 @@ import logging
from typing import TYPE_CHECKING, Any
from aiohasupervisor import SupervisorError
from aiohasupervisor.models import StoreInfo
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_MANUFACTURER, ATTR_NAME
@ -332,12 +333,15 @@ class HassioDataUpdateCoordinator(DataUpdateCoordinator):
addons_info = get_addons_info(self.hass) or {}
addons_stats = get_addons_stats(self.hass)
addons_changelogs = get_addons_changelogs(self.hass)
store_data = get_store(self.hass) or {}
store_data = get_store(self.hass)
repositories = {
repo[ATTR_SLUG]: repo[ATTR_NAME]
for repo in store_data.get("repositories", [])
}
if store_data:
repositories = {
repo[ATTR_SLUG]: repo[ATTR_NAME]
for repo in StoreInfo.from_dict(store_data).repositories
}
else:
repositories = {}
new_data[DATA_KEY_ADDONS] = {
addon[ATTR_SLUG]: {

View File

@ -63,17 +63,6 @@ def api_data[**_P](
return _wrapper
@api_data
async def async_get_addon_store_info(hass: HomeAssistant, slug: str) -> dict:
"""Return add-on store info.
The caller of the function should handle HassioAPIError.
"""
hassio: HassIO = hass.data[DOMAIN]
command = f"/store/addons/{slug}"
return await hassio.send_command(command, method="get")
@bind_hass
async def async_update_diagnostics(hass: HomeAssistant, diagnostics: bool) -> bool:
"""Update Supervisor diagnostics toggle.
@ -84,18 +73,6 @@ async def async_update_diagnostics(hass: HomeAssistant, diagnostics: bool) -> bo
return await hassio.update_diagnostics(diagnostics)
@bind_hass
@api_data
async def async_install_addon(hass: HomeAssistant, slug: str) -> dict:
"""Install add-on.
The caller of the function should handle HassioAPIError.
"""
hassio: HassIO = hass.data[DOMAIN]
command = f"/addons/{slug}/install"
return await hassio.send_command(command, timeout=None)
@bind_hass
@api_data
async def async_update_addon(
@ -374,14 +351,6 @@ class HassIO:
f"/addons/{addon}/changelog", method="get", return_text=True
)
@api_data
def get_store(self) -> Coroutine:
"""Return data from the store.
This method returns a coroutine.
"""
return self.send_command("/store", method="get")
@api_data
def get_ingress_panels(self) -> Coroutine:
"""Return data for Add-on ingress panels.

View File

@ -8,6 +8,7 @@ from pathlib import Path
from typing import TYPE_CHECKING, Any
from unittest.mock import AsyncMock, MagicMock, PropertyMock, patch
from aiohasupervisor.models import StoreInfo
import pytest
from homeassistant.const import STATE_OFF, STATE_ON
@ -227,13 +228,14 @@ def addon_store_info_side_effect_fixture() -> Any | None:
@pytest.fixture(name="addon_store_info")
def addon_store_info_fixture(
supervisor_client: AsyncMock,
addon_store_info_side_effect: Any | None,
) -> Generator[AsyncMock]:
) -> AsyncMock:
"""Mock Supervisor add-on store info."""
# pylint: disable-next=import-outside-toplevel
from .hassio.common import mock_addon_store_info
yield from mock_addon_store_info(addon_store_info_side_effect)
return mock_addon_store_info(supervisor_client, addon_store_info_side_effect)
@pytest.fixture(name="addon_info_side_effect")
@ -245,12 +247,12 @@ def addon_info_side_effect_fixture() -> Any | None:
@pytest.fixture(name="addon_info")
def addon_info_fixture(
supervisor_client: AsyncMock, addon_info_side_effect: Any | None
) -> Generator[AsyncMock]:
) -> AsyncMock:
"""Mock Supervisor add-on info."""
# pylint: disable-next=import-outside-toplevel
from .hassio.common import mock_addon_info
yield from mock_addon_info(supervisor_client, addon_info_side_effect)
return mock_addon_info(supervisor_client, addon_info_side_effect)
@pytest.fixture(name="addon_not_installed")
@ -300,13 +302,12 @@ def install_addon_side_effect_fixture(
@pytest.fixture(name="install_addon")
def install_addon_fixture(
supervisor_client: AsyncMock,
install_addon_side_effect: Any | None,
) -> Generator[AsyncMock]:
) -> AsyncMock:
"""Mock install add-on."""
# pylint: disable-next=import-outside-toplevel
from .hassio.common import mock_install_addon
yield from mock_install_addon(install_addon_side_effect)
supervisor_client.store.install_addon.side_effect = install_addon_side_effect
return supervisor_client.store.install_addon
@pytest.fixture(name="start_addon_side_effect")
@ -406,6 +407,13 @@ def update_addon_fixture() -> Generator[AsyncMock]:
yield from mock_update_addon()
@pytest.fixture(name="store_info")
def store_info_fixture(supervisor_client: AsyncMock) -> AsyncMock:
"""Mock store info."""
supervisor_client.store.info.return_value = StoreInfo(addons=[], repositories=[])
return supervisor_client.store.info
@pytest.fixture(name="supervisor_client")
def supervisor_client() -> Generator[AsyncMock]:
"""Mock the supervisor client."""

View File

@ -9,13 +9,14 @@ from types import MethodType
from typing import Any
from unittest.mock import DEFAULT, AsyncMock, Mock, patch
from aiohasupervisor.models import InstalledAddonComplete
from aiohasupervisor.models import InstalledAddonComplete, StoreAddonComplete
from homeassistant.components.hassio.addon_manager import AddonManager
from homeassistant.core import HomeAssistant
LOGGER = logging.getLogger(__name__)
INSTALLED_ADDON_FIELDS = [field.name for field in fields(InstalledAddonComplete)]
STORE_ADDON_FIELDS = [field.name for field in fields(StoreAddonComplete)]
def mock_to_dict(obj: Mock, fields: list[str]) -> dict[str, Any]:
@ -50,25 +51,34 @@ def mock_get_addon_discovery_info(
def mock_addon_store_info(
supervisor_client: AsyncMock,
addon_store_info_side_effect: Any | None,
) -> Generator[AsyncMock]:
) -> AsyncMock:
"""Mock Supervisor add-on store info."""
with patch(
"homeassistant.components.hassio.addon_manager.async_get_addon_store_info",
side_effect=addon_store_info_side_effect,
) as addon_store_info:
addon_store_info.return_value = {
"available": True,
"installed": None,
"state": None,
"version": "1.0.0",
}
yield addon_store_info
supervisor_client.store.addon_info.side_effect = addon_store_info_side_effect
supervisor_client.store.addon_info.return_value = addon_info = Mock(
spec=StoreAddonComplete,
slug="test",
repository="core",
available=True,
installed=False,
update_available=False,
version="1.0.0",
supervisor_api=False,
supervisor_role="default",
)
addon_info.name = "test"
addon_info.to_dict = MethodType(
lambda self: mock_to_dict(self, STORE_ADDON_FIELDS),
addon_info,
)
return supervisor_client.store.addon_info
def mock_addon_info(
supervisor_client: AsyncMock, addon_info_side_effect: Any | None
) -> Generator[AsyncMock]:
) -> AsyncMock:
"""Mock Supervisor add-on info."""
supervisor_client.addons.addon_info.side_effect = addon_info_side_effect
@ -90,14 +100,14 @@ def mock_addon_info(
lambda self: mock_to_dict(self, INSTALLED_ADDON_FIELDS),
addon_info,
)
yield supervisor_client.addons.addon_info
return supervisor_client.addons.addon_info
def mock_addon_not_installed(
addon_store_info: AsyncMock, addon_info: AsyncMock
) -> AsyncMock:
"""Mock add-on not installed."""
addon_store_info.return_value["available"] = True
addon_store_info.return_value.available = True
return addon_info
@ -105,12 +115,8 @@ def mock_addon_installed(
addon_store_info: AsyncMock, addon_info: AsyncMock
) -> AsyncMock:
"""Mock add-on already installed but not running."""
addon_store_info.return_value = {
"available": True,
"installed": "1.0.0",
"state": "stopped",
"version": "1.0.0",
}
addon_store_info.return_value.available = True
addon_store_info.return_value.installed = True
addon_info.return_value.available = True
addon_info.return_value.hostname = "core-test-addon"
addon_info.return_value.state = "stopped"
@ -120,12 +126,8 @@ def mock_addon_installed(
def mock_addon_running(addon_store_info: AsyncMock, addon_info: AsyncMock) -> AsyncMock:
"""Mock add-on already running."""
addon_store_info.return_value = {
"available": True,
"installed": "1.0.0",
"state": "started",
"version": "1.0.0",
}
addon_store_info.return_value.available = True
addon_store_info.return_value.installed = True
addon_info.return_value.state = "started"
return addon_info
@ -135,15 +137,10 @@ def mock_install_addon_side_effect(
) -> Any | None:
"""Return the install add-on side effect."""
async def install_addon(hass: HomeAssistant, slug):
async def install_addon(addon: str):
"""Mock install add-on."""
addon_store_info.return_value = {
"available": True,
"installed": "1.0.0",
"state": "stopped",
"version": "1.0.0",
}
addon_store_info.return_value.available = True
addon_store_info.return_value.installed = True
addon_info.return_value.available = True
addon_info.return_value.state = "stopped"
addon_info.return_value.version = "1.0.0"
@ -151,16 +148,6 @@ def mock_install_addon_side_effect(
return install_addon
def mock_install_addon(install_addon_side_effect: Any | None) -> Generator[AsyncMock]:
"""Mock install add-on."""
with patch(
"homeassistant.components.hassio.addon_manager.async_install_addon",
side_effect=install_addon_side_effect,
) as install_addon:
yield install_addon
def mock_start_addon_side_effect(
addon_store_info: AsyncMock, addon_info: AsyncMock
) -> Any | None:
@ -168,12 +155,8 @@ def mock_start_addon_side_effect(
async def start_addon(addon: str) -> None:
"""Mock start add-on."""
addon_store_info.return_value = {
"available": True,
"installed": "1.0.0",
"state": "started",
"version": "1.0.0",
}
addon_store_info.return_value.available = True
addon_store_info.return_value.installed = True
addon_info.return_value.available = True
addon_info.return_value.state = "started"

View File

@ -3,8 +3,9 @@
from collections.abc import Generator
import os
import re
from unittest.mock import Mock, patch
from unittest.mock import AsyncMock, Mock, patch
from aiohasupervisor.models import AddonState
from aiohttp.test_utils import TestClient
import pytest
@ -129,7 +130,10 @@ def hassio_handler(
@pytest.fixture
def all_setup_requests(
aioclient_mock: AiohttpClientMocker, request: pytest.FixtureRequest
aioclient_mock: AiohttpClientMocker,
request: pytest.FixtureRequest,
addon_installed: AsyncMock,
store_info,
) -> None:
"""Mock all setup requests."""
include_addons = hasattr(request, "param") and request.param.get(
@ -150,13 +154,6 @@ def all_setup_requests(
},
},
)
aioclient_mock.get(
"http://127.0.0.1/store",
json={
"result": "ok",
"data": {"addons": [], "repositories": []},
},
)
aioclient_mock.get(
"http://127.0.0.1/host/info",
json={
@ -227,44 +224,33 @@ def all_setup_requests(
)
aioclient_mock.post("http://127.0.0.1/refresh_updates", json={"result": "ok"})
addon_installed.return_value.update_available = False
addon_installed.return_value.version = "1.0.0"
addon_installed.return_value.version_latest = "1.0.0"
addon_installed.return_value.repository = "core"
addon_installed.return_value.state = AddonState.STARTED
addon_installed.return_value.icon = False
def mock_addon_info(slug: str):
if slug == "test":
addon_installed.return_value.name = "test"
addon_installed.return_value.slug = "test"
addon_installed.return_value.url = (
"https://github.com/home-assistant/addons/test"
)
addon_installed.return_value.auto_update = True
else:
addon_installed.return_value.name = "test2"
addon_installed.return_value.slug = "test2"
addon_installed.return_value.url = "https://github.com"
addon_installed.return_value.auto_update = False
return addon_installed.return_value
addon_installed.side_effect = mock_addon_info
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={
"result": "ok",
"data": {
"name": "test",
"slug": "test",
"update_available": False,
"version": "1.0.0",
"version_latest": "1.0.0",
"repository": "core",
"state": "started",
"icon": False,
"url": "https://github.com/home-assistant/addons/test",
"auto_update": True,
},
},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={
"result": "ok",
"data": {
"name": "test2",
"slug": "test2",
"update_available": False,
"version": "1.0.0",
"version_latest": "1.0.0",
"repository": "core",
"state": "started",
"icon": False,
"url": "https://github.com",
"auto_update": False,
},
},
)
aioclient_mock.get(
"http://127.0.0.1/core/stats",
json={

View File

@ -43,7 +43,7 @@ async def test_not_available_raises_exception(
addon_info: AsyncMock,
) -> None:
"""Test addon not available raises exception."""
addon_store_info.return_value["available"] = False
addon_store_info.return_value.available = False
addon_info.return_value.available = False
with pytest.raises(AddonError) as err:
@ -198,7 +198,7 @@ async def test_install_addon(
addon_info: AsyncMock,
) -> None:
"""Test install addon."""
addon_store_info.return_value["available"] = True
addon_store_info.return_value.available = True
addon_info.return_value.available = True
await addon_manager.async_install_addon()
@ -213,7 +213,7 @@ async def test_install_addon_error(
addon_info: AsyncMock,
) -> None:
"""Test install addon raises error."""
addon_store_info.return_value["available"] = True
addon_store_info.return_value.available = True
addon_info.return_value.available = True
install_addon.side_effect = HassioAPIError("Boom")

View File

@ -17,7 +17,7 @@ MOCK_ENVIRON = {"SUPERVISOR": "127.0.0.1", "SUPERVISOR_TOKEN": "abcdefgh"}
@pytest.fixture(autouse=True)
def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed, store_info) -> None:
"""Mock all setup requests."""
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
aioclient_mock.get("http://127.0.0.1/supervisor/ping", json={"result": "ok"})
@ -33,13 +33,6 @@ def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
},
},
)
aioclient_mock.get(
"http://127.0.0.1/store",
json={
"result": "ok",
"data": {"addons": [], "repositories": []},
},
)
aioclient_mock.get(
"http://127.0.0.1/host/info",
json={
@ -154,15 +147,7 @@ def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)

View File

@ -18,7 +18,7 @@ MOCK_ENVIRON = {"SUPERVISOR": "127.0.0.1", "SUPERVISOR_TOKEN": "abcdefgh"}
@pytest.fixture(autouse=True)
def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed, store_info) -> None:
"""Mock all setup requests."""
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
aioclient_mock.get("http://127.0.0.1/supervisor/ping", json={"result": "ok"})
@ -34,13 +34,6 @@ def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
},
},
)
aioclient_mock.get(
"http://127.0.0.1/store",
json={
"result": "ok",
"data": {"addons": [], "repositories": []},
},
)
aioclient_mock.get(
"http://127.0.0.1/host/info",
json={
@ -159,15 +152,7 @@ def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)

View File

@ -3,7 +3,7 @@
from datetime import timedelta
import os
from typing import Any
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
import pytest
from voluptuous import Invalid
@ -15,7 +15,6 @@ from homeassistant.components.hassio import (
ADDONS_COORDINATOR,
DOMAIN,
STORAGE_KEY,
async_get_addon_store_info,
get_core_info,
hostname_from_addon_slug,
is_hassio,
@ -52,7 +51,9 @@ def os_info(extra_os_info):
@pytest.fixture(autouse=True)
def mock_all(aioclient_mock: AiohttpClientMocker, os_info) -> None:
def mock_all(
aioclient_mock: AiohttpClientMocker, os_info, store_info, addon_info
) -> None:
"""Mock all setup requests."""
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
aioclient_mock.get("http://127.0.0.1/supervisor/ping", json={"result": "ok"})
@ -68,13 +69,6 @@ def mock_all(aioclient_mock: AiohttpClientMocker, os_info) -> None:
},
},
)
aioclient_mock.get(
"http://127.0.0.1/store",
json={
"result": "ok",
"data": {"addons": [], "repositories": []},
},
)
aioclient_mock.get(
"http://127.0.0.1/host/info",
json={
@ -250,7 +244,9 @@ def mock_all(aioclient_mock: AiohttpClientMocker, os_info) -> None:
async def test_setup_api_ping(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
supervisor_client: AsyncMock,
) -> None:
"""Test setup with API ping."""
with patch.dict(os.environ, MOCK_ENVIRON):
@ -258,7 +254,7 @@ async def test_setup_api_ping(
await hass.async_block_till_done()
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert get_core_info(hass)["version_latest"] == "1.0.0"
assert is_hassio(hass)
@ -293,7 +289,9 @@ async def test_setup_api_panel(
async def test_setup_api_push_api_data(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
supervisor_client: AsyncMock,
) -> None:
"""Test setup with API push."""
with patch.dict(os.environ, MOCK_ENVIRON):
@ -303,14 +301,16 @@ async def test_setup_api_push_api_data(
await hass.async_block_till_done()
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert not aioclient_mock.mock_calls[1][2]["ssl"]
assert aioclient_mock.mock_calls[1][2]["port"] == 9999
assert "watchdog" not in aioclient_mock.mock_calls[1][2]
async def test_setup_api_push_api_data_server_host(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
supervisor_client: AsyncMock,
) -> None:
"""Test setup with API push with active server host."""
with patch.dict(os.environ, MOCK_ENVIRON):
@ -322,7 +322,7 @@ async def test_setup_api_push_api_data_server_host(
await hass.async_block_till_done()
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert not aioclient_mock.mock_calls[1][2]["ssl"]
assert aioclient_mock.mock_calls[1][2]["port"] == 9999
assert not aioclient_mock.mock_calls[1][2]["watchdog"]
@ -332,6 +332,7 @@ async def test_setup_api_push_api_data_default(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
hass_storage: dict[str, Any],
supervisor_client: AsyncMock,
) -> None:
"""Test setup with API push default data."""
with patch.dict(os.environ, MOCK_ENVIRON):
@ -339,7 +340,7 @@ async def test_setup_api_push_api_data_default(
await hass.async_block_till_done()
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert not aioclient_mock.mock_calls[1][2]["ssl"]
assert aioclient_mock.mock_calls[1][2]["port"] == 8123
refresh_token = aioclient_mock.mock_calls[1][2]["refresh_token"]
@ -409,6 +410,7 @@ async def test_setup_api_existing_hassio_user(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
hass_storage: dict[str, Any],
supervisor_client: AsyncMock,
) -> None:
"""Test setup with API push default data."""
user = await hass.auth.async_create_system_user("Hass.io test")
@ -419,14 +421,16 @@ async def test_setup_api_existing_hassio_user(
await hass.async_block_till_done()
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert not aioclient_mock.mock_calls[1][2]["ssl"]
assert aioclient_mock.mock_calls[1][2]["port"] == 8123
assert aioclient_mock.mock_calls[1][2]["refresh_token"] == token.token
async def test_setup_core_push_timezone(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
supervisor_client: AsyncMock,
) -> None:
"""Test setup with API push default data."""
hass.config.time_zone = "testzone"
@ -436,7 +440,7 @@ async def test_setup_core_push_timezone(
await hass.async_block_till_done()
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert aioclient_mock.mock_calls[2][2]["timezone"] == "testzone"
with patch("homeassistant.util.dt.set_default_time_zone"):
@ -446,7 +450,9 @@ async def test_setup_core_push_timezone(
async def test_setup_hassio_no_additional_data(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
supervisor_client: AsyncMock,
) -> None:
"""Test setup with API push default data."""
with (
@ -457,7 +463,7 @@ async def test_setup_hassio_no_additional_data(
await hass.async_block_till_done()
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert aioclient_mock.mock_calls[-1][3]["Authorization"] == "Bearer 123456"
@ -509,6 +515,7 @@ async def test_service_calls(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
caplog: pytest.LogCaptureFixture,
supervisor_client: AsyncMock,
addon_installed,
issue_registry: ir.IssueRegistry,
) -> None:
@ -549,14 +556,14 @@ async def test_service_calls(
)
await hass.async_block_till_done()
assert aioclient_mock.call_count == 22
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 24
assert aioclient_mock.mock_calls[-1][2] == "test"
await hass.services.async_call("hassio", "host_shutdown", {})
await hass.services.async_call("hassio", "host_reboot", {})
await hass.async_block_till_done()
assert aioclient_mock.call_count == 24
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 26
await hass.services.async_call("hassio", "backup_full", {})
await hass.services.async_call(
@ -571,7 +578,7 @@ async def test_service_calls(
)
await hass.async_block_till_done()
assert aioclient_mock.call_count == 26
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 28
assert aioclient_mock.mock_calls[-1][2] == {
"name": "2021-11-13 03:48:00",
"homeassistant": True,
@ -596,7 +603,7 @@ async def test_service_calls(
)
await hass.async_block_till_done()
assert aioclient_mock.call_count == 28
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 30
assert aioclient_mock.mock_calls[-1][2] == {
"addons": ["test"],
"folders": ["ssl"],
@ -615,7 +622,7 @@ async def test_service_calls(
)
await hass.async_block_till_done()
assert aioclient_mock.call_count == 29
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 31
assert aioclient_mock.mock_calls[-1][2] == {
"name": "backup_name",
"location": "backup_share",
@ -631,7 +638,7 @@ async def test_service_calls(
)
await hass.async_block_till_done()
assert aioclient_mock.call_count == 30
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 32
assert aioclient_mock.mock_calls[-1][2] == {
"name": "2021-11-13 03:48:00",
"location": None,
@ -650,7 +657,7 @@ async def test_service_calls(
)
await hass.async_block_till_done()
assert aioclient_mock.call_count == 32
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 34
assert aioclient_mock.mock_calls[-1][2] == {
"name": "2021-11-13 11:48:00",
"location": None,
@ -723,7 +730,9 @@ async def test_addon_service_call_with_complex_slug(
@pytest.mark.usefixtures("hassio_env")
async def test_service_calls_core(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
supervisor_client: AsyncMock,
) -> None:
"""Call core service and check the API calls behind that."""
assert await async_setup_component(hass, "homeassistant", {})
@ -735,12 +744,12 @@ async def test_service_calls_core(
await hass.services.async_call("homeassistant", "stop")
await hass.async_block_till_done()
assert aioclient_mock.call_count == 5
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 5
await hass.services.async_call("homeassistant", "check_config")
await hass.async_block_till_done()
assert aioclient_mock.call_count == 5
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 5
with patch(
"homeassistant.config.async_check_ha_config_file", return_value=None
@ -749,7 +758,7 @@ async def test_service_calls_core(
await hass.async_block_till_done()
assert mock_check_config.called
assert aioclient_mock.call_count == 6
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 6
@pytest.mark.usefixtures("addon_installed")
@ -1105,7 +1114,10 @@ async def test_coordinator_updates_stats_entities_enabled(
],
)
async def test_setup_hardware_integration(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, integration
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
supervisor_client: AsyncMock,
integration,
) -> None:
"""Test setup initiates hardware integration."""
@ -1120,26 +1132,10 @@ async def test_setup_hardware_integration(
await hass.async_block_till_done(wait_background_tasks=True)
assert result
assert aioclient_mock.call_count == 20
assert aioclient_mock.call_count + len(supervisor_client.mock_calls) == 20
assert len(mock_setup_entry.mock_calls) == 1
@pytest.mark.usefixtures("hassio_stubs")
async def test_get_store_addon_info(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test get store add-on info from Supervisor API."""
aioclient_mock.clear_requests()
aioclient_mock.get(
"http://127.0.0.1/store/addons/test",
json={"result": "ok", "data": {"name": "bla"}},
)
data = await async_get_addon_store_info(hass, "test")
assert data["name"] == "bla"
assert aioclient_mock.call_count == 1
def test_hostname_from_addon_slug() -> None:
"""Test hostname_from_addon_slug."""
assert hostname_from_addon_slug("mqtt") == "mqtt"

View File

@ -835,7 +835,7 @@ async def test_system_is_not_ready(
@pytest.mark.parametrize(
"all_setup_requests", [{"include_addons": True}], indirect=True
)
@pytest.mark.usefixtures("all_setup_requests", "addon_installed")
@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issues_detached_addon_missing(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,

View File

@ -563,7 +563,7 @@ async def test_mount_failed_repair_flow(
@pytest.mark.parametrize(
"all_setup_requests", [{"include_addons": True}], indirect=True
)
@pytest.mark.usefixtures("all_setup_requests", "addon_installed")
@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issue_docker_config_repair_flow(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
@ -786,7 +786,7 @@ async def test_supervisor_issue_repair_flow_multiple_data_disks(
@pytest.mark.parametrize(
"all_setup_requests", [{"include_addons": True}], indirect=True
)
@pytest.mark.usefixtures("all_setup_requests", "addon_installed")
@pytest.mark.usefixtures("all_setup_requests")
async def test_supervisor_issue_detached_addon_removed(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,

View File

@ -2,7 +2,7 @@
from datetime import timedelta
import os
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
from freezegun.api import FrozenDateTimeFactory
import pytest
@ -28,7 +28,11 @@ MOCK_ENVIRON = {"SUPERVISOR": "127.0.0.1", "SUPERVISOR_TOKEN": "abcdefgh"}
@pytest.fixture(autouse=True)
def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
def mock_all(
aioclient_mock: AiohttpClientMocker,
addon_installed: AsyncMock,
store_info: AsyncMock,
) -> None:
"""Mock all setup requests."""
_install_default_mocks(aioclient_mock)
_install_test_addon_stats_mock(aioclient_mock)
@ -78,13 +82,6 @@ def _install_default_mocks(aioclient_mock: AiohttpClientMocker):
},
},
)
aioclient_mock.get(
"http://127.0.0.1/store",
json={
"result": "ok",
"data": {"addons": [], "repositories": []},
},
)
aioclient_mock.get(
"http://127.0.0.1/host/info",
json={
@ -176,15 +173,7 @@ def _install_default_mocks(aioclient_mock: AiohttpClientMocker):
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)

View File

@ -22,7 +22,7 @@ MOCK_ENVIRON = {"SUPERVISOR": "127.0.0.1", "SUPERVISOR_TOKEN": "abcdefgh"}
@pytest.fixture(autouse=True)
def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed, store_info) -> None:
"""Mock all setup requests."""
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
aioclient_mock.get("http://127.0.0.1/supervisor/ping", json={"result": "ok"})
@ -38,13 +38,6 @@ def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
},
},
)
aioclient_mock.get(
"http://127.0.0.1/store",
json={
"result": "ok",
"data": {"addons": [], "repositories": []},
},
)
aioclient_mock.get(
"http://127.0.0.1/host/info",
json={
@ -164,15 +157,7 @@ def mock_all(aioclient_mock: AiohttpClientMocker, addon_installed) -> None:
},
)
aioclient_mock.get("http://127.0.0.1/addons/test/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test/info",
json={"result": "ok", "data": {"auto_update": True}},
)
aioclient_mock.get("http://127.0.0.1/addons/test2/changelog", text="")
aioclient_mock.get(
"http://127.0.0.1/addons/test2/info",
json={"result": "ok", "data": {"auto_update": False}},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)

View File

@ -120,6 +120,11 @@ def mock_test_firmware_platform(
yield
@pytest.fixture(autouse=True)
async def fixture_mock_supervisor_client(supervisor_client: AsyncMock):
"""Mock supervisor client in tests."""
def delayed_side_effect() -> Callable[..., Awaitable[None]]:
"""Slows down eager tasks by delaying for an event loop tick."""

View File

@ -25,6 +25,11 @@ from .test_config_flow import (
from tests.common import MockConfigEntry
@pytest.fixture(autouse=True)
async def fixture_mock_supervisor_client(supervisor_client: AsyncMock):
"""Mock supervisor client in tests."""
@pytest.mark.parametrize(
"next_step",
[

View File

@ -247,7 +247,7 @@ async def test_option_flow_install_multi_pan_addon(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.SHOW_PROGRESS
@ -322,7 +322,7 @@ async def test_option_flow_install_multi_pan_addon_zha(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
multipan_manager = await silabs_multiprotocol_addon.get_multiprotocol_addon_manager(
hass
@ -417,7 +417,7 @@ async def test_option_flow_install_multi_pan_addon_zha_other_radio(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
addon_info.return_value.hostname = "core-silabs-multiprotocol"
result = await hass.config_entries.options.async_configure(result["flow_id"])
@ -678,11 +678,8 @@ async def test_option_flow_addon_installed_same_device_uninstall(
assert result["step_id"] == "uninstall_addon"
# Make sure the flasher addon is installed
addon_store_info.return_value = {
"installed": None,
"available": True,
"state": "not_installed",
}
addon_store_info.return_value.installed = False
addon_store_info.return_Value.available = True
result = await hass.config_entries.options.async_configure(
result["flow_id"], {silabs_multiprotocol_addon.CONF_DISABLE_MULTI_PAN: True}
@ -709,7 +706,7 @@ async def test_option_flow_addon_installed_same_device_uninstall(
assert result["description_placeholders"] == {"addon_name": "Silicon Labs Flasher"}
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_flasher")
install_addon.assert_called_once_with("core_silabs_flasher")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.CREATE_ENTRY
@ -805,7 +802,7 @@ async def test_option_flow_flasher_already_running_failure(
assert result["step_id"] == "uninstall_addon"
# The flasher addon is already installed and running, this is bad
addon_store_info.return_value["installed"] = True
addon_store_info.return_value.installed = True
addon_info.return_value.state = "started"
result = await hass.config_entries.options.async_configure(
@ -851,11 +848,8 @@ async def test_option_flow_addon_installed_same_device_flasher_already_installed
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "uninstall_addon"
addon_store_info.return_value = {
"installed": True,
"available": True,
"state": "not_running",
}
addon_store_info.return_value.installed = True
addon_store_info.return_value.available = True
result = await hass.config_entries.options.async_configure(
result["flow_id"], {silabs_multiprotocol_addon.CONF_DISABLE_MULTI_PAN: True}
@ -873,11 +867,8 @@ async def test_option_flow_addon_installed_same_device_flasher_already_installed
assert result["progress_action"] == "start_flasher_addon"
assert result["description_placeholders"] == {"addon_name": "Silicon Labs Flasher"}
addon_store_info.return_value = {
"installed": True,
"available": True,
"state": "not_running",
}
addon_store_info.return_value.installed = True
addon_store_info.return_value.available = True
await hass.async_block_till_done()
install_addon.assert_not_called()
@ -932,11 +923,8 @@ async def test_option_flow_flasher_install_failure(
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "uninstall_addon"
addon_store_info.return_value = {
"installed": None,
"available": True,
"state": "not_installed",
}
addon_store_info.return_value.installed = False
addon_store_info.return_value.available = True
install_addon.side_effect = [AddonError()]
result = await hass.config_entries.options.async_configure(
result["flow_id"], {silabs_multiprotocol_addon.CONF_DISABLE_MULTI_PAN: True}
@ -947,7 +935,7 @@ async def test_option_flow_flasher_install_failure(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_flasher")
install_addon.assert_called_once_with("core_silabs_flasher")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.ABORT
@ -1214,7 +1202,7 @@ async def test_option_flow_install_multi_pan_addon_install_fails(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.ABORT
@ -1257,7 +1245,7 @@ async def test_option_flow_install_multi_pan_addon_start_fails(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.SHOW_PROGRESS
@ -1319,7 +1307,7 @@ async def test_option_flow_install_multi_pan_addon_set_options_fails(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.ABORT
@ -1396,7 +1384,7 @@ async def test_option_flow_install_multi_pan_addon_zha_migration_fails_step_1(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.ABORT
@ -1452,7 +1440,7 @@ async def test_option_flow_install_multi_pan_addon_zha_migration_fails_step_2(
assert result["progress_action"] == "install_addon"
await hass.async_block_till_done()
install_addon.assert_called_once_with(hass, "core_silabs_multiprotocol")
install_addon.assert_called_once_with("core_silabs_multiprotocol")
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert result["type"] is FlowResultType.SHOW_PROGRESS
@ -1669,11 +1657,8 @@ async def test_check_multi_pan_addon_auto_start(
"""Test `check_multi_pan_addon` auto starting the addon."""
addon_info.return_value.state = "not_running"
addon_store_info.return_value = {
"installed": True,
"available": True,
"state": "not_running",
}
addon_store_info.return_value.installed = True
addon_store_info.return_value.available = True
# An error is raised even if we auto-start
with pytest.raises(HomeAssistantError):
@ -1688,11 +1673,8 @@ async def test_check_multi_pan_addon(
"""Test `check_multi_pan_addon`."""
addon_info.return_value.state = "started"
addon_store_info.return_value = {
"installed": True,
"available": True,
"state": "running",
}
addon_store_info.return_value.installed = True
addon_store_info.return_value.available = True
await silabs_multiprotocol_addon.check_multi_pan_addon(hass)
start_addon.assert_not_called()
@ -1719,11 +1701,8 @@ async def test_multi_pan_addon_using_device_not_running(
"""Test `multi_pan_addon_using_device` when the addon isn't running."""
addon_info.return_value.state = "not_running"
addon_store_info.return_value = {
"installed": True,
"available": True,
"state": "not_running",
}
addon_store_info.return_value.installed = True
addon_store_info.return_value.available = True
assert (
await silabs_multiprotocol_addon.multi_pan_addon_using_device(
@ -1753,11 +1732,8 @@ async def test_multi_pan_addon_using_device(
"baudrate": "115200",
"flow_control": True,
}
addon_store_info.return_value = {
"installed": True,
"available": True,
"state": "running",
}
addon_store_info.return_value.installed = True
addon_store_info.return_value.available = True
assert (
await silabs_multiprotocol_addon.multi_pan_addon_using_device(

View File

@ -159,6 +159,7 @@ async def test_options_flow(
}
@pytest.mark.usefixtures("supervisor_client")
@pytest.mark.parametrize(
("usb_data", "model"),
[

View File

@ -341,6 +341,7 @@ async def test_firmware_options_flow(hass: HomeAssistant) -> None:
}
@pytest.mark.usefixtures("supervisor_client")
async def test_options_flow_multipan_uninstall(hass: HomeAssistant) -> None:
"""Test options flow for when multi-PAN firmware is installed."""
mock_integration(hass, MockModule("hassio"))

View File

@ -418,7 +418,7 @@ async def test_zeroconf_not_onboarded_not_installed(
assert addon_info.call_count == 0
assert addon_store_info.call_count == 2
assert install_addon.call_args == call(hass, "core_matter_server")
assert install_addon.call_args == call("core_matter_server")
assert start_addon.call_args == call("core_matter_server")
assert client_connect.call_count == 1
assert result["type"] is FlowResultType.CREATE_ENTRY
@ -733,7 +733,7 @@ async def test_supervisor_discovery_addon_not_installed(
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_matter_server")
assert install_addon.call_args == call("core_matter_server")
assert result["type"] is FlowResultType.SHOW_PROGRESS
assert result["step_id"] == "start_addon"
@ -1291,7 +1291,7 @@ async def test_addon_not_installed(
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_matter_server")
assert install_addon.call_args == call("core_matter_server")
assert result["type"] is FlowResultType.SHOW_PROGRESS
assert result["step_id"] == "start_addon"
@ -1338,7 +1338,7 @@ async def test_addon_not_installed_failures(
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_matter_server")
assert install_addon.call_args == call("core_matter_server")
assert addon_info.call_count == 0
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "addon_install_failed"
@ -1362,7 +1362,7 @@ async def test_addon_not_installed_failures_zeroconf(
)
await hass.async_block_till_done()
assert install_addon.call_args == call(hass, "core_matter_server")
assert install_addon.call_args == call("core_matter_server")
assert addon_info.call_count == 0
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "addon_install_failed"
@ -1410,7 +1410,7 @@ async def test_addon_not_installed_already_configured(
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_matter_server")
assert install_addon.call_args == call("core_matter_server")
assert result["type"] is FlowResultType.SHOW_PROGRESS
assert result["step_id"] == "start_addon"

View File

@ -246,10 +246,10 @@ async def test_raise_addon_task_in_progress(
install_addon_original_side_effect = install_addon.side_effect
async def install_addon_side_effect(hass: HomeAssistant, slug: str) -> None:
async def install_addon_side_effect(slug: str) -> None:
"""Mock install add-on."""
await install_event.wait()
await install_addon_original_side_effect(hass, slug)
await install_addon_original_side_effect(slug)
install_addon.side_effect = install_addon_side_effect
@ -337,7 +337,7 @@ async def test_install_addon(
assert entry.state is ConfigEntryState.SETUP_RETRY
assert addon_store_info.call_count == 3
assert install_addon.call_count == 1
assert install_addon.call_args == call(hass, "core_matter_server")
assert install_addon.call_args == call("core_matter_server")
assert start_addon.call_count == 1
assert start_addon.call_args == call("core_matter_server")

View File

@ -69,7 +69,7 @@ async def no_rpi_fixture(
@pytest.fixture(name="mock_supervisor")
async def mock_supervisor_fixture(
aioclient_mock: AiohttpClientMocker,
aioclient_mock: AiohttpClientMocker, store_info
) -> AsyncGenerator[None]:
"""Mock supervisor."""
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
@ -111,10 +111,6 @@ async def mock_supervisor_fixture(
"homeassistant.components.hassio.HassIO.get_host_info",
return_value={},
),
patch(
"homeassistant.components.hassio.HassIO.get_store",
return_value={},
),
patch(
"homeassistant.components.hassio.HassIO.get_supervisor_info",
return_value={"diagnostics": True},

View File

@ -583,7 +583,7 @@ async def test_usb_discovery(
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_zwave_js")
assert install_addon.call_args == call("core_zwave_js")
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "configure_addon"
@ -881,7 +881,7 @@ async def test_discovery_addon_not_installed(
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_zwave_js")
assert install_addon.call_args == call("core_zwave_js")
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "configure_addon"
@ -1700,7 +1700,7 @@ async def test_addon_not_installed(
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_zwave_js")
assert install_addon.call_args == call("core_zwave_js")
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "configure_addon"
@ -1794,7 +1794,7 @@ async def test_install_addon_failure(
result = await hass.config_entries.flow.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_zwave_js")
assert install_addon.call_args == call("core_zwave_js")
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "addon_install_failed"
@ -2685,7 +2685,7 @@ async def test_options_addon_not_installed(
result = await hass.config_entries.options.async_configure(result["flow_id"])
assert install_addon.call_args == call(hass, "core_zwave_js")
assert install_addon.call_args == call("core_zwave_js")
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "configure_addon"

View File

@ -600,7 +600,7 @@ async def test_install_addon(
assert entry.state is ConfigEntryState.SETUP_RETRY
assert install_addon.call_count == 1
assert install_addon.call_args == call(hass, "core_zwave_js")
assert install_addon.call_args == call("core_zwave_js")
assert set_addon_options.call_count == 1
assert set_addon_options.call_args == call(
hass, "core_zwave_js", {"options": addon_options}