Extract Collection helper from Person integration (#30313)
* Add CRUD foundation * Use collection helper in person integration * Lint/pytest * Add tests * Lint * Create notification
This commit is contained in:
parent
3033dbd86c
commit
b9aba30a6e
14 changed files with 1074 additions and 396 deletions
|
@ -1,19 +1,15 @@
|
|||
"""The tests for the person component."""
|
||||
from unittest.mock import Mock
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import person
|
||||
from homeassistant.components.device_tracker import (
|
||||
ATTR_SOURCE_TYPE,
|
||||
SOURCE_TYPE_GPS,
|
||||
SOURCE_TYPE_ROUTER,
|
||||
)
|
||||
from homeassistant.components.person import (
|
||||
ATTR_SOURCE,
|
||||
ATTR_USER_ID,
|
||||
DOMAIN,
|
||||
PersonManager,
|
||||
)
|
||||
from homeassistant.components.person import ATTR_SOURCE, ATTR_USER_ID, DOMAIN
|
||||
from homeassistant.const import (
|
||||
ATTR_GPS_ACCURACY,
|
||||
ATTR_ID,
|
||||
|
@ -23,20 +19,29 @@ from homeassistant.const import (
|
|||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.core import CoreState, State
|
||||
from homeassistant.helpers import collection
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
assert_setup_component,
|
||||
mock_component,
|
||||
mock_coro_func,
|
||||
mock_restore_cache,
|
||||
)
|
||||
from tests.common import assert_setup_component, mock_component, mock_restore_cache
|
||||
|
||||
DEVICE_TRACKER = "device_tracker.test_tracker"
|
||||
DEVICE_TRACKER_2 = "device_tracker.test_tracker_2"
|
||||
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
@pytest.fixture
|
||||
def storage_collection(hass):
|
||||
"""Return an empty storage collection."""
|
||||
id_manager = collection.IDManager()
|
||||
return person.PersonStorageCollection(
|
||||
person.PersonStore(hass, person.STORAGE_VERSION, person.STORAGE_KEY),
|
||||
logging.getLogger(f"{person.__name__}.storage_collection"),
|
||||
id_manager,
|
||||
collection.YamlCollection(
|
||||
logging.getLogger(f"{person.__name__}.yaml_collection"), id_manager
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def storage_setup(hass, hass_storage, hass_admin_user):
|
||||
"""Storage setup."""
|
||||
|
@ -433,21 +438,21 @@ async def test_load_person_storage_two_nonlinked(hass, hass_storage):
|
|||
|
||||
async def test_ws_list(hass, hass_ws_client, storage_setup):
|
||||
"""Test listing via WS."""
|
||||
manager = hass.data[DOMAIN]
|
||||
manager = hass.data[DOMAIN][1]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
resp = await client.send_json({"id": 6, "type": "person/list"})
|
||||
resp = await client.receive_json()
|
||||
assert resp["success"]
|
||||
assert resp["result"]["storage"] == manager.storage_persons
|
||||
assert resp["result"]["storage"] == manager.async_items()
|
||||
assert len(resp["result"]["storage"]) == 1
|
||||
assert len(resp["result"]["config"]) == 0
|
||||
|
||||
|
||||
async def test_ws_create(hass, hass_ws_client, storage_setup, hass_read_only_user):
|
||||
"""Test creating via WS."""
|
||||
manager = hass.data[DOMAIN]
|
||||
manager = hass.data[DOMAIN][1]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
|
@ -462,7 +467,7 @@ async def test_ws_create(hass, hass_ws_client, storage_setup, hass_read_only_use
|
|||
)
|
||||
resp = await client.receive_json()
|
||||
|
||||
persons = manager.storage_persons
|
||||
persons = manager.async_items()
|
||||
assert len(persons) == 2
|
||||
|
||||
assert resp["success"]
|
||||
|
@ -474,7 +479,7 @@ async def test_ws_create_requires_admin(
|
|||
):
|
||||
"""Test creating via WS requires admin."""
|
||||
hass_admin_user.groups = []
|
||||
manager = hass.data[DOMAIN]
|
||||
manager = hass.data[DOMAIN][1]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
|
@ -489,7 +494,7 @@ async def test_ws_create_requires_admin(
|
|||
)
|
||||
resp = await client.receive_json()
|
||||
|
||||
persons = manager.storage_persons
|
||||
persons = manager.async_items()
|
||||
assert len(persons) == 1
|
||||
|
||||
assert not resp["success"]
|
||||
|
@ -497,10 +502,10 @@ async def test_ws_create_requires_admin(
|
|||
|
||||
async def test_ws_update(hass, hass_ws_client, storage_setup):
|
||||
"""Test updating via WS."""
|
||||
manager = hass.data[DOMAIN]
|
||||
manager = hass.data[DOMAIN][1]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
persons = manager.storage_persons
|
||||
persons = manager.async_items()
|
||||
|
||||
resp = await client.send_json(
|
||||
{
|
||||
|
@ -514,7 +519,7 @@ async def test_ws_update(hass, hass_ws_client, storage_setup):
|
|||
)
|
||||
resp = await client.receive_json()
|
||||
|
||||
persons = manager.storage_persons
|
||||
persons = manager.async_items()
|
||||
assert len(persons) == 1
|
||||
|
||||
assert resp["success"]
|
||||
|
@ -533,10 +538,10 @@ async def test_ws_update_require_admin(
|
|||
):
|
||||
"""Test updating via WS requires admin."""
|
||||
hass_admin_user.groups = []
|
||||
manager = hass.data[DOMAIN]
|
||||
manager = hass.data[DOMAIN][1]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
original = dict(manager.storage_persons[0])
|
||||
original = dict(manager.async_items()[0])
|
||||
|
||||
resp = await client.send_json(
|
||||
{
|
||||
|
@ -551,23 +556,23 @@ async def test_ws_update_require_admin(
|
|||
resp = await client.receive_json()
|
||||
assert not resp["success"]
|
||||
|
||||
not_updated = dict(manager.storage_persons[0])
|
||||
not_updated = dict(manager.async_items()[0])
|
||||
assert original == not_updated
|
||||
|
||||
|
||||
async def test_ws_delete(hass, hass_ws_client, storage_setup):
|
||||
"""Test deleting via WS."""
|
||||
manager = hass.data[DOMAIN]
|
||||
manager = hass.data[DOMAIN][1]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
persons = manager.storage_persons
|
||||
persons = manager.async_items()
|
||||
|
||||
resp = await client.send_json(
|
||||
{"id": 6, "type": "person/delete", "person_id": persons[0]["id"]}
|
||||
)
|
||||
resp = await client.receive_json()
|
||||
|
||||
persons = manager.storage_persons
|
||||
persons = manager.async_items()
|
||||
assert len(persons) == 0
|
||||
|
||||
assert resp["success"]
|
||||
|
@ -581,7 +586,7 @@ async def test_ws_delete_require_admin(
|
|||
):
|
||||
"""Test deleting via WS requires admin."""
|
||||
hass_admin_user.groups = []
|
||||
manager = hass.data[DOMAIN]
|
||||
manager = hass.data[DOMAIN][1]
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
|
@ -589,7 +594,7 @@ async def test_ws_delete_require_admin(
|
|||
{
|
||||
"id": 6,
|
||||
"type": "person/delete",
|
||||
"person_id": manager.storage_persons[0]["id"],
|
||||
"person_id": manager.async_items()[0]["id"],
|
||||
"name": "Updated Name",
|
||||
"device_trackers": [DEVICE_TRACKER_2],
|
||||
"user_id": None,
|
||||
|
@ -598,61 +603,64 @@ async def test_ws_delete_require_admin(
|
|||
resp = await client.receive_json()
|
||||
assert not resp["success"]
|
||||
|
||||
persons = manager.storage_persons
|
||||
persons = manager.async_items()
|
||||
assert len(persons) == 1
|
||||
|
||||
|
||||
async def test_create_invalid_user_id(hass):
|
||||
async def test_create_invalid_user_id(hass, storage_collection):
|
||||
"""Test we do not allow invalid user ID during creation."""
|
||||
manager = PersonManager(hass, Mock(), [])
|
||||
await manager.async_initialize()
|
||||
with pytest.raises(ValueError):
|
||||
await manager.async_create_person(name="Hello", user_id="non-existing")
|
||||
await storage_collection.async_create_item(
|
||||
{"name": "Hello", "user_id": "non-existing"}
|
||||
)
|
||||
|
||||
|
||||
async def test_create_duplicate_user_id(hass, hass_admin_user):
|
||||
async def test_create_duplicate_user_id(hass, hass_admin_user, storage_collection):
|
||||
"""Test we do not allow duplicate user ID during creation."""
|
||||
manager = PersonManager(hass, Mock(async_add_entities=mock_coro_func()), [])
|
||||
await manager.async_initialize()
|
||||
await manager.async_create_person(name="Hello", user_id=hass_admin_user.id)
|
||||
await storage_collection.async_create_item(
|
||||
{"name": "Hello", "user_id": hass_admin_user.id}
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await manager.async_create_person(name="Hello", user_id=hass_admin_user.id)
|
||||
await storage_collection.async_create_item(
|
||||
{"name": "Hello", "user_id": hass_admin_user.id}
|
||||
)
|
||||
|
||||
|
||||
async def test_update_double_user_id(hass, hass_admin_user):
|
||||
async def test_update_double_user_id(hass, hass_admin_user, storage_collection):
|
||||
"""Test we do not allow double user ID during update."""
|
||||
manager = PersonManager(hass, Mock(async_add_entities=mock_coro_func()), [])
|
||||
await manager.async_initialize()
|
||||
await manager.async_create_person(name="Hello", user_id=hass_admin_user.id)
|
||||
person = await manager.async_create_person(name="Hello")
|
||||
await storage_collection.async_create_item(
|
||||
{"name": "Hello", "user_id": hass_admin_user.id}
|
||||
)
|
||||
person = await storage_collection.async_create_item({"name": "Hello"})
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await manager.async_update_person(
|
||||
person_id=person["id"], user_id=hass_admin_user.id
|
||||
await storage_collection.async_update_item(
|
||||
person["id"], {"user_id": hass_admin_user.id}
|
||||
)
|
||||
|
||||
|
||||
async def test_update_invalid_user_id(hass):
|
||||
async def test_update_invalid_user_id(hass, storage_collection):
|
||||
"""Test updating to invalid user ID."""
|
||||
manager = PersonManager(hass, Mock(async_add_entities=mock_coro_func()), [])
|
||||
await manager.async_initialize()
|
||||
person = await manager.async_create_person(name="Hello")
|
||||
person = await storage_collection.async_create_item({"name": "Hello"})
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await manager.async_update_person(
|
||||
person_id=person["id"], user_id="non-existing"
|
||||
await storage_collection.async_update_item(
|
||||
person["id"], {"user_id": "non-existing"}
|
||||
)
|
||||
|
||||
|
||||
async def test_update_person_when_user_removed(hass, hass_read_only_user):
|
||||
async def test_update_person_when_user_removed(
|
||||
hass, storage_setup, hass_read_only_user
|
||||
):
|
||||
"""Update person when user is removed."""
|
||||
manager = PersonManager(hass, Mock(async_add_entities=mock_coro_func()), [])
|
||||
await manager.async_initialize()
|
||||
person = await manager.async_create_person(
|
||||
name="Hello", user_id=hass_read_only_user.id
|
||||
storage_collection = hass.data[DOMAIN][1]
|
||||
|
||||
person = await storage_collection.async_create_item(
|
||||
{"name": "Hello", "user_id": hass_read_only_user.id}
|
||||
)
|
||||
|
||||
await hass.auth.async_remove_user(hass_read_only_user)
|
||||
await hass.async_block_till_done()
|
||||
assert person["user_id"] is None
|
||||
|
||||
assert storage_collection.data[person["id"]]["user_id"] is None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue