mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 07:51:46 -05:00
Refactor picnic tests (#181165)
This commit is contained in:
@@ -1 +1,13 @@
|
||||
"""Tests for the Picnic integration."""
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
|
||||
"""Fixture for setting up the component."""
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -0,0 +1,883 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[sensor.mock_title_cart_items_count-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_cart_items_count',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Cart items count',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Cart items count',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'cart_items_count',
|
||||
'unique_id': '295-6y3-1nf4.cart_items_count',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_cart_items_count-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Cart items count',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_cart_items_count',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '10',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_cart_total_price-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_cart_total_price',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Cart total price',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Cart total price',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'cart_total_price',
|
||||
'unique_id': '295-6y3-1nf4.cart_total_price',
|
||||
'unit_of_measurement': '€',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_cart_total_price-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Cart total price',
|
||||
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '€',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_cart_total_price',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '25.35',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_end_of_last_order_s_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_end_of_last_order_s_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': "End of last order's slot",
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': "End of last order's slot",
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_order_slot_end',
|
||||
'unique_id': '295-6y3-1nf4.last_order_slot_end',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_end_of_last_order_s_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: "Mock Title End of last order's slot",
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_end_of_last_order_s_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2021-02-26T20:15:00+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_end_of_next_delivery_s_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_end_of_next_delivery_s_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': "End of next delivery's slot",
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': "End of next delivery's slot",
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'next_delivery_slot_end',
|
||||
'unique_id': '295-6y3-1nf4.next_delivery_slot_end',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_end_of_next_delivery_s_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: "Mock Title End of next delivery's slot",
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_end_of_next_delivery_s_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_end_of_selected_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_end_of_selected_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'End of selected slot',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'End of selected slot',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'selected_slot_end',
|
||||
'unique_id': '295-6y3-1nf4.selected_slot_end',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_end_of_selected_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title End of selected slot',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_end_of_selected_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2021-03-03T14:45:00+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_estimated_arrival_of_next_delivery-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_estimated_arrival_of_next_delivery',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Estimated arrival of next delivery',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Estimated arrival of next delivery',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'next_delivery_estimated_arrival',
|
||||
'unique_id': '295-6y3-1nf4.next_delivery_estimated_arrival',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_estimated_arrival_of_next_delivery-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Estimated arrival of next delivery',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_estimated_arrival_of_next_delivery',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_expected_end_of_next_delivery-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_expected_end_of_next_delivery',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Expected end of next delivery',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Expected end of next delivery',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'next_delivery_eta_end',
|
||||
'unique_id': '295-6y3-1nf4.next_delivery_eta_end',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_expected_end_of_next_delivery-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Expected end of next delivery',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_expected_end_of_next_delivery',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_expected_start_of_next_delivery-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_expected_start_of_next_delivery',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Expected start of next delivery',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Expected start of next delivery',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'next_delivery_eta_start',
|
||||
'unique_id': '295-6y3-1nf4.next_delivery_eta_start',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_expected_start_of_next_delivery-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Expected start of next delivery',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_expected_start_of_next_delivery',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_last_order_delivery_time-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_last_order_delivery_time',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Last order delivery time',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Last order delivery time',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_order_delivery_time',
|
||||
'unique_id': '295-6y3-1nf4.last_order_delivery_time',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_last_order_delivery_time-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Last order delivery time',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_last_order_delivery_time',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2021-02-26T19:54:05+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_max_order_time_of_last_order-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_max_order_time_of_last_order',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Max order time of last order',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Max order time of last order',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_order_max_order_time',
|
||||
'unique_id': '295-6y3-1nf4.last_order_max_order_time',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_max_order_time_of_last_order-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Max order time of last order',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_max_order_time_of_last_order',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2021-02-25T21:00:00+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_max_order_time_of_selected_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_max_order_time_of_selected_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Max order time of selected slot',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Max order time of selected slot',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'selected_slot_max_order_time',
|
||||
'unique_id': '295-6y3-1nf4.selected_slot_max_order_time',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_max_order_time_of_selected_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Max order time of selected slot',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_max_order_time_of_selected_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2021-03-02T21:00:00+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_minimum_order_value_for_selected_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_minimum_order_value_for_selected_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Minimum order value for selected slot',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Minimum order value for selected slot',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'selected_slot_min_order_value',
|
||||
'unique_id': '295-6y3-1nf4.selected_slot_min_order_value',
|
||||
'unit_of_measurement': '€',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_minimum_order_value_for_selected_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Minimum order value for selected slot',
|
||||
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '€',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_minimum_order_value_for_selected_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '35.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_start_of_last_order_s_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_start_of_last_order_s_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': "Start of last order's slot",
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': "Start of last order's slot",
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_order_slot_start',
|
||||
'unique_id': '295-6y3-1nf4.last_order_slot_start',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_start_of_last_order_s_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: "Mock Title Start of last order's slot",
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_start_of_last_order_s_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2021-02-26T19:15:00+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_start_of_next_delivery_s_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_start_of_next_delivery_s_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': "Start of next delivery's slot",
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': "Start of next delivery's slot",
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'next_delivery_slot_start',
|
||||
'unique_id': '295-6y3-1nf4.next_delivery_slot_start',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_start_of_next_delivery_s_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: "Mock Title Start of next delivery's slot",
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_start_of_next_delivery_s_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_start_of_selected_slot-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_start_of_selected_slot',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Start of selected slot',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Start of selected slot',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'selected_slot_start',
|
||||
'unique_id': '295-6y3-1nf4.selected_slot_start',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_start_of_selected_slot-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'timestamp',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Start of selected slot',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_start_of_selected_slot',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2021-03-03T13:45:00+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_status_of_last_order-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_status_of_last_order',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Status of last order',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Status of last order',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_order_status',
|
||||
'unique_id': '295-6y3-1nf4.last_order_status',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_status_of_last_order-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Status of last order',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_status_of_last_order',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'COMPLETED',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_total_price_of_last_order-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.mock_title_total_price_of_last_order',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Total price of last order',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Total price of last order',
|
||||
'platform': 'picnic',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'last_order_total_price',
|
||||
'unique_id': '295-6y3-1nf4.last_order_total_price',
|
||||
'unit_of_measurement': '€',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.mock_title_total_price_of_last_order-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.ATTRIBUTION: 'attribution'>: 'Data provided by Picnic',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mock Title Total price of last order',
|
||||
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '€',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_title_total_price_of_last_order',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '41.33',
|
||||
})
|
||||
# ---
|
||||
@@ -1,628 +1,373 @@
|
||||
"""The tests for the Picnic sensor platform."""
|
||||
|
||||
import copy
|
||||
from datetime import timedelta
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
from python_picnic_api2.models import Cart, DeliverySummary, User
|
||||
from python_picnic_api2.models import DeliverySummary, Eta
|
||||
import requests
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.picnic import const
|
||||
from homeassistant.components.picnic.const import DOMAIN
|
||||
from homeassistant.components.picnic.sensor import SENSOR_TYPES
|
||||
from homeassistant.components.sensor import SensorDeviceClass
|
||||
from homeassistant.components.picnic.const import DEFAULT_UPDATE_INTERVAL, DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
CONF_ACCESS_TOKEN,
|
||||
CONF_COUNTRY_CODE,
|
||||
CURRENCY_EURO,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_time_changed,
|
||||
async_test_home_assistant,
|
||||
)
|
||||
from . import setup_integration
|
||||
|
||||
DEFAULT_USER_RESPONSE = {
|
||||
"user_id": "295-6y3-1nf4",
|
||||
"firstname": "User",
|
||||
"lastname": "Name",
|
||||
"address": {
|
||||
"house_number": 123,
|
||||
"house_number_ext": "a",
|
||||
"postcode": "4321 AB",
|
||||
"street": "Commonstreet",
|
||||
"city": "Somewhere",
|
||||
},
|
||||
"total_deliveries": 123,
|
||||
"completed_deliveries": 112,
|
||||
}
|
||||
DEFAULT_CART_RESPONSE = {
|
||||
"items": [],
|
||||
"delivery_slots": [
|
||||
{
|
||||
"slot_id": "611a3b074872b23576bef456a",
|
||||
"window_start": "2021-03-03T14:45:00.000+01:00",
|
||||
"window_end": "2021-03-03T15:45:00.000+01:00",
|
||||
"cut_off_time": "2021-03-02T22:00:00.000+01:00",
|
||||
"minimum_order_value": 3500,
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def enable_all_entities(entity_registry_enabled_by_default: None) -> None:
|
||||
"""Make sure all entities are enabled."""
|
||||
|
||||
|
||||
async def test_all_entities(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test all entities."""
|
||||
with patch("homeassistant.components.picnic.PLATFORMS", [Platform.SENSOR]):
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_setup_platform_not_available(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the set-up of the sensor platform if API is not available."""
|
||||
mock_picnic_api.get_user.side_effect = requests.exceptions.ConnectionError
|
||||
mock_picnic_api.get_cart.side_effect = requests.exceptions.ConnectionError
|
||||
mock_picnic_api.get_deliveries.side_effect = requests.exceptions.ConnectionError
|
||||
mock_picnic_api.get_delivery_position.side_effect = (
|
||||
requests.exceptions.ConnectionError
|
||||
)
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
assert hass.states.get("sensor.mock_title_max_order_time_of_selected_slot") is None
|
||||
assert hass.states.get("sensor.mock_title_status_of_last_order") is None
|
||||
assert hass.states.get("sensor.mock_title_total_price_of_last_order") is None
|
||||
|
||||
|
||||
async def test_sensors_no_selected_time_slot(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test sensor states with no explicit selected time slot."""
|
||||
cart = mock_picnic_api.get_cart.return_value
|
||||
cart.selected_slot.state = "IMPLICIT"
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_start_of_selected_slot").state
|
||||
== STATE_UNKNOWN
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_end_of_selected_slot").state == STATE_UNKNOWN
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_max_order_time_of_selected_slot").state
|
||||
== STATE_UNKNOWN
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_minimum_order_value_for_selected_slot").state
|
||||
== STATE_UNKNOWN
|
||||
)
|
||||
|
||||
|
||||
async def test_next_delivery_sensors(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test sensor states when last order is not yet delivered."""
|
||||
delivery = mock_picnic_api.get_deliveries.return_value[0]
|
||||
delivery.raw["delivery_time"] = None
|
||||
delivery.status = "CURRENT"
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_last_order_delivery_time").state
|
||||
== STATE_UNKNOWN
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_start_of_next_delivery").state
|
||||
== "2021-02-26T19:54:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_end_of_next_delivery").state
|
||||
== "2021-02-26T20:14:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_start_of_next_delivery_s_slot").state
|
||||
== "2021-02-26T19:15:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_end_of_next_delivery_s_slot").state
|
||||
== "2021-02-26T20:15:00+00:00"
|
||||
)
|
||||
|
||||
|
||||
async def test_sensors_eta_date_malformed(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test sensor states when last order eta dates are malformed."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
delivery = mock_picnic_api.get_deliveries.return_value[0]
|
||||
delivery.eta2 = Eta(start="wrong-time", end="other-malformed-datetime")
|
||||
delivery.status = "CURRENT"
|
||||
|
||||
freezer.tick(DEFAULT_UPDATE_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_start_of_next_delivery").state
|
||||
== STATE_UNKNOWN
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_end_of_next_delivery").state
|
||||
== STATE_UNKNOWN
|
||||
)
|
||||
|
||||
|
||||
async def test_sensors_use_detailed_eta_if_available(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test sensor states use the more precise delivery position ETA."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
delivery = mock_picnic_api.get_deliveries.return_value[0]
|
||||
delivery.raw["delivery_time"] = None
|
||||
delivery.status = "CURRENT"
|
||||
mock_picnic_api.get_delivery_position.return_value = {
|
||||
"eta_window": {
|
||||
"start": "2021-03-05T10:19:20.452+00:00",
|
||||
"end": "2021-03-05T10:39:20.452+00:00",
|
||||
},
|
||||
],
|
||||
"selected_slot": {"slot_id": "611a3b074872b23576bef456a", "state": "EXPLICIT"},
|
||||
"total_count": 10,
|
||||
"total_price": 2535,
|
||||
}
|
||||
DEFAULT_DELIVERY_RESPONSE = {
|
||||
"delivery_id": "z28fjso23e",
|
||||
"creation_time": "2021-02-24T21:48:46.395+01:00",
|
||||
"slot": {
|
||||
"slot_id": "602473859a40dc24c6b65879",
|
||||
"hub_id": "AMS",
|
||||
"window_start": "2021-02-26T20:15:00.000+01:00",
|
||||
"window_end": "2021-02-26T21:15:00.000+01:00",
|
||||
"cut_off_time": "2021-02-25T22:00:00.000+01:00",
|
||||
"minimum_order_value": 3500,
|
||||
},
|
||||
"eta2": {
|
||||
"start": "2021-02-26T20:54:00.000+01:00",
|
||||
"end": "2021-02-26T21:14:00.000+01:00",
|
||||
},
|
||||
"status": "COMPLETED",
|
||||
"delivery_time": {
|
||||
"start": "2021-02-26T20:54:05.221+01:00",
|
||||
"end": "2021-02-26T20:58:31.802+01:00",
|
||||
},
|
||||
"orders": [
|
||||
{
|
||||
"creation_time": "2021-02-24T21:48:46.418+01:00",
|
||||
"total_price": 3597,
|
||||
},
|
||||
{
|
||||
"creation_time": "2021-02-25T17:10:26.816+01:00",
|
||||
"total_price": 536,
|
||||
},
|
||||
],
|
||||
}
|
||||
"eta": 1614941090000,
|
||||
}
|
||||
|
||||
SENSOR_KEYS = [desc.key for desc in SENSOR_TYPES]
|
||||
freezer.tick(DEFAULT_UPDATE_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
mock_picnic_api.get_delivery_position.assert_called_with(delivery.delivery_id)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_start_of_next_delivery").state
|
||||
== "2021-03-05T10:19:20+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_end_of_next_delivery").state
|
||||
== "2021-03-05T10:39:20+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_estimated_arrival_of_next_delivery").state
|
||||
== "2021-03-05T10:44:50+00:00"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("hass_storage")
|
||||
class TestPicnicSensor(unittest.IsolatedAsyncioTestCase):
|
||||
"""Test the Picnic sensor."""
|
||||
async def test_sensors_no_data(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test sensor states when the api only returns empty objects."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
async def asyncSetUp(self):
|
||||
"""Set up things to be run when tests are started."""
|
||||
self._manager = async_test_home_assistant()
|
||||
self.hass = await self._manager.__aenter__()
|
||||
self.entity_registry = er.async_get(self.hass)
|
||||
mock_picnic_api.get_user.return_value = {}
|
||||
mock_picnic_api.get_cart.return_value = None
|
||||
mock_picnic_api.get_deliveries.return_value = None
|
||||
mock_picnic_api.get_delivery_position.side_effect = ValueError
|
||||
|
||||
# Patch the api client
|
||||
self.picnic_patcher = patch("homeassistant.components.picnic.PicnicAPI")
|
||||
self.picnic_mock = self.picnic_patcher.start()
|
||||
self.picnic_mock().session.auth_token = "3q29fpwhulzes"
|
||||
freezer.tick(DEFAULT_UPDATE_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
# Add a config entry and setup the integration
|
||||
config_data = {
|
||||
CONF_ACCESS_TOKEN: "x-original-picnic-auth-token",
|
||||
CONF_COUNTRY_CODE: "NL",
|
||||
}
|
||||
self.config_entry = MockConfigEntry(
|
||||
domain=const.DOMAIN,
|
||||
data=config_data,
|
||||
unique_id="295-6y3-1nf4",
|
||||
)
|
||||
self.config_entry.add_to_hass(self.hass)
|
||||
|
||||
async def asyncTearDown(self):
|
||||
"""Tear down the test setup, stop hass/patchers."""
|
||||
await self.hass.async_stop(force=True)
|
||||
await self._manager.__aexit__(None, None, None)
|
||||
self.picnic_patcher.stop()
|
||||
|
||||
@property
|
||||
def _coordinator(self):
|
||||
return self.config_entry.runtime_data
|
||||
|
||||
def _assert_sensor(self, name, state=None, cls=None, unit=None, disabled=False):
|
||||
sensor = self.hass.states.get(name)
|
||||
if disabled:
|
||||
assert sensor is None
|
||||
return
|
||||
|
||||
assert sensor.state == state
|
||||
if cls:
|
||||
assert sensor.attributes["device_class"] == cls
|
||||
if unit:
|
||||
assert sensor.attributes["unit_of_measurement"] == unit
|
||||
|
||||
assert sensor.attributes["attribution"] == "Data provided by Picnic"
|
||||
|
||||
async def _setup_platform(
|
||||
self, use_default_responses=False, enable_all_sensors=True
|
||||
for entity_id in (
|
||||
"sensor.mock_title_cart_total_price",
|
||||
"sensor.mock_title_start_of_selected_slot",
|
||||
"sensor.mock_title_end_of_selected_slot",
|
||||
"sensor.mock_title_max_order_time_of_selected_slot",
|
||||
"sensor.mock_title_minimum_order_value_for_selected_slot",
|
||||
"sensor.mock_title_max_order_time_of_last_order",
|
||||
"sensor.mock_title_last_order_delivery_time",
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
):
|
||||
"""Set up the Picnic sensor platform."""
|
||||
if use_default_responses:
|
||||
self.picnic_mock().get_user.return_value = User.from_api(
|
||||
copy.deepcopy(DEFAULT_USER_RESPONSE)
|
||||
)
|
||||
self.picnic_mock().get_cart.return_value = Cart.from_api(
|
||||
copy.deepcopy(DEFAULT_CART_RESPONSE)
|
||||
)
|
||||
self.picnic_mock().get_deliveries.return_value = [
|
||||
DeliverySummary.from_api(copy.deepcopy(DEFAULT_DELIVERY_RESPONSE))
|
||||
]
|
||||
self.picnic_mock().get_delivery_position.return_value = {}
|
||||
assert hass.states.get(entity_id).state == STATE_UNAVAILABLE
|
||||
|
||||
await self.hass.config_entries.async_setup(self.config_entry.entry_id)
|
||||
await self.hass.async_block_till_done()
|
||||
|
||||
if enable_all_sensors:
|
||||
await self._enable_all_sensors()
|
||||
async def test_sensors_malformed_delivery_data(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test sensor states when the delivery api returns not a list."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
async def _enable_all_sensors(self):
|
||||
"""Enable all sensors of the Picnic integration."""
|
||||
# Enable the sensors
|
||||
for sensor_type in SENSOR_KEYS:
|
||||
entry = self.entity_registry.async_get_or_create(
|
||||
Platform.SENSOR, DOMAIN, f"{self.config_entry.unique_id}.{sensor_type}"
|
||||
)
|
||||
updated_entry = self.entity_registry.async_update_entity(
|
||||
entry.entity_id, disabled_by=None
|
||||
)
|
||||
assert updated_entry.disabled is False
|
||||
await self.hass.async_block_till_done()
|
||||
mock_picnic_api.get_deliveries.return_value = {"error": "message"}
|
||||
|
||||
# Trigger a reload of the data
|
||||
async_fire_time_changed(
|
||||
self.hass,
|
||||
dt_util.utcnow()
|
||||
+ timedelta(seconds=config_entries.RELOAD_AFTER_UPDATE_DELAY + 1),
|
||||
)
|
||||
await self.hass.async_block_till_done()
|
||||
freezer.tick(DEFAULT_UPDATE_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
async def test_sensor_setup_platform_not_available(self):
|
||||
"""Test the set-up of the sensor platform if API is not available."""
|
||||
# Configure mock requests to yield exceptions
|
||||
self.picnic_mock().get_user.side_effect = requests.exceptions.ConnectionError
|
||||
self.picnic_mock().get_cart.side_effect = requests.exceptions.ConnectionError
|
||||
self.picnic_mock().get_deliveries.side_effect = (
|
||||
requests.exceptions.ConnectionError
|
||||
)
|
||||
self.picnic_mock().get_delivery_position.side_effect = (
|
||||
requests.exceptions.ConnectionError
|
||||
)
|
||||
await self._setup_platform(enable_all_sensors=False)
|
||||
for entity_id in (
|
||||
"sensor.mock_title_max_order_time_of_last_order",
|
||||
"sensor.mock_title_last_order_delivery_time",
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
):
|
||||
assert hass.states.get(entity_id).state == STATE_UNKNOWN
|
||||
|
||||
# Assert that sensors are not set up
|
||||
assert (
|
||||
self.hass.states.get("sensor.mock_title_max_order_time_of_selected_slot")
|
||||
is None
|
||||
)
|
||||
assert self.hass.states.get("sensor.mock_title_status_of_last_order") is None
|
||||
assert (
|
||||
self.hass.states.get("sensor.mock_title_total_price_of_last_order") is None
|
||||
)
|
||||
|
||||
async def test_sensors_setup(self):
|
||||
"""Test the default sensor setup behaviour."""
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
async def test_sensors_malformed_response(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test sensors become unavailable when the API yields ValueError."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
self._assert_sensor("sensor.mock_title_cart_items_count", "10")
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_cart_total_price",
|
||||
"25.35",
|
||||
unit=CURRENCY_EURO,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_selected_slot",
|
||||
"2021-03-03T13:45:00+00:00",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_end_of_selected_slot",
|
||||
"2021-03-03T14:45:00+00:00",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_max_order_time_of_selected_slot",
|
||||
"2021-03-02T21:00:00+00:00",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_minimum_order_value_for_selected_slot",
|
||||
"35.0",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_last_order_s_slot",
|
||||
"2021-02-26T19:15:00+00:00",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_end_of_last_order_s_slot",
|
||||
"2021-02-26T20:15:00+00:00",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor("sensor.mock_title_status_of_last_order", "COMPLETED")
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_max_order_time_of_last_order",
|
||||
"2021-02-25T21:00:00+00:00",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_last_order_delivery_time",
|
||||
"2021-02-26T19:54:05+00:00",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_total_price_of_last_order",
|
||||
"41.33",
|
||||
unit=CURRENCY_EURO,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
"unknown",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
"unknown",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_next_delivery_s_slot",
|
||||
"unknown",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_end_of_next_delivery_s_slot",
|
||||
"unknown",
|
||||
cls=SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
mock_picnic_api.get_user.side_effect = ValueError
|
||||
mock_picnic_api.get_cart.side_effect = ValueError
|
||||
|
||||
async def test_sensors_setup_disabled_by_default(self):
|
||||
"""Test that some sensors are disabled by default."""
|
||||
await self._setup_platform(use_default_responses=True, enable_all_sensors=False)
|
||||
freezer.tick(DEFAULT_UPDATE_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
self._assert_sensor("sensor.mock_title_cart_items_count", disabled=True)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_last_order_s_slot", disabled=True
|
||||
)
|
||||
self._assert_sensor("sensor.mock_title_end_of_last_order_s_slot", disabled=True)
|
||||
self._assert_sensor("sensor.mock_title_status_of_last_order", disabled=True)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_total_price_of_last_order", disabled=True
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_next_delivery_s_slot",
|
||||
disabled=True,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_end_of_next_delivery_s_slot", disabled=True
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_cart_total_price").state == STATE_UNAVAILABLE
|
||||
)
|
||||
|
||||
async def test_sensors_no_selected_time_slot(self):
|
||||
"""Test sensor states with no explicit selected time slot."""
|
||||
# Adjust cart response
|
||||
cart_response = copy.deepcopy(DEFAULT_CART_RESPONSE)
|
||||
cart_response["selected_slot"]["state"] = "IMPLICIT"
|
||||
|
||||
# Set mock responses
|
||||
self.picnic_mock().get_user.return_value = User.from_api(
|
||||
copy.deepcopy(DEFAULT_USER_RESPONSE)
|
||||
)
|
||||
self.picnic_mock().get_cart.return_value = Cart.from_api(cart_response)
|
||||
self.picnic_mock().get_deliveries.return_value = [
|
||||
DeliverySummary.from_api(copy.deepcopy(DEFAULT_DELIVERY_RESPONSE))
|
||||
]
|
||||
self.picnic_mock().get_delivery_position.return_value = {}
|
||||
await self._setup_platform()
|
||||
async def test_multiple_active_orders(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test sensor values with multiple active orders."""
|
||||
completed = mock_picnic_api.get_deliveries.return_value[0]
|
||||
|
||||
# Assert sensors are unknown
|
||||
self._assert_sensor("sensor.mock_title_start_of_selected_slot", STATE_UNKNOWN)
|
||||
self._assert_sensor("sensor.mock_title_end_of_selected_slot", STATE_UNKNOWN)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_max_order_time_of_selected_slot",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_minimum_order_value_for_selected_slot",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
def _undelivered(window_start: str, window_end: str, eta_start: str, eta_end: str):
|
||||
order = DeliverySummary.from_api(completed.raw.copy())
|
||||
order.raw["delivery_time"] = None
|
||||
order.status = "CURRENT"
|
||||
order.slot.window_start = window_start
|
||||
order.slot.window_end = window_end
|
||||
order.eta2 = Eta(start=eta_start, end=eta_end)
|
||||
return order
|
||||
|
||||
async def test_next_delivery_sensors(self):
|
||||
"""Test sensor states when last order is not yet delivered."""
|
||||
# Adjust default delivery response
|
||||
delivery_response = copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)
|
||||
del delivery_response["delivery_time"]
|
||||
delivery_response["status"] = "CURRENT"
|
||||
undelivered_order = _undelivered(
|
||||
"2022-03-01T09:15:00.000+01:00",
|
||||
"2022-03-01T10:15:00.000+01:00",
|
||||
"2022-03-01T09:30:00.000+01:00",
|
||||
"2022-03-01T09:45:00.000+01:00",
|
||||
)
|
||||
undelivered_order_2 = _undelivered(
|
||||
"2022-03-08T13:15:00.000+01:00",
|
||||
"2022-03-08T14:15:00.000+01:00",
|
||||
"2022-03-08T13:30:00.000+01:00",
|
||||
"2022-03-08T13:45:00.000+01:00",
|
||||
)
|
||||
|
||||
# Set mock responses
|
||||
self.picnic_mock().get_user.return_value = User.from_api(
|
||||
copy.deepcopy(DEFAULT_USER_RESPONSE)
|
||||
)
|
||||
self.picnic_mock().get_cart.return_value = Cart.from_api(
|
||||
copy.deepcopy(DEFAULT_CART_RESPONSE)
|
||||
)
|
||||
self.picnic_mock().get_deliveries.return_value = [
|
||||
DeliverySummary.from_api(delivery_response)
|
||||
]
|
||||
self.picnic_mock().get_delivery_position.return_value = {}
|
||||
await self._setup_platform()
|
||||
mock_picnic_api.get_deliveries.return_value = [
|
||||
undelivered_order_2,
|
||||
undelivered_order,
|
||||
completed,
|
||||
]
|
||||
mock_picnic_api.get_delivery_position.return_value = {}
|
||||
|
||||
# Assert delivery time is not available, but eta is
|
||||
self._assert_sensor("sensor.mock_title_last_order_delivery_time", STATE_UNKNOWN)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
"2021-02-26T19:54:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
"2021-02-26T20:14:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_next_delivery_s_slot",
|
||||
"2021-02-26T19:15:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_end_of_next_delivery_s_slot",
|
||||
"2021-02-26T20:15:00+00:00",
|
||||
)
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
async def test_sensors_eta_date_malformed(self):
|
||||
"""Test sensor states when last order eta dates are malformed."""
|
||||
# Set-up platform with default mock responses
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_start_of_last_order_s_slot").state
|
||||
== "2022-03-08T12:15:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_end_of_last_order_s_slot").state
|
||||
== "2022-03-08T13:15:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_start_of_next_delivery_s_slot").state
|
||||
== "2022-03-01T08:15:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_end_of_next_delivery_s_slot").state
|
||||
== "2022-03-01T09:15:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_start_of_next_delivery").state
|
||||
== "2022-03-01T08:30:00+00:00"
|
||||
)
|
||||
assert (
|
||||
hass.states.get("sensor.mock_title_expected_end_of_next_delivery").state
|
||||
== "2022-03-01T08:45:00+00:00"
|
||||
)
|
||||
|
||||
# Set non-datetime strings as eta
|
||||
eta_dates: dict[str, str] = {
|
||||
"start": "wrong-time",
|
||||
"end": "other-malformed-datetime",
|
||||
}
|
||||
delivery_response = copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)
|
||||
delivery_response["eta2"] = eta_dates
|
||||
delivery_response["status"] = "CURRENT"
|
||||
self.picnic_mock().get_deliveries.return_value = [
|
||||
DeliverySummary.from_api(delivery_response)
|
||||
]
|
||||
await self._coordinator.async_refresh()
|
||||
|
||||
# Assert eta times are not available due to malformed date strings
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
async def test_device_registry_entry(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test if device registry entry is populated correctly."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
async def test_sensors_use_detailed_eta_if_available(self):
|
||||
"""Test sensor states when last order is not yet delivered."""
|
||||
# Set-up platform with default mock responses
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
picnic_service = device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "295-6y3-1nf4"),
|
||||
mock_config_entry.entry_id,
|
||||
)
|
||||
assert picnic_service.model == "295-6y3-1nf4"
|
||||
assert picnic_service.name == "Mock Title"
|
||||
assert picnic_service.entry_type is dr.DeviceEntryType.SERVICE
|
||||
|
||||
# Provide a delivery position response with different ETA
|
||||
# and remove delivery time from response
|
||||
delivery_response = copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)
|
||||
del delivery_response["delivery_time"]
|
||||
delivery_response["status"] = "CURRENT"
|
||||
self.picnic_mock().get_deliveries.return_value = [
|
||||
DeliverySummary.from_api(delivery_response)
|
||||
]
|
||||
self.picnic_mock().get_delivery_position.return_value = {
|
||||
"eta_window": {
|
||||
"start": "2021-03-05T10:19:20.452+00:00",
|
||||
"end": "2021-03-05T10:39:20.452+00:00",
|
||||
},
|
||||
"eta": 1614941090000,
|
||||
}
|
||||
await self._coordinator.async_refresh()
|
||||
|
||||
# Assert detailed ETA is used
|
||||
self.picnic_mock().get_delivery_position.assert_called_with(
|
||||
delivery_response["delivery_id"]
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
"2021-03-05T10:19:20+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
"2021-03-05T10:39:20+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_estimated_arrival_of_next_delivery",
|
||||
"2021-03-05T10:44:50+00:00",
|
||||
)
|
||||
async def test_auth_token_is_saved_on_update(
|
||||
hass: HomeAssistant,
|
||||
mock_picnic_api: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test auth-token changes are reflected by the config entry."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
# The live estimate is cleared again once position data disappears
|
||||
self.picnic_mock().get_delivery_position.return_value = {}
|
||||
async_fire_time_changed(self.hass, dt_util.utcnow() + timedelta(minutes=31))
|
||||
await self.hass.async_block_till_done(wait_background_tasks=True)
|
||||
updated_auth_token = "x-updated-picnic-auth-token"
|
||||
mock_picnic_api.session.auth_token = updated_auth_token
|
||||
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_estimated_arrival_of_next_delivery",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
assert mock_config_entry.data.get(CONF_ACCESS_TOKEN) != updated_auth_token
|
||||
|
||||
async def test_sensors_no_data(self):
|
||||
"""Test sensor states when the api only returns empty objects."""
|
||||
# Setup platform with default responses
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
freezer.tick(DEFAULT_UPDATE_INTERVAL)
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
# Change mock responses to empty data and refresh the coordinator
|
||||
self.picnic_mock().get_user.return_value = {}
|
||||
self.picnic_mock().get_cart.return_value = None
|
||||
self.picnic_mock().get_deliveries.return_value = None
|
||||
self.picnic_mock().get_delivery_position.side_effect = ValueError
|
||||
await self._coordinator.async_refresh()
|
||||
|
||||
# Assert all default-enabled sensors have STATE_UNAVAILABLE
|
||||
# because the last update failed
|
||||
assert self._coordinator.last_update_success is False
|
||||
self._assert_sensor("sensor.mock_title_cart_total_price", STATE_UNAVAILABLE)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_selected_slot", STATE_UNAVAILABLE
|
||||
)
|
||||
self._assert_sensor("sensor.mock_title_end_of_selected_slot", STATE_UNAVAILABLE)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_max_order_time_of_selected_slot",
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_minimum_order_value_for_selected_slot",
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_max_order_time_of_last_order",
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_last_order_delivery_time",
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
|
||||
async def test_sensors_malformed_delivery_data(self):
|
||||
"""Test sensor states when the delivery api returns not a list."""
|
||||
# Setup platform with default responses
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
|
||||
# Change mock responses to empty data and refresh the coordinator
|
||||
self.picnic_mock().get_deliveries.return_value = {"error": "message"}
|
||||
await self._coordinator.async_refresh()
|
||||
|
||||
# Assert all last-order sensors have STATE_UNAVAILABLE
|
||||
# because the delivery info fetch failed
|
||||
assert self._coordinator.last_update_success is True
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_max_order_time_of_last_order",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
self._assert_sensor("sensor.mock_title_last_order_delivery_time", STATE_UNKNOWN)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
|
||||
async def test_sensors_malformed_response(self):
|
||||
"""Test coordinator update fails when API yields ValueError."""
|
||||
# Setup platform with default responses
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
|
||||
# Change mock responses to empty data and refresh the coordinator
|
||||
self.picnic_mock().get_user.side_effect = ValueError
|
||||
self.picnic_mock().get_cart.side_effect = ValueError
|
||||
await self._coordinator.async_refresh()
|
||||
|
||||
# Assert coordinator update failed
|
||||
assert self._coordinator.last_update_success is False
|
||||
|
||||
async def test_multiple_active_orders(self):
|
||||
"""Test sensor values with multiple active orders."""
|
||||
# Create 2 undelivered orders
|
||||
undelivered_order = copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)
|
||||
del undelivered_order["delivery_time"]
|
||||
undelivered_order["status"] = "CURRENT"
|
||||
undelivered_order["slot"]["window_start"] = "2022-03-01T09:15:00.000+01:00"
|
||||
undelivered_order["slot"]["window_end"] = "2022-03-01T10:15:00.000+01:00"
|
||||
undelivered_order["eta2"]["start"] = "2022-03-01T09:30:00.000+01:00"
|
||||
undelivered_order["eta2"]["end"] = "2022-03-01T09:45:00.000+01:00"
|
||||
|
||||
undelivered_order_2 = copy.deepcopy(undelivered_order)
|
||||
undelivered_order_2["slot"]["window_start"] = "2022-03-08T13:15:00.000+01:00"
|
||||
undelivered_order_2["slot"]["window_end"] = "2022-03-08T14:15:00.000+01:00"
|
||||
undelivered_order_2["eta2"]["start"] = "2022-03-08T13:30:00.000+01:00"
|
||||
undelivered_order_2["eta2"]["end"] = "2022-03-08T13:45:00.000+01:00"
|
||||
|
||||
deliveries_response = [
|
||||
DeliverySummary.from_api(undelivered_order_2),
|
||||
DeliverySummary.from_api(undelivered_order),
|
||||
DeliverySummary.from_api(copy.deepcopy(DEFAULT_DELIVERY_RESPONSE)),
|
||||
]
|
||||
|
||||
# Set mock responses
|
||||
self.picnic_mock().get_user.return_value = User.from_api(
|
||||
copy.deepcopy(DEFAULT_USER_RESPONSE)
|
||||
)
|
||||
self.picnic_mock().get_cart.return_value = Cart.from_api(
|
||||
copy.deepcopy(DEFAULT_CART_RESPONSE)
|
||||
)
|
||||
self.picnic_mock().get_deliveries.return_value = deliveries_response
|
||||
self.picnic_mock().get_delivery_position.return_value = {}
|
||||
await self._setup_platform()
|
||||
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_last_order_s_slot",
|
||||
"2022-03-08T12:15:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_end_of_last_order_s_slot",
|
||||
"2022-03-08T13:15:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_start_of_next_delivery_s_slot",
|
||||
"2022-03-01T08:15:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_end_of_next_delivery_s_slot",
|
||||
"2022-03-01T09:15:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_start_of_next_delivery",
|
||||
"2022-03-01T08:30:00+00:00",
|
||||
)
|
||||
self._assert_sensor(
|
||||
"sensor.mock_title_expected_end_of_next_delivery",
|
||||
"2022-03-01T08:45:00+00:00",
|
||||
)
|
||||
|
||||
async def test_device_registry_entry(self):
|
||||
"""Test if device registry entry is populated correctly."""
|
||||
# Setup platform and default mock responses
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
|
||||
device_registry = dr.async_get(self.hass) # pylint: disable=home-assistant-tests-registry-fixtures
|
||||
picnic_service = device_registry.async_get_device_by_identifier(
|
||||
(const.DOMAIN, DEFAULT_USER_RESPONSE["user_id"]),
|
||||
self.config_entry.entry_id,
|
||||
)
|
||||
assert picnic_service.model == DEFAULT_USER_RESPONSE["user_id"]
|
||||
assert picnic_service.name == "Mock Title"
|
||||
assert picnic_service.entry_type is dr.DeviceEntryType.SERVICE
|
||||
|
||||
async def test_auth_token_is_saved_on_update(self):
|
||||
"""Test auth-token changes are reflected by the config entry."""
|
||||
# Setup platform and default mock responses
|
||||
await self._setup_platform(use_default_responses=True)
|
||||
|
||||
# Set a different auth token in the session mock
|
||||
updated_auth_token = "x-updated-picnic-auth-token"
|
||||
self.picnic_mock().session.auth_token = updated_auth_token
|
||||
|
||||
# Verify the updated auth token is not set and fetch data using the coordinator
|
||||
assert self.config_entry.data.get(CONF_ACCESS_TOKEN) != updated_auth_token
|
||||
await self._coordinator.async_refresh()
|
||||
|
||||
# Verify that the updated auth token is saved in the config entry
|
||||
assert self.config_entry.data.get(CONF_ACCESS_TOKEN) == updated_auth_token
|
||||
assert mock_config_entry.data.get(CONF_ACCESS_TOKEN) == updated_auth_token
|
||||
|
||||
Reference in New Issue
Block a user