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 a (#170806)
This commit is contained in:
@@ -53,7 +53,10 @@ async def test_availability(
|
||||
mock_accuweather_client: AsyncMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Ensure that we mark the entities unavailable correctly when service is offline."""
|
||||
"""Ensure that we mark the entities unavailable correctly.
|
||||
|
||||
Test when service is offline.
|
||||
"""
|
||||
entity_id = "sensor.home_cloud_ceiling"
|
||||
await init_integration(hass)
|
||||
|
||||
@@ -99,7 +102,10 @@ async def test_availability_forecast(
|
||||
mock_accuweather_client: AsyncMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Ensure that we mark the entities unavailable correctly when service is offline."""
|
||||
"""Ensure that we mark the entities unavailable correctly.
|
||||
|
||||
Test when service is offline.
|
||||
"""
|
||||
entity_id = "sensor.home_hours_of_sun_day_2"
|
||||
|
||||
await init_integration(hass)
|
||||
|
||||
@@ -45,7 +45,10 @@ async def test_availability(
|
||||
mock_accuweather_client: AsyncMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Ensure that we mark the entities unavailable correctly when service is offline."""
|
||||
"""Ensure that we mark the entities unavailable correctly.
|
||||
|
||||
Test when service is offline.
|
||||
"""
|
||||
entity_id = "weather.home"
|
||||
await init_integration(hass)
|
||||
|
||||
|
||||
@@ -151,7 +151,10 @@ async def test_user_flow_token_polling_error(
|
||||
async def test_user_flow_duplicate_account(
|
||||
hass: HomeAssistant, mock_actron_api: AsyncMock, mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
"""Test duplicate account handling - should abort when same account is already configured."""
|
||||
"""Test duplicate account handling.
|
||||
|
||||
Should abort when same account is already configured.
|
||||
"""
|
||||
# Create an existing config entry for the same user account
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ async def test_generate_structured_data(
|
||||
}
|
||||
),
|
||||
)
|
||||
# Arbitrary data returned by the mock entity (not determined by above schema in test)
|
||||
# Arbitrary data returned by the mock entity
|
||||
# (not determined by above schema in test)
|
||||
assert result.data == {
|
||||
"name": "Tracy Chen",
|
||||
"age": 30,
|
||||
|
||||
@@ -138,7 +138,9 @@ async def test_generate_data_service_structure_fields(
|
||||
"entity_id": TEST_ENTITY_ID,
|
||||
"structure": {
|
||||
"name": {
|
||||
"description": "First and last name of the user such as Alice Smith",
|
||||
"description": (
|
||||
"First and last name of the user such as Alice Smith"
|
||||
),
|
||||
"required": True,
|
||||
"selector": {"text": {}},
|
||||
},
|
||||
@@ -156,7 +158,8 @@ async def test_generate_data_service_structure_fields(
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
# Arbitrary data returned by the mock entity (not determined by above schema in test)
|
||||
# Arbitrary data returned by the mock entity
|
||||
# (not determined by above schema in test)
|
||||
assert result["data"] == {
|
||||
"name": "Tracy Chen",
|
||||
"age": 30,
|
||||
@@ -191,7 +194,9 @@ async def test_generate_data_service_structure_fields(
|
||||
(
|
||||
{
|
||||
"name": {
|
||||
"description": "First and last name of the user such as Alice Smith",
|
||||
"description": (
|
||||
"First and last name of the user such as Alice Smith"
|
||||
),
|
||||
"selector": {"invalid-selector": {}},
|
||||
},
|
||||
},
|
||||
@@ -201,7 +206,9 @@ async def test_generate_data_service_structure_fields(
|
||||
(
|
||||
{
|
||||
"name": {
|
||||
"description": "First and last name of the user such as Alice Smith",
|
||||
"description": (
|
||||
"First and last name of the user such as Alice Smith"
|
||||
),
|
||||
"selector": {
|
||||
"text": {
|
||||
"extra-config": False,
|
||||
@@ -215,7 +222,9 @@ async def test_generate_data_service_structure_fields(
|
||||
(
|
||||
{
|
||||
"name": {
|
||||
"description": "First and last name of the user such as Alice Smith",
|
||||
"description": (
|
||||
"First and last name of the user such as Alice Smith"
|
||||
),
|
||||
},
|
||||
},
|
||||
vol.Invalid,
|
||||
@@ -227,7 +236,9 @@ async def test_generate_data_service_structure_fields(
|
||||
(
|
||||
{
|
||||
"name": {
|
||||
"description": "First and last name of the user such as Alice Smith",
|
||||
"description": (
|
||||
"First and last name of the user such as Alice Smith"
|
||||
),
|
||||
"selector": {"text": {}},
|
||||
"extra-fields": "Some extra fields",
|
||||
},
|
||||
@@ -238,7 +249,9 @@ async def test_generate_data_service_structure_fields(
|
||||
(
|
||||
{
|
||||
"name": {
|
||||
"description": "First and last name of the user such as Alice Smith",
|
||||
"description": (
|
||||
"First and last name of the user such as Alice Smith"
|
||||
),
|
||||
"selector": "invalid-schema",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -101,7 +101,9 @@ async def test_generate_data_preferred_entity(
|
||||
mock_ai_task_entity.supported_features = AITaskEntityFeature(0)
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="AI Task entity ai_task.test_task_entity does not support generating data",
|
||||
match=(
|
||||
"AI Task entity ai_task.test_task_entity does not support generating data"
|
||||
),
|
||||
):
|
||||
await async_generate_data(
|
||||
hass,
|
||||
@@ -433,7 +435,9 @@ async def test_generate_image(
|
||||
mock_ai_task_entity.supported_features = AITaskEntityFeature(0)
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="AI Task entity ai_task.test_task_entity does not support generating images",
|
||||
match=(
|
||||
"AI Task entity ai_task.test_task_entity does not support generating images"
|
||||
),
|
||||
):
|
||||
await async_generate_image(
|
||||
hass,
|
||||
|
||||
@@ -494,7 +494,10 @@ async def test_air_quality_numerical_no_unit_condition_behavior_any(
|
||||
condition_options: dict[str, Any],
|
||||
states: list[ConditionStateDescription],
|
||||
) -> None:
|
||||
"""Test air quality numerical conditions without unit conversion and 'any' behavior."""
|
||||
"""Test air quality numerical conditions.
|
||||
|
||||
Without unit conversion and 'any' behavior.
|
||||
"""
|
||||
await assert_condition_behavior_any(
|
||||
hass,
|
||||
target_entities=target_sensors,
|
||||
@@ -557,7 +560,10 @@ async def test_air_quality_numerical_no_unit_condition_behavior_all(
|
||||
condition_options: dict[str, Any],
|
||||
states: list[ConditionStateDescription],
|
||||
) -> None:
|
||||
"""Test air quality numerical conditions without unit conversion and 'all' behavior."""
|
||||
"""Test air quality numerical conditions.
|
||||
|
||||
Without unit conversion and 'all' behavior.
|
||||
"""
|
||||
await assert_condition_behavior_all(
|
||||
hass,
|
||||
target_entities=target_sensors,
|
||||
|
||||
@@ -239,7 +239,10 @@ async def test_air_quality_trigger_binary_sensor_behavior_any(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test air quality triggers fire for binary_sensor entities with gas, CO, and smoke device classes."""
|
||||
"""Test air quality triggers fire for binary_sensor entities.
|
||||
|
||||
Covers gas, CO, and smoke device classes.
|
||||
"""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
target_entities=target_binary_sensors,
|
||||
@@ -685,7 +688,10 @@ async def test_air_quality_trigger_sensor_crossed_threshold_behavior_first(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test air quality crossed_threshold trigger fires on the first sensor state change."""
|
||||
"""Test air quality crossed_threshold trigger.
|
||||
|
||||
Fires on the first sensor state change.
|
||||
"""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
target_entities=target_sensors,
|
||||
@@ -793,7 +799,10 @@ async def test_air_quality_trigger_sensor_crossed_threshold_behavior_last(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test air quality crossed_threshold trigger fires when the last sensor changes state."""
|
||||
"""Test air quality crossed_threshold trigger.
|
||||
|
||||
Fires when the last sensor changes state.
|
||||
"""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
target_entities=target_sensors,
|
||||
|
||||
@@ -106,11 +106,14 @@ async def test_cloud_creates_no_button(
|
||||
[
|
||||
(
|
||||
AirGradientConnectionError("Something happened"),
|
||||
"An error occurred while communicating with the Airgradient device: Something happened",
|
||||
"An error occurred while communicating with the"
|
||||
" Airgradient device: Something happened",
|
||||
),
|
||||
(
|
||||
AirGradientError("Something else happened"),
|
||||
"An unknown error occurred while communicating with the Airgradient device: Something else happened",
|
||||
"An unknown error occurred while communicating"
|
||||
" with the Airgradient device:"
|
||||
" Something else happened",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -108,11 +108,14 @@ async def test_cloud_creates_no_number(
|
||||
[
|
||||
(
|
||||
AirGradientConnectionError("Something happened"),
|
||||
"An error occurred while communicating with the Airgradient device: Something happened",
|
||||
"An error occurred while communicating with the"
|
||||
" Airgradient device: Something happened",
|
||||
),
|
||||
(
|
||||
AirGradientError("Something else happened"),
|
||||
"An unknown error occurred while communicating with the Airgradient device: Something else happened",
|
||||
"An unknown error occurred while communicating"
|
||||
" with the Airgradient device:"
|
||||
" Something else happened",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -102,11 +102,14 @@ async def test_cloud_creates_no_number(
|
||||
[
|
||||
(
|
||||
AirGradientConnectionError("Something happened"),
|
||||
"An error occurred while communicating with the Airgradient device: Something happened",
|
||||
"An error occurred while communicating with the"
|
||||
" Airgradient device: Something happened",
|
||||
),
|
||||
(
|
||||
AirGradientError("Something else happened"),
|
||||
"An unknown error occurred while communicating with the Airgradient device: Something else happened",
|
||||
"An unknown error occurred while communicating"
|
||||
" with the Airgradient device:"
|
||||
" Something else happened",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -108,11 +108,14 @@ async def test_cloud_creates_no_switch(
|
||||
[
|
||||
(
|
||||
AirGradientConnectionError("Something happened"),
|
||||
"An error occurred while communicating with the Airgradient device: Something happened",
|
||||
"An error occurred while communicating with the"
|
||||
" Airgradient device: Something happened",
|
||||
),
|
||||
(
|
||||
AirGradientError("Something else happened"),
|
||||
"An unknown error occurred while communicating with the Airgradient device: Something else happened",
|
||||
"An unknown error occurred while communicating"
|
||||
" with the Airgradient device:"
|
||||
" Something else happened",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -46,7 +46,10 @@ async def test_sensor(
|
||||
async def test_availability(
|
||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
||||
) -> None:
|
||||
"""Ensure that we mark the entities unavailable correctly when service is offline."""
|
||||
"""Ensure that we mark the entities unavailable correctly.
|
||||
|
||||
Test when service is offline.
|
||||
"""
|
||||
await init_integration(hass, aioclient_mock)
|
||||
|
||||
state = hass.states.get("sensor.home_humidity")
|
||||
|
||||
@@ -225,7 +225,8 @@ async def test_dhcp_discovery_duplicate(
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Should abort immediately since device_id extracted from hostname matches existing entry
|
||||
# Should abort immediately since device_id extracted from
|
||||
# hostname matches existing entry
|
||||
# and update the IP address
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
@@ -19,7 +19,7 @@ from tests.common import MockConfigEntry, snapshot_platform
|
||||
[
|
||||
"airos_loco5ac_ap-ptp.json", # v8 ptp
|
||||
"airos_liteapgps_ap_ptmp_40mhz.json", # v8 ptmp
|
||||
"airos_NanoStation_loco_M5_v6.3.16_XM_sta.json", # v6 XM (different login process)
|
||||
"airos_NanoStation_loco_M5_v6.3.16_XM_sta.json", # v6 XM
|
||||
"airos_NanoStation_M5_sta_v6.3.16.json", # v6 XW
|
||||
],
|
||||
indirect=True,
|
||||
|
||||
@@ -53,7 +53,10 @@ async def test_migration_from_v1_to_v3_unique_id(
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Verify that we can migrate from v1 (pre 2023.9.0) to the latest unique id format."""
|
||||
"""Verify migration from v1 (pre 2023.9.0).
|
||||
|
||||
Migrates to the latest unique id format.
|
||||
"""
|
||||
entry = create_entry(hass, WAVE_SERVICE_INFO, WAVE_DEVICE_INFO)
|
||||
device = create_device(entry, device_registry, WAVE_SERVICE_INFO, WAVE_DEVICE_INFO)
|
||||
|
||||
@@ -94,7 +97,10 @@ async def test_migration_from_v2_to_v3_unique_id(
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Verify that we can migrate from v2 (introduced in 2023.9.0) to the latest unique id format."""
|
||||
"""Verify migration from v2 (introduced in 2023.9.0).
|
||||
|
||||
Migrates to the latest unique id format.
|
||||
"""
|
||||
entry = create_entry(hass, WAVE_SERVICE_INFO, WAVE_DEVICE_INFO)
|
||||
device = create_device(entry, device_registry, WAVE_SERVICE_INFO, WAVE_DEVICE_INFO)
|
||||
|
||||
@@ -135,7 +141,10 @@ async def test_migration_from_v1_and_v2_to_v3_unique_id(
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test if migration works when we have both v1 (pre 2023.9.0) and v2 (introduced in 2023.9.0) unique ids."""
|
||||
"""Test migration with both v1 and v2 unique ids.
|
||||
|
||||
v1 is pre 2023.9.0, v2 introduced in 2023.9.0.
|
||||
"""
|
||||
entry = create_entry(hass, WAVE_SERVICE_INFO, WAVE_DEVICE_INFO)
|
||||
device = create_device(entry, device_registry, WAVE_SERVICE_INFO, WAVE_DEVICE_INFO)
|
||||
|
||||
|
||||
@@ -154,8 +154,9 @@ async def test_form_invalid_system_id(hass: HomeAssistant) -> None:
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert (
|
||||
result["title"]
|
||||
== f"Airzone {CONFIG_ID1[CONF_HOST]}:{CONFIG_ID1[CONF_PORT]} #{CONFIG_ID1[CONF_ID]}"
|
||||
result["title"] == f"Airzone {CONFIG_ID1[CONF_HOST]}"
|
||||
f":{CONFIG_ID1[CONF_PORT]}"
|
||||
f" #{CONFIG_ID1[CONF_ID]}"
|
||||
)
|
||||
assert result["data"][CONF_HOST] == CONFIG_ID1[CONF_HOST]
|
||||
assert result["data"][CONF_PORT] == CONFIG_ID1[CONF_PORT]
|
||||
|
||||
@@ -53,8 +53,8 @@ class MockAlarmControlPanel(AlarmControlPanelEntity):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
supported_features: AlarmControlPanelEntityFeature = AlarmControlPanelEntityFeature(
|
||||
0
|
||||
supported_features: AlarmControlPanelEntityFeature = (
|
||||
AlarmControlPanelEntityFeature(0)
|
||||
),
|
||||
code_format: CodeFormat | None = None,
|
||||
code_arm_required: bool = True,
|
||||
|
||||
@@ -27,7 +27,7 @@ from tests.components.common import (
|
||||
|
||||
@pytest.fixture
|
||||
async def target_alarm_control_panels(hass: HomeAssistant) -> dict[str, list[str]]:
|
||||
"""Create multiple alarm_control_panel entities associated with different targets."""
|
||||
"""Create alarm_control_panel entities for different targets."""
|
||||
return await target_entities(hass, "alarm_control_panel")
|
||||
|
||||
|
||||
|
||||
@@ -446,8 +446,8 @@ async def test_if_fires_on_state_change(
|
||||
await hass.async_block_till_done()
|
||||
assert len(service_calls) == 6
|
||||
assert (
|
||||
service_calls[5].data["some"]
|
||||
== f"armed_vacation - device - {entry.entity_id} - armed_night - armed_vacation - None"
|
||||
service_calls[5].data["some"] == f"armed_vacation - device - {entry.entity_id}"
|
||||
f" - armed_night - armed_vacation - None"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -221,6 +221,6 @@ async def test_alarm_control_panel_not_log_deprecated_state_warning(
|
||||
state = hass.states.get(mock_alarm_control_panel_entity.entity_id)
|
||||
assert state is not None
|
||||
assert (
|
||||
"the 'alarm_state' property and return its state using the AlarmControlPanelState enum"
|
||||
not in caplog.text
|
||||
"the 'alarm_state' property and return its state"
|
||||
" using the AlarmControlPanelState enum" not in caplog.text
|
||||
)
|
||||
|
||||
@@ -27,7 +27,7 @@ from tests.components.common import (
|
||||
|
||||
@pytest.fixture
|
||||
async def target_alarm_control_panels(hass: HomeAssistant) -> dict[str, list[str]]:
|
||||
"""Create multiple alarm control panel entities associated with different targets."""
|
||||
"""Create alarm control panel entities for different targets."""
|
||||
return await target_entities(hass, "alarm_control_panel")
|
||||
|
||||
|
||||
@@ -163,7 +163,11 @@ async def test_alarm_control_panel_state_trigger_behavior_any(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the alarm control panel state trigger fires when any alarm control panel state changes to a specific state."""
|
||||
"""Test alarm control panel state trigger.
|
||||
|
||||
Fires when any alarm control panel state changes to a
|
||||
specific state.
|
||||
"""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
target_entities=target_alarm_control_panels,
|
||||
@@ -259,7 +263,11 @@ async def test_alarm_control_panel_state_trigger_behavior_first(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the alarm control panel state trigger fires when the first alarm control panel changes to a specific state."""
|
||||
"""Test alarm control panel state trigger.
|
||||
|
||||
Fires when the first alarm control panel changes to a
|
||||
specific state.
|
||||
"""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
target_entities=target_alarm_control_panels,
|
||||
@@ -355,7 +363,11 @@ async def test_alarm_control_panel_state_trigger_behavior_last(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the alarm_control_panel state trigger fires when the last alarm_control_panel changes to a specific state."""
|
||||
"""Test alarm_control_panel state trigger.
|
||||
|
||||
Fires when the last alarm_control_panel changes to a
|
||||
specific state.
|
||||
"""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
target_entities=target_alarm_control_panels,
|
||||
|
||||
@@ -118,7 +118,10 @@ async def test_silence(hass: HomeAssistant, mock_notifier: list[ServiceCall]) ->
|
||||
|
||||
|
||||
async def test_silence_can_acknowledge_false(hass: HomeAssistant) -> None:
|
||||
"""Test that attempting to silence an alert with can_acknowledge=False will not silence."""
|
||||
"""Test silencing an alert with can_acknowledge=False.
|
||||
|
||||
Attempting to silence should not silence.
|
||||
"""
|
||||
# Create copy of config where can_acknowledge is False
|
||||
config = deepcopy(TEST_CONFIG)
|
||||
config[DOMAIN][NAME]["can_acknowledge"] = False
|
||||
|
||||
@@ -313,7 +313,9 @@ async def test_serialize_discovery_recovers(
|
||||
{
|
||||
"operation_list": ["on", "auto"],
|
||||
"operation_mode": "auto",
|
||||
"supported_features": water_heater.WaterHeaterEntityFeature.OPERATION_MODE.value,
|
||||
"supported_features": (
|
||||
water_heater.WaterHeaterEntityFeature.OPERATION_MODE.value
|
||||
),
|
||||
},
|
||||
True,
|
||||
),
|
||||
@@ -323,7 +325,9 @@ async def test_serialize_discovery_recovers(
|
||||
{
|
||||
"operation_list": ["on"],
|
||||
"operation_mode": None,
|
||||
"supported_features": water_heater.WaterHeaterEntityFeature.OPERATION_MODE.value,
|
||||
"supported_features": (
|
||||
water_heater.WaterHeaterEntityFeature.OPERATION_MODE.value
|
||||
),
|
||||
},
|
||||
True,
|
||||
),
|
||||
@@ -333,7 +337,9 @@ async def test_serialize_discovery_recovers(
|
||||
{
|
||||
"operation_list": [],
|
||||
"operation_mode": None,
|
||||
"supported_features": water_heater.WaterHeaterEntityFeature.OPERATION_MODE.value,
|
||||
"supported_features": (
|
||||
water_heater.WaterHeaterEntityFeature.OPERATION_MODE.value
|
||||
),
|
||||
},
|
||||
False,
|
||||
),
|
||||
@@ -346,10 +352,12 @@ async def test_mode_controller_is_omitted_if_no_modes_are_set(
|
||||
state_attributes: dict[str, Any],
|
||||
mode_controller_exists: bool,
|
||||
) -> None:
|
||||
"""Test we do not generate an invalid discovery with AlexaModeController during serialize discovery.
|
||||
"""Test we do not generate an invalid AlexaModeController discovery.
|
||||
|
||||
AlexModeControllers need at least 2 modes. If one mode is set, an extra mode will be added for compatibility.
|
||||
If no modes are offered, the mode controller should be omitted to prevent schema validations.
|
||||
AlexModeControllers need at least 2 modes. If one mode is
|
||||
set, an extra mode will be added for compatibility. If no
|
||||
modes are offered, the mode controller should be omitted to
|
||||
prevent schema validations.
|
||||
"""
|
||||
request = get_new_request("Alexa.Discovery", "Discover")
|
||||
|
||||
|
||||
@@ -3505,7 +3505,10 @@ async def test_no_current_target_temp_adjusting_temp(hass: HomeAssistant) -> Non
|
||||
|
||||
|
||||
async def test_thermostat_dual(hass: HomeAssistant) -> None:
|
||||
"""Test thermostat discovery with auto mode, with upper and lower target temperatures."""
|
||||
"""Test thermostat discovery with auto mode.
|
||||
|
||||
Uses upper and lower target temperatures.
|
||||
"""
|
||||
hass.config.units = US_CUSTOMARY_SYSTEM
|
||||
device = (
|
||||
"climate.test_thermostat",
|
||||
|
||||
@@ -125,7 +125,8 @@ async def test_incorrect_channel_type(
|
||||
with pytest.raises(
|
||||
vol.error.MultipleInvalid,
|
||||
match=re.escape(
|
||||
"value must be one of ['controlled_load', 'feed_in', 'general'] for dictionary value @ data['channel_type']"
|
||||
"value must be one of ['controlled_load', 'feed_in',"
|
||||
" 'general'] for dictionary value @ data['channel_type']"
|
||||
),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
|
||||
@@ -80,7 +80,10 @@ async def setup_platform(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Load the Ambient Network integration with the provided OpenAPI and config entry."""
|
||||
"""Load the Ambient Network integration.
|
||||
|
||||
Uses the provided OpenAPI and config entry.
|
||||
"""
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
assert (
|
||||
|
||||
@@ -47,7 +47,10 @@ class AdbDeviceTcpAsyncFake:
|
||||
|
||||
|
||||
class ClientAsyncFakeSuccess:
|
||||
"""A fake of the `ClientAsync` class when the connection and shell commands succeed."""
|
||||
"""A fake of the `ClientAsync` class.
|
||||
|
||||
Used when the connection and shell commands succeed.
|
||||
"""
|
||||
|
||||
def __init__(self, host=ADB_SERVER_HOST, port=DEFAULT_ADB_SERVER_PORT) -> None:
|
||||
"""Initialize a `ClientAsyncFakeSuccess` instance."""
|
||||
@@ -68,7 +71,10 @@ class ClientAsyncFakeFail:
|
||||
self._devices = []
|
||||
|
||||
async def device(self, serial) -> DeviceAsync | None:
|
||||
"""Mock the `ClientAsync.device` method when the device is not connected via ADB."""
|
||||
"""Mock the `ClientAsync.device` method.
|
||||
|
||||
Used when the device is not connected via ADB.
|
||||
"""
|
||||
self._devices = []
|
||||
return None
|
||||
|
||||
@@ -86,7 +92,7 @@ class DeviceAsyncFake:
|
||||
|
||||
|
||||
def patch_connect(success):
|
||||
"""Mock the `adb_shell.adb_device_async.AdbDeviceTcpAsync` and `ClientAsync` classes."""
|
||||
"""Mock the AdbDeviceTcpAsync and `ClientAsync` classes."""
|
||||
|
||||
async def connect_success_python(self, *args, **kwargs):
|
||||
"""Mock the `AdbDeviceTcpAsyncFake.connect` method when it succeeds."""
|
||||
@@ -121,7 +127,10 @@ def patch_shell(response=None, error=False, mac_eth=False, exc=None):
|
||||
"""Mock the `AdbDeviceTcpAsyncFake.shell` and `DeviceAsyncFake.shell` methods."""
|
||||
|
||||
async def shell_success(self, cmd, *args, **kwargs):
|
||||
"""Mock the `AdbDeviceTcpAsyncFake.shell` and `DeviceAsyncFake.shell` methods when they are successful."""
|
||||
"""Mock the AdbDeviceTcpAsyncFake and DeviceAsyncFake shell methods.
|
||||
|
||||
Used when they are successful.
|
||||
"""
|
||||
self.shell_cmd = cmd
|
||||
if cmd == CMD_DEVICE_PROPERTIES:
|
||||
return PROPS_DEV_INFO
|
||||
|
||||
@@ -231,7 +231,10 @@ async def test_setup_with_adbkey(hass: HomeAssistant) -> None:
|
||||
],
|
||||
)
|
||||
async def test_sources(hass: HomeAssistant, config: dict[str, Any]) -> None:
|
||||
"""Test that sources (i.e., apps) are handled correctly for Android and Fire TV devices."""
|
||||
"""Test that sources (i.e., apps) are handled correctly.
|
||||
|
||||
Covers Android and Fire TV devices.
|
||||
"""
|
||||
conf_apps = {
|
||||
"com.app.test1": "TEST 1",
|
||||
"com.app.test3": None,
|
||||
@@ -300,7 +303,10 @@ async def test_sources(hass: HomeAssistant, config: dict[str, Any]) -> None:
|
||||
async def test_exclude_sources(
|
||||
hass: HomeAssistant, config: dict[str, Any], expected_sources: list[str]
|
||||
) -> None:
|
||||
"""Test that sources (i.e., apps) are handled correctly when the `exclude_unnamed_apps` config parameter is provided."""
|
||||
"""Test sources (i.e., apps) handling.
|
||||
|
||||
When the `exclude_unnamed_apps` config parameter is provided.
|
||||
"""
|
||||
conf_apps = {
|
||||
"com.app.test1": "TEST 1",
|
||||
"com.app.test3": None,
|
||||
@@ -352,7 +358,10 @@ async def test_exclude_sources(
|
||||
async def _test_select_source(
|
||||
hass: HomeAssistant, config, conf_apps, source, expected_arg, method_patch
|
||||
) -> None:
|
||||
"""Test that the methods for launching and stopping apps are called correctly when selecting a source."""
|
||||
"""Test methods for launching and stopping apps.
|
||||
|
||||
Verifies they are called correctly when selecting a source.
|
||||
"""
|
||||
patch_key, entity_id, config_entry = _setup(config)
|
||||
config_entry.add_to_hass(hass)
|
||||
hass.config_entries.async_update_entry(config_entry, options={CONF_APPS: conf_apps})
|
||||
@@ -406,7 +415,10 @@ async def test_select_source_androidtv(
|
||||
|
||||
|
||||
async def test_androidtv_select_source_overridden_app_name(hass: HomeAssistant) -> None:
|
||||
"""Test that when an app name is overridden via the `apps` configuration parameter, the app is launched correctly."""
|
||||
"""Test app name overridden via `apps` config parameter.
|
||||
|
||||
Verifies the app is launched correctly.
|
||||
"""
|
||||
# Evidence that the default YouTube app ID will be overridden
|
||||
conf_apps = {
|
||||
"com.youtube.test": "YouTube",
|
||||
@@ -461,7 +473,7 @@ async def test_select_source_firetv(
|
||||
async def test_setup_fail(
|
||||
hass: HomeAssistant, config: dict[str, Any], connect: bool
|
||||
) -> None:
|
||||
"""Test that the entity is not created when the ADB connection is not established."""
|
||||
"""Test entity is not created when ADB connection is not established."""
|
||||
patch_key, entity_id, config_entry = _setup(config)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
@@ -511,7 +523,7 @@ async def test_adb_command(hass: HomeAssistant) -> None:
|
||||
|
||||
|
||||
async def test_adb_command_unicode_decode_error(hass: HomeAssistant) -> None:
|
||||
"""Test sending a command via the `androidtv.adb_command` service that raises a UnicodeDecodeError exception."""
|
||||
"""Test adb_command service raising UnicodeDecodeError."""
|
||||
patch_key, entity_id, config_entry = _setup(CONFIG_ANDROID_DEFAULT)
|
||||
config_entry.add_to_hass(hass)
|
||||
command = "test command"
|
||||
@@ -571,7 +583,7 @@ async def test_adb_command_key(hass: HomeAssistant) -> None:
|
||||
|
||||
|
||||
async def test_adb_command_get_properties(hass: HomeAssistant) -> None:
|
||||
"""Test sending the "GET_PROPERTIES" command via the `androidtv.adb_command` service."""
|
||||
"""Test GET_PROPERTIES command via adb_command service."""
|
||||
patch_key, entity_id, config_entry = _setup(CONFIG_ANDROID_DEFAULT)
|
||||
config_entry.add_to_hass(hass)
|
||||
command = "GET_PROPERTIES"
|
||||
@@ -632,7 +644,7 @@ async def test_learn_sendevent(hass: HomeAssistant) -> None:
|
||||
|
||||
|
||||
async def test_update_lock_not_acquired(hass: HomeAssistant) -> None:
|
||||
"""Test that the state does not get updated when a `LockNotAcquiredException` is raised."""
|
||||
"""Test state not updated on `LockNotAcquiredException`."""
|
||||
patch_key, entity_id, config_entry = _setup(CONFIG_ANDROID_DEFAULT)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
@@ -793,7 +805,8 @@ async def test_get_image_http(
|
||||
) -> None:
|
||||
"""Test taking a screen capture.
|
||||
|
||||
This is based on `test_get_image_http` in tests/components/media_player/test_init.py.
|
||||
This is based on `test_get_image_http` in
|
||||
tests/components/media_player/test_init.py.
|
||||
"""
|
||||
patch_key, entity_id, config_entry = _setup(CONFIG_ANDROID_DEFAULT)
|
||||
config_entry.add_to_hass(hass)
|
||||
@@ -1101,7 +1114,8 @@ async def test_exception(hass: HomeAssistant, caplog: pytest.LogCaptureFixture)
|
||||
caplog.clear()
|
||||
caplog.set_level(logging.ERROR)
|
||||
|
||||
# When an unforeseen exception occurs, we close the ADB connection and raise the exception
|
||||
# When an unforeseen exception occurs, we close
|
||||
# the ADB connection and raise the exception
|
||||
with patchers.PATCH_ANDROIDTV_UPDATE_EXCEPTION:
|
||||
await async_update_entity(hass, entity_id)
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ async def test_services_remote_custom(hass: HomeAssistant, config) -> None:
|
||||
|
||||
|
||||
async def test_remote_unicode_decode_error(hass: HomeAssistant) -> None:
|
||||
"""Test sending a command via the send_command remote service that raises a UnicodeDecodeError exception."""
|
||||
"""Test send_command remote service raising UnicodeDecodeError."""
|
||||
patch_key, entity_id, config_entry = _setup(CONFIG_ANDROID_DEFAULT)
|
||||
config_entry.add_to_hass(hass)
|
||||
response = b"test response"
|
||||
|
||||
@@ -287,8 +287,10 @@ async def test_user_flow_pairing_connection_closed(
|
||||
) -> None:
|
||||
"""Test async_finish_pairing raises ConnectionClosed.
|
||||
|
||||
This is when the user canceled pairing on the Android TV itself before calling async_finish_pairing.
|
||||
We call async_start_pairing again which succeeds and we have a chance to enter a new PIN.
|
||||
This is when the user canceled pairing on the Android TV
|
||||
itself before calling async_finish_pairing. We call
|
||||
async_start_pairing again which succeeds and we have a
|
||||
chance to enter a new PIN.
|
||||
"""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
@@ -358,7 +360,9 @@ async def test_user_flow_pairing_connection_closed_followed_by_cannot_connect(
|
||||
mock_unload_entry: AsyncMock,
|
||||
mock_api: MagicMock,
|
||||
) -> None:
|
||||
"""Test async_finish_pairing raises ConnectionClosed and then async_start_pairing raises CannotConnect.
|
||||
"""Test async_finish_pairing raises ConnectionClosed.
|
||||
|
||||
Then async_start_pairing raises CannotConnect.
|
||||
|
||||
This is when the user unplugs the Android TV before calling async_finish_pairing.
|
||||
We call async_start_pairing again which fails with CannotConnect so we abort.
|
||||
@@ -478,7 +482,10 @@ async def test_user_flow_already_configured_host_not_changed_no_reload_entry(
|
||||
mock_unload_entry: AsyncMock,
|
||||
mock_api: MagicMock,
|
||||
) -> None:
|
||||
"""Test we abort the user flow if already configured and no reload if host not changed."""
|
||||
"""Test we abort user flow if already configured.
|
||||
|
||||
No reload if host not changed.
|
||||
"""
|
||||
host = "1.2.3.4"
|
||||
name = "My Android TV"
|
||||
mac = "1A:2B:3C:4D:5E:6F"
|
||||
@@ -743,7 +750,10 @@ async def test_zeroconf_flow_already_configured_host_changed_reloads_entry(
|
||||
mock_unload_entry: AsyncMock,
|
||||
mock_api: MagicMock,
|
||||
) -> None:
|
||||
"""Test we abort the zeroconf flow if already configured and reload if host or name changed."""
|
||||
"""Test we abort zeroconf flow if already configured.
|
||||
|
||||
Reload if host or name changed.
|
||||
"""
|
||||
host = "1.2.3.4"
|
||||
name = "My Android TV"
|
||||
mac = "1A:2B:3C:4D:5E:6F"
|
||||
@@ -799,7 +809,10 @@ async def test_zeroconf_flow_already_configured_host_not_changed_no_reload_entry
|
||||
mock_unload_entry: AsyncMock,
|
||||
mock_api: MagicMock,
|
||||
) -> None:
|
||||
"""Test we abort the zeroconf flow if already configured and no reload if host and name not changed."""
|
||||
"""Test we abort zeroconf flow if already configured.
|
||||
|
||||
No reload if host and name not changed.
|
||||
"""
|
||||
host = "1.2.3.4"
|
||||
name = "My Android TV"
|
||||
mac = "1A:2B:3C:4D:5E:6F"
|
||||
@@ -870,13 +883,16 @@ async def test_zeroconf_flow_abort_if_mac_is_missing(
|
||||
assert result["reason"] == "cannot_connect"
|
||||
|
||||
|
||||
async def test_zeroconf_flow_already_configured_zeroconf_has_multiple_invalid_ip_addresses(
|
||||
async def test_zeroconf_flow_configured_zeroconf_invalid_ips(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_unload_entry: AsyncMock,
|
||||
mock_api: MagicMock,
|
||||
) -> None:
|
||||
"""Test we abort the zeroconf flow if already configured and zeroconf has invalid ip addresses."""
|
||||
"""Test we abort zeroconf flow if already configured.
|
||||
|
||||
Zeroconf has invalid ip addresses.
|
||||
"""
|
||||
host = "1.2.3.4"
|
||||
name = "My Android TV"
|
||||
mac = "1A:2B:3C:4D:5E:6F"
|
||||
|
||||
@@ -65,7 +65,10 @@ async def test_config_entry_reauth_at_setup(
|
||||
async def test_config_entry_reauth_while_reconnecting(
|
||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
|
||||
) -> None:
|
||||
"""Test the Android TV Remote configuration entry needs reauth while reconnecting."""
|
||||
"""Test the Android TV Remote config entry needs reauth.
|
||||
|
||||
Occurs while reconnecting.
|
||||
"""
|
||||
invalid_auth_callback: Callable | None = None
|
||||
|
||||
def mocked_keep_reconnecting(callback: Callable):
|
||||
|
||||
@@ -19,7 +19,10 @@ MEDIA_PLAYER_ENTITY = "media_player.my_android_tv"
|
||||
async def test_media_player_receives_push_updates(
|
||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
|
||||
) -> None:
|
||||
"""Test the Android TV Remote media player receives push updates and state is updated."""
|
||||
"""Test the Android TV Remote media player push updates.
|
||||
|
||||
Receives push updates and state is updated.
|
||||
"""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
hass.config_entries.async_update_entry(
|
||||
mock_config_entry,
|
||||
|
||||
@@ -151,7 +151,9 @@ def anova_api_mock(
|
||||
"type": "RA2L1-128",
|
||||
},
|
||||
"system-info-details": {
|
||||
"firmware-version-raw": "VM178_A_02.02.00_MKE15-128",
|
||||
"firmware-version-raw": (
|
||||
"VM178_A_02.02.00_MKE15-128"
|
||||
),
|
||||
"systick": 607026,
|
||||
"version-string": "VM171_A_02.02.00 RA2L1-128",
|
||||
},
|
||||
|
||||
@@ -43,6 +43,9 @@ async def test_sensors(hass: HomeAssistant, anova_api: AnovaApi) -> None:
|
||||
|
||||
@pytest.mark.usefixtures("anova_api_no_data")
|
||||
async def test_no_data_sensors(hass: HomeAssistant) -> None:
|
||||
"""Test that if we have no data for the device, and we have not set it up previously, It is not immediately set up."""
|
||||
"""Test no data and no previous setup.
|
||||
|
||||
Device is not immediately set up.
|
||||
"""
|
||||
await async_init_integration(hass)
|
||||
assert hass.states.get("sensor.anova_precision_cooker_triac_temperature") is None
|
||||
|
||||
@@ -122,7 +122,11 @@ def mock_create_stream() -> Generator[AsyncMock]:
|
||||
"""Create a stream of messages with the specified content blocks."""
|
||||
stop_reason = "end_turn"
|
||||
container = None
|
||||
refusal_magic_string = "ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL_1FAEFB6177B4672DEE07F9D3AFC62588CCD2631EDCF22E8CCC1FB35B501C9C86"
|
||||
refusal_magic_string = (
|
||||
"ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL_"
|
||||
"1FAEFB6177B4672DEE07F9D3AFC62588"
|
||||
"CCD2631EDCF22E8CCC1FB35B501C9C86"
|
||||
)
|
||||
for message in kwargs.get("messages"):
|
||||
if message["role"] != "user":
|
||||
continue
|
||||
|
||||
@@ -225,7 +225,10 @@ async def test_generate_structured_data_legacy_extended_thinking(
|
||||
mock_create_stream: AsyncMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test AI Task structured data generation with legacy method and extended_thinking."""
|
||||
"""Test AI Task structured data generation.
|
||||
|
||||
Uses legacy method with extended_thinking.
|
||||
"""
|
||||
mock_create_stream.return_value = [
|
||||
(
|
||||
*create_thinking_block(
|
||||
@@ -281,7 +284,10 @@ async def test_generate_structured_data_legacy_extra_text_block(
|
||||
mock_create_stream: AsyncMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test AI Task structured data generation with legacy method and extra text block."""
|
||||
"""Test AI Task structured data generation.
|
||||
|
||||
Uses legacy method with extra text block.
|
||||
"""
|
||||
mock_create_stream.return_value = [
|
||||
(
|
||||
*create_thinking_block(
|
||||
@@ -553,7 +559,9 @@ async def test_generate_data_invalid_attachments(
|
||||
pytest.raises(
|
||||
HomeAssistantError,
|
||||
match=re.escape(
|
||||
"The Claude Haiku 4.5 model does not support text/plain file types (for `doorbell_snapshot.txt`)"
|
||||
"The Claude Haiku 4.5 model does not support"
|
||||
" text/plain file types"
|
||||
" (for `doorbell_snapshot.txt`)"
|
||||
),
|
||||
),
|
||||
):
|
||||
|
||||
@@ -170,7 +170,11 @@ async def test_creating_conversation_subentry_not_loaded(
|
||||
(APITimeoutError(request=None), "timeout_connect"),
|
||||
(
|
||||
BadRequestError(
|
||||
message="Your credit balance is too low to access the Claude API. Please go to Plans & Billing to upgrade or purchase credits.",
|
||||
message=(
|
||||
"Your credit balance is too low to access"
|
||||
" the Claude API. Please go to Plans &"
|
||||
" Billing to upgrade or purchase credits."
|
||||
),
|
||||
response=Response(
|
||||
status_code=400,
|
||||
request=Request(method="POST", url=URL()),
|
||||
|
||||
@@ -457,7 +457,9 @@ async def test_function_exception(
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"content": '{"error":"HomeAssistantError","error_text":"Test tool exception"}',
|
||||
"content": (
|
||||
'{"error":"HomeAssistantError","error_text":"Test tool exception"}'
|
||||
),
|
||||
"tool_use_id": "toolu_0123456789AbCdEfGhIjKlM",
|
||||
"type": "tool_result",
|
||||
}
|
||||
@@ -996,7 +998,12 @@ async def test_web_search(
|
||||
citations=[
|
||||
CitationsWebSearchResultLocation(
|
||||
type="web_search_result_location",
|
||||
cited_text="This release iterates on some of the features we introduced in the last couple of releases, but also...",
|
||||
cited_text=(
|
||||
"This release iterates on some of"
|
||||
" the features we introduced in"
|
||||
" the last couple of releases,"
|
||||
" but also..."
|
||||
),
|
||||
encrypted_index="AAA==",
|
||||
title="Home Assistant Release",
|
||||
url="https://www.example.com/todays-news",
|
||||
@@ -1010,7 +1017,12 @@ async def test_web_search(
|
||||
citations=[
|
||||
CitationsWebSearchResultLocation(
|
||||
type="web_search_result_location",
|
||||
cited_text="Breaking news from around the world today includes major events in technology, politics, and culture...",
|
||||
cited_text=(
|
||||
"Breaking news from around the"
|
||||
" world today includes major"
|
||||
" events in technology, politics,"
|
||||
" and culture..."
|
||||
),
|
||||
encrypted_index="AQE=",
|
||||
title="Breaking News",
|
||||
url="https://www.newssite.com/breaking-news",
|
||||
@@ -1507,7 +1519,12 @@ async def test_bash_code_execution_error(
|
||||
TextEditorCodeExecutionToolResultError(
|
||||
type="text_editor_code_execution_tool_result_error",
|
||||
error_code="unavailable",
|
||||
error_message="Tool response parsing error for view: Failed to parse tool response as JSON: unexpected character: line 1 column 1 (char 0)",
|
||||
error_message=(
|
||||
"Tool response parsing error for view:"
|
||||
" Failed to parse tool response as JSON:"
|
||||
" unexpected character:"
|
||||
" line 1 column 1 (char 0)"
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1888,7 +1905,14 @@ async def test_container_reused(
|
||||
conversation.chat_log.AssistantContent(
|
||||
agent_id="conversation.claude_conversation",
|
||||
content="To get today's news, I'll perform a web search",
|
||||
thinking_content="The user is asking about today's news, which requires current, real-time information. This is clearly something that requires recent information beyond my knowledge cutoff. I should use the web_search tool to find today's news.",
|
||||
thinking_content=(
|
||||
"The user is asking about today's news,"
|
||||
" which requires current, real-time"
|
||||
" information. This is clearly something"
|
||||
" that requires recent information beyond"
|
||||
" my knowledge cutoff. I should use the"
|
||||
" web_search tool to find today's news."
|
||||
),
|
||||
native=ContentDetails(thinking_signature="ErU/V+ayA=="),
|
||||
tool_calls=[
|
||||
llm.ToolInput(
|
||||
@@ -1936,7 +1960,12 @@ async def test_container_reused(
|
||||
citations=[
|
||||
CitationWebSearchResultLocationParam(
|
||||
type="web_search_result_location",
|
||||
cited_text="This release iterates on some of the features we introduced in the last couple of releases, but also...",
|
||||
cited_text=(
|
||||
"This release iterates on some of"
|
||||
" the features we introduced in"
|
||||
" the last couple of releases,"
|
||||
" but also..."
|
||||
),
|
||||
encrypted_index="AAA==",
|
||||
title="Home Assistant Release",
|
||||
url="https://www.example.com/todays-news",
|
||||
@@ -1949,7 +1978,12 @@ async def test_container_reused(
|
||||
citations=[
|
||||
CitationWebSearchResultLocationParam(
|
||||
type="web_search_result_location",
|
||||
cited_text="Breaking news from around the world today includes major events in technology, politics, and culture...",
|
||||
cited_text=(
|
||||
"Breaking news from around the"
|
||||
" world today includes major"
|
||||
" events in technology, politics,"
|
||||
" and culture..."
|
||||
),
|
||||
encrypted_index="AQE=",
|
||||
title="Breaking News",
|
||||
url="https://www.newssite.com/breaking-news",
|
||||
|
||||
@@ -43,7 +43,11 @@ MINOR_VERSION = AnthropicConfigFlow.MINOR_VERSION
|
||||
(APITimeoutError(request=None), "Request timed out"),
|
||||
(
|
||||
BadRequestError(
|
||||
message="Your credit balance is too low to access the Claude API. Please go to Plans & Billing to upgrade or purchase credits.",
|
||||
message=(
|
||||
"Your credit balance is too low to access"
|
||||
" the Claude API. Please go to Plans &"
|
||||
" Billing to upgrade or purchase credits."
|
||||
),
|
||||
response=Response(
|
||||
status_code=400,
|
||||
request=Request(method="POST", url=URL()),
|
||||
@@ -558,7 +562,10 @@ async def test_migration_from_v1_to_v2_with_same_keys(
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migration from version 1 to version 2 with same API keys consolidates entries."""
|
||||
"""Test migration v1 to v2 with same API keys.
|
||||
|
||||
Consolidates entries.
|
||||
"""
|
||||
# Create two v1 config entries with the same API key
|
||||
options = {
|
||||
"recommended": True,
|
||||
|
||||
@@ -148,7 +148,7 @@ def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
|
||||
@pytest.fixture
|
||||
def get_devices_fixture_heat_pump() -> bool:
|
||||
"""Return whether the device in the get_devices fixture should be a heat pump water heater."""
|
||||
"""Return whether the device in the get_devices fixture should be a heat pump."""
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ async def test_state(
|
||||
async def test_state_away_mode_unsupported(
|
||||
hass: HomeAssistant, init_integration: MockConfigEntry
|
||||
) -> None:
|
||||
"""Test that away mode is not supported if the water heater does not support vacation mode."""
|
||||
"""Test away mode unsupported if water heater lacks vacation mode."""
|
||||
state = hass.states.get("water_heater.my_water_heater")
|
||||
assert (
|
||||
state.attributes.get(ATTR_SUPPORTED_FEATURES)
|
||||
|
||||
@@ -44,7 +44,8 @@ async def test_config_flow_duplicate_host_port(
|
||||
"""Test duplicate config flow setup with the same host / port."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
# Assign the same host and port, which we should reject since the entry already exists.
|
||||
# Assign the same host and port, which we should reject since
|
||||
# the entry already exists.
|
||||
mock_request_status.return_value = MOCK_STATUS
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}, data=CONF_DATA
|
||||
@@ -52,7 +53,8 @@ async def test_config_flow_duplicate_host_port(
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
# Now we change the host with a different serial number and add it again. This should be successful.
|
||||
# Now we change the host with a different serial number and
|
||||
# add it again. This should be successful.
|
||||
another_host = CONF_DATA | {CONF_HOST: "another_host"}
|
||||
mock_request_status.return_value = MOCK_STATUS | {
|
||||
"SERIALNO": MOCK_STATUS["SERIALNO"] + "ZZZ"
|
||||
@@ -72,11 +74,12 @@ async def test_config_flow_duplicate_serial_number(
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_request_status: AsyncMock,
|
||||
) -> None:
|
||||
"""Test duplicate config flow setup with different host but the same serial number."""
|
||||
"""Test duplicate config flow with different host, same serial."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
# Assign the different host and port, but we should still reject the creation since the
|
||||
# serial number is the same as the existing entry.
|
||||
# Assign the different host and port, but we should still reject
|
||||
# the creation since the serial number is the same as the
|
||||
# existing entry.
|
||||
mock_request_status.return_value = MOCK_STATUS
|
||||
another_host = CONF_DATA | {CONF_HOST: "another_host"}
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@@ -128,7 +131,8 @@ async def test_flow_works(
|
||||
(MOCK_MINIMAL_STATUS | {"UPSNAME": "Friendly Name"}, "Friendly Name"),
|
||||
(MOCK_MINIMAL_STATUS | {"MODEL": "MODEL X"}, "MODEL X"),
|
||||
(MOCK_MINIMAL_STATUS | {"SERIALNO": "ZZZZ"}, "ZZZZ"),
|
||||
# Some models report "Blank" as the serial number, which we should treat it as not reported.
|
||||
# Some models report "Blank" as the serial number,
|
||||
# which we should treat it as not reported.
|
||||
(MOCK_MINIMAL_STATUS | {"SERIALNO": "Blank"}, "APC UPS"),
|
||||
(MOCK_MINIMAL_STATUS | {}, "APC UPS"),
|
||||
],
|
||||
@@ -140,7 +144,9 @@ async def test_flow_minimal_status(
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_request_status: AsyncMock,
|
||||
) -> None:
|
||||
"""Test successful creation of config entries via user configuration when minimal status is reported.
|
||||
"""Test successful creation of config entries via user configuration.
|
||||
|
||||
Minimal status is reported.
|
||||
|
||||
We test different combinations of minimal statuses, where the title of the
|
||||
integration will vary.
|
||||
|
||||
@@ -28,13 +28,16 @@ from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
# We should create devices for the entities and prefix their IDs with "MyUPS".
|
||||
MOCK_STATUS,
|
||||
# Contains "SERIALNO" but no "UPSNAME" field.
|
||||
# We should create devices for the entities and prefix their IDs with default "APC UPS".
|
||||
# We should create devices for the entities and prefix
|
||||
# their IDs with default "APC UPS".
|
||||
MOCK_MINIMAL_STATUS | {"SERIALNO": "XXXX"},
|
||||
# Does not contain either "SERIALNO" field or "UPSNAME" field.
|
||||
# Our integration should work fine without it by falling back to config entry ID as unique
|
||||
# ID and "APC UPS" as the default name.
|
||||
# Our integration should work fine without it by falling
|
||||
# back to config entry ID as unique ID and "APC UPS" as the
|
||||
# default name.
|
||||
MOCK_MINIMAL_STATUS,
|
||||
# Some models report "Blank" as SERIALNO, but we should treat it as not reported.
|
||||
# Some models report "Blank" as SERIALNO, but we should
|
||||
# treat it as not reported.
|
||||
MOCK_MINIMAL_STATUS | {"SERIALNO": "Blank"},
|
||||
],
|
||||
indirect=True,
|
||||
@@ -102,7 +105,7 @@ async def test_availability(
|
||||
mock_request_status: AsyncMock,
|
||||
init_integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Ensure that we mark the entity's availability properly when network is down / back up."""
|
||||
"""Ensure we mark entity availability properly when network is down."""
|
||||
device_slug = slugify(mock_request_status.return_value["UPSNAME"])
|
||||
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||
assert state
|
||||
|
||||
@@ -93,9 +93,11 @@ async def test_manual_update_entity(
|
||||
hass: HomeAssistant,
|
||||
mock_request_status: AsyncMock,
|
||||
) -> None:
|
||||
"""Test multiple simultaneous manual update entity via service homeassistant/update_entity.
|
||||
"""Test multiple simultaneous manual update entity.
|
||||
|
||||
We should only do network call once for the multiple simultaneous update entity services.
|
||||
Uses the service homeassistant/update_entity. We should only do
|
||||
network call once for the multiple simultaneous update entity
|
||||
services.
|
||||
"""
|
||||
device_slug = slugify(mock_request_status.return_value["UPSNAME"])
|
||||
# Assert the initial state of sensor.ups_load.
|
||||
@@ -142,7 +144,8 @@ async def test_manual_update_entity(
|
||||
("mock_request_status", "entity_id", "known_status"),
|
||||
[
|
||||
pytest.param(
|
||||
# Even though the "LASTSTEST" field is not available, we should still create the entity.
|
||||
# Even though the "LASTSTEST" field is not available,
|
||||
# we should still create the entity.
|
||||
MOCK_MINIMAL_STATUS,
|
||||
"sensor.apc_ups_last_self_test",
|
||||
MOCK_MINIMAL_STATUS | {"LASTSTEST": "1970-01-01 00:00:00 +0000"},
|
||||
@@ -169,7 +172,7 @@ async def test_sensor_unknown(
|
||||
entity_id: str,
|
||||
known_status: dict[str, str],
|
||||
) -> None:
|
||||
"""Test if our integration can properly mark certain sensors as known/unknown when it becomes so."""
|
||||
"""Test marking sensors as known/unknown when status changes."""
|
||||
base_status = mock_request_status.return_value
|
||||
|
||||
# The state should be unknown initially.
|
||||
@@ -208,7 +211,7 @@ async def test_deprecated_sensor_issue(
|
||||
entity_key: str,
|
||||
issue_key: str,
|
||||
) -> None:
|
||||
"""Ensure the issue lists automations and scripts referencing a deprecated sensor."""
|
||||
"""Ensure issue lists automations/scripts referencing deprecated sensor."""
|
||||
issue_registry = ir.async_get(hass)
|
||||
unique_id = f"{mock_request_status.return_value['SERIALNO']}_{entity_key}"
|
||||
entity_id = entity_registry.async_get_entity_id("sensor", DOMAIN, unique_id)
|
||||
|
||||
@@ -148,7 +148,7 @@ async def test_api_state_change_with_invalid_json(
|
||||
async def test_api_state_change_with_string_body(
|
||||
hass: HomeAssistant, mock_api_client: TestClient
|
||||
) -> None:
|
||||
"""Test if API sends appropriate error if we send a string instead of a JSON object."""
|
||||
"""Test API error when sending a string instead of a JSON object."""
|
||||
resp = await mock_api_client.post(
|
||||
"/api/states/bad.entity.id", json='"{"state": "new_state"}"'
|
||||
)
|
||||
@@ -442,7 +442,9 @@ RESP_REQUIRED = {
|
||||
)
|
||||
}
|
||||
RESP_UNSUPPORTED = {
|
||||
"message": "Service does not support responses. Remove return_response from request."
|
||||
"message": (
|
||||
"Service does not support responses. Remove return_response from request."
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -621,7 +623,7 @@ async def test_api_template_with_invalid_json(
|
||||
async def test_api_template_error_with_string_body(
|
||||
hass: HomeAssistant, mock_api_client: TestClient
|
||||
) -> None:
|
||||
"""Test that the API returns an appropriate error when a string is sent in the body."""
|
||||
"""Test the API returns an error when a string is sent in the body."""
|
||||
hass.states.async_set("sensor.temperature", 10)
|
||||
|
||||
resp = await mock_api_client.post(
|
||||
|
||||
@@ -311,7 +311,11 @@ def test_aprs_listener_rx_msg_object(mock_ais: MagicMock) -> None:
|
||||
see = Mock()
|
||||
|
||||
sample_msg = aprslib.parse(
|
||||
"CEEWO2-14>APLWS2,qAU,CEEWO2-15:;V4310251 *121203h5105.72N/00131.89WO085/024/A=033178!w&,!Clb=3.5m/s calibration 21% 404.40MHz Type=RS41 batt=2.7V Details on http://radiosondy.info/"
|
||||
"CEEWO2-14>APLWS2,qAU,CEEWO2-15:;V4310251 "
|
||||
"*121203h5105.72N/00131.89WO085/024/A=033178"
|
||||
"!w&,!Clb=3.5m/s calibration 21% 404.40MHz "
|
||||
"Type=RS41 batt=2.7V Details on "
|
||||
"http://radiosondy.info/"
|
||||
)
|
||||
|
||||
listener = device_tracker.AprsListenerThread(
|
||||
@@ -326,7 +330,11 @@ def test_aprs_listener_rx_msg_object(mock_ais: MagicMock) -> None:
|
||||
attributes={
|
||||
"gps_accuracy": 0,
|
||||
"altitude": 10112.654400000001,
|
||||
"comment": "Clb=3.5m/s calibration 21% 404.40MHz Type=RS41 batt=2.7V Details on http://radiosondy.info/",
|
||||
"comment": (
|
||||
"Clb=3.5m/s calibration 21% 404.40MHz"
|
||||
" Type=RS41 batt=2.7V Details on"
|
||||
" http://radiosondy.info/"
|
||||
),
|
||||
"course": 85,
|
||||
"speed": 44.448,
|
||||
},
|
||||
|
||||
@@ -29,7 +29,7 @@ def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
|
||||
@pytest.fixture
|
||||
def mock_aquacell_api() -> Generator[MagicMock]:
|
||||
"""Build a fixture for the Aquacell API that authenticates successfully and returns a single softener."""
|
||||
"""Build a fixture for the Aquacell API that returns a softener."""
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.aquacell.AquacellApi",
|
||||
|
||||
@@ -55,7 +55,10 @@ VALID_DATA_SERVICE_INFO = fake_service_info(
|
||||
"Aranet4 12345",
|
||||
"0000fce0-0000-1000-8000-00805f9b34fb",
|
||||
{
|
||||
1794: b'\x21\x00\x02\x01\x00\x00\x00\x01\x8a\x02\xa5\x01\xb1&"Y\x01,\x01\xe8\x00\x88'
|
||||
1794: (
|
||||
b"\x21\x00\x02\x01\x00\x00\x00\x01\x8a\x02"
|
||||
b'\xa5\x01\xb1&"Y\x01,\x01\xe8\x00\x88'
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -63,7 +66,10 @@ VALID_DATA_SERVICE_INFO_WITH_NO_NAME = fake_service_info(
|
||||
None,
|
||||
"0000fce0-0000-1000-8000-00805f9b34fb",
|
||||
{
|
||||
1794: b'\x21\x00\x02\x01\x00\x00\x00\x01\x8a\x02\xa5\x01\xb1&"Y\x01,\x01\xe8\x00\x88'
|
||||
1794: (
|
||||
b"\x21\x00\x02\x01\x00\x00\x00\x01\x8a\x02"
|
||||
b'\xa5\x01\xb1&"Y\x01,\x01\xe8\x00\x88'
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -71,7 +77,10 @@ VALID_ARANET2_DATA_SERVICE_INFO = fake_service_info(
|
||||
"Aranet2 12345",
|
||||
"0000fce0-0000-1000-8000-00805f9b34fb",
|
||||
{
|
||||
1794: b"\x01!\x04\x04\x01\x00\x00\x00\x00\x00\xf0\x01\x00\x00\x0c\x02\x00O\x00<\x00\x01\x00\x80"
|
||||
1794: (
|
||||
b"\x01!\x04\x04\x01\x00\x00\x00\x00\x00"
|
||||
b"\xf0\x01\x00\x00\x0c\x02\x00O\x00<\x00\x01\x00\x80"
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -79,7 +88,10 @@ VALID_ARANET_RADIATION_DATA_SERVICE_INFO = fake_service_info(
|
||||
"Aranet\u2622 12345",
|
||||
"0000fce0-0000-1000-8000-00805f9b34fb",
|
||||
{
|
||||
1794: b"\x02!&\x04\x01\x00`-\x00\x00\x08\x98\x05\x00n\x00\x00d\x00,\x01\xfd\x00\xc7"
|
||||
1794: (
|
||||
b"\x02!&\x04\x01\x00`-\x00\x00\x08"
|
||||
b"\x98\x05\x00n\x00\x00d\x00,\x01\xfd\x00\xc7"
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -87,6 +99,9 @@ VALID_ARANET_RADON_DATA_SERVICE_INFO = fake_service_info(
|
||||
"AranetRn+ 12345",
|
||||
"0000fce0-0000-1000-8000-00805f9b34fb",
|
||||
{
|
||||
1794: b"\x03!\x04\x06\x01\x00\x00\x00\x07\x00\xfe\x01\xc9'\xce\x01\x00d\x01X\x02\xf6\x01\x08"
|
||||
1794: (
|
||||
b"\x03!\x04\x06\x01\x00\x00\x00\x07\x00"
|
||||
b"\xfe\x01\xc9'\xce\x01\x00d\x01X\x02\xf6\x01\x08"
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -707,7 +707,7 @@ async def test_pipeline_from_audio_stream_with_cloud_auth_fail(
|
||||
init_components,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test creating a pipeline from an audio stream but the cloud authentication fails."""
|
||||
"""Test pipeline from audio stream when cloud authentication fails."""
|
||||
|
||||
events: list[assist_pipeline.PipelineEvent] = []
|
||||
|
||||
|
||||
@@ -1053,7 +1053,7 @@ async def test_sentence_trigger_overrides_conversation_agent(
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
pipeline_data: assist_pipeline.pipeline.PipelineData,
|
||||
) -> None:
|
||||
"""Test that sentence triggers are checked before a non-default conversation agent."""
|
||||
"""Test sentence triggers checked before non-default agent."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"automation",
|
||||
@@ -1281,7 +1281,8 @@ async def test_intent_continue_conversation(
|
||||
]
|
||||
assert results[1]["intent_output"]["continue_conversation"] is True
|
||||
|
||||
# Change conversation agent to default one and register sentence trigger that should not be called
|
||||
# Change conversation agent to default one and register
|
||||
# sentence trigger that should not be called
|
||||
await assist_pipeline.pipeline.async_update_pipeline(
|
||||
hass, pipeline, conversation_engine=None
|
||||
)
|
||||
@@ -1367,7 +1368,7 @@ async def test_stt_language_used_instead_of_conversation_language(
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that the STT language is used first when the conversation language is '*' (all languages)."""
|
||||
"""Test STT language is used first when conversation language is '*'."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
events: list[assist_pipeline.PipelineEvent] = []
|
||||
@@ -1443,7 +1444,7 @@ async def test_tts_language_used_instead_of_conversation_language(
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that the TTS language is used after STT when the conversation language is '*' (all languages)."""
|
||||
"""Test TTS language used after STT when conversation language is '*'."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
events: list[assist_pipeline.PipelineEvent] = []
|
||||
@@ -1519,7 +1520,7 @@ async def test_pipeline_language_used_instead_of_conversation_language(
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that the pipeline language is used last when the conversation language is '*' (all languages)."""
|
||||
"""Test pipeline language used last when conversation language is '*'."""
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
events: list[assist_pipeline.PipelineEvent] = []
|
||||
@@ -2042,7 +2043,7 @@ async def test_acknowledge_other_agents(
|
||||
area_registry: ar.AreaRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test that acknowledge sound is only played when intents are processed locally for other agents."""
|
||||
"""Test acknowledge sound only plays for locally processed intents."""
|
||||
area_1 = area_registry.async_get_or_create("area_1")
|
||||
|
||||
light_1 = entity_registry.async_get_or_create(
|
||||
@@ -2163,7 +2164,7 @@ async def test_stt_vad_enabled_based_on_audio_processing(
|
||||
pipeline_data: assist_pipeline.pipeline.PipelineData,
|
||||
mock_chat_session: chat_session.ChatSession,
|
||||
) -> None:
|
||||
"""Test that VAD is enabled only when audio_processing.requires_external_vad is True."""
|
||||
"""Test VAD enabled only when requires_external_vad is True."""
|
||||
|
||||
async def audio_data():
|
||||
yield make_10ms_chunk(b"silence!")
|
||||
|
||||
@@ -287,7 +287,7 @@ async def test_audio_pipeline_with_wake_word_no_timeout(
|
||||
init_components,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test events from a pipeline run with audio input/output + wake word with no timeout."""
|
||||
"""Test pipeline run with audio input/output + wake word, no timeout."""
|
||||
events = []
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
@@ -1850,7 +1850,7 @@ async def test_wake_word_cooldown_same_id(
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that duplicate wake word detections with the same id are blocked during the cooldown period."""
|
||||
"""Test duplicate wake word detections blocked during cooldown."""
|
||||
client_1 = await hass_ws_client(hass)
|
||||
client_2 = await hass_ws_client(hass)
|
||||
|
||||
@@ -2009,7 +2009,7 @@ async def test_wake_word_cooldown_different_entities(
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that duplicate wake word detections are blocked even with different wake word entities."""
|
||||
"""Test duplicate wake word detections blocked across entities."""
|
||||
client_pipeline = await hass_ws_client(hass)
|
||||
await client_pipeline.send_json_auto_id(
|
||||
{
|
||||
@@ -2543,7 +2543,7 @@ async def test_stt_cooldown_same_id(
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that two speech-to-text pipelines cannot run within the cooldown period if they have the same wake word."""
|
||||
"""Test two STT pipelines cannot run in cooldown with same wake word."""
|
||||
client_1 = await hass_ws_client(hass)
|
||||
client_2 = await hass_ws_client(hass)
|
||||
|
||||
@@ -2614,7 +2614,7 @@ async def test_stt_cooldown_different_ids(
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test that two speech-to-text pipelines can run within the cooldown period if they have the different wake words."""
|
||||
"""Test two STT pipelines can run in cooldown with different wake words."""
|
||||
client_1 = await hass_ws_client(hass)
|
||||
client_2 = await hass_ws_client(hass)
|
||||
|
||||
|
||||
@@ -588,7 +588,7 @@ async def test_vad_sensitivity_entity(
|
||||
async def test_pipeline_entity_not_found(
|
||||
hass: HomeAssistant, init_components: ConfigEntry, entity: MockAssistSatellite
|
||||
) -> None:
|
||||
"""Test that setting the pipeline entity id to a non-existent entity raises an error."""
|
||||
"""Test setting pipeline entity id to non-existent entity errors."""
|
||||
audio_stream = object()
|
||||
|
||||
# Set to an entity that doesn't exist
|
||||
@@ -601,7 +601,7 @@ async def test_pipeline_entity_not_found(
|
||||
async def test_vad_sensitivity_entity_not_found(
|
||||
hass: HomeAssistant, init_components: ConfigEntry, entity: MockAssistSatellite
|
||||
) -> None:
|
||||
"""Test that setting the vad sensitivity entity id to a non-existent entity raises an error."""
|
||||
"""Test setting vad sensitivity entity id to non-existent entity errors."""
|
||||
audio_stream = object()
|
||||
|
||||
# Set to an entity that doesn't exist
|
||||
@@ -807,7 +807,7 @@ async def test_start_conversation_reject_builtin_agent(
|
||||
async def test_start_conversation_default_preannounce(
|
||||
hass: HomeAssistant, init_components: ConfigEntry, entity: MockAssistSatellite
|
||||
) -> None:
|
||||
"""Test starting a conversation on a device with the default preannouncement sound."""
|
||||
"""Test starting a conversation with the default preannounce sound."""
|
||||
|
||||
async def async_start_conversation(start_announcement):
|
||||
assert PREANNOUNCE_URL in start_announcement.preannounce_media_id
|
||||
|
||||
@@ -110,7 +110,7 @@ async def test_assist_satellite_state_trigger_behavior_any(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the assist satellite state trigger fires when any assist satellite state changes to a specific state."""
|
||||
"""Test assist satellite trigger fires when any satellite changes state."""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
target_entities=target_assist_satellites,
|
||||
@@ -163,7 +163,7 @@ async def test_assist_satellite_state_trigger_behavior_first(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the assist satellite state trigger fires when the first assist satellite changes to a specific state."""
|
||||
"""Test assist satellite trigger fires when first satellite changes state."""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
target_entities=target_assist_satellites,
|
||||
@@ -216,7 +216,7 @@ async def test_assist_satellite_state_trigger_behavior_last(
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the assist_satellite state trigger fires when the last assist_satellite changes to a specific state."""
|
||||
"""Test assist satellite trigger fires when last satellite changes state."""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
target_entities=target_assist_satellites,
|
||||
|
||||
@@ -319,7 +319,7 @@ async def test_get_configuration_not_implemented(
|
||||
entity: MockAssistSatellite,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test getting stub satellite configuration when the entity doesn't implement the method."""
|
||||
"""Test getting stub config when entity lacks the method."""
|
||||
ws_client = await hass_ws_client(hass)
|
||||
|
||||
with patch.object(
|
||||
|
||||
@@ -183,7 +183,7 @@ def mock_controller_connect_http(mock_devices_http):
|
||||
|
||||
|
||||
def make_async_get_data_side_effect(fail_types=None):
|
||||
"""Return a side effect for async_get_data that fails for specified AsusData types."""
|
||||
"""Return a side effect for async_get_data that fails for types."""
|
||||
fail_types = set(fail_types or [])
|
||||
|
||||
def side_effect(datatype, *args, **kwargs):
|
||||
|
||||
@@ -60,7 +60,7 @@ SENSORS_ALL_HTTP = [
|
||||
def create_device_registry_devices_fixture(
|
||||
hass: HomeAssistant, device_registry: dr.DeviceRegistry
|
||||
):
|
||||
"""Create device registry devices so the device tracker entities are enabled when added."""
|
||||
"""Create device registry devices so device tracker entities are enabled."""
|
||||
config_entry = MockConfigEntry(domain="something_else")
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
|
||||
@@ -101,7 +101,25 @@ def load_migration_jwt_fixture() -> str:
|
||||
def load_reauth_jwt_wrong_account_fixture() -> str:
|
||||
"""Load JWT fixture data for wrong account during reauth."""
|
||||
# Different userId, no email match
|
||||
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpbnN0YWxsSWQiOiIiLCJyZWdpb24iOiJpcmVsYW5kLXByb2QtYXdzIiwiYXBwbGljYXRpb25JZCI6IiIsInVzZXJJZCI6ImRpZmZlcmVudC11c2VyLWlkIiwidkluc3RhbGxJZCI6ZmFsc2UsInZQYXNzd29yZCI6dHJ1ZSwidkVtYWlsIjp0cnVlLCJ2UGhvbmUiOnRydWUsImhhc0luc3RhbGxJZCI6ZmFsc2UsImhhc1Bhc3N3b3JkIjpmYWxzZSwiaGFzRW1haWwiOmZhbHNlLCJoYXNQaG9uZSI6ZmFsc2UsImlzTG9ja2VkT3V0IjpmYWxzZSwiY2FwdGNoYSI6IiIsImVtYWlsIjpbImRpZmZlcmVudEBlbWFpbC50bGQiXSwicGhvbmUiOltdLCJleHBpcmVzQXQiOiIyMDI0LTEyLTE4VDEzOjU0OjA1LjEzNFoiLCJ0ZW1wb3JhcnlBY2NvdW50Q3JlYXRpb25QYXNzd29yZExpbmsiOiIiLCJpYXQiOjE3MjQxNjIwNDUsImV4cCI6MTczNDUzMDA0NSwib2F1dGgiOnsiYXBwX25hbWUiOiJIb21lIEFzc2lzdGFudCIsImNsaWVudF9pZCI6ImIzY2QzZjBiLWZiOTctNGQ2Yy1iZWU5LWFmN2FiMDQ3NThjNyIsInJlZGlyZWN0X3VyaSI6Imh0dHBzOi8vYWNjb3VudC1saW5rLm5hYnVjYXNhLmNvbS9hdXRob3JpemVfY2FsbGJhY2siLCJwYXJ0bmVyX2lkIjoiNjU3OTc0ODgxMDY2Y2E0OGM5OWMwODI2In19.mK9nTAv7glYgtpLIkVF_dsrjrkRKYemdKfKMkgnafCU"
|
||||
return (
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
|
||||
"eyJpbnN0YWxsSWQiOiIiLCJyZWdpb24iOiJpcmVsYW5kLXByb2QtYXdzIi"
|
||||
"wiYXBwbGljYXRpb25JZCI6IiIsInVzZXJJZCI6ImRpZmZlcmVudC11c2Vy"
|
||||
"LWlkIiwidkluc3RhbGxJZCI6ZmFsc2UsInZQYXNzd29yZCI6dHJ1ZSwidk"
|
||||
"VtYWlsIjp0cnVlLCJ2UGhvbmUiOnRydWUsImhhc0luc3RhbGxJZCI6ZmFs"
|
||||
"c2UsImhhc1Bhc3N3b3JkIjpmYWxzZSwiaGFzRW1haWwiOmZhbHNlLCJoYX"
|
||||
"NQaG9uZSI6ZmFsc2UsImlzTG9ja2VkT3V0IjpmYWxzZSwiY2FwdGNoYSI6"
|
||||
"IiIsImVtYWlsIjpbImRpZmZlcmVudEBlbWFpbC50bGQiXSwicGhvbmUiOl"
|
||||
"tdLCJleHBpcmVzQXQiOiIyMDI0LTEyLTE4VDEzOjU0OjA1LjEzNFoiLCJ0"
|
||||
"ZW1wb3JhcnlBY2NvdW50Q3JlYXRpb25QYXNzd29yZExpbmsiOiIiLCJpYX"
|
||||
"QiOjE3MjQxNjIwNDUsImV4cCI6MTczNDUzMDA0NSwib2F1dGgiOnsiYXBw"
|
||||
"X25hbWUiOiJIb21lIEFzc2lzdGFudCIsImNsaWVudF9pZCI6ImIzY2QzZj"
|
||||
"BiLWZiOTctNGQ2Yy1iZWU5LWFmN2FiMDQ3NThjNyIsInJlZGlyZWN0X3Vy"
|
||||
"aSI6Imh0dHBzOi8vYWNjb3VudC1saW5rLm5hYnVjYXNhLmNvbS9hdXRob3"
|
||||
"JpemVfY2FsbGJhY2siLCJwYXJ0bmVyX2lkIjoiNjU3OTc0ODgxMDY2Y2E0"
|
||||
"OGM5OWMwODI2In19."
|
||||
"mK9nTAv7glYgtpLIkVF_dsrjrkRKYemdKfKMkgnafCU"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="client_credentials", autouse=True)
|
||||
|
||||
@@ -223,7 +223,7 @@ async def test_reauth_wrong_account(
|
||||
reauth_jwt_wrong_account: str,
|
||||
jwt: str,
|
||||
) -> None:
|
||||
"""Test the reauthentication aborts, if user tries to reauthenticate with another account."""
|
||||
"""Test reauthentication aborts if user uses another account."""
|
||||
assert mock_config_entry.data["token"]["access_token"] == jwt
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
@@ -283,7 +283,7 @@ async def test_legacy_migration_with_email_match(
|
||||
mock_legacy_config_entry: MockConfigEntry,
|
||||
migration_jwt: str,
|
||||
) -> None:
|
||||
"""Test migration from legacy username/password config to OAuth with email validation."""
|
||||
"""Test migration from legacy config to OAuth with email validation."""
|
||||
|
||||
mock_legacy_config_entry.add_to_hass(hass)
|
||||
|
||||
@@ -373,7 +373,8 @@ async def test_legacy_migration_wrong_email(
|
||||
aioclient_mock.post(
|
||||
OAUTH2_TOKEN,
|
||||
json={
|
||||
"access_token": reauth_jwt_wrong_account, # JWT with email: ["different@email.tld"]
|
||||
# JWT with email: ["different@email.tld"]
|
||||
"access_token": reauth_jwt_wrong_account,
|
||||
"expires_in": 86399,
|
||||
"refresh_token": "mock-refresh-token",
|
||||
"token_type": "Bearer",
|
||||
@@ -404,7 +405,7 @@ async def test_legacy_migration_no_email_in_jwt(
|
||||
mock_legacy_config_entry: MockConfigEntry,
|
||||
jwt: str, # JWT with empty email array
|
||||
) -> None:
|
||||
"""Test migration from legacy config succeeds when JWT has no email (can't validate)."""
|
||||
"""Test legacy migration succeeds when JWT has no email."""
|
||||
|
||||
mock_legacy_config_entry.add_to_hass(hass)
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ async def test_load_unload(hass: HomeAssistant) -> None:
|
||||
async def test_load_triggers_ble_discovery(
|
||||
hass: HomeAssistant, mock_discovery: Mock
|
||||
) -> None:
|
||||
"""Test that loading a lock that supports offline ble operation passes the keys to yalexe_ble."""
|
||||
"""Test loading a lock with offline BLE passes keys to yalexe_ble."""
|
||||
|
||||
august_lock_with_key = await _mock_lock_with_offline_key(hass)
|
||||
august_lock_without_key = await _mock_operative_august_lock_detail(hass)
|
||||
|
||||
@@ -125,7 +125,7 @@ async def test_login_new_user_and_trying_refresh_token(
|
||||
async def test_auth_code_checks_local_only_user(
|
||||
hass: HomeAssistant, aiohttp_client: ClientSessionGenerator
|
||||
) -> None:
|
||||
"""Test local only user cannot exchange auth code for refresh tokens when external."""
|
||||
"""Test local only user cannot exchange auth code when external."""
|
||||
client = await async_setup_auth(hass, aiohttp_client, setup_api=True)
|
||||
resp = await client.post(
|
||||
"/auth/login_flow",
|
||||
|
||||
@@ -413,7 +413,7 @@ async def test_well_known_auth_info(
|
||||
expected_url_prefix: str,
|
||||
extra_response_data: dict[str, str],
|
||||
) -> None:
|
||||
"""Test the well-known OAuth authorization server endpoint with different URL configurations."""
|
||||
"""Test well-known OAuth endpoint with different URL configurations."""
|
||||
await async_process_ha_core_config(hass, config)
|
||||
client = await async_setup_auth(hass, aiohttp_client, setup_api=True)
|
||||
resp = await client.get(
|
||||
|
||||
@@ -2892,7 +2892,7 @@ async def test_automation_bad_trigger_variables(
|
||||
async def test_automation_this_var_always(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test automation always has reference to this, even with no variable or trigger variables configured."""
|
||||
"""Test automation always has reference to this, even without variables."""
|
||||
calls = async_mock_service(hass, "test", "automation")
|
||||
|
||||
assert await async_setup_component(
|
||||
@@ -3899,7 +3899,10 @@ async def test_action_backward_compatibility(
|
||||
"condition": {"condition": "template", "value_template": "{{ True }}"},
|
||||
"conditions": {"condition": "template", "value_template": "{{ True }}"},
|
||||
},
|
||||
"Cannot specify both 'condition' and 'conditions'. Please use 'conditions' only.",
|
||||
(
|
||||
"Cannot specify both 'condition' and 'conditions'."
|
||||
" Please use 'conditions' only."
|
||||
),
|
||||
),
|
||||
(
|
||||
{
|
||||
|
||||
@@ -53,14 +53,16 @@ def mock_client(mock_agent_backup: AgentBackup) -> Generator[AsyncMock]:
|
||||
|
||||
# Mock the paginator for list_objects_v2
|
||||
client.get_paginator = MagicMock()
|
||||
client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
paginate = client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [
|
||||
{"Contents": [{"Key": tar_file}, {"Key": metadata_file}]}
|
||||
]
|
||||
|
||||
client.create_multipart_upload.return_value = {"UploadId": "upload_id"}
|
||||
client.upload_part.return_value = {"ETag": "etag"}
|
||||
|
||||
# to simplify this mock, we assume that backup is always "iterated" over, while metadata is always "read" as a whole
|
||||
# to simplify this mock, we assume that backup is always
|
||||
# "iterated" over, while metadata is always "read" as a whole
|
||||
class MockStream:
|
||||
async def iter_chunks(self) -> AsyncIterator[bytes]:
|
||||
yield b"backup data"
|
||||
|
||||
@@ -184,9 +184,8 @@ async def test_agents_get_backup_does_not_throw_on_not_found(
|
||||
mock_client: MagicMock,
|
||||
) -> None:
|
||||
"""Test agent get backup does not throw on a backup not found."""
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
{"Contents": []}
|
||||
]
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [{"Contents": []}]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
await client.send_json_auto_id({"type": "backup/details", "backup_id": "random"})
|
||||
@@ -209,7 +208,8 @@ async def test_agents_list_backups_with_corrupted_metadata(
|
||||
agent = S3BackupAgent(hass, mock_config_entry)
|
||||
|
||||
# Set up mock responses for both valid and corrupted metadata files
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [
|
||||
{
|
||||
"Contents": [
|
||||
{
|
||||
@@ -276,9 +276,8 @@ async def test_agents_delete_not_throwing_on_not_found(
|
||||
mock_client: MagicMock,
|
||||
) -> None:
|
||||
"""Test agent delete backup does not throw on a backup not found."""
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
{"Contents": []}
|
||||
]
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [{"Contents": []}]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
@@ -410,7 +409,8 @@ async def test_agents_download(
|
||||
)
|
||||
assert resp.status == 200
|
||||
assert await resp.content.read() == b"backup data"
|
||||
# Coordinator first refresh reads metadata (1) + download reads metadata (1) + tar (1)
|
||||
# Coordinator first refresh reads metadata (1) +
|
||||
# download reads metadata (1) + tar (1)
|
||||
assert mock_client.get_object.call_count == 3
|
||||
|
||||
|
||||
@@ -437,7 +437,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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +469,8 @@ async def test_cache_expiration(
|
||||
metadata_content = json.dumps(mock_agent_backup.as_dict())
|
||||
mock_body = AsyncMock()
|
||||
mock_body.read.return_value = metadata_content.encode()
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [
|
||||
{
|
||||
"Contents": [
|
||||
{
|
||||
@@ -570,7 +573,8 @@ async def test_list_backups_with_pagination(
|
||||
|
||||
# Setup mock client
|
||||
mock_client = mock_config_entry.runtime_data.client
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [
|
||||
page1,
|
||||
page2,
|
||||
]
|
||||
|
||||
@@ -61,10 +61,9 @@ async def test_sensor_availability(
|
||||
assert (state := hass.states.get("sensor.bucket_test_total_size_of_backups"))
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
mock_client.get_paginator.return_value.paginate.side_effect = None
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
{"Contents": []}
|
||||
]
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.side_effect = None
|
||||
paginate.return_value.__aiter__.return_value = [{"Contents": []}]
|
||||
freezer.tick(SCAN_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
@@ -93,9 +92,8 @@ async def test_calculate_backups_size(
|
||||
expected_pagination_call: dict,
|
||||
) -> None:
|
||||
"""Test the total size of backups calculation with and without prefix."""
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
{"Contents": []}
|
||||
]
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [{"Contents": []}]
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert (state := hass.states.get("sensor.bucket_test_total_size_of_backups"))
|
||||
@@ -107,7 +105,8 @@ async def test_calculate_backups_size(
|
||||
mock_body.read.return_value = metadata_content.encode()
|
||||
mock_client.get_object.return_value = {"Body": mock_body}
|
||||
|
||||
mock_client.get_paginator.return_value.paginate.return_value.__aiter__.return_value = [
|
||||
paginate = mock_client.get_paginator.return_value.paginate
|
||||
paginate.return_value.__aiter__.return_value = [
|
||||
{
|
||||
"Contents": [
|
||||
{"Key": "backup.tar"},
|
||||
|
||||
@@ -34,13 +34,68 @@ API_DISCOVERY_PORT_MANAGEMENT = {
|
||||
"name": "IO Port Management",
|
||||
}
|
||||
|
||||
APPLICATIONS_LIST_RESPONSE = """<reply result="ok">
|
||||
<application Name="fenceguard" NiceName="AXIS Fence Guard" Vendor="Axis Communications" Version="2.2-6" ApplicationID="47775" License="None" Status="Running" ConfigurationPage="local/fenceguard/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
||||
<application Name="loiteringguard" NiceName="AXIS Loitering Guard" Vendor="Axis Communications" Version="2.2-6" ApplicationID="46775" License="None" Status="Running" ConfigurationPage="local/loiteringguard/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
||||
<application Name="motionguard" NiceName="AXIS Motion Guard" Vendor="Axis Communications" Version="2.2-6" ApplicationID="48170" License="None" Status="Running" ConfigurationPage="local/motionguard/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
||||
<application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.2-0" ApplicationID="143440" License="None" Status="Running" ConfigurationPage="local/vmd/config.html" VendorHomePage="http://www.axis.com" />
|
||||
<application Name="objectanalytics" NiceName="AXIS Object Analytics" Vendor="Axis Communications" Version="1.0-0" ApplicationID="143440" License="None" Status="Running" ConfigurationPage="local/vmd/config.html" VendorHomePage="http://www.axis.com" />
|
||||
</reply>"""
|
||||
APPLICATIONS_LIST_RESPONSE = (
|
||||
'<reply result="ok">\n'
|
||||
" <application"
|
||||
' Name="fenceguard"'
|
||||
' NiceName="AXIS Fence Guard"'
|
||||
' Vendor="Axis Communications"'
|
||||
' Version="2.2-6"'
|
||||
' ApplicationID="47775"'
|
||||
' License="None"'
|
||||
' Status="Running"'
|
||||
' ConfigurationPage="local/fenceguard/config.html"'
|
||||
' VendorHomePage="http://www.axis.com"'
|
||||
' LicenseName="Proprietary"'
|
||||
" />\n"
|
||||
" <application"
|
||||
' Name="loiteringguard"'
|
||||
' NiceName="AXIS Loitering Guard"'
|
||||
' Vendor="Axis Communications"'
|
||||
' Version="2.2-6"'
|
||||
' ApplicationID="46775"'
|
||||
' License="None"'
|
||||
' Status="Running"'
|
||||
' ConfigurationPage="local/loiteringguard/config.html"'
|
||||
' VendorHomePage="http://www.axis.com"'
|
||||
' LicenseName="Proprietary"'
|
||||
" />\n"
|
||||
" <application"
|
||||
' Name="motionguard"'
|
||||
' NiceName="AXIS Motion Guard"'
|
||||
' Vendor="Axis Communications"'
|
||||
' Version="2.2-6"'
|
||||
' ApplicationID="48170"'
|
||||
' License="None"'
|
||||
' Status="Running"'
|
||||
' ConfigurationPage="local/motionguard/config.html"'
|
||||
' VendorHomePage="http://www.axis.com"'
|
||||
' LicenseName="Proprietary"'
|
||||
" />\n"
|
||||
" <application"
|
||||
' Name="vmd"'
|
||||
' NiceName="AXIS Video Motion Detection"'
|
||||
' Vendor="Axis Communications"'
|
||||
' Version="4.2-0"'
|
||||
' ApplicationID="143440"'
|
||||
' License="None"'
|
||||
' Status="Running"'
|
||||
' ConfigurationPage="local/vmd/config.html"'
|
||||
' VendorHomePage="http://www.axis.com"'
|
||||
" />\n"
|
||||
" <application"
|
||||
' Name="objectanalytics"'
|
||||
' NiceName="AXIS Object Analytics"'
|
||||
' Vendor="Axis Communications"'
|
||||
' Version="1.0-0"'
|
||||
' ApplicationID="143440"'
|
||||
' License="None"'
|
||||
' Status="Running"'
|
||||
' ConfigurationPage="local/vmd/config.html"'
|
||||
' VendorHomePage="http://www.axis.com"'
|
||||
" />\n"
|
||||
"</reply>"
|
||||
)
|
||||
|
||||
BASIC_DEVICE_INFO_RESPONSE = {
|
||||
"apiVersion": "1.1",
|
||||
|
||||
@@ -64,14 +64,18 @@ from tests.common import snapshot_platform
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/MotionGuard/Camera1Profile1",
|
||||
"topic": (
|
||||
"tnsaxis:CameraApplicationPlatform/MotionGuard/Camera1Profile1"
|
||||
),
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
}
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/LoiteringGuard/Camera1Profile1",
|
||||
"topic": (
|
||||
"tnsaxis:CameraApplicationPlatform/LoiteringGuard/Camera1Profile1"
|
||||
),
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
}
|
||||
@@ -85,7 +89,9 @@ from tests.common import snapshot_platform
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario1",
|
||||
"topic": (
|
||||
"tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario1"
|
||||
),
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
}
|
||||
@@ -100,7 +106,9 @@ from tests.common import snapshot_platform
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario8",
|
||||
"topic": (
|
||||
"tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario8"
|
||||
),
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
}
|
||||
@@ -149,7 +157,9 @@ async def test_binary_sensors(
|
||||
"data_value": "1",
|
||||
},
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1ScenarioANY",
|
||||
"topic": (
|
||||
"tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1ScenarioANY"
|
||||
),
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
},
|
||||
|
||||
@@ -75,5 +75,5 @@ async def test_camera(
|
||||
@pytest.mark.parametrize("param_properties_payload", [PROPERTY_DATA])
|
||||
@pytest.mark.usefixtures("config_entry_setup")
|
||||
async def test_camera_disabled(hass: HomeAssistant) -> None:
|
||||
"""Test that Axis camera platform is loaded properly but does not create camera entity."""
|
||||
"""Test Axis camera platform loads but does not create camera entity."""
|
||||
assert len(hass.states.async_entity_ids(CAMERA_DOMAIN)) == 0
|
||||
|
||||
@@ -283,7 +283,10 @@ async def test_reconfiguration_flow_update_configuration(
|
||||
ssdp_st="mock_st",
|
||||
upnp={
|
||||
"st": "urn:axis-com:service:BasicService:1",
|
||||
"usn": f"uuid:Upnp-BasicDevice-1_0-{MAC}::urn:axis-com:service:BasicService:1",
|
||||
"usn": (
|
||||
f"uuid:Upnp-BasicDevice-1_0-{MAC}"
|
||||
"::urn:axis-com:service:BasicService:1"
|
||||
),
|
||||
"ext": "",
|
||||
"server": (
|
||||
"Linux/4.14.173-axis8, UPnP/1.0, Portable SDK for UPnP"
|
||||
|
||||
@@ -227,7 +227,7 @@ async def test_event(
|
||||
mock_managed_streaming: Mock,
|
||||
event: str | None,
|
||||
) -> None:
|
||||
"""Test listening to events from Hass. and getting an event with a newline in the state."""
|
||||
"""Test listening to events and getting an event with a newline."""
|
||||
|
||||
hass.states.async_set("sensor.test_sensor", event)
|
||||
|
||||
|
||||
@@ -281,7 +281,11 @@ async def test_agents_error_on_download_not_found(
|
||||
[
|
||||
(
|
||||
HttpResponseError("http error"),
|
||||
"Error during backup operation in async_delete_backup: Status None, message: http error",
|
||||
(
|
||||
"Error during backup operation in"
|
||||
" async_delete_backup:"
|
||||
" Status None, message: http error"
|
||||
),
|
||||
),
|
||||
(
|
||||
ServiceRequestError("timeout"),
|
||||
|
||||
Reference in New Issue
Block a user