Add tests for Tractive integration (#118470)

Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
This commit is contained in:
Maciej Bieniek 2024-05-30 12:45:11 +02:00 committed by GitHub
parent fc5d58effd
commit cf51179009
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 1686 additions and 18 deletions

View File

@ -1470,12 +1470,6 @@ omit =
homeassistant/components/traccar_server/entity.py
homeassistant/components/traccar_server/helpers.py
homeassistant/components/traccar_server/sensor.py
homeassistant/components/tractive/__init__.py
homeassistant/components/tractive/binary_sensor.py
homeassistant/components/tractive/device_tracker.py
homeassistant/components/tractive/entity.py
homeassistant/components/tractive/sensor.py
homeassistant/components/tractive/switch.py
homeassistant/components/tradfri/__init__.py
homeassistant/components/tradfri/base_class.py
homeassistant/components/tradfri/coordinator.py

View File

@ -1 +1,18 @@
"""Tests for the tractive integration."""
from unittest.mock import patch
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def init_integration(
hass: HomeAssistant, entry: MockConfigEntry
) -> MockConfigEntry:
"""Set up the Tractive integration in Home Assistant."""
entry.add_to_hass(hass)
with patch("homeassistant.components.tractive.TractiveClient._listen"):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

View File

@ -1,14 +1,16 @@
"""Common fixtures for the Tractive tests."""
from collections.abc import Generator
from typing import Any
from unittest.mock import AsyncMock, Mock, patch
from aiotractive.trackable_object import TrackableObject
from aiotractive.tracker import Tracker
import pytest
from homeassistant.components.tractive.const import DOMAIN
from homeassistant.components.tractive.const import DOMAIN, SERVER_UNAVAILABLE
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
from homeassistant.helpers.dispatcher import async_dispatcher_send
from tests.common import MockConfigEntry, load_json_object_fixture
@ -17,7 +19,72 @@ from tests.common import MockConfigEntry, load_json_object_fixture
def mock_tractive_client() -> Generator[AsyncMock, None, None]:
"""Mock a Tractive client."""
trackable_object = load_json_object_fixture("tractive/trackable_object.json")
def send_hardware_event(
entry: MockConfigEntry, event: dict[str, Any] | None = None
):
"""Send hardware event."""
if event is None:
event = {
"tracker_id": "device_id_123",
"hardware": {"battery_level": 88},
"tracker_state": "operational",
"charging_state": "CHARGING",
}
entry.runtime_data.client._send_hardware_update(event)
def send_wellness_event(
entry: MockConfigEntry, event: dict[str, Any] | None = None
):
"""Send wellness event."""
if event is None:
event = {
"pet_id": "pet_id_123",
"sleep": {"minutes_day_sleep": 100, "minutes_night_sleep": 300},
"wellness": {"activity_label": "ok", "sleep_label": "good"},
"activity": {
"calories": 999,
"minutes_goal": 200,
"minutes_active": 150,
"minutes_rest": 122,
},
}
entry.runtime_data.client._send_wellness_update(event)
def send_position_event(
entry: MockConfigEntry, event: dict[str, Any] | None = None
):
"""Send position event."""
if event is None:
event = {
"tracker_id": "device_id_123",
"position": {
"latlong": [22.333, 44.555],
"accuracy": 99,
"sensor_used": "GPS",
},
}
entry.runtime_data.client._send_position_update(event)
def send_switch_event(entry: MockConfigEntry, event: dict[str, Any] | None = None):
"""Send switch event."""
if event is None:
event = {
"tracker_id": "device_id_123",
"buzzer_control": {"active": True},
"led_control": {"active": False},
"live_tracking": {"active": True},
}
entry.runtime_data.client._send_switch_update(event)
def send_server_unavailable_event(hass):
"""Send server unavailable event."""
async_dispatcher_send(hass, f"{SERVER_UNAVAILABLE}-12345")
trackable_object = load_json_object_fixture("trackable_object.json", DOMAIN)
tracker_details = load_json_object_fixture("tracker_details.json", DOMAIN)
tracker_hw_info = load_json_object_fixture("tracker_hw_info.json", DOMAIN)
tracker_pos_report = load_json_object_fixture("tracker_pos_report.json", DOMAIN)
with (
patch(
"homeassistant.components.tractive.aiotractive.Tractive", autospec=True
@ -33,7 +100,21 @@ def mock_tractive_client() -> Generator[AsyncMock, None, None]:
details=AsyncMock(return_value=trackable_object),
),
]
client.tracker.return_value = Mock(spec=Tracker)
client.tracker.return_value = AsyncMock(
spec=Tracker,
details=AsyncMock(return_value=tracker_details),
hw_info=AsyncMock(return_value=tracker_hw_info),
pos_report=AsyncMock(return_value=tracker_pos_report),
set_live_tracking_active=AsyncMock(return_value={"pending": True}),
set_buzzer_active=AsyncMock(return_value={"pending": True}),
set_led_active=AsyncMock(return_value={"pending": True}),
)
client.send_hardware_event = send_hardware_event
client.send_wellness_event = send_wellness_event
client.send_position_event = send_position_event
client.send_switch_event = send_switch_event
client.send_server_unavailable_event = send_server_unavailable_event
yield client

View File

@ -1,7 +1,8 @@
{
"device_id": "54321",
"device_id": "device_id_123",
"_id": "pet_id_123",
"details": {
"_id": "xyz123",
"_id": "pet_id_123",
"_version": "123abc",
"name": "Test Pet",
"pet_type": "DOG",

View File

@ -0,0 +1,38 @@
{
"_id": "device_id_123",
"_version": "abcd-123-efgh-456",
"hw_id": "device_id_123",
"model_number": "TG4422",
"hw_edition": "BLUE-WHITE",
"bluetooth_mac": null,
"geofence_sensitivity": "HIGH",
"battery_save_mode": null,
"read_only": false,
"demo": false,
"self_test_available": false,
"capabilities": [
"LT",
"BUZZER",
"LT_BLE",
"LED_BLE",
"BUZZER_BLE",
"HW_REPORTS_BLE",
"WIFI_SCAN_REPORTS_BLE",
"LED",
"ACTIVITY_TRACKING",
"WIFI_ZONE",
"SLEEP_TRACKING"
],
"supported_geofence_types": ["CIRCLE", "RECTANGLE", "POLYGON"],
"fw_version": "123.456",
"state": "OPERATIONAL",
"state_reason": "POWER_SAVING",
"charging_state": "NOT_CHARGING",
"battery_state": "FULL",
"power_saving_zone_id": "abcdef12345",
"prioritized_zone_id": "098765",
"prioritized_zone_type": "POWER_SAVING",
"prioritized_zone_last_seen_at": 1716106551,
"prioritized_zone_entered_at": 1716105066,
"_type": "tracker"
}

View File

@ -0,0 +1,11 @@
{
"time": 1716105966,
"battery_level": 96,
"clip_mounted_state": null,
"_id": "device_id_123",
"_type": "device_hw_report",
"_version": "e87646946",
"report_id": "098123",
"power_saving_zone_id": "abcdef12345",
"hw_status": null
}

View File

@ -0,0 +1,16 @@
{
"time": 1716106551,
"time_rcvd": 1716106561,
"pos_status": null,
"latlong": [33.222222, 44.555555],
"speed": null,
"pos_uncertainty": 30,
"_id": "device_id_123",
"_type": "device_pos_report",
"_version": "b7422b930",
"altitude": 85,
"report_id": "098123",
"sensor_used": "KNOWN_WIFI",
"nearby_user_id": null,
"power_saving_zone_id": "abcdef12345"
}

View File

@ -0,0 +1,95 @@
# serializer version: 1
# name: test_binary_sensor[binary_sensor.test_pet_tracker_battery_charging-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'binary_sensor.test_pet_tracker_battery_charging',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.BATTERY_CHARGING: 'battery_charging'>,
'original_icon': None,
'original_name': 'Tracker battery charging',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_battery_charging',
'unique_id': 'pet_id_123_battery_charging',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor[binary_sensor.test_pet_tracker_battery_charging-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery_charging',
'friendly_name': 'Test Pet Tracker battery charging',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.test_pet_tracker_battery_charging',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_sensor[binary_sensor.test_pet_tracker_battery_charging-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'binary_sensor.test_pet_tracker_battery_charging',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.BATTERY_CHARGING: 'battery_charging'>,
'original_icon': None,
'original_name': 'Tracker battery charging',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_battery_charging',
'unique_id': 'pet_id_123_battery_charging',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[binary_sensor.test_pet_tracker_battery_charging-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery_charging',
'friendly_name': 'Test Pet Tracker battery charging',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.test_pet_tracker_battery_charging',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---

View File

@ -0,0 +1,103 @@
# serializer version: 1
# name: test_device_tracker[device_tracker.test_pet_tracker-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'device_tracker',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'device_tracker.test_pet_tracker',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Tracker',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker',
'unique_id': 'pet_id_123',
'unit_of_measurement': None,
})
# ---
# name: test_device_tracker[device_tracker.test_pet_tracker-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'battery_level': 88,
'friendly_name': 'Test Pet Tracker',
'gps_accuracy': 99,
'latitude': 22.333,
'longitude': 44.555,
'source_type': <SourceType.GPS: 'gps'>,
}),
'context': <ANY>,
'entity_id': 'device_tracker.test_pet_tracker',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'not_home',
})
# ---
# name: test_sensor[device_tracker.test_pet_tracker-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'device_tracker',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'device_tracker.test_pet_tracker',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Tracker',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker',
'unique_id': 'pet_id_123',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[device_tracker.test_pet_tracker-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'battery_level': 88,
'friendly_name': 'Test Pet Tracker',
'gps_accuracy': 99,
'latitude': 22.333,
'longitude': 44.555,
'source_type': <SourceType.GPS: 'gps'>,
}),
'context': <ANY>,
'entity_id': 'device_tracker.test_pet_tracker',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'not_home',
})
# ---

