test_ha_sensor_scope.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. """Home Assistant printer sensors keep to the caller's printers."""
  2. from __future__ import annotations
  3. from unittest.mock import AsyncMock, patch
  4. import pytest
  5. from httpx import AsyncClient
  6. from backend.app.services.ha_sensor_manager import ha_sensor_manager
  7. from backend.tests.integration.test_printer_scope_1727 import _admin_token, _auth, _group, _user
  8. pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
  9. PERMS = ["printers:read", "smart_plugs:read", "smart_plugs:create", "smart_plugs:update", "smart_plugs:delete"]
  10. @pytest.fixture(autouse=True)
  11. def _no_live_ha():
  12. with patch.object(ha_sensor_manager, "refresh_one", AsyncMock()):
  13. yield
  14. def _door(printer_id: int, entity: str = "binary_sensor.door") -> dict:
  15. return {"name": "Door", "entity_id": entity, "kind": "binary", "alert_state": "on", "printer_id": printer_id}
  16. async def _setup(client: AsyncClient, printer_factory):
  17. a, b = await printer_factory(name="A"), await printer_factory(name="B")
  18. token = await _admin_token(client)
  19. admin = _auth(token)
  20. perms = await _group(client, token, "perms", permissions=PERMS)
  21. team = await _group(client, token, "team", printer_ids=[a.id])
  22. member = _auth((await _user(client, token, "member", [perms, team]))[0])
  23. ids = {}
  24. for name, printer in (("ours", a.id), ("theirs", b.id)):
  25. created = await client.post("/api/v1/ha-sensors/", headers=admin, json=_door(printer))
  26. assert created.status_code == 200, created.text
  27. ids[name] = created.json()["id"]
  28. return a.id, b.id, admin, member, ids
  29. async def test_a_member_lists_and_reads_only_sensors_of_their_printers(async_client: AsyncClient, printer_factory):
  30. a_id, b_id, admin, member, ids = await _setup(async_client, printer_factory)
  31. listed = await async_client.get("/api/v1/ha-sensors/", headers=member)
  32. filtered = await async_client.get("/api/v1/ha-sensors/", headers=member, params={"printer_id": b_id})
  33. ours = await async_client.get(f"/api/v1/ha-sensors/{ids['ours']}", headers=member)
  34. theirs = await async_client.get(f"/api/v1/ha-sensors/{ids['theirs']}", headers=member)
  35. missing = await async_client.get("/api/v1/ha-sensors/999999", headers=member)
  36. everything = await async_client.get("/api/v1/ha-sensors/", headers=admin)
  37. assert [s["id"] for s in listed.json()] == [ids["ours"]]
  38. assert filtered.json() == []
  39. assert ours.status_code == 200
  40. assert (
  41. (theirs.status_code, theirs.json())
  42. == (missing.status_code, missing.json())
  43. == (
  44. 404,
  45. {"detail": "Sensor not found"},
  46. )
  47. )
  48. assert len(everything.json()) == 2
  49. async def test_a_member_changes_only_sensors_of_their_printers(async_client: AsyncClient, printer_factory):
  50. a_id, b_id, admin, member, ids = await _setup(async_client, printer_factory)
  51. patched_theirs = await async_client.patch(
  52. f"/api/v1/ha-sensors/{ids['theirs']}", headers=member, json={"block_print": True}
  53. )
  54. deleted_theirs = await async_client.delete(f"/api/v1/ha-sensors/{ids['theirs']}", headers=member)
  55. patched_ours = await async_client.patch(f"/api/v1/ha-sensors/{ids['ours']}", headers=member, json={"name": "Lid"})
  56. deleted_ours = await async_client.delete(f"/api/v1/ha-sensors/{ids['ours']}", headers=member)
  57. assert (patched_theirs.status_code, deleted_theirs.status_code) == (404, 404)
  58. assert (patched_ours.status_code, deleted_ours.status_code) == (200, 200)
  59. left = (await async_client.get(f"/api/v1/ha-sensors/{ids['theirs']}", headers=admin)).json()
  60. assert left["block_print"] is False
  61. async def test_a_member_binds_sensors_to_their_printers_only(async_client: AsyncClient, printer_factory):
  62. a_id, b_id, admin, member, ids = await _setup(async_client, printer_factory)
  63. theirs = await async_client.post("/api/v1/ha-sensors/", headers=member, json=_door(b_id, "binary_sensor.lid"))
  64. missing = await async_client.post("/api/v1/ha-sensors/", headers=member, json=_door(999_999, "binary_sensor.lid"))
  65. ours = await async_client.post("/api/v1/ha-sensors/", headers=member, json=_door(a_id, "binary_sensor.lid"))
  66. assert (
  67. (theirs.status_code, theirs.json())
  68. == (missing.status_code, missing.json())
  69. == (
  70. 404,
  71. {"detail": "Printer not found"},
  72. )
  73. )
  74. assert ours.status_code == 200
  75. on_b = (await async_client.get("/api/v1/ha-sensors/", headers=admin, params={"printer_id": b_id})).json()
  76. assert [s["entity_id"] for s in on_b] == ["binary_sensor.door"]