mirror of https://github.com/home-assistant/core
Add support for snapshot testing (#88323)
* Add support for snapshot testing * Use snapshots in Elgato diagnostics test * Use snapshots in Elgato sensor test * Fix flake8 warning * Slightly improve serialized output * Remove snapshot naming in elgato sensor tests * Improve snapshoting of via_device_id in device registry item * Update pylint typehints plugin for snapshot fixture typing * Use snapshots in Elgato configflow test * Use snapshots in Bluetooth repair issue tests
This commit is contained in:
parent
325674ec44
commit
6891eb7ed1
|
@ -134,6 +134,7 @@ _TEST_FIXTURES: dict[str, list[str] | str] = {
|
|||
"recorder_db_url": "str",
|
||||
"recorder_mock": "Recorder",
|
||||
"requests_mock": "requests_mock.Mocker",
|
||||
"snapshot": "SnapshotAssertion",
|
||||
"tmp_path": "Path",
|
||||
}
|
||||
_TEST_FUNCTION_MATCH = TypeHintMatch(
|
||||
|
|
|
@ -32,6 +32,7 @@ pytest-xdist==2.5.0
|
|||
pytest==7.2.1
|
||||
requests_mock==1.10.0
|
||||
respx==0.20.1
|
||||
syrupy==4.0.0
|
||||
tomli==2.0.1;python_version<"3.11"
|
||||
tqdm==4.64.0
|
||||
types-atomicwrites==1.4.1
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# serializer version: 1
|
||||
# name: test_issue_outdated_haos
|
||||
IssueRegistryItemSnapshot({
|
||||
'created': <ANY>,
|
||||
'dismissed_version': None,
|
||||
'domain': 'bluetooth',
|
||||
'is_persistent': False,
|
||||
'issue_id': 'haos_outdated',
|
||||
})
|
||||
# ---
|
|
@ -8,6 +8,7 @@ from bleak import BleakError
|
|||
from bleak.backends.scanner import AdvertisementData, BLEDevice
|
||||
from bluetooth_adapters import DEFAULT_ADDRESS
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components import bluetooth
|
||||
from homeassistant.components.bluetooth import (
|
||||
|
@ -2873,6 +2874,7 @@ async def test_issue_outdated_haos(
|
|||
mock_bleak_scanner_start: MagicMock,
|
||||
one_adapter: None,
|
||||
operating_system_85: None,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test we create an issue on outdated haos."""
|
||||
entry = MockConfigEntry(
|
||||
|
@ -2886,6 +2888,7 @@ async def test_issue_outdated_haos(
|
|||
registry = async_get_issue_registry(hass)
|
||||
issue = registry.async_get_issue(DOMAIN, "haos_outdated")
|
||||
assert issue is not None
|
||||
assert issue == snapshot
|
||||
|
||||
|
||||
async def test_issue_outdated_haos_no_adapters(
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
# serializer version: 1
|
||||
# name: test_full_user_flow_implementation
|
||||
FlowResultSnapshot({
|
||||
'context': dict({
|
||||
'source': 'user',
|
||||
'unique_id': 'CN11A1A00001',
|
||||
}),
|
||||
'data': dict({
|
||||
'host': '127.0.0.1',
|
||||
'mac': None,
|
||||
'port': 9123,
|
||||
}),
|
||||
'description': None,
|
||||
'description_placeholders': None,
|
||||
'flow_id': <ANY>,
|
||||
'handler': 'elgato',
|
||||
'options': dict({
|
||||
}),
|
||||
'result': ConfigEntrySnapshot({
|
||||
'data': dict({
|
||||
'host': '127.0.0.1',
|
||||
'mac': None,
|
||||
'port': 9123,
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'domain': 'elgato',
|
||||
'entry_id': <ANY>,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'title': 'CN11A1A00001',
|
||||
'unique_id': 'CN11A1A00001',
|
||||
'version': 1,
|
||||
}),
|
||||
'title': 'CN11A1A00001',
|
||||
'type': <FlowResultType.CREATE_ENTRY: 'create_entry'>,
|
||||
'version': 1,
|
||||
})
|
||||
# ---
|
||||
# name: test_full_zeroconf_flow_implementation
|
||||
FlowResultSnapshot({
|
||||
'context': dict({
|
||||
'confirm_only': True,
|
||||
'source': 'zeroconf',
|
||||
'unique_id': 'CN11A1A00001',
|
||||
}),
|
||||
'data': dict({
|
||||
'host': '127.0.0.1',
|
||||
'mac': 'AA:BB:CC:DD:EE:FF',
|
||||
'port': 9123,
|
||||
}),
|
||||
'description': None,
|
||||
'description_placeholders': None,
|
||||
'flow_id': <ANY>,
|
||||
'handler': 'elgato',
|
||||
'options': dict({
|
||||
}),
|
||||
'result': ConfigEntrySnapshot({
|
||||
'data': dict({
|
||||
'host': '127.0.0.1',
|
||||
'mac': 'AA:BB:CC:DD:EE:FF',
|
||||
'port': 9123,
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'domain': 'elgato',
|
||||
'entry_id': <ANY>,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'zeroconf',
|
||||
'title': 'CN11A1A00001',
|
||||
'unique_id': 'CN11A1A00001',
|
||||
'version': 1,
|
||||
}),
|
||||
'title': 'CN11A1A00001',
|
||||
'type': <FlowResultType.CREATE_ENTRY: 'create_entry'>,
|
||||
'version': 1,
|
||||
})
|
||||
# ---
|
||||
# name: test_zeroconf_during_onboarding
|
||||
FlowResultSnapshot({
|
||||
'context': dict({
|
||||
'source': 'zeroconf',
|
||||
'unique_id': 'CN11A1A00001',
|
||||
}),
|
||||
'data': dict({
|
||||
'host': '127.0.0.1',
|
||||
'mac': 'AA:BB:CC:DD:EE:FF',
|
||||
'port': 9123,
|
||||
}),
|
||||
'description': None,
|
||||
'description_placeholders': None,
|
||||
'flow_id': <ANY>,
|
||||
'handler': 'elgato',
|
||||
'options': dict({
|
||||
}),
|
||||
'result': ConfigEntrySnapshot({
|
||||
'data': dict({
|
||||
'host': '127.0.0.1',
|
||||
'mac': 'AA:BB:CC:DD:EE:FF',
|
||||
'port': 9123,
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'domain': 'elgato',
|
||||
'entry_id': <ANY>,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'zeroconf',
|
||||
'title': 'CN11A1A00001',
|
||||
'unique_id': 'CN11A1A00001',
|
||||
'version': 1,
|
||||
}),
|
||||
'title': 'CN11A1A00001',
|
||||
'type': <FlowResultType.CREATE_ENTRY: 'create_entry'>,
|
||||
'version': 1,
|
||||
})
|
||||
# ---
|
|
@ -0,0 +1,25 @@
|
|||
# serializer version: 1
|
||||
# name: test_diagnostics
|
||||
dict({
|
||||
'info': dict({
|
||||
'display_name': 'Frenck',
|
||||
'features': list([
|
||||
'lights',
|
||||
]),
|
||||
'firmware_build_number': 192,
|
||||
'firmware_version': '1.0.3',
|
||||
'hardware_board_type': 53,
|
||||
'mac_address': None,
|
||||
'product_name': 'Elgato Key Light',
|
||||
'serial_number': 'CN11A1A00001',
|
||||
'wifi': None,
|
||||
}),
|
||||
'state': dict({
|
||||
'brightness': 21,
|
||||
'hue': None,
|
||||
'on': True,
|
||||
'saturation': None,
|
||||
'temperature': 297,
|
||||
}),
|
||||
})
|
||||
# ---
|
|
@ -0,0 +1,415 @@
|
|||
# serializer version: 1
|
||||
# name: test_sensors[sensor.frenck_battery-key-light-mini]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'battery',
|
||||
'friendly_name': 'Frenck Battery',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': '%',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.frenck_battery',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '78.57',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_battery-key-light-mini].1
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.frenck_battery',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Battery',
|
||||
'platform': 'elgato',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'GW24L1A02987_battery',
|
||||
'unit_of_measurement': '%',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_battery-key-light-mini].2
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'configuration_url': None,
|
||||
'connections': set({
|
||||
tuple(
|
||||
'mac',
|
||||
'aa:bb:cc:dd:ee:ff',
|
||||
),
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': '202',
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'elgato',
|
||||
'GW24L1A02987',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'manufacturer': 'Elgato',
|
||||
'model': 'Elgato Key Light Mini',
|
||||
'name': 'Frenck',
|
||||
'name_by_user': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '1.0.4 (229)',
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_battery_voltage-key-light-mini]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'voltage',
|
||||
'friendly_name': 'Frenck Battery voltage',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.frenck_battery_voltage',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '3.86',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_battery_voltage-key-light-mini].1
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.frenck_battery_voltage',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.VOLTAGE: 'voltage'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Battery voltage',
|
||||
'platform': 'elgato',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'GW24L1A02987_voltage',
|
||||
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_battery_voltage-key-light-mini].2
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'configuration_url': None,
|
||||
'connections': set({
|
||||
tuple(
|
||||
'mac',
|
||||
'aa:bb:cc:dd:ee:ff',
|
||||
),
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': '202',
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'elgato',
|
||||
'GW24L1A02987',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'manufacturer': 'Elgato',
|
||||
'model': 'Elgato Key Light Mini',
|
||||
'name': 'Frenck',
|
||||
'name_by_user': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '1.0.4 (229)',
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_current-key-light-mini]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'current',
|
||||
'friendly_name': 'Frenck Charging current',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.frenck_charging_current',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '3.008',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_current-key-light-mini].1
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.frenck_charging_current',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.CURRENT: 'current'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Charging current',
|
||||
'platform': 'elgato',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'GW24L1A02987_input_charge_current',
|
||||
'unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_current-key-light-mini].2
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'configuration_url': None,
|
||||
'connections': set({
|
||||
tuple(
|
||||
'mac',
|
||||
'aa:bb:cc:dd:ee:ff',
|
||||
),
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': '202',
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'elgato',
|
||||
'GW24L1A02987',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'manufacturer': 'Elgato',
|
||||
'model': 'Elgato Key Light Mini',
|
||||
'name': 'Frenck',
|
||||
'name_by_user': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '1.0.4 (229)',
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_power-key-light-mini]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'power',
|
||||
'friendly_name': 'Frenck Charging power',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.frenck_charging_power',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '12.66',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_power-key-light-mini].1
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.frenck_charging_power',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Charging power',
|
||||
'platform': 'elgato',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'GW24L1A02987_charge_power',
|
||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_power-key-light-mini].2
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'configuration_url': None,
|
||||
'connections': set({
|
||||
tuple(
|
||||
'mac',
|
||||
'aa:bb:cc:dd:ee:ff',
|
||||
),
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': '202',
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'elgato',
|
||||
'GW24L1A02987',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'manufacturer': 'Elgato',
|
||||
'model': 'Elgato Key Light Mini',
|
||||
'name': 'Frenck',
|
||||
'name_by_user': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '1.0.4 (229)',
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_voltage-key-light-mini]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'voltage',
|
||||
'friendly_name': 'Frenck Charging voltage',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.frenck_charging_voltage',
|
||||
'last_changed': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '4.208',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_voltage-key-light-mini].1
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.frenck_charging_voltage',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.VOLTAGE: 'voltage'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Charging voltage',
|
||||
'platform': 'elgato',
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'GW24L1A02987_input_charge_voltage',
|
||||
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.frenck_charging_voltage-key-light-mini].2
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'configuration_url': None,
|
||||
'connections': set({
|
||||
tuple(
|
||||
'mac',
|
||||
'aa:bb:cc:dd:ee:ff',
|
||||
),
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': '202',
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'elgato',
|
||||
'GW24L1A02987',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'manufacturer': 'Elgato',
|
||||
'model': 'Elgato Key Light Mini',
|
||||
'name': 'Frenck',
|
||||
'name_by_user': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '1.0.4 (229)',
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
|
@ -3,11 +3,12 @@ from unittest.mock import AsyncMock, MagicMock
|
|||
|
||||
from elgato import ElgatoConnectionError
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.components.elgato.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PORT, CONF_SOURCE
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SOURCE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
|
@ -18,6 +19,7 @@ async def test_full_user_flow_implementation(
|
|||
hass: HomeAssistant,
|
||||
mock_elgato_config_flow: MagicMock,
|
||||
mock_setup_entry: AsyncMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the full manual user flow from start to finish."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -33,14 +35,7 @@ async def test_full_user_flow_implementation(
|
|||
)
|
||||
|
||||
assert result2.get("type") == FlowResultType.CREATE_ENTRY
|
||||
assert result2.get("title") == "CN11A1A00001"
|
||||
assert result2.get("data") == {
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_MAC: None,
|
||||
CONF_PORT: 9123,
|
||||
}
|
||||
assert "result" in result2
|
||||
assert result2["result"].unique_id == "CN11A1A00001"
|
||||
assert result2 == snapshot
|
||||
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert len(mock_elgato_config_flow.info.mock_calls) == 1
|
||||
|
@ -50,6 +45,7 @@ async def test_full_zeroconf_flow_implementation(
|
|||
hass: HomeAssistant,
|
||||
mock_elgato_config_flow: MagicMock,
|
||||
mock_setup_entry: AsyncMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the zeroconf flow from start to finish."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -81,14 +77,7 @@ async def test_full_zeroconf_flow_implementation(
|
|||
)
|
||||
|
||||
assert result2.get("type") == FlowResultType.CREATE_ENTRY
|
||||
assert result2.get("title") == "CN11A1A00001"
|
||||
assert result2.get("data") == {
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||
CONF_PORT: 9123,
|
||||
}
|
||||
assert "result" in result2
|
||||
assert result2["result"].unique_id == "CN11A1A00001"
|
||||
assert result2 == snapshot
|
||||
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert len(mock_elgato_config_flow.info.mock_calls) == 1
|
||||
|
@ -204,6 +193,7 @@ async def test_zeroconf_during_onboarding(
|
|||
mock_elgato_config_flow: MagicMock,
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_onboarding: MagicMock,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the zeroconf creates an entry during onboarding."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -221,14 +211,7 @@ async def test_zeroconf_during_onboarding(
|
|||
)
|
||||
|
||||
assert result.get("type") == FlowResultType.CREATE_ENTRY
|
||||
assert result.get("title") == "CN11A1A00001"
|
||||
assert result.get("data") == {
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||
CONF_PORT: 9123,
|
||||
}
|
||||
assert "result" in result
|
||||
assert result["result"].unique_id == "CN11A1A00001"
|
||||
assert result == snapshot
|
||||
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert len(mock_elgato_config_flow.info.mock_calls) == 1
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""Tests for the diagnostics data provided by the Elgato integration."""
|
||||
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
@ -11,27 +13,10 @@ async def test_diagnostics(
|
|||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
init_integration: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test diagnostics."""
|
||||
assert await get_diagnostics_for_config_entry(
|
||||
hass, hass_client, init_integration
|
||||
) == {
|
||||
"info": {
|
||||
"display_name": "Frenck",
|
||||
"firmware_build_number": 192,
|
||||
"firmware_version": "1.0.3",
|
||||
"hardware_board_type": 53,
|
||||
"mac_address": None,
|
||||
"product_name": "Elgato Key Light",
|
||||
"serial_number": "CN11A1A00001",
|
||||
"wifi": None,
|
||||
"features": ["lights"],
|
||||
},
|
||||
"state": {
|
||||
"on": True,
|
||||
"brightness": 21,
|
||||
"hue": None,
|
||||
"saturation": None,
|
||||
"temperature": 297,
|
||||
},
|
||||
}
|
||||
assert (
|
||||
await get_diagnostics_for_config_entry(hass, hass_client, init_integration)
|
||||
== snapshot
|
||||
)
|
||||
|
|
|
@ -1,23 +1,7 @@
|
|||
"""Tests for the Elgato sensor platform."""
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.elgato.const import DOMAIN
|
||||
from homeassistant.components.sensor import (
|
||||
ATTR_STATE_CLASS,
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_DEVICE_CLASS,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_ICON,
|
||||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
PERCENTAGE,
|
||||
EntityCategory,
|
||||
UnitOfElectricCurrent,
|
||||
UnitOfElectricPotential,
|
||||
UnitOfPower,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
|
@ -28,129 +12,34 @@ pytestmark = [
|
|||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
@pytest.mark.parametrize(
|
||||
"entity_id",
|
||||
[
|
||||
"sensor.frenck_battery",
|
||||
"sensor.frenck_battery_voltage",
|
||||
"sensor.frenck_charging_current",
|
||||
"sensor.frenck_charging_power",
|
||||
"sensor.frenck_charging_voltage",
|
||||
],
|
||||
)
|
||||
async def test_sensors(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_id: str,
|
||||
) -> None:
|
||||
"""Test the Elgato sensors."""
|
||||
|
||||
# Battery sensor
|
||||
state = hass.states.get("sensor.frenck_battery")
|
||||
assert state
|
||||
assert state.state == "78.57"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.BATTERY
|
||||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Frenck Battery"
|
||||
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
|
||||
assert not state.attributes.get(ATTR_ICON)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state == snapshot
|
||||
|
||||
entry = entity_registry.async_get("sensor.frenck_battery")
|
||||
assert entry
|
||||
assert entry.unique_id == "GW24L1A02987_battery"
|
||||
assert entry.entity_category == EntityCategory.DIAGNOSTIC
|
||||
assert entry.options == {"sensor": {"suggested_display_precision": 0}}
|
||||
entry = entity_registry.async_get(entity_id)
|
||||
assert entry == snapshot
|
||||
|
||||
# Battery voltage sensor
|
||||
state = hass.states.get("sensor.frenck_battery_voltage")
|
||||
assert state
|
||||
assert state.state == "3.86"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.VOLTAGE
|
||||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Frenck Battery voltage"
|
||||
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfElectricPotential.VOLT
|
||||
)
|
||||
assert not state.attributes.get(ATTR_ICON)
|
||||
|
||||
entry = entity_registry.async_get("sensor.frenck_battery_voltage")
|
||||
assert entry
|
||||
assert entry.unique_id == "GW24L1A02987_voltage"
|
||||
assert entry.entity_category == EntityCategory.DIAGNOSTIC
|
||||
assert entry.options == {
|
||||
"sensor": {"suggested_display_precision": 2},
|
||||
"sensor.private": {
|
||||
"suggested_unit_of_measurement": UnitOfElectricPotential.VOLT
|
||||
},
|
||||
}
|
||||
|
||||
# Charging current sensor
|
||||
state = hass.states.get("sensor.frenck_charging_current")
|
||||
assert state
|
||||
assert state.state == "3.008"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.CURRENT
|
||||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Frenck Charging current"
|
||||
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfElectricCurrent.AMPERE
|
||||
)
|
||||
assert not state.attributes.get(ATTR_ICON)
|
||||
|
||||
entry = entity_registry.async_get("sensor.frenck_charging_current")
|
||||
assert entry
|
||||
assert entry.unique_id == "GW24L1A02987_input_charge_current"
|
||||
assert entry.entity_category == EntityCategory.DIAGNOSTIC
|
||||
assert entry.options == {
|
||||
"sensor": {"suggested_display_precision": 2},
|
||||
"sensor.private": {
|
||||
"suggested_unit_of_measurement": UnitOfElectricCurrent.AMPERE
|
||||
},
|
||||
}
|
||||
|
||||
# Charging power sensor
|
||||
state = hass.states.get("sensor.frenck_charging_power")
|
||||
assert state
|
||||
assert state.state == "12.66"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.POWER
|
||||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Frenck Charging power"
|
||||
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfPower.WATT
|
||||
assert not state.attributes.get(ATTR_ICON)
|
||||
|
||||
entry = entity_registry.async_get("sensor.frenck_charging_power")
|
||||
assert entry
|
||||
assert entry.unique_id == "GW24L1A02987_charge_power"
|
||||
assert entry.entity_category == EntityCategory.DIAGNOSTIC
|
||||
assert entry.options == {"sensor": {"suggested_display_precision": 0}}
|
||||
|
||||
# Charging voltage sensor
|
||||
state = hass.states.get("sensor.frenck_charging_voltage")
|
||||
assert state
|
||||
assert state.state == "4.208"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.VOLTAGE
|
||||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Frenck Charging voltage"
|
||||
assert state.attributes.get(ATTR_STATE_CLASS) is SensorStateClass.MEASUREMENT
|
||||
assert (
|
||||
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfElectricPotential.VOLT
|
||||
)
|
||||
assert not state.attributes.get(ATTR_ICON)
|
||||
|
||||
entry = entity_registry.async_get("sensor.frenck_charging_voltage")
|
||||
assert entry
|
||||
assert entry.unique_id == "GW24L1A02987_input_charge_voltage"
|
||||
assert entry.entity_category == EntityCategory.DIAGNOSTIC
|
||||
assert entry.options == {
|
||||
"sensor": {"suggested_display_precision": 2},
|
||||
"sensor.private": {
|
||||
"suggested_unit_of_measurement": UnitOfElectricPotential.VOLT
|
||||
},
|
||||
}
|
||||
|
||||
# Check if the entity is well registered in the device registry
|
||||
assert entry.device_id
|
||||
device_entry = device_registry.async_get(entry.device_id)
|
||||
assert device_entry
|
||||
assert device_entry.configuration_url is None
|
||||
assert device_entry.connections == {
|
||||
(dr.CONNECTION_NETWORK_MAC, "aa:bb:cc:dd:ee:ff")
|
||||
}
|
||||
assert device_entry.entry_type is None
|
||||
assert device_entry.identifiers == {(DOMAIN, "GW24L1A02987")}
|
||||
assert device_entry.manufacturer == "Elgato"
|
||||
assert device_entry.model == "Elgato Key Light Mini"
|
||||
assert device_entry.name == "Frenck"
|
||||
assert device_entry.sw_version == "1.0.4 (229)"
|
||||
assert device_entry.hw_version == "202"
|
||||
assert device_entry == snapshot
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -30,6 +30,7 @@ import multidict
|
|||
import pytest
|
||||
import pytest_socket
|
||||
import requests_mock
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant import core as ha, loader, runner, util
|
||||
from homeassistant.auth.const import GROUP_ID_ADMIN, GROUP_ID_READ_ONLY
|
||||
|
@ -61,6 +62,7 @@ from homeassistant.util import dt as dt_util, location
|
|||
from homeassistant.util.json import json_loads
|
||||
|
||||
from .ignore_uncaught_exceptions import IGNORE_UNCAUGHT_EXCEPTIONS
|
||||
from .syrupy import HomeAssistantSnapshotExtension
|
||||
from .typing import (
|
||||
ClientSessionGenerator,
|
||||
MockHAClientWebSocket,
|
||||
|
@ -1382,3 +1384,9 @@ def entity_registry(hass: HomeAssistant) -> er.EntityRegistry:
|
|||
def issue_registry(hass: HomeAssistant) -> ir.IssueRegistry:
|
||||
"""Return the issue registry from the current hass instance."""
|
||||
return ir.async_get(hass)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def snapshot(snapshot: SnapshotAssertion) -> SnapshotAssertion:
|
||||
"""Return snapshot assertion fixture with the Home Assistant extension."""
|
||||
return snapshot.use_extension(HomeAssistantSnapshotExtension)
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
"""Home Assistant extension for Syrupy."""
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import suppress
|
||||
import dataclasses
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import attr
|
||||
import attrs
|
||||
from syrupy.extensions.amber import AmberDataSerializer, AmberSnapshotExtension
|
||||
from syrupy.location import PyTestLocation
|
||||
from syrupy.types import (
|
||||
PropertyFilter,
|
||||
PropertyMatcher,
|
||||
PropertyPath,
|
||||
SerializableData,
|
||||
SerializedData,
|
||||
)
|
||||
import voluptuous as vol
|
||||
import voluptuous_serialize
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import State
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers import (
|
||||
area_registry as ar,
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
issue_registry as ir,
|
||||
)
|
||||
|
||||
|
||||
class _ANY:
|
||||
"""Represent any value."""
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "<ANY>"
|
||||
|
||||
|
||||
ANY = _ANY()
|
||||
|
||||
__all__ = ["HomeAssistantSnapshotExtension"]
|
||||
|
||||
|
||||
class AreaRegistryEntrySnapshot(dict):
|
||||
"""Tiny wrapper to represent an area registry entry in snapshots."""
|
||||
|
||||
|
||||
class ConfigEntrySnapshot(dict):
|
||||
"""Tiny wrapper to represent a config entry in snapshots."""
|
||||
|
||||
|
||||
class DeviceRegistryEntrySnapshot(dict):
|
||||
"""Tiny wrapper to represent a device registry entry in snapshots."""
|
||||
|
||||
|
||||
class EntityRegistryEntrySnapshot(dict):
|
||||
"""Tiny wrapper to represent an entity registry entry in snapshots."""
|
||||
|
||||
|
||||
class FlowResultSnapshot(dict):
|
||||
"""Tiny wrapper to represent a flow result in snapshots."""
|
||||
|
||||
|
||||
class IssueRegistryItemSnapshot(dict):
|
||||
"""Tiny wrapper to represent an entity registry entry in snapshots."""
|
||||
|
||||
|
||||
class StateSnapshot(dict):
|
||||
"""Tiny wrapper to represent an entity state in snapshots."""
|
||||
|
||||
|
||||
class HomeAssistantSnapshotSerializer(AmberDataSerializer):
|
||||
"""Home Assistant snapshot serializer for Syrupy.
|
||||
|
||||
Handles special cases for Home Assistant data structures.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _serialize(
|
||||
cls,
|
||||
data: SerializableData,
|
||||
*,
|
||||
depth: int = 0,
|
||||
exclude: PropertyFilter | None = None,
|
||||
matcher: PropertyMatcher | None = None,
|
||||
path: PropertyPath = (),
|
||||
visited: set[Any] | None = None,
|
||||
) -> SerializedData:
|
||||
"""Pre-process data before serializing.
|
||||
|
||||
This allows us to handle specific cases for Home Assistant data structures.
|
||||
"""
|
||||
if isinstance(data, State):
|
||||
serializable_data = cls._serializable_state(data)
|
||||
elif isinstance(data, ar.AreaEntry):
|
||||
serializable_data = cls._serializable_area_registry_entry(data)
|
||||
elif isinstance(data, dr.DeviceEntry):
|
||||
serializable_data = cls._serializable_device_registry_entry(data)
|
||||
elif isinstance(data, er.RegistryEntry):
|
||||
serializable_data = cls._serializable_entity_registry_entry(data)
|
||||
elif isinstance(data, ir.IssueEntry):
|
||||
serializable_data = cls._serializable_issue_registry_entry(data)
|
||||
elif isinstance(data, dict) and "flow_id" in data and "handler" in data:
|
||||
serializable_data = cls._serializable_flow_result(data)
|
||||
elif isinstance(data, vol.Schema):
|
||||
serializable_data = voluptuous_serialize.convert(data)
|
||||
elif isinstance(data, ConfigEntry):
|
||||
serializable_data = cls._serializable_config_entry(data)
|
||||
elif dataclasses.is_dataclass(data):
|
||||
serializable_data = dataclasses.asdict(data)
|
||||
else:
|
||||
serializable_data = data
|
||||
with suppress(TypeError):
|
||||
if attr.has(data):
|
||||
serializable_data = attrs.asdict(data)
|
||||
|
||||
return super()._serialize(
|
||||
serializable_data,
|
||||
depth=depth,
|
||||
exclude=exclude,
|
||||
matcher=matcher,
|
||||
path=path,
|
||||
visited=visited,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _serializable_area_registry_entry(cls, data: ar.AreaEntry) -> SerializableData:
|
||||
"""Prepare a Home Assistant area registry entry for serialization."""
|
||||
serialized = AreaRegistryEntrySnapshot(attrs.asdict(data) | {"id": ANY})
|
||||
serialized.pop("_json_repr")
|
||||
return serialized
|
||||
|
||||
@classmethod
|
||||
def _serializable_config_entry(cls, data: ConfigEntry) -> SerializableData:
|
||||
"""Prepare a Home Assistant config entry for serialization."""
|
||||
return ConfigEntrySnapshot(data.as_dict() | {"entry_id": ANY})
|
||||
|
||||
@classmethod
|
||||
def _serializable_device_registry_entry(
|
||||
cls, data: dr.DeviceEntry
|
||||
) -> SerializableData:
|
||||
"""Prepare a Home Assistant device registry entry for serialization."""
|
||||
serialized = DeviceRegistryEntrySnapshot(
|
||||
attrs.asdict(data)
|
||||
| {
|
||||
"config_entries": ANY,
|
||||
"id": ANY,
|
||||
}
|
||||
)
|
||||
if serialized["via_device_id"] is not None:
|
||||
serialized["via_device_id"] = ANY
|
||||
serialized.pop("_json_repr")
|
||||
return serialized
|
||||
|
||||
@classmethod
|
||||
def _serializable_entity_registry_entry(
|
||||
cls, data: er.RegistryEntry
|
||||
) -> SerializableData:
|
||||
"""Prepare a Home Assistant entity registry entry for serialization."""
|
||||
serialized = EntityRegistryEntrySnapshot(
|
||||
attrs.asdict(data)
|
||||
| {
|
||||
"config_entry_id": ANY,
|
||||
"device_id": ANY,
|
||||
"id": ANY,
|
||||
}
|
||||
)
|
||||
serialized.pop("_json_repr")
|
||||
return serialized
|
||||
|
||||
@classmethod
|
||||
def _serializable_flow_result(cls, data: FlowResult) -> SerializableData:
|
||||
"""Prepare a Home Assistant flow result for serialization."""
|
||||
return FlowResultSnapshot(data | {"flow_id": ANY})
|
||||
|
||||
@classmethod
|
||||
def _serializable_issue_registry_entry(
|
||||
cls, data: ir.IssueEntry
|
||||
) -> SerializableData:
|
||||
"""Prepare a Home Assistant issue registry entry for serialization."""
|
||||
return IssueRegistryItemSnapshot(data.to_json() | {"created": ANY})
|
||||
|
||||
@classmethod
|
||||
def _serializable_state(cls, data: State) -> SerializableData:
|
||||
"""Prepare a Home Assistant State for serialization."""
|
||||
return StateSnapshot(
|
||||
data.as_dict()
|
||||
| {
|
||||
"context": ANY,
|
||||
"last_changed": ANY,
|
||||
"last_updated": ANY,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class HomeAssistantSnapshotExtension(AmberSnapshotExtension):
|
||||
"""Home Assistant extension for Syrupy."""
|
||||
|
||||
VERSION = "1"
|
||||
"""Current version of serialization format.
|
||||
|
||||
Need to be bumped when we change the HomeAssistantSnapshotSerializer.
|
||||
"""
|
||||
|
||||
serializer_class: type[AmberDataSerializer] = HomeAssistantSnapshotSerializer
|
||||
|
||||
@classmethod
|
||||
def dirname(cls, *, test_location: PyTestLocation) -> str:
|
||||
"""Return the directory for the snapshot files.
|
||||
|
||||
Syrupy, by default, uses the `__snapshosts__` directory in the same
|
||||
folder as the test file. For Home Assistant, this is changed to just
|
||||
`snapshots` in the same folder as the test file, to match our `fixtures`
|
||||
folder structure.
|
||||
"""
|
||||
test_dir = Path(test_location.filepath).parent
|
||||
return str(test_dir.joinpath("snapshots"))
|
Loading…
Reference in New Issue