View File

@ -21,6 +21,7 @@
}),
'trackables': list([
dict({
'_id': '**REDACTED**',
'details': dict({
'_id': '**REDACTED**',
'_type': 'pet_detail',
@ -64,7 +65,7 @@
'weight': 23700,
'weight_is_default': None,
}),
'device_id': '54321',
'device_id': 'device_id_123',
}),
]),
})

View File

@ -0,0 +1,524 @@
# serializer version: 1
# name: test_sensor[sensor.test_pet_activity-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'good',
'low',
'ok',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_activity',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Activity',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'activity',
'unique_id': 'pet_id_123_activity_label',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[sensor.test_pet_activity-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Test Pet Activity',
'options': list([
'good',
'low',
'ok',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_activity',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'ok',
})
# ---
# name: test_sensor[sensor.test_pet_activity_time-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_activity_time',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Activity time',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'activity_time',
'unique_id': 'pet_id_123_minutes_active',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensor[sensor.test_pet_activity_time-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Activity time',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_activity_time',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '150',
})
# ---
# name: test_sensor[sensor.test_pet_calories_burned-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_calories_burned',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Calories burned',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'calories',
'unique_id': 'pet_id_123_calories',
'unit_of_measurement': 'kcal',
})
# ---
# name: test_sensor[sensor.test_pet_calories_burned-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Calories burned',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': 'kcal',
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_calories_burned',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '999',
})
# ---
# name: test_sensor[sensor.test_pet_daily_goal-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_daily_goal',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Daily goal',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'daily_goal',
'unique_id': 'pet_id_123_daily_goal',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensor[sensor.test_pet_daily_goal-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Daily goal',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_daily_goal',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '200',
})
# ---
# name: test_sensor[sensor.test_pet_day_sleep-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_day_sleep',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Day sleep',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'minutes_day_sleep',
'unique_id': 'pet_id_123_minutes_day_sleep',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensor[sensor.test_pet_day_sleep-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Day sleep',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_day_sleep',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '100',
})
# ---
# name: test_sensor[sensor.test_pet_night_sleep-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_night_sleep',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Night sleep',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'minutes_night_sleep',
'unique_id': 'pet_id_123_minutes_night_sleep',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensor[sensor.test_pet_night_sleep-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Night sleep',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_night_sleep',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '300',
})
# ---
# name: test_sensor[sensor.test_pet_rest_time-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_rest_time',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Rest time',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'rest_time',
'unique_id': 'pet_id_123_minutes_rest',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensor[sensor.test_pet_rest_time-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Rest time',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_rest_time',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '122',
})
# ---
# name: test_sensor[sensor.test_pet_sleep-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'good',
'low',
'ok',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.test_pet_sleep',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Sleep',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'sleep',
'unique_id': 'pet_id_123_sleep_label',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[sensor.test_pet_sleep-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Test Pet Sleep',
'options': list([
'good',
'low',
'ok',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_sleep',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'good',
})
# ---
# name: test_sensor[sensor.test_pet_tracker_battery-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.test_pet_tracker_battery',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
'original_icon': None,
'original_name': 'Tracker battery',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_battery_level',
'unique_id': 'pet_id_123_battery_level',
'unit_of_measurement': '%',
})
# ---
# name: test_sensor[sensor.test_pet_tracker_battery-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery',
'friendly_name': 'Test Pet Tracker battery',
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_tracker_battery',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '88',
})
# ---
# name: test_sensor[sensor.test_pet_tracker_state-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'inaccurate_position',
'not_reporting',
'operational',
'system_shutdown_user',
'system_startup',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.test_pet_tracker_state',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Tracker state',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_state',
'unique_id': 'pet_id_123_tracker_state',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[sensor.test_pet_tracker_state-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Test Pet Tracker state',
'options': list([
'inaccurate_position',
'not_reporting',
'operational',
'system_shutdown_user',
'system_startup',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.test_pet_tracker_state',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'operational',
})
# ---

View File

@ -0,0 +1,277 @@
# serializer version: 1
# name: test_sensor[switch.test_pet_live_tracking-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'switch.test_pet_live_tracking',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Live tracking',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'live_tracking',
'unique_id': 'pet_id_123_live_tracking',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[switch.test_pet_live_tracking-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Live tracking',
}),
'context': <ANY>,
'entity_id': 'switch.test_pet_live_tracking',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_sensor[switch.test_pet_tracker_buzzer-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'switch.test_pet_tracker_buzzer',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Tracker buzzer',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_buzzer',
'unique_id': 'pet_id_123_buzzer',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[switch.test_pet_tracker_buzzer-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Tracker buzzer',
}),
'context': <ANY>,
'entity_id': 'switch.test_pet_tracker_buzzer',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_sensor[switch.test_pet_tracker_led-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'switch.test_pet_tracker_led',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Tracker LED',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_led',
'unique_id': 'pet_id_123_led',
'unit_of_measurement': None,
})
# ---
# name: test_sensor[switch.test_pet_tracker_led-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Tracker LED',
}),
'context': <ANY>,
'entity_id': 'switch.test_pet_tracker_led',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_switch[switch.test_pet_live_tracking-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'switch.test_pet_live_tracking',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Live tracking',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'live_tracking',
'unique_id': 'pet_id_123_live_tracking',
'unit_of_measurement': None,
})
# ---
# name: test_switch[switch.test_pet_live_tracking-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Live tracking',
}),
'context': <ANY>,
'entity_id': 'switch.test_pet_live_tracking',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_switch[switch.test_pet_tracker_buzzer-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'switch.test_pet_tracker_buzzer',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Tracker buzzer',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_buzzer',
'unique_id': 'pet_id_123_buzzer',
'unit_of_measurement': None,
})
# ---
# name: test_switch[switch.test_pet_tracker_buzzer-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Tracker buzzer',
}),
'context': <ANY>,
'entity_id': 'switch.test_pet_tracker_buzzer',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_switch[switch.test_pet_tracker_led-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'switch.test_pet_tracker_led',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Tracker LED',
'platform': 'tractive',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'tracker_led',
'unique_id': 'pet_id_123_led',
'unit_of_measurement': None,
})
# ---
# name: test_switch[switch.test_pet_tracker_led-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Test Pet Tracker LED',
}),
'context': <ANY>,
'entity_id': 'switch.test_pet_tracker_led',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---

