1
0
mirror of https://github.com/home-assistant/core.git synced 2026-06-02 13:44:32 +01:00

prusalink: extract press_button_and_verify fixture for button tests (#170332)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Heikki Henriksen
2026-05-26 23:29:54 +02:00
committed by GitHub
parent 4ef409f3cd
commit 6efb3fffa3
+54 -99
View File
@@ -1,5 +1,6 @@
"""Test Prusalink buttons."""
from collections.abc import Awaitable, Callable
from unittest.mock import patch
from pyprusalink.types import Conflict
@@ -10,8 +11,6 @@ from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import async_setup_component
from tests.typing import ClientSessionGenerator
@pytest.fixture(autouse=True)
def setup_button_platform_only():
@@ -20,6 +19,45 @@ def setup_button_platform_only():
yield
@pytest.fixture
def press_button_and_verify(
hass: HomeAssistant,
) -> Callable[[str, str], Awaitable[None]]:
"""Return a helper that asserts the press path for a PrusaLink button.
The helper verifies the entity is in the `unknown` state, that pressing it
invokes the matching pyprusalink method once, and that a `Conflict` from
the API surfaces as `HomeAssistantError`.
"""
async def _press_and_verify(entity_id: str, method: str) -> None:
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "unknown"
with patch(f"pyprusalink.PrusaLink.{method}") as mock_meth:
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
mock_meth.assert_awaited_once()
with (
pytest.raises(HomeAssistantError),
patch(f"pyprusalink.PrusaLink.{method}", side_effect=Conflict),
):
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
return _press_and_verify
@pytest.mark.parametrize(
("object_id", "method"),
[
@@ -31,40 +69,15 @@ async def test_button_pause_cancel(
hass: HomeAssistant,
mock_config_entry,
mock_api,
hass_client: ClientSessionGenerator,
mock_job_api_printing,
mock_get_status_printing,
object_id,
method,
press_button_and_verify,
object_id: str,
method: str,
) -> None:
"""Test cancel and pause button."""
entity_id = f"button.{object_id}"
"""Test cancel and pause buttons in PRINTING state."""
assert await async_setup_component(hass, "prusalink", {})
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "unknown"
with patch(f"pyprusalink.PrusaLink.{method}") as mock_meth:
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
assert len(mock_meth.mock_calls) == 1
# Verify it calls correct method + does error handling
with (
pytest.raises(HomeAssistantError),
patch(f"pyprusalink.PrusaLink.{method}", side_effect=Conflict),
):
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
await press_button_and_verify(f"button.{object_id}", method)
@pytest.mark.parametrize(
@@ -78,86 +91,28 @@ async def test_button_resume_cancel(
hass: HomeAssistant,
mock_config_entry,
mock_api,
hass_client: ClientSessionGenerator,
mock_job_api_paused,
object_id,
method,
press_button_and_verify,
object_id: str,
method: str,
) -> None:
"""Test resume button."""
entity_id = f"button.{object_id}"
"""Test cancel and resume buttons in PAUSED state."""
assert await async_setup_component(hass, "prusalink", {})
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "unknown"
with (
patch(f"pyprusalink.PrusaLink.{method}") as mock_meth,
patch(
"homeassistant.components.prusalink.coordinator.PrusaLinkUpdateCoordinator._fetch_data"
),
):
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
assert len(mock_meth.mock_calls) == 1
# Verify it calls correct method + does error handling
with (
pytest.raises(HomeAssistantError),
patch(f"pyprusalink.PrusaLink.{method}", side_effect=Conflict),
):
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
await press_button_and_verify(f"button.{object_id}", method)
async def test_button_continue(
hass: HomeAssistant,
mock_config_entry,
mock_api,
hass_client: ClientSessionGenerator,
mock_job_api_attention,
press_button_and_verify,
) -> None:
"""Test continue button is enabled in ATTENTION state and calls continue_job."""
entity_id = "button.workshop_mock_title_continue_job"
assert await async_setup_component(hass, "prusalink", {})
state = hass.states.get(entity_id)
assert state is not None
assert state.state == "unknown"
with (
patch("pyprusalink.PrusaLink.continue_job") as mock_meth,
patch(
"homeassistant.components.prusalink.coordinator.PrusaLinkUpdateCoordinator._fetch_data"
),
):
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
assert len(mock_meth.mock_calls) == 1
# Verify error handling — Conflict raised by API surfaces as HomeAssistantError
with (
pytest.raises(HomeAssistantError),
patch("pyprusalink.PrusaLink.continue_job", side_effect=Conflict),
):
await hass.services.async_call(
"button",
"press",
{"entity_id": entity_id},
blocking=True,
)
await press_button_and_verify(
"button.workshop_mock_title_continue_job", "continue_job"
)
async def test_button_continue_unavailable_when_printing(