Fix line length violations in tests/components a (#170806)

This commit is contained in:
Franck Nijhof
2026-05-15 13:07:01 -04:00
committed by GitHub
parent 63b199c865
commit a9207988f5
72 changed files with 541 additions and 196 deletions
+8 -2
View File
@@ -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)
+4 -1
View File
@@ -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)
+2 -1
View File
@@ -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,
+20 -7
View File
@@ -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",
},
},
+6 -2
View File
@@ -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,
+12 -3
View File
@@ -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,
+5 -2
View File
@@ -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",
),
],
)
+5 -2
View File
@@ -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",
),
],
)
+5 -2
View File
@@ -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",
),
],
)
+5 -2
View File
@@ -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",
),
],
)
+4 -1
View File
@@ -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")
+2 -1
View File
@@ -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"
+1 -1
View File
@@ -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,
+12 -3
View File
@@ -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)
+3 -2
View File
@@ -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,
+4 -1
View File
@@ -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
+14 -6
View File
@@ -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")
+4 -1
View File
@@ -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(
+4 -1
View File
@@ -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 (
+13 -4
View File
@@ -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
+24 -10
View File
@@ -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)
+1 -1
View File
@@ -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,
+3 -1
View File
@@ -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",
},
+4 -1
View File
@@ -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
+5 -1
View File
@@ -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
+11 -3
View File
@@ -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",
+9 -2
View File
@@ -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,
+1 -1
View File
@@ -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)
+13 -7
View File
@@ -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.
+8 -5
View File
@@ -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
+8 -5
View File
@@ -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)
+5 -3
View File
@@ -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(
+10 -2
View File
@@ -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,
},
+1 -1
View File
@@ -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",
+20 -5
View File
@@ -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(
+1 -1
View File
@@ -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):
+1 -1
View File
@@ -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)
+19 -1
View File
@@ -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)
+5 -4
View File
@@ -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)
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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",
+1 -1
View File
@@ -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(
+5 -2
View File
@@ -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."
),
),
(
{
+4 -2
View File
@@ -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"
+15 -11
View File
@@ -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,
]
+7 -8
View File
@@ -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"},
+62 -7
View File
@@ -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",
+15 -5
View File
@@ -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",
},
+1 -1
View File
@@ -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
+4 -1
View File
@@ -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"),