Skip to content

Commit ffcd516

Browse files
yuxincsfrenck
andauthored
Use fixtures instead of helper functions for APCUPSD tests (home-assistant#151172)
Co-authored-by: Franck Nijhof <[email protected]>
1 parent e94a7b2 commit ffcd516

File tree

9 files changed

+393
-394
lines changed

9 files changed

+393
-394
lines changed

homeassistant/components/apcupsd/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from .coordinator import APCUPSdConfigEntry, APCUPSdCoordinator
1111

12-
PLATFORMS: Final = (Platform.BINARY_SENSOR, Platform.SENSOR)
12+
PLATFORMS: Final = [Platform.BINARY_SENSOR, Platform.SENSOR]
1313

1414

1515
async def async_setup_entry(

tests/components/apcupsd/__init__.py

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,8 @@
44

55
from collections import OrderedDict
66
from typing import Final
7-
from unittest.mock import patch
87

9-
from homeassistant.components.apcupsd.const import DOMAIN
10-
from homeassistant.components.apcupsd.coordinator import APCUPSdData
11-
from homeassistant.config_entries import SOURCE_USER
128
from homeassistant.const import CONF_HOST, CONF_PORT
13-
from homeassistant.core import HomeAssistant
14-
15-
from tests.common import MockConfigEntry
169

1710
CONF_DATA: Final = {CONF_HOST: "test", CONF_PORT: 1234}
1811

@@ -79,33 +72,3 @@
7972
("END APC", "1970-01-01 00:00:00 0000"),
8073
]
8174
)
82-
83-
84-
async def async_init_integration(
85-
hass: HomeAssistant,
86-
*,
87-
host: str = "test",
88-
status: dict[str, str] | None = None,
89-
entry_id: str = "mocked-config-entry-id",
90-
) -> MockConfigEntry:
91-
"""Set up the APC UPS Daemon integration in HomeAssistant."""
92-
if status is None:
93-
status = MOCK_STATUS
94-
95-
entry = MockConfigEntry(
96-
entry_id=entry_id,
97-
version=1,
98-
domain=DOMAIN,
99-
title="APCUPSd",
100-
data=CONF_DATA | {CONF_HOST: host},
101-
unique_id=APCUPSdData(status).serial_no,
102-
source=SOURCE_USER,
103-
)
104-
105-
entry.add_to_hass(hass)
106-
107-
with patch("aioapcaccess.request_status", return_value=status):
108-
assert await hass.config_entries.async_setup(entry.entry_id)
109-
await hass.async_block_till_done()
110-
111-
return entry
Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
"""Common fixtures for the APC UPS Daemon (APCUPSD) tests."""
22

3-
from collections.abc import Generator
3+
from collections.abc import AsyncGenerator, Generator
44
from unittest.mock import AsyncMock, patch
55

66
import pytest
77

8+
from homeassistant.components.apcupsd import PLATFORMS
9+
from homeassistant.components.apcupsd.const import DOMAIN
10+
from homeassistant.components.apcupsd.coordinator import APCUPSdData
11+
from homeassistant.config_entries import SOURCE_USER
12+
from homeassistant.const import Platform
13+
from homeassistant.core import HomeAssistant
14+
15+
from . import CONF_DATA, MOCK_STATUS
16+
17+
from tests.common import MockConfigEntry
18+
819

920
@pytest.fixture
1021
def mock_setup_entry() -> Generator[AsyncMock]:
@@ -13,3 +24,58 @@ def mock_setup_entry() -> Generator[AsyncMock]:
1324
"homeassistant.components.apcupsd.async_setup_entry", return_value=True
1425
) as mock_setup_entry:
1526
yield mock_setup_entry
27+
28+
29+
@pytest.fixture
30+
async def mock_request_status(
31+
request: pytest.FixtureRequest,
32+
) -> AsyncGenerator[AsyncMock]:
33+
"""Return a mocked aioapcaccess.request_status function."""
34+
mocked_status = getattr(request, "param", None) or MOCK_STATUS
35+
36+
with patch("aioapcaccess.request_status") as mock_request_status:
37+
mock_request_status.return_value = mocked_status
38+
yield mock_request_status
39+
40+
41+
@pytest.fixture
42+
def mock_config_entry(
43+
request: pytest.FixtureRequest,
44+
mock_request_status: AsyncMock,
45+
) -> MockConfigEntry:
46+
"""Mock setting up a config entry."""
47+
entry_id = getattr(request, "param", None)
48+
49+
return MockConfigEntry(
50+
entry_id=entry_id,
51+
version=1,
52+
domain=DOMAIN,
53+
title="APC UPS Daemon",
54+
data=CONF_DATA,
55+
unique_id=APCUPSdData(mock_request_status.return_value).serial_no,
56+
source=SOURCE_USER,
57+
)
58+
59+
60+
@pytest.fixture
61+
def platforms() -> list[Platform]:
62+
"""Fixture to specify platforms to test."""
63+
return PLATFORMS
64+
65+
66+
@pytest.fixture
67+
async def init_integration(
68+
request: pytest.FixtureRequest,
69+
hass: HomeAssistant,
70+
mock_config_entry: MockConfigEntry,
71+
mock_request_status: AsyncMock,
72+
platforms: list[Platform],
73+
) -> MockConfigEntry:
74+
"""Set up APC UPS Daemon integration for testing."""
75+
mock_config_entry.add_to_hass(hass)
76+
77+
with patch("homeassistant.components.apcupsd.PLATFORMS", platforms):
78+
await hass.config_entries.async_setup(mock_config_entry.entry_id)
79+
await hass.async_block_till_done()
80+
81+
return mock_config_entry

