Scope device uniqueness per parent, null type/location for sub-components, hide sub-components from list, flat battery summary for parent devices

This commit is contained in:
2026-06-09 19:26:31 -05:00
parent 2a54cd8297
commit 23eeeafff7
7 changed files with 340 additions and 42 deletions
+93
View File
@@ -975,3 +975,96 @@ def test_subcomponent_ha_entity_id(client):
resp = client.get("/device/2")
assert resp.status_code == 200
assert b"Hub" in resp.data
# ------------------------------------------------------------------ #
# Sub-component hierarchy — parent_key, null type/location, list hiding
# ------------------------------------------------------------------ #
def _setup_parent_with_two_children(client):
"""Hub (top-level, Sensor type, Living Room) with Sensor A and Sensor B."""
client.post("/device/add", data={
"name": "Hub", "battery_slots": "0", "battery_size": "",
"device_type": "Sensor", "location": "Living Room",
}, follow_redirects=True)
client.post("/device/add", data={
"name": "Sensor A", "battery_slots": "1", "battery_size": "AA", "parent_id": "1",
}, follow_redirects=True)
client.post("/device/add", data={
"name": "Sensor B", "battery_slots": "1", "battery_size": "AA", "parent_id": "1",
}, follow_redirects=True)
def test_device_list_hides_subcomponents(client):
_setup_parent_with_two_children(client)
resp = client.get("/device/")
assert resp.status_code == 200
assert b"Hub" in resp.data
assert b"Sensor A" not in resp.data
assert b"Sensor B" not in resp.data
def test_subcomponent_type_location_null(client):
_setup_parent_with_two_children(client)
# Sub-component detail shows inherited type/location from parent
resp = client.get("/device/2")
assert resp.status_code == 200
assert b"Sensor" in resp.data
assert b"Living Room" in resp.data
assert b"inherited" in resp.data
# Submitting type/location in edit for sub-component should have no effect
client.post("/device/2/edit", data={
"name": "Sensor A", "battery_slots": "1",
"device_type": "Remote Control", "location": "Bedroom",
"parent_id": "1", # keep sub-component relationship
})
resp2 = client.get("/device/2")
assert b"Remote Control" not in resp2.data
assert b"Bedroom" not in resp2.data
def test_subcomponent_name_unique_per_parent(client):
_setup_parent_with_two_children(client)
# Duplicate top-level name → 400
resp = client.post("/device/add", data={
"name": "Hub", "battery_slots": "0", "battery_size": "",
})
assert resp.status_code == 400
assert b"already exists" in resp.data
# Duplicate child name within same parent → 400
resp = client.post("/device/add", data={
"name": "Sensor A", "battery_slots": "1", "battery_size": "AA", "parent_id": "1",
})
assert resp.status_code == 400
assert b"already exists" in resp.data
# Same child name under a DIFFERENT parent → success
client.post("/device/add", data={
"name": "Hub 2", "battery_slots": "0", "battery_size": "",
}) # id=4
resp = client.post("/device/add", data={
"name": "Sensor A", "battery_slots": "1", "battery_size": "AA", "parent_id": "4",
}, follow_redirects=True)
assert resp.status_code == 200
def test_parent_battery_summary_flat(client):
_setup_parent_with_two_children(client)
client.post("/battery/add", data={"brand": "Eneloop", "count": "2"}) # ids 1, 2
client.post("/device/2/install-one", data={"battery_id": "1"})
client.post("/device/3/install-one", data={"battery_id": "2"})
resp = client.get("/device/1")
assert resp.status_code == 200
# Flat table has Component column heading
assert b"Component" in resp.data
# Both batteries appear
assert b"Eneloop 001" in resp.data
assert b"Eneloop 002" in resp.data
# Both child names linked in the component column
assert b"Sensor A" in resp.data
assert b"Sensor B" in resp.data
# Only one "Installed Batteries" heading
assert resp.data.count(b"Installed Batteries") == 1