Files
core/tests/components/hassio/test_switch.py
2025-10-04 02:22:59 +02:00

306 lines
9.2 KiB
Python

"""The tests for the hassio switch."""
from collections.abc import AsyncGenerator
import os
from unittest.mock import AsyncMock, patch
import pytest
from homeassistant.components.hassio import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .common import MOCK_REPOSITORIES, MOCK_STORE_ADDONS
from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker
MOCK_ENVIRON = {"SUPERVISOR": "127.0.0.1", "SUPERVISOR_TOKEN": "abcdefgh"}
@pytest.fixture
async def setup_integration(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
) -> AsyncGenerator[MockConfigEntry]:
"""Set up the hassio integration and enable entity."""
config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=DOMAIN)
config_entry.add_to_hass(hass)
with patch.dict(os.environ, MOCK_ENVIRON):
result = await async_setup_component(
hass,
"hassio",
{"http": {"server_port": 9999, "server_host": "127.0.0.1"}, "hassio": {}},
)
assert result
await hass.async_block_till_done()
yield config_entry
async def enable_entity(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
config_entry: MockConfigEntry,
entity_id: str,
) -> None:
"""Enable an entity and reload the config entry."""
entity_registry.async_update_entity(entity_id, disabled_by=None)
await hass.config_entries.async_reload(config_entry.entry_id)
await hass.async_block_till_done()
@pytest.fixture(autouse=True)
def mock_all(
aioclient_mock: AiohttpClientMocker,
addon_installed: AsyncMock,
store_info: AsyncMock,
addon_changelog: AsyncMock,
addon_stats: AsyncMock,
resolution_info: AsyncMock,
) -> None:
"""Mock all setup requests."""
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
aioclient_mock.post("http://127.0.0.1/supervisor/options", json={"result": "ok"})
aioclient_mock.get(
"http://127.0.0.1/info",
json={
"result": "ok",
"data": {
"supervisor": "222",
"homeassistant": "0.110.0",
"hassos": "1.2.3",
},
},
)
aioclient_mock.get(
"http://127.0.0.1/host/info",
json={
"result": "ok",
"data": {
"result": "ok",
"data": {
"chassis": "vm",
"operating_system": "Debian GNU/Linux 10 (buster)",
"kernel": "4.19.0-6-amd64",
},
},
},
)
aioclient_mock.get(
"http://127.0.0.1/core/info",
json={"result": "ok", "data": {"version_latest": "1.0.0", "version": "1.0.0"}},
)
aioclient_mock.get(
"http://127.0.0.1/os/info",
json={
"result": "ok",
"data": {
"version_latest": "1.0.0",
"version": "1.0.0",
"update_available": False,
},
},
)
aioclient_mock.get(
"http://127.0.0.1/supervisor/info",
json={
"result": "ok",
"data": {
"result": "ok",
"version": "1.0.0",
"version_latest": "1.0.0",
"auto_update": True,
"addons": [
{
"name": "test",
"state": "started",
"slug": "test",
"installed": True,
"update_available": True,
"icon": False,
"version": "2.0.0",
"version_latest": "2.0.1",
"repository": "core",
"url": "https://github.com/home-assistant/addons/test",
},
{
"name": "test-two",
"state": "stopped",
"slug": "test-two",
"installed": True,
"update_available": False,
"icon": True,
"version": "3.1.0",
"version_latest": "3.1.0",
"repository": "core",
"url": "https://github.com",
},
],
},
},
)
aioclient_mock.get(
"http://127.0.0.1/core/stats",
json={
"result": "ok",
"data": {
"cpu_percent": 0.99,
"memory_usage": 182611968,
"memory_limit": 3977146368,
"memory_percent": 4.59,
"network_rx": 362570232,
"network_tx": 82374138,
"blk_read": 46010945536,
"blk_write": 15051526144,
},
},
)
aioclient_mock.get(
"http://127.0.0.1/supervisor/stats",
json={
"result": "ok",
"data": {
"cpu_percent": 0.99,
"memory_usage": 182611968,
"memory_limit": 3977146368,
"memory_percent": 4.59,
"network_rx": 362570232,
"network_tx": 82374138,
"blk_read": 46010945536,
"blk_write": 15051526144,
},
},
)
aioclient_mock.get(
"http://127.0.0.1/ingress/panels", json={"result": "ok", "data": {"panels": {}}}
)
aioclient_mock.get(
"http://127.0.0.1/network/info",
json={
"result": "ok",
"data": {
"host_internet": True,
"supervisor_internet": True,
},
},
)
@pytest.mark.parametrize(
("store_addons", "store_repositories"), [(MOCK_STORE_ADDONS, MOCK_REPOSITORIES)]
)
@pytest.mark.parametrize(
("entity_id", "expected", "addon_state"),
[
("switch.test", "on", "started"),
("switch.test_two", "off", "stopped"),
],
)
async def test_switch_state(
hass: HomeAssistant,
entity_id: str,
expected: str,
addon_state: str,
entity_registry: er.EntityRegistry,
addon_installed: AsyncMock,
setup_integration: MockConfigEntry,
) -> None:
"""Test hassio addon switch state."""
addon_installed.return_value.state = addon_state
# Verify that the entity is disabled by default.
assert hass.states.get(entity_id) is None
# Enable the entity.
await enable_entity(hass, entity_registry, setup_integration, entity_id)
# Verify that the entity have the expected state.
state = hass.states.get(entity_id)
assert state is not None
assert state.state == expected
@pytest.mark.parametrize(
("store_addons", "store_repositories"), [(MOCK_STORE_ADDONS, MOCK_REPOSITORIES)]
)
async def test_switch_turn_on(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
entity_registry: er.EntityRegistry,
addon_installed: AsyncMock,
setup_integration: MockConfigEntry,
) -> None:
"""Test turning on addon switch."""
entity_id = "switch.test_two"
addon_installed.return_value.state = "stopped"
# Mock the start addon API call
aioclient_mock.post("http://127.0.0.1/addons/test-two/start", json={"result": "ok"})
# Verify that the entity is disabled by default.
assert hass.states.get(entity_id) is None
# Enable the entity.
await enable_entity(hass, entity_registry, setup_integration, entity_id)
# Verify initial state is off
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "off"
# Turn on the switch
await hass.services.async_call(
"switch",
"turn_on",
{"entity_id": entity_id},
blocking=True,
)
# Verify the API was called
assert aioclient_mock.mock_calls[-1][1].path == "/addons/test-two/start"
assert aioclient_mock.mock_calls[-1][0] == "POST"
@pytest.mark.parametrize(
("store_addons", "store_repositories"), [(MOCK_STORE_ADDONS, MOCK_REPOSITORIES)]
)
async def test_switch_turn_off(
hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker,
entity_registry: er.EntityRegistry,
addon_installed: AsyncMock,
setup_integration: MockConfigEntry,
) -> None:
"""Test turning off addon switch."""
entity_id = "switch.test"
addon_installed.return_value.state = "started"
# Mock the stop addon API call
aioclient_mock.post("http://127.0.0.1/addons/test/stop", json={"result": "ok"})
# Verify that the entity is disabled by default.
assert hass.states.get(entity_id) is None
# Enable the entity.
await enable_entity(hass, entity_registry, setup_integration, entity_id)
# Verify initial state is on
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "on"
# Turn off the switch
await hass.services.async_call(
"switch",
"turn_off",
{"entity_id": entity_id},
blocking=True,
)
# Verify the API was called
assert aioclient_mock.mock_calls[-1][1].path == "/addons/test/stop"
assert aioclient_mock.mock_calls[-1][0] == "POST"