|
|
@@ -0,0 +1,100 @@
|
|
|
+"""Home Assistant printer sensors keep to the caller's printers."""
|
|
|
+
|
|
|
+from __future__ import annotations
|
|
|
+
|
|
|
+from unittest.mock import AsyncMock, patch
|
|
|
+
|
|
|
+import pytest
|
|
|
+from httpx import AsyncClient
|
|
|
+
|
|
|
+from backend.app.services.ha_sensor_manager import ha_sensor_manager
|
|
|
+from backend.tests.integration.test_printer_scope_1727 import _admin_token, _auth, _group, _user
|
|
|
+
|
|
|
+pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
|
|
|
+
|
|
|
+PERMS = ["printers:read", "smart_plugs:read", "smart_plugs:create", "smart_plugs:update", "smart_plugs:delete"]
|
|
|
+
|
|
|
+
|
|
|
+@pytest.fixture(autouse=True)
|
|
|
+def _no_live_ha():
|
|
|
+ with patch.object(ha_sensor_manager, "refresh_one", AsyncMock()):
|
|
|
+ yield
|
|
|
+
|
|
|
+
|
|
|
+def _door(printer_id: int, entity: str = "binary_sensor.door") -> dict:
|
|
|
+ return {"name": "Door", "entity_id": entity, "kind": "binary", "alert_state": "on", "printer_id": printer_id}
|
|
|
+
|
|
|
+
|
|
|
+async def _setup(client: AsyncClient, printer_factory):
|
|
|
+ a, b = await printer_factory(name="A"), await printer_factory(name="B")
|
|
|
+ token = await _admin_token(client)
|
|
|
+ admin = _auth(token)
|
|
|
+ perms = await _group(client, token, "perms", permissions=PERMS)
|
|
|
+ team = await _group(client, token, "team", printer_ids=[a.id])
|
|
|
+ member = _auth((await _user(client, token, "member", [perms, team]))[0])
|
|
|
+ ids = {}
|
|
|
+ for name, printer in (("ours", a.id), ("theirs", b.id)):
|
|
|
+ created = await client.post("/api/v1/ha-sensors/", headers=admin, json=_door(printer))
|
|
|
+ assert created.status_code == 200, created.text
|
|
|
+ ids[name] = created.json()["id"]
|
|
|
+ return a.id, b.id, admin, member, ids
|
|
|
+
|
|
|
+
|
|
|
+async def test_a_member_lists_and_reads_only_sensors_of_their_printers(async_client: AsyncClient, printer_factory):
|
|
|
+ a_id, b_id, admin, member, ids = await _setup(async_client, printer_factory)
|
|
|
+
|
|
|
+ listed = await async_client.get("/api/v1/ha-sensors/", headers=member)
|
|
|
+ filtered = await async_client.get("/api/v1/ha-sensors/", headers=member, params={"printer_id": b_id})
|
|
|
+ ours = await async_client.get(f"/api/v1/ha-sensors/{ids['ours']}", headers=member)
|
|
|
+ theirs = await async_client.get(f"/api/v1/ha-sensors/{ids['theirs']}", headers=member)
|
|
|
+ missing = await async_client.get("/api/v1/ha-sensors/999999", headers=member)
|
|
|
+ everything = await async_client.get("/api/v1/ha-sensors/", headers=admin)
|
|
|
+
|
|
|
+ assert [s["id"] for s in listed.json()] == [ids["ours"]]
|
|
|
+ assert filtered.json() == []
|
|
|
+ assert ours.status_code == 200
|
|
|
+ assert (
|
|
|
+ (theirs.status_code, theirs.json())
|
|
|
+ == (missing.status_code, missing.json())
|
|
|
+ == (
|
|
|
+ 404,
|
|
|
+ {"detail": "Sensor not found"},
|
|
|
+ )
|
|
|
+ )
|
|
|
+ assert len(everything.json()) == 2
|
|
|
+
|
|
|
+
|
|
|
+async def test_a_member_changes_only_sensors_of_their_printers(async_client: AsyncClient, printer_factory):
|
|
|
+ a_id, b_id, admin, member, ids = await _setup(async_client, printer_factory)
|
|
|
+
|
|
|
+ patched_theirs = await async_client.patch(
|
|
|
+ f"/api/v1/ha-sensors/{ids['theirs']}", headers=member, json={"block_print": True}
|
|
|
+ )
|
|
|
+ deleted_theirs = await async_client.delete(f"/api/v1/ha-sensors/{ids['theirs']}", headers=member)
|
|
|
+ patched_ours = await async_client.patch(f"/api/v1/ha-sensors/{ids['ours']}", headers=member, json={"name": "Lid"})
|
|
|
+ deleted_ours = await async_client.delete(f"/api/v1/ha-sensors/{ids['ours']}", headers=member)
|
|
|
+
|
|
|
+ assert (patched_theirs.status_code, deleted_theirs.status_code) == (404, 404)
|
|
|
+ assert (patched_ours.status_code, deleted_ours.status_code) == (200, 200)
|
|
|
+ left = (await async_client.get(f"/api/v1/ha-sensors/{ids['theirs']}", headers=admin)).json()
|
|
|
+ assert left["block_print"] is False
|
|
|
+
|
|
|
+
|
|
|
+async def test_a_member_binds_sensors_to_their_printers_only(async_client: AsyncClient, printer_factory):
|
|
|
+ a_id, b_id, admin, member, ids = await _setup(async_client, printer_factory)
|
|
|
+
|
|
|
+ theirs = await async_client.post("/api/v1/ha-sensors/", headers=member, json=_door(b_id, "binary_sensor.lid"))
|
|
|
+ missing = await async_client.post("/api/v1/ha-sensors/", headers=member, json=_door(999_999, "binary_sensor.lid"))
|
|
|
+ ours = await async_client.post("/api/v1/ha-sensors/", headers=member, json=_door(a_id, "binary_sensor.lid"))
|
|
|
+
|
|
|
+ assert (
|
|
|
+ (theirs.status_code, theirs.json())
|
|
|
+ == (missing.status_code, missing.json())
|
|
|
+ == (
|
|
|
+ 404,
|
|
|
+ {"detail": "Printer not found"},
|
|
|
+ )
|
|
|
+ )
|
|
|
+ assert ours.status_code == 200
|
|
|
+ on_b = (await async_client.get("/api/v1/ha-sensors/", headers=admin, params={"printer_id": b_id})).json()
|
|
|
+ assert [s["entity_id"] for s in on_b] == ["binary_sensor.door"]
|