mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Fix line length violations in tests/components c (#170845)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
parent
95878222fd
commit
2af7f43ed7
@@ -351,8 +351,9 @@ def get_api_events(
|
||||
async def api_call(entity_id: str) -> dict[str, Any]:
|
||||
client = await hass_client()
|
||||
response = await client.get(
|
||||
# The start/end times are arbitrary since they are ignored by `_mock_calendar`
|
||||
# which just returns all events for the calendar.
|
||||
# The start/end times are arbitrary since they are
|
||||
# ignored by `_mock_calendar` which just returns all
|
||||
# events for the calendar.
|
||||
f"/api/calendars/{entity_id}?start=2022-01-01&end=2022-01-01"
|
||||
)
|
||||
assert response.status == HTTPStatus.OK
|
||||
@@ -732,7 +733,10 @@ async def test_all_day_event(
|
||||
freezer: FrozenDateTimeFactory,
|
||||
target_datetime: datetime.datetime,
|
||||
) -> None:
|
||||
"""Test that the event lasting the whole day is returned, if it's early in the local day."""
|
||||
"""Test that the event lasting the whole day is returned.
|
||||
|
||||
Specifically when it's early in the local day.
|
||||
"""
|
||||
freezer.move_to(target_datetime.replace(tzinfo=dt_util.get_default_time_zone()))
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
@@ -912,7 +916,10 @@ async def test_event_rrule_all_day_early(
|
||||
freezer: FrozenDateTimeFactory,
|
||||
target_datetime: datetime.datetime,
|
||||
) -> None:
|
||||
"""Test that the recurring all day event is returned early in the local day, and not on the first occurrence."""
|
||||
"""Test recurring all day event is returned early in the day.
|
||||
|
||||
Verifies it's not returned on the first occurrence.
|
||||
"""
|
||||
freezer.move_to(target_datetime.replace(tzinfo=dt_util.get_default_time_zone()))
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
@@ -1199,7 +1206,10 @@ async def test_config_entry_supported_components(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test that calendars are only created for VEVENT types when using a config entry."""
|
||||
"""Test calendars are only created for VEVENT types.
|
||||
|
||||
This applies when using a config entry.
|
||||
"""
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
||||
|
||||
@@ -57,7 +57,10 @@ async def mock_setup_platform(
|
||||
mock_setup_integration: None,
|
||||
config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Fixture to setup platforms used in the test and fixtures are set up in the right order."""
|
||||
"""Fixture to set up platforms used in the test.
|
||||
|
||||
Ensures fixtures are set up in the right order.
|
||||
"""
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -573,18 +576,24 @@ async def test_list_events_missing_fields(hass: HomeAssistant) -> None:
|
||||
"start_date_time": "2023-06-22T04:30:00-06:00",
|
||||
"end_date_time": "2023-06-22T04:30:00-06:00",
|
||||
},
|
||||
"Expected end time to be after start time (2023-06-22 04:30:00-06:00, 2023-06-22 04:30:00-06:00)",
|
||||
"Expected end time to be after start time"
|
||||
" (2023-06-22 04:30:00-06:00,"
|
||||
" 2023-06-22 04:30:00-06:00)",
|
||||
),
|
||||
(
|
||||
{
|
||||
"start_date_time": "2023-06-22T04:30:00",
|
||||
"end_date_time": "2023-06-22T04:30:00",
|
||||
},
|
||||
"Expected end time to be after start time (2023-06-22 04:30:00, 2023-06-22 04:30:00)",
|
||||
"Expected end time to be after start time"
|
||||
" (2023-06-22 04:30:00,"
|
||||
" 2023-06-22 04:30:00)",
|
||||
),
|
||||
(
|
||||
{"start_date_time": "2023-06-22", "end_date_time": "2023-06-22"},
|
||||
"Expected end time to be after start time (2023-06-22 00:00:00, 2023-06-22 00:00:00)",
|
||||
"Expected end time to be after start time"
|
||||
" (2023-06-22 00:00:00,"
|
||||
" 2023-06-22 00:00:00)",
|
||||
),
|
||||
(
|
||||
{"start_date_time": "2023-06-22 10:00:00", "duration": "0"},
|
||||
|
||||
@@ -139,7 +139,7 @@ class LegacyTriggerFormat(TriggerFormat):
|
||||
|
||||
@dataclass
|
||||
class TargetTriggerFormat(TriggerFormat):
|
||||
"""Target trigger format using platform: calendar.event_started/ended with target."""
|
||||
"""Target trigger format using event_started/ended."""
|
||||
|
||||
id: str = "target"
|
||||
|
||||
|
||||
@@ -502,7 +502,10 @@ async def test_play_media_unknown_type(
|
||||
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Unsupported media type for Cambridge Audio device: unsupported_content_type",
|
||||
match=(
|
||||
"Unsupported media type for Cambridge Audio"
|
||||
" device: unsupported_content_type"
|
||||
),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
MP_DOMAIN,
|
||||
|
||||
@@ -168,9 +168,10 @@ def mock_create_stream_fixture() -> Generator[Mock]:
|
||||
async def mock_test_webrtc_cameras(hass: HomeAssistant) -> None:
|
||||
"""Initialize test WebRTC cameras with native RTC support."""
|
||||
|
||||
# Cannot use the fixture mock_camera_web_rtc as it's mocking Camera.async_handle_web_rtc_offer
|
||||
# and native support is checked by verify the function "async_handle_web_rtc_offer" was
|
||||
# overwritten(implemented) or not
|
||||
# Cannot use the fixture mock_camera_web_rtc as it's
|
||||
# mocking Camera.async_handle_web_rtc_offer and native
|
||||
# support is checked by verifying the function
|
||||
# "async_handle_web_rtc_offer" was overwritten or not
|
||||
class BaseCamera(camera.Camera):
|
||||
"""Base Camera."""
|
||||
|
||||
@@ -182,7 +183,10 @@ async def mock_test_webrtc_cameras(hass: HomeAssistant) -> None:
|
||||
return STREAM_SOURCE
|
||||
|
||||
class AsyncNoCandidateCamera(BaseCamera):
|
||||
"""Mock Camera with native async WebRTC support but not implemented candidate support."""
|
||||
"""Mock Camera with native async WebRTC support.
|
||||
|
||||
Does not implement candidate support.
|
||||
"""
|
||||
|
||||
_attr_name = "Async No Candidate"
|
||||
|
||||
|
||||
@@ -93,7 +93,8 @@ def test_turbojpeg_load_failure(
|
||||
(
|
||||
"homeassistant.components.camera.img_util",
|
||||
logging.ERROR,
|
||||
"Error loading libturbojpeg; Camera snapshot performance will be sub-optimal",
|
||||
"Error loading libturbojpeg; Camera snapshot"
|
||||
" performance will be sub-optimal",
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@@ -836,7 +836,7 @@ async def _register_test_webrtc_provider(hass: HomeAssistant) -> Callable[[], No
|
||||
session_id: str,
|
||||
send_message: WebRTCSendMessage,
|
||||
) -> None:
|
||||
"""Handle the WebRTC offer and return the answer via the provided callback."""
|
||||
"""Handle the WebRTC offer and return the answer."""
|
||||
send_message(WebRTCAnswer("answer"))
|
||||
|
||||
async def async_on_webrtc_candidate(
|
||||
@@ -917,7 +917,7 @@ async def test_camera_capabilities_webrtc(
|
||||
async def test_webrtc_provider_not_added_for_native_webrtc(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test that a WebRTC provider is not added to a camera when the camera has native WebRTC support."""
|
||||
"""Test that a WebRTC provider is not added for native WebRTC."""
|
||||
camera_obj = get_camera_from_entity_id(hass, "camera.async")
|
||||
assert camera_obj
|
||||
assert camera_obj._webrtc_provider is None
|
||||
|
||||
@@ -212,7 +212,10 @@ async def test_ws_get_client_config_no_rtc_camera(
|
||||
assert not msg["success"]
|
||||
assert msg["error"] == {
|
||||
"code": "webrtc_get_client_config_failed",
|
||||
"message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
|
||||
"message": (
|
||||
"Camera does not support WebRTC,"
|
||||
" frontend_stream_types={<StreamType.HLS: 'hls'>}"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -276,7 +279,7 @@ async def test_websocket_webrtc_offer_webrtc_provider_deprecated(
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
register_test_provider: SomeTestProvider,
|
||||
) -> None:
|
||||
"""Test initiating a WebRTC stream with a webrtc provider with the deprecated class."""
|
||||
"""Test initiating a WebRTC stream with a deprecated provider."""
|
||||
await _test_websocket_webrtc_offer_webrtc_provider(
|
||||
hass,
|
||||
hass_ws_client,
|
||||
@@ -443,7 +446,10 @@ async def test_websocket_webrtc_offer_invalid_stream_type(
|
||||
assert not response["success"]
|
||||
assert response["error"] == {
|
||||
"code": "webrtc_offer_failed",
|
||||
"message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
|
||||
"message": (
|
||||
"Camera does not support WebRTC,"
|
||||
" frontend_stream_types={<StreamType.HLS: 'hls'>}"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -508,15 +514,19 @@ async def test_ws_webrtc_candidate(
|
||||
(
|
||||
{"sdpMLineIndex": 0},
|
||||
(
|
||||
'Field "candidate" of type str is missing in RTCIceCandidateInit instance'
|
||||
" for dictionary value @ data['candidate']. Got {'sdpMLineIndex': 0}"
|
||||
'Field "candidate" of type str is missing in'
|
||||
" RTCIceCandidateInit instance for dictionary"
|
||||
" value @ data['candidate']."
|
||||
" Got {'sdpMLineIndex': 0}"
|
||||
),
|
||||
),
|
||||
(
|
||||
{"candidate": "candidate", "sdpMLineIndex": -1},
|
||||
(
|
||||
"sdpMLineIndex must be greater than or equal to 0 for dictionary value @ "
|
||||
"data['candidate']. Got {'candidate': 'candidate', 'sdpMLineIndex': -1}"
|
||||
"sdpMLineIndex must be greater than or equal"
|
||||
" to 0 for dictionary value @"
|
||||
" data['candidate']. Got {'candidate':"
|
||||
" 'candidate', 'sdpMLineIndex': -1}"
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -669,7 +679,10 @@ async def test_ws_webrtc_candidate_invalid_stream_type(
|
||||
assert not response["success"]
|
||||
assert response["error"] == {
|
||||
"code": "webrtc_candidate_failed",
|
||||
"message": "Camera does not support WebRTC, frontend_stream_types={<StreamType.HLS: 'hls'>}",
|
||||
"message": (
|
||||
"Camera does not support WebRTC,"
|
||||
" frontend_stream_types={<StreamType.HLS: 'hls'>}"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -174,7 +174,10 @@ async def test_command_error(
|
||||
service: str,
|
||||
mock_method: str,
|
||||
) -> None:
|
||||
"""Test that a device error raises HomeAssistantError without marking entity unavailable."""
|
||||
"""Test device error raises HomeAssistantError.
|
||||
|
||||
The entity should not be marked as unavailable.
|
||||
"""
|
||||
getattr(mock_casper_glow, mock_method).side_effect = CasperGlowError(
|
||||
"Connection failed"
|
||||
)
|
||||
@@ -198,7 +201,7 @@ async def test_state_update_via_callback_after_command_failure(
|
||||
mock_casper_glow: MagicMock,
|
||||
fire_callbacks: Callable[[GlowState], Awaitable[None]],
|
||||
) -> None:
|
||||
"""Test that device callbacks correctly update state even after a command failure."""
|
||||
"""Test callbacks update state after a command failure."""
|
||||
mock_casper_glow.turn_on.side_effect = CasperGlowError("Connection failed")
|
||||
|
||||
# Fail a command — entity remains in last known state (unknown), not unavailable
|
||||
|
||||
@@ -120,7 +120,7 @@ async def test_select_state_update_via_callback_after_command_failure(
|
||||
mock_casper_glow: MagicMock,
|
||||
fire_callbacks: Callable[[GlowState], Awaitable[None]],
|
||||
) -> None:
|
||||
"""Test that device callbacks correctly update state even after a command failure."""
|
||||
"""Test callbacks update state after a command failure."""
|
||||
mock_casper_glow.set_brightness_and_dimming_time.side_effect = CasperGlowError(
|
||||
"Connection failed"
|
||||
)
|
||||
|
||||
@@ -231,7 +231,11 @@ async def test_temperature_features_is_valid(
|
||||
|
||||
with pytest.raises(
|
||||
ServiceValidationError,
|
||||
match="Set temperature action was used with the 'Target temperature' parameter but the entity does not support it",
|
||||
match=(
|
||||
"Set temperature action was used with the"
|
||||
" 'Target temperature' parameter but the"
|
||||
" entity does not support it"
|
||||
),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
@@ -245,7 +249,11 @@ async def test_temperature_features_is_valid(
|
||||
|
||||
with pytest.raises(
|
||||
ServiceValidationError,
|
||||
match="Set temperature action was used with the 'Lower/Upper target temperature' parameter but the entity does not support it",
|
||||
match=(
|
||||
"Set temperature action was used with the"
|
||||
" 'Lower/Upper target temperature' parameter"
|
||||
" but the entity does not support it"
|
||||
),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
@@ -380,7 +388,10 @@ async def test_mode_validation(
|
||||
|
||||
with pytest.raises(
|
||||
ServiceValidationError,
|
||||
match="Horizontal swing mode invalid is not valid. Valid horizontal swing modes are: on, off",
|
||||
match=(
|
||||
"Horizontal swing mode invalid is not valid."
|
||||
" Valid horizontal swing modes are: on, off"
|
||||
),
|
||||
) as exc:
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
@@ -392,8 +403,8 @@ async def test_mode_validation(
|
||||
blocking=True,
|
||||
)
|
||||
assert (
|
||||
str(exc.value)
|
||||
== "Horizontal swing mode invalid is not valid. Valid horizontal swing modes are: on, off"
|
||||
str(exc.value) == "Horizontal swing mode invalid is not valid."
|
||||
" Valid horizontal swing modes are: on, off"
|
||||
)
|
||||
assert exc.value.translation_key == "not_valid_horizontal_swing_mode"
|
||||
|
||||
@@ -703,7 +714,10 @@ async def test_target_temp_high_higher_than_low(
|
||||
|
||||
with pytest.raises(
|
||||
ServiceValidationError,
|
||||
match="'Lower target temperature' cannot be higher than 'Upper target temperature'",
|
||||
match=(
|
||||
"'Lower target temperature' cannot be higher"
|
||||
" than 'Upper target temperature'"
|
||||
),
|
||||
) as exc:
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
|
||||
@@ -334,7 +334,7 @@ async def test_set_temperature_no_entities(
|
||||
|
||||
|
||||
async def test_set_temperature_not_supported(hass: HomeAssistant) -> None:
|
||||
"""Test HassClimateSetTemperature intent when climate entity doesn't support required feature."""
|
||||
"""Test HassClimateSetTemperature intent without support."""
|
||||
assert await async_setup_component(hass, "homeassistant", {})
|
||||
await climate_intent.async_setup_intents(hass)
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ async def test_climate_state_trigger_behavior_any(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the climate state trigger fires when any climate state changes to a specific state."""
|
||||
"""Test climate trigger fires on any state change."""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
target_entities=target_climates,
|
||||
@@ -295,7 +295,7 @@ async def test_climate_state_attribute_trigger_behavior_any(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the climate state trigger fires when any climate state changes to a specific state."""
|
||||
"""Test climate attribute trigger fires on any change."""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
target_entities=target_climates,
|
||||
@@ -353,7 +353,7 @@ async def test_climate_state_trigger_behavior_first(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the climate state trigger fires when the first climate changes to a specific state."""
|
||||
"""Test climate trigger fires on first state change."""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
target_entities=target_climates,
|
||||
@@ -414,7 +414,7 @@ async def test_climate_state_attribute_trigger_behavior_first(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[tuple[tuple[str, dict], int]],
|
||||
) -> None:
|
||||
"""Test that the climate state trigger fires when the first climate state changes to a specific state."""
|
||||
"""Test climate attribute trigger fires on first change."""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
target_entities=target_climates,
|
||||
@@ -472,7 +472,7 @@ async def test_climate_state_trigger_behavior_last(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the climate state trigger fires when the last climate changes to a specific state."""
|
||||
"""Test climate trigger fires on last state change."""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
target_entities=target_climates,
|
||||
@@ -533,7 +533,7 @@ async def test_climate_state_attribute_trigger_behavior_last(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[tuple[tuple[str, dict], int]],
|
||||
) -> None:
|
||||
"""Test that the climate state trigger fires when the last climate state changes to a specific state."""
|
||||
"""Test climate attribute trigger fires on last change."""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
target_entities=target_climates,
|
||||
|
||||
@@ -499,7 +499,8 @@ async def test_agents_upload_fail(
|
||||
[
|
||||
(
|
||||
CloudApiNonRetryableError("Boom!", code="NC-SH-FH-03"),
|
||||
"The backup size of 13.37GB is too large to be uploaded to Home Assistant Cloud",
|
||||
"The backup size of 13.37GB is too large to be"
|
||||
" uploaded to Home Assistant Cloud",
|
||||
),
|
||||
(
|
||||
CloudApiNonRetryableError("Boom!", code="NC-CE-01"),
|
||||
|
||||
@@ -270,7 +270,7 @@ async def test_async_handle_chat_log_service_sets_structured_output_non_strict(
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_cloud_login: None,
|
||||
) -> None:
|
||||
"""Ensure structured output requests always disable strict validation via service."""
|
||||
"""Ensure structured output disables strict validation."""
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ async def test_login_view_mfa_required_tokens_missing(
|
||||
setup_cloud: None,
|
||||
hass_client: ClientSessionGenerator,
|
||||
) -> None:
|
||||
"""Test logging in when MFA is required, code is provided, but session tokens are missing."""
|
||||
"""Test MFA login when code is given but tokens are missing."""
|
||||
cloud_client = await hass_client()
|
||||
cloud.login.side_effect = MFARequired(mfa_tokens={})
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ async def test_async_listen_cloudhook_change_cloud_setup_later(
|
||||
cloud: MagicMock,
|
||||
set_cloud_prefs: Callable[[dict[str, Any]], Coroutine[Any, Any, None]],
|
||||
) -> None:
|
||||
"""Test async_listen_cloudhook_change works when cloud is set up after listener registration."""
|
||||
"""Test cloudhook change listener with late cloud setup."""
|
||||
webhook_id = "mock-webhook-id"
|
||||
cloudhook_url = "https://cloudhook.nabu.casa/abcdefg"
|
||||
|
||||
|
||||
@@ -411,7 +411,9 @@ async def test_multipart_upload_consistent_part_sizes(
|
||||
assert len(uploaded_part_sizes) >= 2, "Expected at least 2 parts"
|
||||
non_trailing_parts = uploaded_part_sizes[:-1]
|
||||
assert all(size == MULTIPART_MIN_PART_SIZE_BYTES for size in non_trailing_parts), (
|
||||
f"All non-trailing parts should be {MULTIPART_MIN_PART_SIZE_BYTES} bytes, got {non_trailing_parts}"
|
||||
f"All non-trailing parts should be"
|
||||
f" {MULTIPART_MIN_PART_SIZE_BYTES} bytes,"
|
||||
f" got {non_trailing_parts}"
|
||||
)
|
||||
|
||||
# Verify the trailing part contains the remainder
|
||||
@@ -524,7 +526,9 @@ async def test_error_during_delete(
|
||||
assert response["success"]
|
||||
assert response["result"] == {
|
||||
"agent_errors": {
|
||||
f"{DOMAIN}.{mock_config_entry.entry_id}": "Failed during async_delete_backup"
|
||||
f"{DOMAIN}.{mock_config_entry.entry_id}": (
|
||||
"Failed during async_delete_backup"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,8 @@ async def _async_execute_service(hass: HomeAssistant, service_data: dict[str, An
|
||||
assert state
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
# Call the shared service, our above mock should return the base64 decoded fixture 1x1 pixel
|
||||
# Call the shared service, our above mock should return
|
||||
# the base64 decoded fixture 1x1 pixel
|
||||
await hass.services.async_call(DOMAIN, SERVICE_TURN_ON, service_data, blocking=True)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
@@ -293,7 +294,7 @@ async def test_file(hass: HomeAssistant, setup_integration) -> None:
|
||||
@patch("os.path.isfile", Mock(return_value=True))
|
||||
@patch("os.access", Mock(return_value=True))
|
||||
async def test_file_denied_dir(hass: HomeAssistant, setup_integration) -> None:
|
||||
"""Test that the file only service fails to read an image in a dir not explicitly allowed."""
|
||||
"""Test file service fails for images in disallowed dirs."""
|
||||
service_data = {
|
||||
ATTR_PATH: "/path/to/a/dir/not/allowed/image.png",
|
||||
ATTR_ENTITY_ID: LIGHT_ENTITY,
|
||||
|
||||
@@ -95,7 +95,9 @@ async def test_setup_platform_yaml(
|
||||
"payload_off": "0",
|
||||
"value_template": "{{ value | multiply(0.1) }}",
|
||||
"icon": (
|
||||
'{% if this.attributes.icon=="mdi:icon2" %} mdi:icon1 {% else %} mdi:icon2 {% endif %}'
|
||||
'{% if this.attributes.icon=="mdi:icon2" %}'
|
||||
" mdi:icon1"
|
||||
" {% else %} mdi:icon2 {% endif %}"
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -261,8 +263,8 @@ async def test_updating_to_often(
|
||||
wait_till_event.set()
|
||||
await asyncio.sleep(0)
|
||||
assert (
|
||||
"Updating Command Line Binary Sensor Test took longer than the scheduled update interval"
|
||||
not in caplog.text
|
||||
"Updating Command Line Binary Sensor Test took longer"
|
||||
" than the scheduled update interval" not in caplog.text
|
||||
)
|
||||
|
||||
# Simulate update takes too long
|
||||
@@ -274,8 +276,8 @@ async def test_updating_to_often(
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert (
|
||||
"Updating Command Line Binary Sensor Test took longer than the scheduled update interval"
|
||||
in caplog.text
|
||||
"Updating Command Line Binary Sensor Test took longer"
|
||||
" than the scheduled update interval" in caplog.text
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -286,8 +286,8 @@ async def test_updating_to_often(
|
||||
|
||||
assert not called
|
||||
assert (
|
||||
"Updating Command Line Cover Test took longer than the scheduled update interval"
|
||||
not in caplog.text
|
||||
"Updating Command Line Cover Test took longer"
|
||||
" than the scheduled update interval" not in caplog.text
|
||||
)
|
||||
async_fire_time_changed(hass, dt_util.now() + timedelta(seconds=11))
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
@@ -295,8 +295,8 @@ async def test_updating_to_often(
|
||||
called.clear()
|
||||
|
||||
assert (
|
||||
"Updating Command Line Cover Test took longer than the scheduled update interval"
|
||||
not in caplog.text
|
||||
"Updating Command Line Cover Test took longer"
|
||||
" than the scheduled update interval" not in caplog.text
|
||||
)
|
||||
|
||||
# Simulate update takes too long
|
||||
@@ -310,8 +310,8 @@ async def test_updating_to_often(
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert called
|
||||
assert (
|
||||
"Updating Command Line Cover Test took longer than the scheduled update interval"
|
||||
in caplog.text
|
||||
"Updating Command Line Cover Test took longer"
|
||||
" than the scheduled update interval" in caplog.text
|
||||
)
|
||||
|
||||
|
||||
@@ -442,7 +442,12 @@ async def test_icon_template(hass: HomeAssistant) -> None:
|
||||
"command_close": f"echo 0 > {path}",
|
||||
"command_stop": f"echo 0 > {path}",
|
||||
"name": "Test",
|
||||
"icon": '{% if this.attributes.icon=="mdi:icon2" %} mdi:icon1 {% else %} mdi:icon2 {% endif %}',
|
||||
"icon": (
|
||||
"{% if this.attributes.icon=="
|
||||
'"mdi:icon2" %} mdi:icon1'
|
||||
" {% else %} mdi:icon2"
|
||||
" {% endif %}"
|
||||
),
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -149,7 +149,9 @@ async def test_template_render_with_quote(hass: HomeAssistant) -> None:
|
||||
{
|
||||
"sensor": {
|
||||
"name": "Test",
|
||||
"command": 'echo "{{ states.sensor.input_sensor.state }}" "3 4"',
|
||||
"command": (
|
||||
'echo "{{ states.sensor.input_sensor.state }}" "3 4"'
|
||||
),
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -269,8 +271,12 @@ async def test_return_code(
|
||||
"sensor": {
|
||||
"name": "Test",
|
||||
"command": (
|
||||
'echo { \\"key\\": \\"some_json_value\\", \\"another_key\\": '
|
||||
'\\"another_json_value\\", \\"key_three\\": \\"value_three\\" }'
|
||||
'echo { \\"key\\":'
|
||||
' \\"some_json_value\\",'
|
||||
' \\"another_key\\":'
|
||||
' \\"another_json_value\\",'
|
||||
' \\"key_three\\":'
|
||||
' \\"value_three\\" }'
|
||||
),
|
||||
"json_attributes": ["key", "another_key", "key_three"],
|
||||
}
|
||||
@@ -300,8 +306,12 @@ async def test_update_with_json_attrs(
|
||||
"sensor": {
|
||||
"name": "Test",
|
||||
"command": (
|
||||
'echo { \\"key\\": \\"some_json_value\\", \\"another_key\\": '
|
||||
'\\"another_json_value\\", \\"key_three\\": \\"value_three\\" }'
|
||||
'echo { \\"key\\":'
|
||||
' \\"some_json_value\\",'
|
||||
' \\"another_key\\":'
|
||||
' \\"another_json_value\\",'
|
||||
' \\"key_three\\":'
|
||||
' \\"value_three\\" }'
|
||||
),
|
||||
"json_attributes": ["key", "another_key", "key_three"],
|
||||
"value_template": '{{ value_json["key"] }}',
|
||||
@@ -431,8 +441,12 @@ async def test_update_with_json_attrs_bad_json(
|
||||
"sensor": {
|
||||
"name": "Test",
|
||||
"command": (
|
||||
'echo { \\"key\\": \\"some_json_value\\", \\"another_key\\": '
|
||||
'\\"another_json_value\\", \\"key_three\\": \\"value_three\\" }'
|
||||
'echo { \\"key\\":'
|
||||
' \\"some_json_value\\",'
|
||||
' \\"another_key\\":'
|
||||
' \\"another_json_value\\",'
|
||||
' \\"key_three\\":'
|
||||
' \\"value_three\\" }'
|
||||
),
|
||||
"json_attributes": [
|
||||
"key",
|
||||
@@ -468,8 +482,12 @@ async def test_update_with_missing_json_attrs(
|
||||
"sensor": {
|
||||
"name": "Test",
|
||||
"command": (
|
||||
'echo { \\"key\\": \\"some_json_value\\", \\"another_key\\": '
|
||||
'\\"another_json_value\\", \\"key_three\\": \\"value_three\\" }'
|
||||
'echo { \\"key\\":'
|
||||
' \\"some_json_value\\",'
|
||||
' \\"another_key\\":'
|
||||
' \\"another_json_value\\",'
|
||||
' \\"key_three\\":'
|
||||
' \\"value_three\\" }'
|
||||
),
|
||||
"json_attributes": ["key", "another_key"],
|
||||
}
|
||||
@@ -519,7 +537,7 @@ async def test_update_with_unnecessary_json_attrs(
|
||||
async def test_update_with_json_attrs_with_json_attrs_path(
|
||||
hass: HomeAssistant, load_yaml_integration: None
|
||||
) -> None:
|
||||
"""Test using json_attributes_path to select a different part of the json object as root."""
|
||||
"""Test json_attributes_path selects a different root."""
|
||||
|
||||
entity_state = hass.states.get("sensor.test")
|
||||
assert entity_state
|
||||
@@ -618,8 +636,8 @@ async def test_updating_to_often(
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert (
|
||||
"Updating Command Line Sensor Test took longer than the scheduled update interval"
|
||||
not in caplog.text
|
||||
"Updating Command Line Sensor Test took longer"
|
||||
" than the scheduled update interval" not in caplog.text
|
||||
)
|
||||
|
||||
# Simulate update takes too long
|
||||
@@ -631,8 +649,8 @@ async def test_updating_to_often(
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert (
|
||||
"Updating Command Line Sensor Test took longer than the scheduled update interval"
|
||||
in caplog.text
|
||||
"Updating Command Line Sensor Test took longer"
|
||||
" than the scheduled update interval" in caplog.text
|
||||
)
|
||||
|
||||
|
||||
@@ -719,7 +737,9 @@ async def test_scrape_sensor_device_timestamp(
|
||||
"name": "Test",
|
||||
"command": "echo January 17, 2022",
|
||||
"device_class": "date",
|
||||
"value_template": "{{ strptime(value, '%B %d, %Y').strftime('%Y-%m-%d') }}",
|
||||
"value_template": (
|
||||
"{{ strptime(value, '%B %d, %Y').strftime('%Y-%m-%d') }}"
|
||||
),
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -751,7 +771,9 @@ async def test_template_not_error_when_data_is_none(
|
||||
"name": "Test",
|
||||
"command": "failed command",
|
||||
"unit_of_measurement": "MB",
|
||||
"value_template": "{{ (value.split('\t')[0]|int(0)/1000)|round(3) }}",
|
||||
"value_template": (
|
||||
"{{ (value.split('\t')[0]|int(0)/1000)|round(3) }}"
|
||||
),
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -853,9 +875,13 @@ async def test_availability_json_attributes_without_value_template(
|
||||
"name": "Test",
|
||||
"command": "echo January 17, 2022",
|
||||
"device_class": "date",
|
||||
"value_template": "{{ strptime(value, '%B %d, %Y').strftime('%Y-%m-%d') }}",
|
||||
"value_template": (
|
||||
"{{ strptime(value, '%B %d, %Y').strftime('%Y-%m-%d') }}"
|
||||
),
|
||||
"availability": '{{ states("sensor.input1")=="on" }}',
|
||||
"icon": "mdi:o{{ 'n' if states('sensor.input1')=='on' else 'ff' }}",
|
||||
"icon": (
|
||||
"mdi:o{{ 'n' if states('sensor.input1')=='on' else 'ff' }}"
|
||||
),
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -929,8 +955,8 @@ async def test_template_render_with_availability_syntax_error(
|
||||
assert state.state == "1"
|
||||
|
||||
assert (
|
||||
"Error rendering availability template for sensor.test: UndefinedError: 'what_the_heck' is undefined"
|
||||
in caplog.text
|
||||
"Error rendering availability template for sensor.test:"
|
||||
" UndefinedError: 'what_the_heck' is undefined" in caplog.text
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -123,7 +123,8 @@ async def test_state_value(hass: HomeAssistant) -> None:
|
||||
"command_off": f"echo 0 > {path}",
|
||||
"value_template": '{{ value=="1" }}',
|
||||
"icon": (
|
||||
'{% if value=="1" %} mdi:on {% else %} mdi:off {% endif %}'
|
||||
'{% if value=="1" %} mdi:on'
|
||||
" {% else %} mdi:off {% endif %}"
|
||||
),
|
||||
"name": "Test",
|
||||
}
|
||||
@@ -556,7 +557,10 @@ async def test_templating(hass: HomeAssistant) -> None:
|
||||
"command_off": f"echo 0 > {path}",
|
||||
"value_template": '{{ value=="1" }}',
|
||||
"icon": (
|
||||
'{% if this.attributes.icon=="mdi:icon2" %} mdi:icon1 {% else %} mdi:icon2 {% endif %}'
|
||||
"{% if this.attributes.icon=="
|
||||
'"mdi:icon2" %} mdi:icon1'
|
||||
" {% else %} mdi:icon2"
|
||||
" {% endif %}"
|
||||
),
|
||||
"name": "Test",
|
||||
}
|
||||
@@ -568,7 +572,10 @@ async def test_templating(hass: HomeAssistant) -> None:
|
||||
"command_off": f"echo 0 > {path}",
|
||||
"value_template": '{{ value=="1" }}',
|
||||
"icon": (
|
||||
'{% if states("switch.test")=="off" %} mdi:off {% else %} mdi:on {% endif %}'
|
||||
'{% if states("switch.test")=='
|
||||
'"off" %} mdi:off'
|
||||
" {% else %} mdi:on"
|
||||
" {% endif %}"
|
||||
),
|
||||
"name": "Test2",
|
||||
},
|
||||
@@ -647,8 +654,8 @@ async def test_updating_to_often(
|
||||
|
||||
assert not called
|
||||
assert (
|
||||
"Updating Command Line Switch Test took longer than the scheduled update interval"
|
||||
not in caplog.text
|
||||
"Updating Command Line Switch Test took longer"
|
||||
" than the scheduled update interval" not in caplog.text
|
||||
)
|
||||
async_fire_time_changed(hass, dt_util.now() + timedelta(seconds=11))
|
||||
await hass.async_block_till_done()
|
||||
@@ -656,8 +663,8 @@ async def test_updating_to_often(
|
||||
called.clear()
|
||||
|
||||
assert (
|
||||
"Updating Command Line Switch Test took longer than the scheduled update interval"
|
||||
not in caplog.text
|
||||
"Updating Command Line Switch Test took longer"
|
||||
" than the scheduled update interval" not in caplog.text
|
||||
)
|
||||
|
||||
# Simulate update takes too long
|
||||
@@ -671,8 +678,8 @@ async def test_updating_to_often(
|
||||
await hass.async_block_till_done()
|
||||
assert called
|
||||
assert (
|
||||
"Updating Command Line Switch Test took longer than the scheduled update interval"
|
||||
in caplog.text
|
||||
"Updating Command Line Switch Test took longer"
|
||||
" than the scheduled update interval" in caplog.text
|
||||
)
|
||||
|
||||
|
||||
|
||||
+30
-19
@@ -219,7 +219,10 @@ class BasicTriggerStateDescription(TypedDict):
|
||||
|
||||
|
||||
class TriggerStateDescription(BasicTriggerStateDescription):
|
||||
"""Test state and expected service call count for both included and excluded entities."""
|
||||
"""Test state and expected service call count.
|
||||
|
||||
Covers both included and excluded entities.
|
||||
"""
|
||||
|
||||
excluded_state: StateDescription # State for entities not meant to be targeted
|
||||
# State for the *other* targeted entities (the ones not under direct test).
|
||||
@@ -237,7 +240,9 @@ class ConditionStateDescription(TypedDict):
|
||||
excluded_state: StateDescription # State for entities not meant to be targeted
|
||||
|
||||
condition_true: bool # If the condition is expected to evaluate to true
|
||||
condition_true_first_entity: bool # If the condition is expected to evaluate to true for the first targeted entity
|
||||
# If the condition is expected to evaluate to true
|
||||
# for the first targeted entity
|
||||
condition_true_first_entity: bool
|
||||
|
||||
|
||||
def _parametrize_condition_states(
|
||||
@@ -836,7 +841,7 @@ def parametrize_numerical_attribute_changed_trigger_states(
|
||||
attribute_value_scale: float = 1.0,
|
||||
attribute_required: bool = False,
|
||||
) -> list[tuple[str, dict[str, Any], list[TriggerStateDescription]]]:
|
||||
"""Parametrize states and expected service call counts for numerical-changed triggers.
|
||||
"""Parametrize states for numerical-changed triggers.
|
||||
|
||||
Generates state sequences for a trigger that fires whenever an attribute
|
||||
crosses or matches a "changed" threshold (modes "any" / "above" / "below").
|
||||
@@ -982,7 +987,7 @@ def parametrize_numerical_attribute_crossed_threshold_trigger_states(
|
||||
attribute_value_scale: float = 1.0,
|
||||
attribute_required: bool = False,
|
||||
) -> list[tuple[str, dict[str, Any], list[TriggerStateDescription]]]:
|
||||
"""Parametrize states and expected service call counts for numerical crossed-threshold triggers.
|
||||
"""Parametrize states for numerical crossed-threshold triggers.
|
||||
|
||||
Generates state sequences for a trigger that fires when an attribute
|
||||
crosses a threshold boundary. The trigger is exercised across four
|
||||
@@ -1150,11 +1155,11 @@ def parametrize_numerical_state_value_changed_trigger_states(
|
||||
trigger_options: dict[str, Any] | None = None,
|
||||
unit_attributes: dict | None = None,
|
||||
) -> list[tuple[str, dict[str, Any], list[TriggerStateDescription]]]:
|
||||
"""Parametrize states and expected service call counts for numerical state-value changed triggers.
|
||||
"""Parametrize states for numerical state-value changed triggers.
|
||||
|
||||
Unlike parametrize_numerical_attribute_changed_trigger_states, this is for
|
||||
entities where the tracked numerical value is in state.state (e.g. sensor
|
||||
entities), not in an attribute.
|
||||
Unlike parametrize_numerical_attribute_changed_trigger_states,
|
||||
this is for entities where the tracked numerical value is in
|
||||
state.state (e.g. sensor entities), not in an attribute.
|
||||
"""
|
||||
from homeassistant.const import ATTR_DEVICE_CLASS # noqa: PLC0415
|
||||
|
||||
@@ -1231,7 +1236,7 @@ def parametrize_numerical_state_value_crossed_threshold_trigger_states(
|
||||
trigger_options: dict[str, Any] | None = None,
|
||||
unit_attributes: dict | None = None,
|
||||
) -> list[tuple[str, dict[str, Any], list[TriggerStateDescription]]]:
|
||||
"""Parametrize states and expected service call counts for numerical state-value crossed threshold triggers.
|
||||
"""Parametrize states for numerical state-value crossed threshold triggers.
|
||||
|
||||
Unlike parametrize_numerical_attribute_crossed_threshold_trigger_states,
|
||||
this is for entities where the tracked numerical value is in state.state
|
||||
@@ -1332,7 +1337,7 @@ async def arm_trigger(
|
||||
trigger_target: dict,
|
||||
calls: list[str],
|
||||
) -> None:
|
||||
"""Arm the specified trigger and record fired entity_ids in calls when it triggers."""
|
||||
"""Arm the trigger and record fired entity_ids in calls."""
|
||||
options = {CONF_OPTIONS: {**trigger_options}} if trigger_options is not None else {}
|
||||
|
||||
trigger_config = {
|
||||
@@ -1481,7 +1486,7 @@ async def _validate_condition_options(
|
||||
*,
|
||||
valid: bool,
|
||||
) -> None:
|
||||
"""Assert that a condition accepts or rejects the given options during validation."""
|
||||
"""Assert that a condition accepts or rejects the given options."""
|
||||
config: dict[str, Any] = {
|
||||
CONF_CONDITION: condition,
|
||||
CONF_TARGET: {ATTR_LABEL_ID: "test_label"},
|
||||
@@ -1911,10 +1916,11 @@ def parametrize_numerical_condition_above_below_any(
|
||||
threshold_unit: str | None | UndefinedType = UNDEFINED,
|
||||
unit_attributes: dict | None = None,
|
||||
) -> list[tuple[str, dict[str, Any], list[ConditionStateDescription]]]:
|
||||
"""Parametrize above/below/between threshold cases for state-value numerical conditions under behavior=any.
|
||||
"""Parametrize threshold cases for state-value numerical conditions.
|
||||
|
||||
Generates state sequences for a condition that reads its tracked value
|
||||
directly from `state.state` (e.g. a sensor with a temperature device
|
||||
Uses behavior=any. Generates state sequences for a condition
|
||||
that reads its tracked value directly from `state.state`
|
||||
(e.g. a sensor with a temperature device
|
||||
class). The condition is exercised across three threshold types in turn
|
||||
— "above", "below", "between" — and for each, the helper invokes
|
||||
`parametrize_condition_states_any` with target/other states populated
|
||||
@@ -2033,7 +2039,9 @@ def parametrize_numerical_condition_above_below_all(
|
||||
threshold_unit: str | None | UndefinedType = UNDEFINED,
|
||||
unit_attributes: dict | None = None,
|
||||
) -> list[tuple[str, dict[str, Any], list[ConditionStateDescription]]]:
|
||||
"""Parametrize above/below/between threshold cases for state-value numerical conditions under behavior=all.
|
||||
"""Parametrize threshold cases for state-value numerical conditions.
|
||||
|
||||
Uses behavior=all.
|
||||
|
||||
See `parametrize_numerical_condition_above_below_any` for the structure
|
||||
of the generated test cases; the only difference is that this helper
|
||||
@@ -2153,10 +2161,11 @@ def parametrize_numerical_attribute_condition_above_below_any(
|
||||
attribute_required: bool = False,
|
||||
attribute_value_scale: float = 1.0,
|
||||
) -> list[tuple[str, dict[str, Any], list[ConditionStateDescription]]]:
|
||||
"""Parametrize above/below/between threshold cases for attribute-based numerical conditions under behavior=any.
|
||||
"""Parametrize threshold cases for attribute-based numerical conditions.
|
||||
|
||||
Generates state sequences for a condition that reads its tracked value
|
||||
from a state attribute (e.g. `climate.target_humidity`). The condition
|
||||
Uses behavior=any. Generates state sequences for a condition
|
||||
that reads its tracked value from a state attribute
|
||||
(e.g. `climate.target_humidity`). The condition
|
||||
is exercised across three threshold types in turn — "above", "below",
|
||||
"between" — and for each, the helper invokes
|
||||
`parametrize_condition_states_any` with target/other states populated
|
||||
@@ -2300,7 +2309,9 @@ def parametrize_numerical_attribute_condition_above_below_all(
|
||||
attribute_required: bool = False,
|
||||
attribute_value_scale: float = 1.0,
|
||||
) -> list[tuple[str, dict[str, Any], list[ConditionStateDescription]]]:
|
||||
"""Parametrize above/below/between threshold cases for attribute-based numerical conditions under behavior=all.
|
||||
"""Parametrize threshold cases for attribute-based numerical conditions.
|
||||
|
||||
Uses behavior=all.
|
||||
|
||||
See `parametrize_numerical_attribute_condition_above_below_any` for the
|
||||
structure of the generated test cases; the only difference is that this
|
||||
|
||||
@@ -22,7 +22,7 @@ async def test_binary_sensor_entities_snapshot(
|
||||
mock_connector: MagicMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Snapshot test for binary sensor entities creation, unique IDs, and device info."""
|
||||
"""Snapshot test for binary sensor entity creation."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
snapshot_compit_entities(hass, entity_registry, snapshot, Platform.BINARY_SENSOR)
|
||||
|
||||
@@ -57,7 +57,7 @@ async def test_async_step_user_failed_auth(
|
||||
mock_compit_api: AsyncMock,
|
||||
mock_setup_entry: AsyncMock,
|
||||
) -> None:
|
||||
"""Test user step with invalid authentication then success after error is cleared."""
|
||||
"""Test user step with invalid auth then success."""
|
||||
mock_compit_api.side_effect = [exception, True]
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@@ -129,7 +129,7 @@ async def test_async_step_reauth_confirm_failed_auth(
|
||||
mock_compit_api: AsyncMock,
|
||||
mock_setup_entry: AsyncMock,
|
||||
) -> None:
|
||||
"""Test reauth confirm step with invalid authentication then success after error is cleared."""
|
||||
"""Test reauth confirm step with invalid auth then success."""
|
||||
mock_compit_api.side_effect = [exception, True]
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
@@ -42,7 +42,7 @@ async def test_number_unknown_device_parameters(
|
||||
mock_connector: MagicMock,
|
||||
mock_return_value: Any,
|
||||
) -> None:
|
||||
"""Test that number entity shows unknown when get_parameter_value returns invalid values."""
|
||||
"""Test number entity shows unknown for invalid values."""
|
||||
|
||||
mock_connector.get_current_value.side_effect = lambda device_id, parameter_code: (
|
||||
mock_return_value
|
||||
|
||||
@@ -44,7 +44,7 @@ async def test_select_unknown_device_parameters(
|
||||
mock_connector: MagicMock,
|
||||
mock_return_value: Any,
|
||||
) -> None:
|
||||
"""Test that select entity shows unknown when get_current_option returns various invalid values."""
|
||||
"""Test select entity shows unknown for invalid values."""
|
||||
mock_connector.get_current_option.side_effect = lambda device_id, parameter_code: (
|
||||
mock_return_value
|
||||
)
|
||||
|
||||
@@ -42,7 +42,7 @@ async def test_sensor_return_value_enum_sensor(
|
||||
mock_return_value: Any | None,
|
||||
test_description: str,
|
||||
) -> None:
|
||||
"""Test that sensor entity shows unknown when get_current_option returns various invalid values."""
|
||||
"""Test sensor entity shows unknown for invalid values."""
|
||||
mock_connector.get_current_value.side_effect = lambda device_id, parameter_code: (
|
||||
mock_return_value
|
||||
)
|
||||
@@ -59,7 +59,7 @@ async def test_sensor_enum_value_cannot_return_number(
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_connector: MagicMock,
|
||||
) -> None:
|
||||
"""Test that sensor entity shows unknown when get_current_option returns various invalid values."""
|
||||
"""Test sensor entity shows unknown for invalid values."""
|
||||
mock_connector.get_current_value.side_effect = lambda device_id, parameter_code: (
|
||||
123 # Invalid enum value
|
||||
)
|
||||
@@ -102,7 +102,7 @@ async def test_sensor_number_value_cannot_return_enum(
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_connector: MagicMock,
|
||||
) -> None:
|
||||
"""Test that sensor entity shows unknown when get_current_value returns enum instead of number."""
|
||||
"""Test sensor shows unknown when value is an enum, not a number."""
|
||||
mock_connector.get_current_value.side_effect = lambda device_id, parameter_code: (
|
||||
"eco" # Invalid number value
|
||||
)
|
||||
|
||||
@@ -43,7 +43,7 @@ async def test_water_heater_unknown_temperature(
|
||||
mock_connector: MagicMock,
|
||||
mock_return_value: Any,
|
||||
) -> None:
|
||||
"""Test that water heater shows unknown temperature when get_current_value returns invalid values."""
|
||||
"""Test water heater shows unknown temp for invalid values."""
|
||||
mock_connector.get_current_value.side_effect = lambda device_id, parameter_code: (
|
||||
mock_return_value
|
||||
)
|
||||
|
||||
@@ -455,7 +455,8 @@ async def test_initialize_flow_unmet_dependency(
|
||||
mock_integration(
|
||||
hass, MockModule(domain="dependency_1", config_schema=config_schema)
|
||||
)
|
||||
# The test2 config flow should fail because dependency_1 can't be automatically setup
|
||||
# The test2 config flow should fail because
|
||||
# dependency_1 can't be automatically set up
|
||||
mock_integration(
|
||||
hass,
|
||||
MockModule(domain="test2", partial_manifest={"dependencies": ["dependency_1"]}),
|
||||
@@ -3303,7 +3304,7 @@ async def test_flow_with_multiple_schema_errors(
|
||||
async def test_flow_with_multiple_schema_errors_base(
|
||||
hass: HomeAssistant, client: TestClient
|
||||
) -> None:
|
||||
"""Test an config flow with multiple schema errors where fields are not in the schema."""
|
||||
"""Test config flow with multiple schema errors."""
|
||||
mock_integration(
|
||||
hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True))
|
||||
)
|
||||
|
||||
@@ -470,7 +470,10 @@ async def test_remove_config_entry_from_device_if_integration_remove(
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test removing config entry from device doesn't lead to an error when the integration removes the entry."""
|
||||
"""Test removing config entry from device.
|
||||
|
||||
Should not error when the integration removes the entry.
|
||||
"""
|
||||
assert await async_setup_component(hass, "config", {})
|
||||
ws_client = await hass_ws_client(hass)
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ RE_REQUEST_DOMAIN = re.compile(r".*tests\/components\/([^/]+)\/.*")
|
||||
|
||||
@pytest.fixture(scope="session", autouse=find_spec("zeroconf") is not None)
|
||||
def patch_zeroconf_multiple_catcher() -> Generator[None]:
|
||||
"""If installed, patch zeroconf wrapper that detects if multiple instances are used."""
|
||||
"""Patch zeroconf wrapper that detects multiple instances."""
|
||||
with patch(
|
||||
"homeassistant.components.zeroconf.install_multiple_zeroconf_catcher",
|
||||
side_effect=lambda zc: None,
|
||||
|
||||
@@ -320,7 +320,11 @@ async def test_extra_systen_prompt(
|
||||
hass: HomeAssistant, mock_conversation_input: ConversationInput
|
||||
) -> None:
|
||||
"""Test that extra system prompt works."""
|
||||
extra_system_prompt = "Garage door cover.garage_door has been left open for 30 minutes. We asked the user if they want to close it."
|
||||
extra_system_prompt = (
|
||||
"Garage door cover.garage_door has been left open"
|
||||
" for 30 minutes. We asked the user if they want"
|
||||
" to close it."
|
||||
)
|
||||
extra_system_prompt2 = (
|
||||
"User person.paulus came home. Asked him what he wants to do."
|
||||
)
|
||||
|
||||
@@ -738,7 +738,8 @@ async def test_error_no_device_in_area(
|
||||
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"]
|
||||
== "Sorry, I am not aware of any device called missing entity in the kitchen area"
|
||||
== "Sorry, I am not aware of any device called"
|
||||
" missing entity in the kitchen area"
|
||||
)
|
||||
|
||||
|
||||
@@ -889,7 +890,7 @@ async def test_error_no_domain(hass: HomeAssistant) -> None:
|
||||
|
||||
@pytest.mark.usefixtures("init_components")
|
||||
async def test_error_no_domain_exposed(hass: HomeAssistant) -> None:
|
||||
"""Test error message when devices/entities exist for a domain but are not exposed."""
|
||||
"""Test error when entities exist but are not exposed."""
|
||||
hass.states.async_set("fan.test_fan", "off")
|
||||
expose_entity(hass, "fan.test_fan", False)
|
||||
await hass.async_block_till_done()
|
||||
@@ -944,7 +945,7 @@ async def test_error_no_domain_in_area_exposed(
|
||||
entity_registry: er.EntityRegistry,
|
||||
area_registry: ar.AreaRegistry,
|
||||
) -> None:
|
||||
"""Test error message when devices/entities for a domain exist in an area but are not exposed."""
|
||||
"""Test error when area entities exist but are not exposed."""
|
||||
area_kitchen = area_registry.async_get_or_create("kitchen_id")
|
||||
area_kitchen = area_registry.async_update(area_kitchen.id, name="kitchen")
|
||||
|
||||
@@ -1023,7 +1024,7 @@ async def test_error_no_domain_on_floor_exposed(
|
||||
area_registry: ar.AreaRegistry,
|
||||
floor_registry: fr.FloorRegistry,
|
||||
) -> None:
|
||||
"""Test error message when devices/entities for a domain exist on a floor but are not exposed."""
|
||||
"""Test error when floor entities exist but are not exposed."""
|
||||
floor_ground = floor_registry.async_create("ground")
|
||||
area_kitchen = area_registry.async_get_or_create("kitchen_id")
|
||||
area_kitchen = area_registry.async_update(
|
||||
@@ -1169,7 +1170,7 @@ async def test_error_no_device_class_in_area_exposed(
|
||||
entity_registry: er.EntityRegistry,
|
||||
area_registry: ar.AreaRegistry,
|
||||
) -> None:
|
||||
"""Test error message when entities of a device class exist in an area but are not exposed."""
|
||||
"""Test error when device class entities in area are not exposed."""
|
||||
area_bedroom = area_registry.async_get_or_create("bedroom_id")
|
||||
area_bedroom = area_registry.async_update(area_bedroom.id, name="bedroom")
|
||||
bedroom_window = entity_registry.async_get_or_create("cover", "demo", "1234")
|
||||
@@ -1205,7 +1206,7 @@ async def test_error_no_device_class_on_floor_exposed(
|
||||
area_registry: ar.AreaRegistry,
|
||||
floor_registry: fr.FloorRegistry,
|
||||
) -> None:
|
||||
"""Test error message when entities of a device class exist in on a floor but are not exposed."""
|
||||
"""Test error when device class entities on floor are not exposed."""
|
||||
floor_ground = floor_registry.async_create("ground")
|
||||
|
||||
area_bedroom = area_registry.async_get_or_create("bedroom_id")
|
||||
@@ -1333,7 +1334,7 @@ async def test_error_duplicate_names(
|
||||
async def test_duplicate_names_but_one_is_exposed(
|
||||
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
||||
) -> None:
|
||||
"""Test when multiple devices have the same name (or alias), but only one of them is exposed."""
|
||||
"""Test duplicate names where only one is exposed."""
|
||||
kitchen_light_1 = entity_registry.async_get_or_create("light", "demo", "1234")
|
||||
kitchen_light_2 = entity_registry.async_get_or_create("light", "demo", "5678")
|
||||
|
||||
@@ -1371,7 +1372,7 @@ async def test_error_duplicate_names_same_area(
|
||||
area_registry: ar.AreaRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test error message when multiple devices have the same name (or alias) in the same area."""
|
||||
"""Test error when duplicate names exist in same area."""
|
||||
area_kitchen = area_registry.async_get_or_create("kitchen_id")
|
||||
area_kitchen = area_registry.async_update(area_kitchen.id, name="kitchen")
|
||||
|
||||
@@ -1405,7 +1406,8 @@ async def test_error_duplicate_names_same_area(
|
||||
)
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"]
|
||||
== f"Sorry, there are multiple devices called {name} in the {area_kitchen.name} area"
|
||||
== f"Sorry, there are multiple devices called"
|
||||
f" {name} in the {area_kitchen.name} area"
|
||||
)
|
||||
|
||||
# question
|
||||
@@ -1419,7 +1421,8 @@ async def test_error_duplicate_names_same_area(
|
||||
)
|
||||
assert (
|
||||
result.response.speech["plain"]["speech"]
|
||||
== f"Sorry, there are multiple devices called {name} in the {area_kitchen.name} area"
|
||||
== f"Sorry, there are multiple devices called"
|
||||
f" {name} in the {area_kitchen.name} area"
|
||||
)
|
||||
|
||||
|
||||
@@ -1429,7 +1432,7 @@ async def test_duplicate_names_same_area_but_one_is_exposed(
|
||||
area_registry: ar.AreaRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test when multiple devices have the same name (or alias) in the same area but only one is exposed."""
|
||||
"""Test duplicate names in same area with one exposed."""
|
||||
area_kitchen = area_registry.async_get_or_create("kitchen_id")
|
||||
area_kitchen = area_registry.async_update(area_kitchen.id, name="kitchen")
|
||||
|
||||
@@ -1472,7 +1475,7 @@ async def test_duplicate_names_different_areas(
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test preferred area when multiple devices have the same name (or alias) in different areas."""
|
||||
"""Test preferred area with duplicate names in different areas."""
|
||||
area_kitchen = area_registry.async_get_or_create("kitchen_id")
|
||||
area_kitchen = area_registry.async_update(area_kitchen.id, name="kitchen")
|
||||
|
||||
@@ -1594,7 +1597,7 @@ async def test_error_no_timer_support(
|
||||
area_registry: ar.AreaRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test error message when a device does not support timers (no handler is registered)."""
|
||||
"""Test error when device has no timer support."""
|
||||
area_kitchen = area_registry.async_create("kitchen")
|
||||
|
||||
entry = MockConfigEntry()
|
||||
@@ -1910,7 +1913,7 @@ async def test_same_aliased_entities_in_different_areas(
|
||||
area_registry: ar.AreaRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test that entities with the same alias (but different names) in different areas can be targeted."""
|
||||
"""Test same-alias entities in different areas."""
|
||||
area_kitchen = area_registry.async_get_or_create("kitchen_id")
|
||||
area_kitchen = area_registry.async_update(area_kitchen.id, name="kitchen")
|
||||
|
||||
@@ -2030,7 +2033,7 @@ async def test_device_id_in_handler(hass: HomeAssistant) -> None:
|
||||
|
||||
@pytest.mark.usefixtures("init_components")
|
||||
async def test_name_wildcard_lower_priority(hass: HomeAssistant) -> None:
|
||||
"""Test that the default agent does not prioritize a {name} slot when it's a wildcard."""
|
||||
"""Test default agent deprioritizes wildcard name slot."""
|
||||
|
||||
class OrderBeerIntentHandler(intent.IntentHandler):
|
||||
intent_type = "OrderBeer"
|
||||
@@ -2268,7 +2271,7 @@ async def test_intent_entity_remove_custom_name(
|
||||
entity_registry: er.EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that removing a custom name allows targeting the entity by its auto-generated name again."""
|
||||
"""Test removing custom name restores auto-generated name."""
|
||||
context = Context()
|
||||
entity = MockLight("kitchen light", STATE_ON)
|
||||
entity._attr_unique_id = "1234"
|
||||
@@ -2698,7 +2701,7 @@ async def test_custom_sentences_priority(
|
||||
hass_admin_user: MockUser,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that user intents from custom_sentences have priority over builtin intents/sentences."""
|
||||
"""Test custom_sentences have priority over builtins."""
|
||||
with tempfile.NamedTemporaryFile(
|
||||
mode="w+",
|
||||
encoding="utf-8",
|
||||
@@ -2755,7 +2758,7 @@ async def test_config_sentences_priority(
|
||||
hass_admin_user: MockUser,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that user intents from configuration.yaml have priority over builtin intents/sentences.
|
||||
"""Test config intents have priority over builtins.
|
||||
|
||||
Also test that they follow proper selection logic.
|
||||
"""
|
||||
|
||||
@@ -158,7 +158,7 @@ async def test_empty_response(hass: HomeAssistant) -> None:
|
||||
async def test_response_same_sentence(
|
||||
hass: HomeAssistant, service_calls: list[ServiceCall]
|
||||
) -> None:
|
||||
"""Test the conversation response action with multiple triggers using the same sentence."""
|
||||
"""Test conversation response with same sentence triggers."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"automation",
|
||||
@@ -249,7 +249,7 @@ async def test_response_same_sentence_with_error(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the conversation response action with multiple triggers using the same sentence and an error."""
|
||||
"""Test conversation response with same sentence and error."""
|
||||
caplog.set_level(logging.ERROR)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
@@ -300,7 +300,7 @@ async def test_response_same_sentence_with_error(
|
||||
async def test_subscribe_trigger_does_not_interfere_with_responses(
|
||||
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||
) -> None:
|
||||
"""Test that subscribing to a trigger from the websocket API does not interfere with responses."""
|
||||
"""Test trigger subscription does not interfere with responses."""
|
||||
websocket_client = await hass_ws_client()
|
||||
await websocket_client.send_json_auto_id(
|
||||
{
|
||||
@@ -671,7 +671,9 @@ async def test_trigger_with_device_id(hass: HomeAssistant) -> None:
|
||||
"command": ["test sentence"],
|
||||
},
|
||||
"action": {
|
||||
"set_conversation_response": "{{ trigger.device_id }} - {{ trigger.satellite_id }}",
|
||||
"set_conversation_response": (
|
||||
"{{ trigger.device_id }} - {{ trigger.satellite_id }}"
|
||||
),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -50,7 +50,9 @@ async def test_pressing_button(
|
||||
BUTTON_DOMAIN,
|
||||
SERVICE_PRESS,
|
||||
{
|
||||
ATTR_ENTITY_ID: "button.cookidoo_clear_shopping_list_and_additional_purchases",
|
||||
ATTR_ENTITY_ID: (
|
||||
"button.cookidoo_clear_shopping_list_and_additional_purchases"
|
||||
),
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
@@ -78,7 +80,9 @@ async def test_pressing_button_exception(
|
||||
BUTTON_DOMAIN,
|
||||
SERVICE_PRESS,
|
||||
{
|
||||
ATTR_ENTITY_ID: "button.cookidoo_clear_shopping_list_and_additional_purchases",
|
||||
ATTR_ENTITY_ID: (
|
||||
"button.cookidoo_clear_shopping_list_and_additional_purchases"
|
||||
),
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
@@ -269,7 +269,11 @@ async def test_migration_from_with_error(
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data=config_data,
|
||||
title=f"MIGRATION_TEST from {from_version}.{from_minor_version} with login exception '{login_exception}'",
|
||||
title=(
|
||||
f"MIGRATION_TEST from {from_version}."
|
||||
f"{from_minor_version} with login"
|
||||
f" exception '{login_exception}'"
|
||||
),
|
||||
version=from_version,
|
||||
minor_version=from_minor_version,
|
||||
unique_id=unique_id,
|
||||
|
||||
@@ -273,9 +273,10 @@ async def config_entry_with_empty_status(hass: HomeAssistant) -> MockConfigEntry
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_warned_fan_speeds():
|
||||
"""Reset the warned unknown fan speeds set before each test."""
|
||||
# TODO(2026.7.0): When support for unknown fan speeds is removed, delete this fixture.
|
||||
# This is necessary because `warned_unknown_fan_speeds` is a class variable and would persist
|
||||
# across tests otherwise.
|
||||
# TODO(2026.7.0): When support for unknown fan speeds
|
||||
# is removed, delete this fixture. This is necessary
|
||||
# because `warned_unknown_fan_speeds` is a class variable
|
||||
# and would persist across tests otherwise.
|
||||
CoolmasterClimate.warned_unknown_fan_speeds.clear()
|
||||
yield
|
||||
CoolmasterClimate.warned_unknown_fan_speeds.clear()
|
||||
|
||||
@@ -201,7 +201,7 @@ async def test_counter_state_trigger_behavior_any(
|
||||
trigger_options: dict[str, Any] | None,
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the counter state trigger fires when any counter state changes to a specific state."""
|
||||
"""Test counter trigger fires on any state change."""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
target_entities=target_counters,
|
||||
@@ -232,7 +232,7 @@ async def test_counter_state_trigger_behavior_first(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the counter state trigger fires when the first counter changes to a specific state."""
|
||||
"""Test counter trigger fires on first state change."""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
target_entities=target_counters,
|
||||
@@ -263,7 +263,7 @@ async def test_counter_state_trigger_behavior_last(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the counter state trigger fires when the last counter changes to a specific state."""
|
||||
"""Test counter trigger fires on last state change."""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
target_entities=target_counters,
|
||||
|
||||
@@ -48,7 +48,8 @@ async def test_services(
|
||||
await call_service(hass, SERVICE_TOGGLE, ent5)
|
||||
await call_service(hass, SERVICE_TOGGLE, ent6)
|
||||
|
||||
# entities should be either closed or closing, depending on if they report transitional states
|
||||
# entities should be either closed or closing,
|
||||
# depending on if they report transitional states
|
||||
assert is_closed(hass, ent1)
|
||||
assert is_closing(hass, ent2, 50)
|
||||
assert is_closed(hass, ent3)
|
||||
@@ -66,7 +67,8 @@ async def test_services(
|
||||
await call_service(hass, SERVICE_TOGGLE, ent5)
|
||||
await call_service(hass, SERVICE_TOGGLE, ent6)
|
||||
|
||||
# entities should be in correct state depending on the SUPPORT_STOP feature and cover position
|
||||
# entities should be in correct state depending on
|
||||
# the SUPPORT_STOP feature and cover position
|
||||
assert is_open(hass, ent1)
|
||||
assert is_closed(hass, ent2, 0)
|
||||
assert is_open(hass, ent3)
|
||||
@@ -82,7 +84,8 @@ async def test_services(
|
||||
await call_service(hass, SERVICE_TOGGLE, ent5)
|
||||
await call_service(hass, SERVICE_TOGGLE, ent6)
|
||||
|
||||
# entities should be in correct state depending on the SUPPORT_STOP feature and cover position
|
||||
# entities should be in correct state depending on
|
||||
# the SUPPORT_STOP feature and cover position
|
||||
assert is_closed(hass, ent1)
|
||||
assert is_opening(hass, ent2, 0, closed=True)
|
||||
assert is_closed(hass, ent3)
|
||||
|
||||
Reference in New Issue
Block a user