mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Create individual devices for telegram_bot chats (#176606)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI
parent
a55511f3fb
commit
ac6aedab34
@@ -3,6 +3,7 @@
|
||||
import logging
|
||||
from typing import Protocol, cast
|
||||
|
||||
import telegram
|
||||
from telegram import Bot
|
||||
from telegram.constants import InputMediaType
|
||||
from telegram.error import InvalidToken, TelegramError
|
||||
@@ -33,6 +34,7 @@ from homeassistant.exceptions import (
|
||||
)
|
||||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
issue_registry as ir,
|
||||
)
|
||||
@@ -104,6 +106,7 @@ from .const import (
|
||||
CHAT_ACTION_UPLOAD_VIDEO_NOTE,
|
||||
CHAT_ACTION_UPLOAD_VOICE,
|
||||
CONF_API_ENDPOINT,
|
||||
CONF_CHAT_ID,
|
||||
CONF_CONFIG_ENTRY_ID,
|
||||
DEFAULT_API_ENDPOINT,
|
||||
DOMAIN,
|
||||
@@ -705,6 +708,50 @@ async def async_migrate_entry(
|
||||
updated,
|
||||
)
|
||||
|
||||
# version 1.2 -> 1.3: move each chat's notify entity onto its own per-chat device
|
||||
# (linked to the bot device) and strip the chat subentries from the bot device, leaving
|
||||
# it associated with only (entry, None).
|
||||
if version == 1 and config_entry.minor_version < 3:
|
||||
device_registry = dr.async_get(hass)
|
||||
entity_registry = er.async_get(hass)
|
||||
# Up to 1.2 the entry has a single device, the bot device, shared by every chat
|
||||
devices = dr.async_entries_for_config_entry(
|
||||
device_registry, config_entry.entry_id
|
||||
)
|
||||
if devices:
|
||||
bot_device = devices[0]
|
||||
bot_id = next(
|
||||
identifier
|
||||
for domain, identifier in bot_device.identifiers
|
||||
if domain == DOMAIN
|
||||
)
|
||||
notify_entities = {
|
||||
entity.config_subentry_id: entity
|
||||
for entity in er.async_entries_for_config_entry(
|
||||
entity_registry, config_entry.entry_id
|
||||
)
|
||||
# The event entity (no subentry) stays on the shared bot device
|
||||
if entity.config_subentry_id is not None
|
||||
}
|
||||
for subentry_id, subentry in config_entry.subentries.items():
|
||||
per_chat_device = device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
config_subentry_id=subentry_id,
|
||||
identifiers={(DOMAIN, f"{bot_id}_{subentry.data[CONF_CHAT_ID]}")},
|
||||
via_device=(DOMAIN, bot_id),
|
||||
)
|
||||
if entity := notify_entities.get(subentry_id):
|
||||
entity_registry.async_update_entity(
|
||||
entity.entity_id, device_id=per_chat_device.id
|
||||
)
|
||||
# Strip this chat's subentry from the bot device, leaving (entry, None)
|
||||
device_registry.async_update_device(
|
||||
bot_device.id,
|
||||
remove_config_entry_id=config_entry.entry_id,
|
||||
remove_config_subentry_id=subentry_id,
|
||||
)
|
||||
hass.config_entries.async_update_entry(config_entry, minor_version=3)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -906,6 +953,18 @@ def _warn_chat_id_migration(service: ServiceCall) -> set[int]:
|
||||
return chat_ids
|
||||
|
||||
|
||||
def bot_device_info(config_entry: TelegramBotConfigEntry, bot_id: int) -> dr.DeviceInfo:
|
||||
"""Return device info for the shared bot device."""
|
||||
return dr.DeviceInfo(
|
||||
name=config_entry.title,
|
||||
entry_type=dr.DeviceEntryType.SERVICE,
|
||||
manufacturer="Telegram",
|
||||
model=config_entry.data[CONF_PLATFORM].capitalize(),
|
||||
sw_version=telegram.__version__,
|
||||
identifiers={(DOMAIN, f"{bot_id}")},
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: TelegramBotConfigEntry) -> bool:
|
||||
"""Create the Telegram bot from config entry."""
|
||||
bot: Bot = await hass.async_add_executor_job(initialize_bot, hass, entry.data)
|
||||
@@ -933,6 +992,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: TelegramBotConfigEntry)
|
||||
)
|
||||
entry.runtime_data = notify_service
|
||||
|
||||
# Create the bot device before the platforms are set up, so the per-chat devices can
|
||||
# resolve it as their via_device no matter which platform is set up first
|
||||
dr.async_get(hass).async_get_or_create(
|
||||
config_entry_id=entry.entry_id, **bot_device_info(entry, bot.id)
|
||||
)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
entry.async_on_unload(entry.add_update_listener(update_listener))
|
||||
|
||||
@@ -192,7 +192,7 @@ class TelegramBotConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Telegram."""
|
||||
|
||||
VERSION = 1
|
||||
MINOR_VERSION = 2
|
||||
MINOR_VERSION = 3
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
"""Base entity for Telegram bot integration."""
|
||||
|
||||
import telegram
|
||||
|
||||
from homeassistant.const import CONF_PLATFORM
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.entity import Entity, EntityDescription
|
||||
|
||||
from . import TelegramBotConfigEntry
|
||||
from .const import DOMAIN
|
||||
from . import TelegramBotConfigEntry, bot_device_info
|
||||
|
||||
|
||||
class TelegramBotEntity(Entity):
|
||||
@@ -28,11 +23,4 @@ class TelegramBotEntity(Entity):
|
||||
self.service = config_entry.runtime_data
|
||||
|
||||
self._attr_unique_id = f"{self.bot_id}_{entity_description.key}"
|
||||
self._attr_device_info = DeviceInfo(
|
||||
name=config_entry.title,
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
manufacturer="Telegram",
|
||||
model=config_entry.data[CONF_PLATFORM].capitalize(),
|
||||
sw_version=telegram.__version__,
|
||||
identifiers={(DOMAIN, f"{self.bot_id}")},
|
||||
)
|
||||
self._attr_device_info = bot_device_info(config_entry, self.bot_id)
|
||||
|
||||
@@ -12,7 +12,7 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import TelegramBotConfigEntry
|
||||
from .const import ATTR_TITLE, CONF_CHAT_ID
|
||||
from .const import ATTR_TITLE, CONF_CHAT_ID, DOMAIN
|
||||
from .entity import TelegramBotEntity
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ async def async_setup_entry(
|
||||
class TelegramBotNotifyEntity(TelegramBotEntity, NotifyEntity):
|
||||
"""Representation of a telegram bot notification entity."""
|
||||
|
||||
_attr_name = None
|
||||
_attr_supported_features = NotifyEntityFeature.TITLE
|
||||
|
||||
def __init__(
|
||||
@@ -45,7 +46,12 @@ class TelegramBotNotifyEntity(TelegramBotEntity, NotifyEntity):
|
||||
config_entry, NotifyEntityDescription(key=subentry.data[CONF_CHAT_ID])
|
||||
)
|
||||
self.chat_id = subentry.data[CONF_CHAT_ID]
|
||||
self._attr_name = subentry.title
|
||||
# Each chat gets its own device (keyed per chat) linked to the shared bot device.
|
||||
device_info = self._attr_device_info
|
||||
assert device_info is not None
|
||||
device_info["identifiers"] = {(DOMAIN, f"{self.bot_id}_{self.chat_id}")}
|
||||
device_info["name"] = subentry.title
|
||||
device_info["via_device"] = (DOMAIN, f"{self.bot_id}")
|
||||
|
||||
@override
|
||||
async def async_send_message(self, message: str, title: str | None = None) -> None:
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
"""Init tests for the Telegram Bot integration."""
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.telegram_bot.const import (
|
||||
ATTR_PARSER,
|
||||
CONF_ALLOWED_CHAT_IDS,
|
||||
CONF_API_ENDPOINT,
|
||||
CONF_CHAT_ID,
|
||||
DEFAULT_API_ENDPOINT,
|
||||
DOMAIN,
|
||||
PARSER_MD,
|
||||
PLATFORM_BROADCAST,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.config_entries import ConfigEntryState, ConfigSubentryData
|
||||
from homeassistant.const import CONF_API_KEY, CONF_PLATFORM
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
@@ -19,7 +24,7 @@ async def test_migration_error(
|
||||
hass: HomeAssistant,
|
||||
mock_external_calls: None,
|
||||
) -> None:
|
||||
"""Test migrate config entry from 1.1 to 1.2."""
|
||||
"""Test migrate config entry from unsupported version."""
|
||||
|
||||
mock_config_entry = MockConfigEntry(
|
||||
unique_id="mock api key",
|
||||
@@ -43,7 +48,7 @@ async def test_migrate_entry_from_1_1(
|
||||
hass: HomeAssistant,
|
||||
mock_external_calls: None,
|
||||
) -> None:
|
||||
"""Test migrate config entry from 1.1 to 1.2."""
|
||||
"""Test migrate config entry from 1.1, chaining through to the latest version."""
|
||||
|
||||
mock_config_entry = MockConfigEntry(
|
||||
unique_id="mock api key",
|
||||
@@ -61,9 +66,199 @@ async def test_migrate_entry_from_1_1(
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
assert mock_config_entry.version == 1
|
||||
assert mock_config_entry.minor_version == 2
|
||||
assert mock_config_entry.minor_version == 3
|
||||
assert mock_config_entry.data == {
|
||||
CONF_PLATFORM: PLATFORM_BROADCAST,
|
||||
CONF_API_KEY: "mock api key",
|
||||
CONF_API_ENDPOINT: DEFAULT_API_ENDPOINT,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"chats_without_notify_entity",
|
||||
[
|
||||
pytest.param((), id="notify entities intact"),
|
||||
pytest.param((654321,), id="notify entity deleted"),
|
||||
],
|
||||
)
|
||||
async def test_migrate_entry_to_per_chat_devices(
|
||||
hass: HomeAssistant,
|
||||
mock_external_calls: None,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
chats_without_notify_entity: tuple[int, ...],
|
||||
) -> None:
|
||||
"""Test migrating a shared bot device to per-chat devices."""
|
||||
bot_id = 123456 # test_user id from mock_external_calls
|
||||
chat_ids = (123456, 654321)
|
||||
config_entry = MockConfigEntry(
|
||||
unique_id="mock api key",
|
||||
domain=DOMAIN,
|
||||
minor_version=2,
|
||||
data={
|
||||
CONF_PLATFORM: PLATFORM_BROADCAST,
|
||||
CONF_API_KEY: "mock api key",
|
||||
CONF_API_ENDPOINT: DEFAULT_API_ENDPOINT,
|
||||
},
|
||||
options={ATTR_PARSER: PARSER_MD},
|
||||
subentries_data=[
|
||||
ConfigSubentryData(
|
||||
unique_id="123456",
|
||||
data={CONF_CHAT_ID: 123456},
|
||||
subentry_type=CONF_ALLOWED_CHAT_IDS,
|
||||
title="chat 1",
|
||||
),
|
||||
ConfigSubentryData(
|
||||
unique_id="654321",
|
||||
data={CONF_CHAT_ID: 654321},
|
||||
subentry_type=CONF_ALLOWED_CHAT_IDS,
|
||||
title="chat 2",
|
||||
),
|
||||
],
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
subentry_ids = list(config_entry.subentries)
|
||||
|
||||
# Pre-migration state: one shared bot device associated with the config entry (None)
|
||||
# and every chat subentry, holding the event entity and every chat's notify entity.
|
||||
bot_device = device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
identifiers={(DOMAIN, str(bot_id))},
|
||||
)
|
||||
for subentry_id in subentry_ids:
|
||||
bot_device = device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
config_subentry_id=subentry_id,
|
||||
identifiers={(DOMAIN, str(bot_id))},
|
||||
)
|
||||
assert bot_device.config_entries_subentries == {
|
||||
config_entry.entry_id: {None, *subentry_ids}
|
||||
}
|
||||
|
||||
event_entity = entity_registry.async_get_or_create(
|
||||
"event",
|
||||
DOMAIN,
|
||||
f"{bot_id}_update_event",
|
||||
config_entry=config_entry,
|
||||
device_id=bot_device.id,
|
||||
)
|
||||
notify_entities = {
|
||||
chat_id: entity_registry.async_get_or_create(
|
||||
"notify",
|
||||
DOMAIN,
|
||||
f"{bot_id}_{chat_id}",
|
||||
config_entry=config_entry,
|
||||
config_subentry_id=subentry_id,
|
||||
device_id=bot_device.id,
|
||||
)
|
||||
for subentry_id, chat_id in zip(subentry_ids, chat_ids, strict=True)
|
||||
if chat_id not in chats_without_notify_entity
|
||||
}
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
assert config_entry.minor_version == 3
|
||||
|
||||
# Each chat has its own device, owned by that chat's subentry and linked to the bot
|
||||
# device.
|
||||
chat_devices = {
|
||||
chat_id: device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{bot_id}_{chat_id}")}
|
||||
)
|
||||
for chat_id in chat_ids
|
||||
}
|
||||
for subentry_id, chat_id in zip(subentry_ids, chat_ids, strict=True):
|
||||
chat_device = chat_devices[chat_id]
|
||||
assert chat_device is not None
|
||||
assert chat_device.config_entries_subentries == {
|
||||
config_entry.entry_id: {subentry_id}
|
||||
}
|
||||
assert chat_device.via_device_id == bot_device.id
|
||||
|
||||
# Every notify entity that survived is moved onto its chat's device
|
||||
for chat_id, notify_entity in notify_entities.items():
|
||||
assert (
|
||||
entity_registry.async_get(notify_entity.entity_id).device_id
|
||||
== chat_devices[chat_id].id
|
||||
)
|
||||
|
||||
# The bot device ends up associated with only (entry, None), keeping the event entity
|
||||
bot_device = device_registry.async_get(bot_device.id)
|
||||
assert bot_device is not None
|
||||
assert bot_device.config_entries_subentries == {config_entry.entry_id: {None}}
|
||||
assert entity_registry.async_get(event_entity.entity_id).device_id == bot_device.id
|
||||
|
||||
|
||||
async def test_per_chat_devices(
|
||||
hass: HomeAssistant,
|
||||
mock_broadcast_config_entry: MockConfigEntry,
|
||||
mock_external_calls: None,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Each chat gets its own device linked to the config-entry-level bot device."""
|
||||
mock_broadcast_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_broadcast_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entry_id = mock_broadcast_config_entry.entry_id
|
||||
|
||||
# The bot device belongs to the config entry (no subentry) and holds the event entity
|
||||
bot_device = device_registry.async_get_device(identifiers={(DOMAIN, "123456")})
|
||||
assert bot_device is not None
|
||||
assert bot_device.config_entries_subentries == {entry_id: {None}}
|
||||
assert bot_device.name == "Mock Title"
|
||||
|
||||
for chat_id, chat_name in ((123456, "mock chat 1"), (654321, "mock chat 2")):
|
||||
subentry_id = next(
|
||||
sid
|
||||
for sid, subentry in mock_broadcast_config_entry.subentries.items()
|
||||
if subentry.data[CONF_CHAT_ID] == chat_id
|
||||
)
|
||||
chat_device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"123456_{chat_id}")}
|
||||
)
|
||||
assert chat_device is not None
|
||||
assert chat_device.config_entries_subentries == {entry_id: {subentry_id}}
|
||||
assert chat_device.via_device_id == bot_device.id
|
||||
# The device is named after the chat, and its notify entity takes the device name
|
||||
assert chat_device.name == chat_name
|
||||
notify_entity_id = entity_registry.async_get_entity_id(
|
||||
"notify", DOMAIN, f"123456_{chat_id}"
|
||||
)
|
||||
assert notify_entity_id is not None
|
||||
assert entity_registry.async_get(notify_entity_id).device_id == chat_device.id
|
||||
assert hass.states.get(notify_entity_id).name == chat_name
|
||||
|
||||
|
||||
async def test_remove_chat_subentry_removes_per_chat_device(
|
||||
hass: HomeAssistant,
|
||||
mock_broadcast_config_entry: MockConfigEntry,
|
||||
mock_external_calls: None,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Removing a chat subentry removes just its per-chat device and notify entity."""
|
||||
mock_broadcast_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_broadcast_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
subentry_id = next(
|
||||
sid
|
||||
for sid, subentry in mock_broadcast_config_entry.subentries.items()
|
||||
if subentry.data[CONF_CHAT_ID] == 123456
|
||||
)
|
||||
assert device_registry.async_get_device(identifiers={(DOMAIN, "123456_123456")})
|
||||
assert entity_registry.async_get_entity_id("notify", DOMAIN, "123456_123456")
|
||||
|
||||
hass.config_entries.async_remove_subentry(mock_broadcast_config_entry, subentry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# The removed chat's device and notify entity are gone; the other chat and the bot
|
||||
# device remain
|
||||
assert not device_registry.async_get_device(identifiers={(DOMAIN, "123456_123456")})
|
||||
assert not entity_registry.async_get_entity_id("notify", DOMAIN, "123456_123456")
|
||||
assert device_registry.async_get_device(identifiers={(DOMAIN, "123456_654321")})
|
||||
assert device_registry.async_get_device(identifiers={(DOMAIN, "123456")})
|
||||
|
||||
@@ -43,7 +43,7 @@ async def test_send_message(
|
||||
NOTIFY_DOMAIN,
|
||||
SERVICE_SEND_MESSAGE,
|
||||
{
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat",
|
||||
ATTR_MESSAGE: "mock message",
|
||||
ATTR_TITLE: "mock title",
|
||||
},
|
||||
@@ -64,7 +64,7 @@ async def test_send_message(
|
||||
message_thread_id=None,
|
||||
)
|
||||
|
||||
state = hass.states.get("notify.mock_title_mock_chat")
|
||||
state = hass.states.get("notify.mock_chat")
|
||||
assert state
|
||||
assert state.state == "2025-01-09T12:00:00+00:00"
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ async def test_send_message(
|
||||
{
|
||||
ATTR_CHAT_ID: 12345678,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -322,7 +322,7 @@ async def test_send_message_with_inline_keyboard(
|
||||
{
|
||||
ATTR_CHAT_ID: 12345678,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -368,9 +368,9 @@ async def test_send_sticker_partial_error(
|
||||
assert err.value.translation_key == "multiple_errors"
|
||||
assert err.value.translation_placeholders == {
|
||||
"errors": (
|
||||
"`entity_id` notify.mock_title_mock_chat_1:"
|
||||
"`entity_id` notify.mock_chat_1:"
|
||||
" mock network error\n"
|
||||
"`entity_id` notify.mock_title_mock_chat_2:"
|
||||
"`entity_id` notify.mock_chat_2:"
|
||||
" mock network error"
|
||||
)
|
||||
}
|
||||
@@ -588,7 +588,7 @@ async def test_send_file(hass: HomeAssistant, webhook_bot, service: str) -> None
|
||||
{
|
||||
ATTR_CHAT_ID: 12345678,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1076,7 +1076,7 @@ async def test_send_message_with_config_entry(
|
||||
{
|
||||
ATTR_CHAT_ID: 123456,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_1",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_1",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1187,7 +1187,7 @@ async def test_delete_message(
|
||||
{
|
||||
ATTR_CHAT_ID: 123456,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_1",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_1",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1616,7 +1616,7 @@ async def test_send_video(
|
||||
{
|
||||
ATTR_CHAT_ID: 123456,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_1",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_1",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1648,7 +1648,7 @@ async def test_send_video(
|
||||
{
|
||||
ATTR_CHAT_ID: 123456,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_1",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_1",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1837,7 +1837,7 @@ async def test_send_message_multi_target(
|
||||
{
|
||||
ATTR_CHAT_ID: 654321,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_2",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_2",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1857,7 +1857,7 @@ async def test_notify_entity_send_message(
|
||||
response = await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_SEND_MESSAGE,
|
||||
{ATTR_ENTITY_ID: "notify.mock_title_mock_chat_2", ATTR_MESSAGE: "test_message"},
|
||||
{ATTR_ENTITY_ID: "notify.mock_chat_2", ATTR_MESSAGE: "test_message"},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
@@ -1867,7 +1867,7 @@ async def test_notify_entity_send_message(
|
||||
{
|
||||
ATTR_CHAT_ID: 654321,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_2",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_2",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1921,7 +1921,7 @@ async def test_migrate_chat_id(
|
||||
{
|
||||
ATTR_CHAT_ID: 654321,
|
||||
ATTR_MESSAGE_ID: 12345,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_2",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_2",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2616,7 +2616,7 @@ async def test_send_media_group(
|
||||
"chats": [
|
||||
{
|
||||
ATTR_CHAT_ID: 123456,
|
||||
ATTR_ENTITY_ID: "notify.mock_title_mock_chat_1",
|
||||
ATTR_ENTITY_ID: "notify.mock_chat_1",
|
||||
ATTR_MESSAGE_ID: [12345, 12346, 12347, 12348],
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user