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 privatepull/128087/head
parent
f504c27972
commit
a9aa5ad229
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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]: {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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={
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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": {}}}
|
||||
)
|
||||
|
|
|
@ -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": {}}}
|
||||
)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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": {}}}
|
||||
)
|
||||
|
|
|
@ -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": {}}}
|
||||
)
|
||||
|
|
|
@ -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."""
|
||||
|
||||
|
|
|
@ -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",
|
||||
[
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -159,6 +159,7 @@ async def test_options_flow(
|
|||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("supervisor_client")
|
||||
@pytest.mark.parametrize(
|
||||
("usb_data", "model"),
|
||||
[
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue