1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 08:41:59 +00:00

more cover

This commit is contained in:
J. Nick Koston
2025-12-22 21:58:58 -10:00
parent 4bec2dc75c
commit da8e23f968
2 changed files with 92 additions and 24 deletions

View File

@@ -4,6 +4,12 @@ esphome:
# Enable MAC suffix - host MAC is 98:35:69:ab:f6:79, suffix is "abf679"
# friendly_name becomes "Test Device abf679"
name_add_mac_suffix: true
# Sub-devices for testing empty-name entities on devices
devices:
- id: sub_device_1
name: Sub Device One
- id: sub_device_2
name: Sub Device Two
host:
@@ -93,3 +99,27 @@ text_sensor:
id: text_num_start
lambda: return {"test"};
update_interval: 60s
button:
# Test 12: Named entity on sub-device -> object_id from entity name
- platform: template
name: "Device Button"
id: button_on_device
device_id: sub_device_1
on_press: []
# Test 13: Empty name on sub-device -> object_id from device name
# Device name "Sub Device One" -> object_id = "sub_device_one"
- platform: template
name: ""
id: button_empty_on_device1
device_id: sub_device_1
on_press: []
# Test 14: Empty name on different sub-device
# Device name "Sub Device Two" -> object_id = "sub_device_two"
- platform: template
name: ""
id: button_empty_on_device2
device_id: sub_device_2
on_press: []

View File

@@ -14,7 +14,9 @@ See: https://github.com/esphome/backlog/issues/76
Test cases covered:
- Named entities with various characters (uppercase, special chars, hyphens, etc.)
- Empty-name entities (has_own_name=false, uses device's friendly_name)
- Empty-name entities on main device (uses device's friendly_name with MAC suffix)
- Empty-name entities on sub-devices (uses sub-device's name)
- Named entities on sub-devices (uses entity name, not device name)
- MAC suffix handling (name_add_mac_suffix modifies friendly_name at runtime)
- Both object_id string and hash (key) verification
"""
@@ -48,6 +50,15 @@ NAMED_ENTITIES = [
("My Very Long Switch Name Here", "my_very_long_switch_name_here"),
# text_sensor platform
("123 Start", "123_start"),
# button platform - named entity on sub-device (uses entity name, not device name)
("Device Button", "device_button"),
]
# Sub-device names and their expected object_ids for empty-name entities
# Format: (device_name, expected_object_id)
SUB_DEVICE_EMPTY_NAME_ENTITIES = [
("Sub Device One", "sub_device_one"),
("Sub Device Two", "sub_device_two"),
]
@@ -122,47 +133,74 @@ async def test_object_id_api_verification(
f"Python hash {hash_from_name:#x}, API key {entity.key:#x}"
)
# === Test 2: Verify empty-name entity (has_own_name=false) ===
# When entity has no name, the name field is empty in the API message
# and the entity uses device's friendly_name (with MAC suffix) for display
assert "" in entity_map, (
"Empty-name entity not found. "
f"Available entity names: {list(entity_map.keys())}"
)
empty_name_entity = entity_map[""]
# === Test 2: Verify empty-name entities ===
# Empty-name entities have name="" in API, object_id comes from:
# - Main device: friendly_name (with MAC suffix)
# - Sub-device: device name
# object_id is computed from friendly_name (which includes MAC suffix)
expected_object_id_empty = compute_expected_object_id(expected_friendly_name)
assert empty_name_entity.object_id == expected_object_id_empty, (
f"Empty-name entity: object_id mismatch. "
f"API: '{empty_name_entity.object_id}', expected: '{expected_object_id_empty}'"
# Get all empty-name entities
empty_name_entities = [e for e in entities if e.name == ""]
# We expect 3: 1 on main device, 2 on sub-devices
assert len(empty_name_entities) == 3, (
f"Expected 3 empty-name entities, got {len(empty_name_entities)}"
)
# Hash is also computed from friendly_name with MAC suffix
expected_hash_empty = fnv1_hash_object_id(expected_friendly_name)
assert empty_name_entity.key == expected_hash_empty, (
f"Empty-name entity: hash mismatch. "
f"API key: {empty_name_entity.key:#x}, expected: {expected_hash_empty:#x}"
)
# Build device_id -> device_name map from device_info
device_id_to_name = {d.device_id: d.name for d in device_info.devices}
# Verify each empty-name entity
for entity in empty_name_entities:
if entity.device_id == 0:
# Main device - uses friendly_name with MAC suffix
expected_name = expected_friendly_name
else:
# Sub-device - uses device name
assert entity.device_id in device_id_to_name, (
f"Entity device_id {entity.device_id} not found in devices"
)
expected_name = device_id_to_name[entity.device_id]
expected_object_id = compute_expected_object_id(expected_name)
assert entity.object_id == expected_object_id, (
f"Empty-name entity (device_id={entity.device_id}): object_id mismatch. "
f"API: '{entity.object_id}', expected: '{expected_object_id}' "
f"(from name '{expected_name}')"
)
# Verify hash matches
expected_hash = fnv1_hash_object_id(expected_name)
assert entity.key == expected_hash, (
f"Empty-name entity (device_id={entity.device_id}): hash mismatch. "
f"API key: {entity.key:#x}, expected: {expected_hash:#x}"
)
# === Test 3: Verify ALL entities can have object_id computed from API data ===
# This is the key property for removing object_id from the API protocol
for entity in entities:
# Use entity name if present, otherwise device's friendly_name
name_for_object_id = entity.name or device_info.friendly_name
if entity.name:
# Named entity - use entity name
name_for_object_id = entity.name
elif entity.device_id == 0:
# Empty name on main device - use friendly_name
name_for_object_id = device_info.friendly_name
else:
# Empty name on sub-device - use device name
name_for_object_id = device_id_to_name[entity.device_id]
# Compute object_id from the appropriate name
computed_object_id = compute_expected_object_id(name_for_object_id)
# Verify it matches what the API returned
assert entity.object_id == computed_object_id, (
f"Entity (name='{entity.name}'): object_id cannot be computed. "
f"Entity (name='{entity.name}', device_id={entity.device_id}): "
f"object_id cannot be computed. "
f"API: '{entity.object_id}', Computed from '{name_for_object_id}': '{computed_object_id}'"
)
# Verify hash can also be computed
computed_hash = fnv1_hash_object_id(name_for_object_id)
assert entity.key == computed_hash, (
f"Entity (name='{entity.name}'): hash cannot be computed. "
f"Entity (name='{entity.name}', device_id={entity.device_id}): "
f"hash cannot be computed. "
f"API key: {entity.key:#x}, Computed: {computed_hash:#x}"
)