View File

@ -0,0 +1,29 @@
"""Test the Tractive binary sensor platform."""
from unittest.mock import AsyncMock, patch
from syrupy import SnapshotAssertion
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import init_integration
from tests.common import MockConfigEntry, snapshot_platform
async def test_binary_sensor(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test states of the binary sensor."""
with patch("homeassistant.components.tractive.PLATFORMS", [Platform.BINARY_SENSOR]):
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_hardware_event(mock_config_entry)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)

View File

@ -0,0 +1,61 @@
"""Test the Tractive device tracker platform."""
from unittest.mock import AsyncMock, patch
from syrupy import SnapshotAssertion
from homeassistant.components.device_tracker import SourceType
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import init_integration
from tests.common import MockConfigEntry, snapshot_platform
async def test_device_tracker(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test states of the device_tracker."""
with patch(
"homeassistant.components.tractive.PLATFORMS", [Platform.DEVICE_TRACKER]
):
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_position_event(mock_config_entry)
mock_tractive_client.send_hardware_event(mock_config_entry)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
async def test_source_type_phone(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the device tracker with source type phone."""
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_position_event(
mock_config_entry,
{
"tracker_id": "device_id_123",
"position": {
"latlong": [22.333, 44.555],
"accuracy": 99,
"sensor_used": "PHONE",
},
},
)
mock_tractive_client.send_hardware_event(mock_config_entry)
await hass.async_block_till_done()
assert (
hass.states.get("device_tracker.test_pet_tracker").attributes["source_type"]
is SourceType.BLUETOOTH
)

View File

@ -1,12 +1,12 @@
"""Test the Tractive diagnostics."""
from unittest.mock import AsyncMock, patch
from unittest.mock import AsyncMock
from syrupy import SnapshotAssertion
from homeassistant.components.tractive.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from . import init_integration
from tests.common import MockConfigEntry
from tests.components.diagnostics import get_diagnostics_for_config_entry
@ -21,9 +21,8 @@ async def test_entry_diagnostics(
mock_config_entry: MockConfigEntry,
) -> None:
"""Test config entry diagnostics."""
mock_config_entry.add_to_hass(hass)
with patch("homeassistant.components.tractive.PLATFORMS", []):
assert await async_setup_component(hass, DOMAIN, {})
await init_integration(hass, mock_config_entry)
result = await get_diagnostics_for_config_entry(
hass, hass_client, mock_config_entry
)

View File

@ -0,0 +1,163 @@
"""Test init of Tractive integration."""
from unittest.mock import AsyncMock, patch
from aiotractive.exceptions import TractiveError, UnauthorizedError
import pytest
from homeassistant.components.tractive.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from . import init_integration
from tests.common import MockConfigEntry
async def test_setup_entry(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test a successful setup entry."""
await init_integration(hass, mock_config_entry)
assert mock_config_entry.state is ConfigEntryState.LOADED
async def test_unload_entry(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test successful unload of entry."""
await init_integration(hass, mock_config_entry)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert mock_config_entry.state is ConfigEntryState.LOADED
with patch("homeassistant.components.tractive.TractiveClient.unsubscribe"):
assert await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
assert not hass.data.get(DOMAIN)
@pytest.mark.parametrize(
("method", "exc", "entry_state"),
[
("authenticate", UnauthorizedError, ConfigEntryState.SETUP_ERROR),
("authenticate", TractiveError, ConfigEntryState.SETUP_RETRY),
("trackable_objects", TractiveError, ConfigEntryState.SETUP_RETRY),
],
)
async def test_setup_failed(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
method: str,
exc: Exception,
entry_state: ConfigEntryState,
) -> None:
"""Test for setup failure."""
getattr(mock_tractive_client, method).side_effect = exc
await init_integration(hass, mock_config_entry)
assert mock_config_entry.state is entry_state
async def test_config_not_ready(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test for setup failure if the tracker_details doesn't contain '_id'."""
mock_tractive_client.tracker.return_value.details.return_value.pop("_id")
await init_integration(hass, mock_config_entry)
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
async def test_trackable_without_details(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test a successful setup entry."""
mock_tractive_client.trackable_objects.return_value[0].details.return_value = {
"device_id": "xyz098"
}
await init_integration(hass, mock_config_entry)
assert (
"Tracker xyz098 has no details and will be skipped. This happens for shared trackers"
in caplog.text
)
assert mock_config_entry.state is ConfigEntryState.LOADED
async def test_trackable_without_device_id(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test a successful setup entry."""
mock_tractive_client.trackable_objects.return_value[0].details.return_value = {
"device_id": None
}
await init_integration(hass, mock_config_entry)
assert mock_config_entry.state is ConfigEntryState.LOADED
async def test_unsubscribe_on_ha_stop(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test unsuscribe when HA stops."""
await init_integration(hass, mock_config_entry)
with patch(
"homeassistant.components.tractive.TractiveClient.unsubscribe"
) as mock_unsuscribe:
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
await hass.async_block_till_done()
assert mock_unsuscribe.called
async def test_server_unavailable(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test states of the sensor."""
entity_id = "sensor.test_pet_tracker_battery"
await init_integration(hass, mock_config_entry)
# send event to make the entity available
mock_tractive_client.send_hardware_event(mock_config_entry)
await hass.async_block_till_done()
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE
# send server unavailable event, the entity should be unavailable
mock_tractive_client.send_server_unavailable_event(hass)
await hass.async_block_till_done()
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
# send event to make the entity available once again
mock_tractive_client.send_hardware_event(mock_config_entry)
await hass.async_block_till_done()
assert hass.states.get(entity_id).state != STATE_UNAVAILABLE

View File

@ -0,0 +1,30 @@
"""Test the Tractive sensor platform."""
from unittest.mock import AsyncMock, patch
from syrupy import SnapshotAssertion
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import init_integration
from tests.common import MockConfigEntry, snapshot_platform
async def test_sensor(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test states of the sensor."""
with patch("homeassistant.components.tractive.PLATFORMS", [Platform.SENSOR]):
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_hardware_event(mock_config_entry)
mock_tractive_client.send_wellness_event(mock_config_entry)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)

View File

@ -0,0 +1,228 @@
"""Test the Tractive switch platform."""
from unittest.mock import AsyncMock, patch
from aiotractive.exceptions import TractiveError
from syrupy import SnapshotAssertion
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
Platform,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import init_integration
from tests.common import MockConfigEntry, snapshot_platform
async def test_switch(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test states of the switch."""
with patch("homeassistant.components.tractive.PLATFORMS", [Platform.SWITCH]):
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_switch_event(mock_config_entry)
await hass.async_block_till_done()
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
async def test_switch_on(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the switch can be turned on."""
entity_id = "switch.test_pet_tracker_led"
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_switch_event(mock_config_entry)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OFF
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_tractive_client.send_switch_event(
mock_config_entry,
{"tracker_id": "device_id_123", "led_control": {"active": True}},
)
await hass.async_block_till_done()
assert mock_tractive_client.tracker.return_value.set_led_active.call_count == 1
assert (
mock_tractive_client.tracker.return_value.set_led_active.call_args[0][0] is True
)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_ON
async def test_switch_off(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the switch can be turned off."""
entity_id = "switch.test_pet_tracker_buzzer"
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_switch_event(mock_config_entry)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_ON
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_tractive_client.send_switch_event(
mock_config_entry,
{"tracker_id": "device_id_123", "buzzer_control": {"active": False}},
)
await hass.async_block_till_done()
assert mock_tractive_client.tracker.return_value.set_buzzer_active.call_count == 1
assert (
mock_tractive_client.tracker.return_value.set_buzzer_active.call_args[0][0]
is False
)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OFF
async def test_live_tracking_switch(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the live_tracking switch."""
entity_id = "switch.test_pet_live_tracking"
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_switch_event(mock_config_entry)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_ON
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
mock_tractive_client.send_switch_event(
mock_config_entry,
{"tracker_id": "device_id_123", "live_tracking": {"active": False}},
)
await hass.async_block_till_done()
assert (
mock_tractive_client.tracker.return_value.set_live_tracking_active.call_count
== 1
)
assert (
mock_tractive_client.tracker.return_value.set_live_tracking_active.call_args[0][
0
]
is False
)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OFF
async def test_switch_on_with_exception(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the switch turn on with exception."""
entity_id = "switch.test_pet_tracker_led"
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_switch_event(mock_config_entry)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OFF
mock_tractive_client.tracker.return_value.set_led_active.side_effect = TractiveError
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OFF
async def test_switch_off_with_exception(
hass: HomeAssistant,
mock_tractive_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test the switch turn off with exception."""
entity_id = "switch.test_pet_tracker_buzzer"
await init_integration(hass, mock_config_entry)
mock_tractive_client.send_switch_event(mock_config_entry)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_ON
mock_tractive_client.tracker.return_value.set_buzzer_active.side_effect = (
TractiveError
)
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_ON