tests/components/apcupsd/snapshots/test_init.ambr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# serializer version: 1
2-
# name: test_async_setup_entry[status0][device_MyUPS_XXXXXXXXXXXX]
2+
# name: test_async_setup_entry[mock_request_status0-mocked-config-entry-id][device_MyUPS_XXXXXXXXXXXX]
33
DeviceRegistryEntrySnapshot({
44
'area_id': None,
55
'config_entries': <ANY>,
@@ -30,7 +30,7 @@
3030
'via_device_id': None,
3131
})
3232
# ---
33-
# name: test_async_setup_entry[status1][device_APC UPS_XXXX]
33+
# name: test_async_setup_entry[mock_request_status1-mocked-config-entry-id][device_APC UPS_XXXX]
3434
DeviceRegistryEntrySnapshot({
3535
'area_id': None,
3636
'config_entries': <ANY>,
@@ -61,7 +61,7 @@
6161
'via_device_id': None,
6262
})
6363
# ---
64-
# name: test_async_setup_entry[status2][device_APC UPS_<no serial>]
64+
# name: test_async_setup_entry[mock_request_status2-mocked-config-entry-id][device_APC UPS_<no serial>]
6565
DeviceRegistryEntrySnapshot({
6666
'area_id': None,
6767
'config_entries': <ANY>,
@@ -92,7 +92,7 @@
9292
'via_device_id': None,
9393
})
9494
# ---
95-
# name: test_async_setup_entry[status3][device_APC UPS_Blank]
95+
# name: test_async_setup_entry[mock_request_status3-mocked-config-entry-id][device_APC UPS_Blank]
9696
DeviceRegistryEntrySnapshot({
9797
'area_id': None,
9898
'config_entries': <ANY>,
Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Test binary sensors of APCUPSd integration."""
22

3-
from unittest.mock import patch
3+
from unittest.mock import AsyncMock
44

55
import pytest
66
from syrupy.assertion import SnapshotAssertion
@@ -10,47 +10,60 @@
1010
from homeassistant.helpers import entity_registry as er
1111
from homeassistant.util import slugify
1212

13-
from . import MOCK_STATUS, async_init_integration
13+
from . import MOCK_STATUS
1414

15-
from tests.common import snapshot_platform
15+
from tests.common import MockConfigEntry, snapshot_platform
16+
17+
pytestmark = pytest.mark.usefixtures(
18+
"entity_registry_enabled_by_default", "init_integration"
19+
)
20+
21+
22+
@pytest.fixture
23+
def platforms() -> list[Platform]:
24+
"""Overridden fixture to specify platforms to test."""
25+
return [Platform.BINARY_SENSOR]
1626

1727

1828
async def test_binary_sensor(
1929
hass: HomeAssistant,
2030
entity_registry: er.EntityRegistry,
2131
snapshot: SnapshotAssertion,
32+
mock_config_entry: MockConfigEntry,
2233
) -> None:
23-
"""Test states of binary sensors."""
24-
with patch("homeassistant.components.apcupsd.PLATFORMS", [Platform.BINARY_SENSOR]):
25-
config_entry = await async_init_integration(hass, status=MOCK_STATUS)
26-
await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id)
34+
"""Test states of binary sensor entities."""
35+
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
2736

2837

29-
async def test_no_binary_sensor(hass: HomeAssistant) -> None:
38+
@pytest.mark.parametrize(
39+
"mock_request_status",
40+
[{k: v for k, v in MOCK_STATUS.items() if k != "STATFLAG"}],
41+
indirect=True,
42+
)
43+
async def test_no_binary_sensor(
44+
hass: HomeAssistant,
45+
mock_request_status: AsyncMock,
46+
) -> None:
3047
"""Test binary sensor when STATFLAG is not available."""
31-
status = MOCK_STATUS.copy()
32-
status.pop("STATFLAG")
33-
await async_init_integration(hass, status=status)
34-
35-
device_slug = slugify(MOCK_STATUS["UPSNAME"])
48+
device_slug = slugify(mock_request_status.return_value["UPSNAME"])
3649
state = hass.states.get(f"binary_sensor.{device_slug}_online_status")
3750
assert state is None
3851

3952

4053
@pytest.mark.parametrize(
41-
("override", "expected"),
54+
("mock_request_status", "expected"),
4255
[
43-
("0x008", "on"),
44-
("0x02040010 Status Flag", "off"),
56+
(MOCK_STATUS | {"STATFLAG": "0x008"}, "on"),
57+
(MOCK_STATUS | {"STATFLAG": "0x02040010 Status Flag"}, "off"),
4558
],
59+
indirect=["mock_request_status"],
4660
)
47-
async def test_statflag(hass: HomeAssistant, override: str, expected: str) -> None:
61+
async def test_statflag(
62+
hass: HomeAssistant,
63+
mock_request_status: AsyncMock,
64+
expected: str,
65+
) -> None:
4866
"""Test binary sensor for different STATFLAG values."""
49-
status = MOCK_STATUS.copy()
50-
status["STATFLAG"] = override
51-
await async_init_integration(hass, status=status)
52-
53-
device_slug = slugify(MOCK_STATUS["UPSNAME"])
54-
assert (
55-
hass.states.get(f"binary_sensor.{device_slug}_online_status").state == expected
56-
)
67+
device_slug = slugify(mock_request_status.return_value["UPSNAME"])
68+
state = hass.states.get(f"binary_sensor.{device_slug}_online_status")
69+
assert state.state == expected

0 commit comments

Comments
 (0)