mirror of
https://github.com/home-assistant/core.git
synced 2026-04-20 08:29:39 +02:00
Prevent empty aliases in registries (#156061)
Co-authored-by: J. Diego Rodríguez Royo <jdrr1998@hotmail.com> Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
committed by
Bram Kragten
parent
0547153730
commit
67550731b3
@@ -65,8 +65,10 @@ def websocket_create_area(
|
||||
data.pop("id")
|
||||
|
||||
if "aliases" in data:
|
||||
# Convert aliases to a set
|
||||
data["aliases"] = set(data["aliases"])
|
||||
# Create a set for the aliases without:
|
||||
# - Empty strings
|
||||
# - Trailing and leading whitespace characters in the individual aliases
|
||||
data["aliases"] = {s_strip for s in data["aliases"] if (s_strip := s.strip())}
|
||||
|
||||
if "labels" in data:
|
||||
# Convert labels to a set
|
||||
@@ -133,8 +135,10 @@ def websocket_update_area(
|
||||
data.pop("id")
|
||||
|
||||
if "aliases" in data:
|
||||
# Convert aliases to a set
|
||||
data["aliases"] = set(data["aliases"])
|
||||
# Create a set for the aliases without:
|
||||
# - Empty strings
|
||||
# - Trailing and leading whitespace characters in the individual aliases
|
||||
data["aliases"] = {s_strip for s in data["aliases"] if (s_strip := s.strip())}
|
||||
|
||||
if "labels" in data:
|
||||
# Convert labels to a set
|
||||
|
||||
@@ -227,8 +227,10 @@ def websocket_update_entity(
|
||||
changes[key] = msg[key]
|
||||
|
||||
if "aliases" in msg:
|
||||
# Convert aliases to a set
|
||||
changes["aliases"] = set(msg["aliases"])
|
||||
# Create a set for the aliases without:
|
||||
# - Empty strings
|
||||
# - Trailing and leading whitespace characters in the individual aliases
|
||||
changes["aliases"] = {s_strip for s in msg["aliases"] if (s_strip := s.strip())}
|
||||
|
||||
if "labels" in msg:
|
||||
# Convert labels to a set
|
||||
|
||||
@@ -61,8 +61,10 @@ def websocket_create_floor(
|
||||
data.pop("id")
|
||||
|
||||
if "aliases" in data:
|
||||
# Convert aliases to a set
|
||||
data["aliases"] = set(data["aliases"])
|
||||
# Create a set for the aliases without:
|
||||
# - Empty strings
|
||||
# - Trailing and leading whitespace characters in the individual aliases
|
||||
data["aliases"] = {s_strip for s in data["aliases"] if (s_strip := s.strip())}
|
||||
|
||||
try:
|
||||
entry = registry.async_create(**data)
|
||||
@@ -117,8 +119,10 @@ def websocket_update_floor(
|
||||
data.pop("id")
|
||||
|
||||
if "aliases" in data:
|
||||
# Convert aliases to a set
|
||||
data["aliases"] = set(data["aliases"])
|
||||
# Create a set for the aliases without:
|
||||
# - Empty strings
|
||||
# - Trailing and leading whitespace characters in the individual aliases
|
||||
data["aliases"] = {s_strip for s in data["aliases"] if (s_strip := s.strip())}
|
||||
|
||||
try:
|
||||
entry = registry.async_update(**data)
|
||||
|
||||
@@ -172,6 +172,39 @@ async def test_create_area(
|
||||
}
|
||||
assert len(area_registry.areas) == 2
|
||||
|
||||
# Create area with invalid aliases
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"aliases": [" alias_1 ", "", " "],
|
||||
"floor_id": "first_floor",
|
||||
"icon": "mdi:garage",
|
||||
"labels": ["label_1", "label_2"],
|
||||
"name": "mock 3",
|
||||
"picture": "/image/example.png",
|
||||
"temperature_entity_id": "sensor.mock_temperature",
|
||||
"humidity_entity_id": "sensor.mock_humidity",
|
||||
"type": "config/area_registry/create",
|
||||
}
|
||||
)
|
||||
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["success"]
|
||||
assert msg["result"] == {
|
||||
"aliases": unordered(["alias_1"]),
|
||||
"area_id": ANY,
|
||||
"floor_id": "first_floor",
|
||||
"icon": "mdi:garage",
|
||||
"labels": unordered(["label_1", "label_2"]),
|
||||
"name": "mock 3",
|
||||
"picture": "/image/example.png",
|
||||
"created_at": utcnow().timestamp(),
|
||||
"modified_at": utcnow().timestamp(),
|
||||
"temperature_entity_id": "sensor.mock_temperature",
|
||||
"humidity_entity_id": "sensor.mock_humidity",
|
||||
}
|
||||
assert len(area_registry.areas) == 3
|
||||
|
||||
|
||||
async def test_create_area_with_name_already_in_use(
|
||||
client: MockHAClientWebSocket, area_registry: ar.AreaRegistry
|
||||
@@ -304,6 +337,40 @@ async def test_update_area(
|
||||
}
|
||||
assert len(area_registry.areas) == 1
|
||||
|
||||
modified_at = datetime.fromisoformat("2024-07-16T13:55:00.900075+00:00")
|
||||
freezer.move_to(modified_at)
|
||||
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "config/area_registry/update",
|
||||
"aliases": ["alias_1", "", " ", " alias_2 "],
|
||||
"area_id": area.id,
|
||||
"floor_id": None,
|
||||
"humidity_entity_id": None,
|
||||
"icon": None,
|
||||
"labels": [],
|
||||
"picture": None,
|
||||
"temperature_entity_id": None,
|
||||
}
|
||||
)
|
||||
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["result"] == {
|
||||
"aliases": unordered(["alias_1", "alias_2"]),
|
||||
"area_id": area.id,
|
||||
"floor_id": None,
|
||||
"icon": None,
|
||||
"labels": [],
|
||||
"name": "mock 2",
|
||||
"picture": None,
|
||||
"temperature_entity_id": None,
|
||||
"humidity_entity_id": None,
|
||||
"created_at": created_at.timestamp(),
|
||||
"modified_at": modified_at.timestamp(),
|
||||
}
|
||||
assert len(area_registry.areas) == 1
|
||||
|
||||
|
||||
async def test_update_area_with_same_name(
|
||||
client: MockHAClientWebSocket, area_registry: ar.AreaRegistry
|
||||
|
||||
@@ -887,6 +887,49 @@ async def test_update_entity(
|
||||
},
|
||||
}
|
||||
|
||||
# Add illegal terms to aliases
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "config/entity_registry/update",
|
||||
"entity_id": "test_domain.world",
|
||||
"aliases": ["alias_1", "alias_2", "", " alias_3 ", " "],
|
||||
}
|
||||
)
|
||||
|
||||
msg = await client.receive_json()
|
||||
assert msg["success"]
|
||||
|
||||
assert msg["result"] == {
|
||||
"entity_entry": {
|
||||
"aliases": unordered(["alias_1", "alias_2", "alias_3"]),
|
||||
"area_id": "mock-area-id",
|
||||
"capabilities": None,
|
||||
"categories": {"scope1": "id", "scope3": "other_id"},
|
||||
"config_entry_id": None,
|
||||
"config_subentry_id": None,
|
||||
"created_at": created.timestamp(),
|
||||
"device_class": "custom_device_class",
|
||||
"device_id": None,
|
||||
"disabled_by": None,
|
||||
"entity_category": None,
|
||||
"entity_id": "test_domain.world",
|
||||
"has_entity_name": False,
|
||||
"hidden_by": "user", # We exchange strings over the WS API, not enums
|
||||
"icon": "icon:after update",
|
||||
"id": ANY,
|
||||
"labels": unordered(["label1", "label2"]),
|
||||
"modified_at": modified.timestamp(),
|
||||
"name": "after update",
|
||||
"options": {"sensor": {"unit_of_measurement": "beard_second"}},
|
||||
"original_device_class": None,
|
||||
"original_icon": None,
|
||||
"original_name": None,
|
||||
"platform": "test_platform",
|
||||
"translation_key": None,
|
||||
"unique_id": "1234",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
async def test_update_entity_require_restart(
|
||||
hass: HomeAssistant, client: MockHAClientWebSocket, freezer: FrozenDateTimeFactory
|
||||
|
||||
@@ -122,6 +122,30 @@ async def test_create_floor(
|
||||
"level": 2,
|
||||
}
|
||||
|
||||
# Floor with invalid aliases
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"name": "Third floor",
|
||||
"type": "config/floor_registry/create",
|
||||
"aliases": ["", " "],
|
||||
"icon": "mdi:home-floor-2",
|
||||
"level": 3,
|
||||
}
|
||||
)
|
||||
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert len(floor_registry.floors) == 3
|
||||
assert msg["result"] == {
|
||||
"aliases": [],
|
||||
"created_at": utcnow().timestamp(),
|
||||
"icon": "mdi:home-floor-2",
|
||||
"floor_id": "third_floor",
|
||||
"modified_at": utcnow().timestamp(),
|
||||
"name": "Third floor",
|
||||
"level": 3,
|
||||
}
|
||||
|
||||
|
||||
async def test_create_floor_with_name_already_in_use(
|
||||
client: MockHAClientWebSocket,
|
||||
@@ -249,6 +273,60 @@ async def test_update_floor(
|
||||
"level": None,
|
||||
}
|
||||
|
||||
# Add invalid aliases
|
||||
modified_at = datetime.fromisoformat("2024-07-16T13:55:00.900075+00:00")
|
||||
freezer.move_to(modified_at)
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"floor_id": floor.floor_id,
|
||||
"name": "First floor",
|
||||
"aliases": ["top floor", "attic", "", " "],
|
||||
"icon": None,
|
||||
"level": None,
|
||||
"type": "config/floor_registry/update",
|
||||
}
|
||||
)
|
||||
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert len(floor_registry.floors) == 1
|
||||
assert msg["result"] == {
|
||||
"aliases": unordered(["top floor", "attic"]),
|
||||
"created_at": created_at.timestamp(),
|
||||
"icon": None,
|
||||
"floor_id": floor.floor_id,
|
||||
"modified_at": modified_at.timestamp(),
|
||||
"name": "First floor",
|
||||
"level": None,
|
||||
}
|
||||
|
||||
# Add alias with trailing and leading whitespaces
|
||||
modified_at = datetime.fromisoformat("2024-07-16T13:55:00.900075+00:00")
|
||||
freezer.move_to(modified_at)
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"floor_id": floor.floor_id,
|
||||
"name": "First floor",
|
||||
"aliases": ["top floor", "attic", "solaio "],
|
||||
"icon": None,
|
||||
"level": None,
|
||||
"type": "config/floor_registry/update",
|
||||
}
|
||||
)
|
||||
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert len(floor_registry.floors) == 1
|
||||
assert msg["result"] == {
|
||||
"aliases": unordered(["top floor", "attic", "solaio"]),
|
||||
"created_at": created_at.timestamp(),
|
||||
"icon": None,
|
||||
"floor_id": floor.floor_id,
|
||||
"modified_at": modified_at.timestamp(),
|
||||
"name": "First floor",
|
||||
"level": None,
|
||||
}
|
||||
|
||||
|
||||
async def test_update_with_name_already_in_use(
|
||||
client: MockHAClientWebSocket,
|
||||
|
||||
Reference in New Issue
Block a user