mirror of
https://github.com/home-assistant/core.git
synced 2025-08-30 09:51:37 +02:00
Improve test of REST endpoint /api/services (#150897)
This commit is contained in:
144
tests/components/api/snapshots/test_init.ambr
Normal file
144
tests/components/api/snapshots/test_init.ambr
Normal file
@@ -0,0 +1,144 @@
|
||||
# serializer version: 1
|
||||
# name: test_api_get_services
|
||||
list([
|
||||
dict({
|
||||
'domain': 'group',
|
||||
'services': dict({
|
||||
'reload': dict({
|
||||
'description': 'Reloads group configuration, entities, and notify services from YAML-configuration.',
|
||||
'fields': dict({
|
||||
}),
|
||||
'name': 'Reload',
|
||||
}),
|
||||
'remove': dict({
|
||||
'description': 'Removes a group.',
|
||||
'fields': dict({
|
||||
'object_id': dict({
|
||||
'description': 'Object ID of this group. This object ID is used as part of the entity ID. Entity ID format: [domain].[object_id].',
|
||||
'example': 'test_group',
|
||||
'name': 'Object ID',
|
||||
'required': True,
|
||||
'selector': dict({
|
||||
'object': dict({
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'name': 'Remove',
|
||||
}),
|
||||
'set': dict({
|
||||
'description': 'Creates/Updates a group.',
|
||||
'fields': dict({
|
||||
'add_entities': dict({
|
||||
'description': 'List of members to be added to the group. Cannot be used in combination with `Entities` or `Remove entities`.',
|
||||
'example': 'domain.entity_id1, domain.entity_id2',
|
||||
'name': 'Add entities',
|
||||
'selector': dict({
|
||||
'entity': dict({
|
||||
'multiple': True,
|
||||
'reorder': False,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'all': dict({
|
||||
'description': 'Enable this option if the group should only be used when all entities are in state `on`.',
|
||||
'name': 'All',
|
||||
'selector': dict({
|
||||
'boolean': dict({
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'entities': dict({
|
||||
'description': 'List of all members in the group. Cannot be used in combination with `Add entities` or `Remove entities`.',
|
||||
'example': 'domain.entity_id1, domain.entity_id2',
|
||||
'name': 'Entities',
|
||||
'selector': dict({
|
||||
'entity': dict({
|
||||
'multiple': True,
|
||||
'reorder': False,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'icon': dict({
|
||||
'description': 'Name of the icon for the group.',
|
||||
'example': 'mdi:camera',
|
||||
'name': 'Icon',
|
||||
'selector': dict({
|
||||
'icon': dict({
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'name': dict({
|
||||
'description': 'Name of the group.',
|
||||
'example': 'My test group',
|
||||
'name': 'Name',
|
||||
'selector': dict({
|
||||
'text': dict({
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'object_id': dict({
|
||||
'description': 'Object ID of this group. This object ID is used as part of the entity ID. Entity ID format: [domain].[object_id].',
|
||||
'example': 'test_group',
|
||||
'name': 'Object ID',
|
||||
'required': True,
|
||||
'selector': dict({
|
||||
'text': dict({
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'remove_entities': dict({
|
||||
'description': 'List of members to be removed from a group. Cannot be used in combination with `Entities` or `Add entities`.',
|
||||
'example': 'domain.entity_id1, domain.entity_id2',
|
||||
'name': 'Remove entities',
|
||||
'selector': dict({
|
||||
'entity': dict({
|
||||
'multiple': True,
|
||||
'reorder': False,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'name': 'Set',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_api_get_services.1
|
||||
dict({
|
||||
'domain': 'logger',
|
||||
'services': dict({
|
||||
'set_default_level': dict({
|
||||
'description': 'Translated description',
|
||||
'fields': dict({
|
||||
'level': dict({
|
||||
'description': 'Field description',
|
||||
'example': 'Field example',
|
||||
'name': 'Field name',
|
||||
'selector': dict({
|
||||
'select': dict({
|
||||
'options': list([
|
||||
'debug',
|
||||
'info',
|
||||
'warning',
|
||||
'error',
|
||||
'fatal',
|
||||
'critical',
|
||||
]),
|
||||
'translation_key': 'level',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'name': 'Translated name',
|
||||
}),
|
||||
'set_level': dict({
|
||||
'description': '',
|
||||
'fields': dict({
|
||||
}),
|
||||
'name': '',
|
||||
}),
|
||||
}),
|
||||
})
|
||||
# ---
|
@@ -4,18 +4,24 @@ import asyncio
|
||||
from http import HTTPStatus
|
||||
import json
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import ANY, patch
|
||||
|
||||
from aiohttp import ServerDisconnectedError, web
|
||||
from aiohttp.test_utils import TestClient
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import const, core as ha
|
||||
from homeassistant.auth.models import Credentials
|
||||
from homeassistant.bootstrap import DATA_LOGGING
|
||||
from homeassistant.components.group import DOMAIN as DOMAIN_GROUP
|
||||
from homeassistant.components.logger import DOMAIN as DOMAIN_LOGGER
|
||||
from homeassistant.components.system_health import DOMAIN as DOMAIN_SYSTEM_HEALTH
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.loader import Integration
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util.yaml.loader import JSON_TYPE
|
||||
|
||||
from tests.common import CLIENT_ID, MockUser, async_mock_service
|
||||
from tests.typing import ClientSessionGenerator
|
||||
@@ -315,17 +321,72 @@ async def test_api_get_event_listeners(
|
||||
|
||||
|
||||
async def test_api_get_services(
|
||||
hass: HomeAssistant, mock_api_client: TestClient
|
||||
hass: HomeAssistant,
|
||||
mock_api_client: TestClient,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test if we can get a dict describing current services."""
|
||||
# Set up an integration that has services
|
||||
assert await async_setup_component(hass, DOMAIN_GROUP, {DOMAIN_GROUP: {}})
|
||||
|
||||
# Set up an integration that has no services
|
||||
assert await async_setup_component(hass, DOMAIN_SYSTEM_HEALTH, {})
|
||||
|
||||
resp = await mock_api_client.get(const.URL_API_SERVICES)
|
||||
data = await resp.json()
|
||||
local_services = hass.services.async_services()
|
||||
|
||||
for serv_domain in data:
|
||||
local = local_services.pop(serv_domain["domain"])
|
||||
assert data == snapshot
|
||||
|
||||
assert serv_domain["services"].keys() == local.keys()
|
||||
# Set up an integration with legacy translations in services.yaml
|
||||
def _load_services_file(hass: HomeAssistant, integration: Integration) -> JSON_TYPE:
|
||||
return {
|
||||
"set_default_level": {
|
||||
"description": "Translated description",
|
||||
"fields": {
|
||||
"level": {
|
||||
"description": "Field description",
|
||||
"example": "Field example",
|
||||
"name": "Field name",
|
||||
"selector": {
|
||||
"select": {
|
||||
"options": [
|
||||
"debug",
|
||||
"info",
|
||||
"warning",
|
||||
"error",
|
||||
"fatal",
|
||||
"critical",
|
||||
],
|
||||
"translation_key": "level",
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
"name": "Translated name",
|
||||
},
|
||||
"set_level": None,
|
||||
}
|
||||
|
||||
await async_setup_component(hass, DOMAIN_LOGGER, {DOMAIN_LOGGER: {}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.helpers.service._load_services_file",
|
||||
side_effect=_load_services_file,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.helpers.service.translation.async_get_translations",
|
||||
return_value={},
|
||||
),
|
||||
):
|
||||
resp = await mock_api_client.get(const.URL_API_SERVICES)
|
||||
|
||||
data2 = await resp.json()
|
||||
|
||||
assert data2 == [*data, {"domain": DOMAIN_LOGGER, "services": ANY}]
|
||||
|
||||
assert data2[-1] == snapshot
|
||||
|
||||
|
||||
async def test_api_call_service_no_data(
|
||||
|
Reference in New Issue
Block a user