Implemented full test coverage

This commit is contained in:
Robin Lintermann 2025-05-22 10:18:30 +00:00
parent 00ccaf1ff9
commit 3ad45d4a30
12 changed files with 131 additions and 15 deletions

View File

@ -1,7 +1,7 @@
{
"entity": {
"switch": {
"smartmode": {
"smart_mode": {
"default": "mdi:refresh-auto"
}
}

View File

@ -8,5 +8,5 @@
"iot_class": "cloud_push",
"loggers": ["pysmarlaapi", "pysignalr"],
"quality_scale": "bronze",
"requirements": ["pysmarlaapi==0.7.2"]
"requirements": ["pysmarlaapi==0.8.1"]
}

View File

@ -29,7 +29,7 @@ rules:
log-when-unavailable: todo
parallel-updates: todo
reauthentication-flow: todo
test-coverage: todo
test-coverage: done
# Gold
devices: done

View File

@ -20,8 +20,8 @@
},
"entity": {
"switch": {
"smartmode": {
"name": "Smart mode"
"smart_mode": {
"name": "Smart Mode"
}
}
}

View File

@ -24,16 +24,16 @@ class SmarlaSwitchEntityDescription(SwitchEntityDescription):
SWITCHES: list[SmarlaSwitchEntityDescription] = [
SmarlaSwitchEntityDescription(
key="cradle",
key="swing_active",
name=None,
service="babywiege",
property="swing_active",
),
SmarlaSwitchEntityDescription(
key="smartmode",
translation_key="smartmode",
key="smart_mode",
translation_key="smart_mode",
service="babywiege",
property="smartmode",
property="smart_mode",
),
]

2
requirements_all.txt generated
View File

@ -2335,7 +2335,7 @@ pysma==0.7.5
pysmappee==0.2.29
# homeassistant.components.smarla
pysmarlaapi==0.7.2
pysmarlaapi==0.8.1
# homeassistant.components.smartthings
pysmartthings==3.2.2

View File

@ -1908,7 +1908,7 @@ pysma==0.7.5
pysmappee==0.2.29
# homeassistant.components.smarla
pysmarlaapi==0.7.2
pysmarlaapi==0.8.1
# homeassistant.components.smartthings
pysmartthings==3.2.2

View File

@ -18,5 +18,3 @@ MOCK_ACCESS_TOKEN = base64.b64encode(
).decode()
MOCK_USER_INPUT = {CONF_ACCESS_TOKEN: MOCK_ACCESS_TOKEN}
MOCK_URL = "https://someurl.net"

View File

@ -0,0 +1,11 @@
"""Common test utilities for entity component tests."""
from homeassistant.components.smarla.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
def get_entity_id_by_unique_id(hass: HomeAssistant, platform: str, unique_id: str):
"""Get entity id by its unique id."""
registry = er.async_get(hass)
return registry.async_get_entity_id(platform, DOMAIN, unique_id)

View File

@ -11,7 +11,7 @@ import pytest
from homeassistant.components.smarla.const import DOMAIN
from homeassistant.config_entries import SOURCE_USER
from . import MOCK_ACCESS_TOKEN_JSON, MOCK_SERIAL_NUMBER, MOCK_URL, MOCK_USER_INPUT
from . import MOCK_ACCESS_TOKEN_JSON, MOCK_SERIAL_NUMBER, MOCK_USER_INPUT
from tests.common import MockConfigEntry
@ -49,7 +49,17 @@ def mock_connection() -> Generator[MagicMock]:
),
):
connection = mock_connection.return_value
connection.url = MOCK_URL
connection.token = AuthToken.from_json(MOCK_ACCESS_TOKEN_JSON)
connection.refresh_token.return_value = True
yield connection
@pytest.fixture
def mock_federwiege() -> Generator[MagicMock]:
"""Mock the Federwiege instance."""
with patch(
"homeassistant.components.smarla.Federwiege", autospec=True
) as mock_federwiege:
federwiege = mock_federwiege.return_value
federwiege.serial_number = MOCK_SERIAL_NUMBER
yield federwiege

View File

@ -0,0 +1,25 @@
"""Test switch platform for Swing2Sleep Smarla integration."""
from unittest.mock import AsyncMock, patch
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def test_init_invalid_auth(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_connection
) -> None:
"""Test init invalid authentication behavior."""
# Add the mock entry to hass
mock_config_entry.add_to_hass(hass)
with patch.object(
mock_connection, "refresh_token", new=AsyncMock(return_value=False)
):
# Set up the platform
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR

View File

@ -0,0 +1,72 @@
"""Test switch platform for Swing2Sleep Smarla integration."""
from pysmarlaapi.federwiege.classes import Property
import pytest
from homeassistant.components.smarla.switch import SWITCHES
from homeassistant.components.switch import (
DOMAIN as SWITCH_DOMAIN,
SwitchEntityDescription,
)
from homeassistant.const import (
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
Platform,
)
from homeassistant.core import HomeAssistant
from .common import get_entity_id_by_unique_id
from tests.common import MockConfigEntry
@pytest.mark.parametrize("switch_desc", SWITCHES)
async def test_switch_behavior(
hass: HomeAssistant,
switch_desc: SwitchEntityDescription,
mock_config_entry: MockConfigEntry,
mock_connection,
mock_federwiege,
) -> None:
"""Test SmarlaSwitch on/off behavior."""
# Assign switch property to federwiege
mock_property = Property[bool](None, False)
mock_federwiege.get_property.return_value = mock_property
# Add the mock entry to hass
mock_config_entry.add_to_hass(hass)
# Set up the platform
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Get entity id by unique id
unique_id = f"{mock_federwiege.serial_number}-{switch_desc.key}"
entity_id = get_entity_id_by_unique_id(hass, Platform.SWITCH, unique_id)
assert entity_id is not None
# Check entity initial state
assert hass.states.get(entity_id).state == STATE_OFF
# Turn on
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{"entity_id": entity_id},
blocking=True,
)
mock_property.set(True, push=False)
await mock_property.notify_listeners()
assert hass.states.get(entity_id).state == STATE_ON
# Turn off
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{"entity_id": entity_id},
blocking=True,
)
mock_property.set(False, push=False)
await mock_property.notify_listeners()
assert hass.states.get(entity_id).state == STATE_OFF