Files

182 lines
5.8 KiB
Python

"""Tests for webhooks."""
from ipaddress import IPv4Network
from unittest.mock import AsyncMock, patch
from telegram.error import TimedOut
from homeassistant.components.telegram_bot.bot import ALLOWED_UPDATES
from homeassistant.components.telegram_bot.const import DOMAIN
from homeassistant.components.telegram_bot.webhooks import TELEGRAM_WEBHOOK_URL
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
from tests.typing import ClientSessionGenerator
async def test_set_webhooks_failed(
hass: HomeAssistant,
mock_webhooks_config_entry: MockConfigEntry,
mock_external_calls: None,
mock_register_webhook: None,
) -> None:
"""Test set webhooks failed."""
mock_webhooks_config_entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.telegram_bot.webhooks.secrets.choice",
return_value="DEADBEEF12345678DEADBEEF87654321",
),
patch(
"homeassistant.components.telegram_bot.webhooks.Bot.set_webhook",
) as mock_set_webhook,
patch(
"homeassistant.components.telegram_bot.webhooks.Application.start",
AsyncMock(),
) as mock_start,
):
mock_set_webhook.side_effect = [TimedOut("mock timeout"), False]
await hass.config_entries.async_setup(mock_webhooks_config_entry.entry_id)
await hass.async_block_till_done()
await hass.async_stop()
# first fail with exception, second fail with False
assert mock_set_webhook.call_count == 2
# SETUP_ERROR is result of RuntimeError(
# "Failed to register webhook with Telegram") in webhooks.py
assert mock_webhooks_config_entry.state is ConfigEntryState.SETUP_ERROR
# test fail after retries
mock_set_webhook.reset_mock()
mock_set_webhook.side_effect = TimedOut("mock timeout")
await hass.config_entries.async_reload(mock_webhooks_config_entry.entry_id)
await hass.async_block_till_done()
# 3 retries
assert mock_set_webhook.call_count == 3
assert mock_webhooks_config_entry.state is ConfigEntryState.SETUP_ERROR
await hass.async_block_till_done()
assert mock_start.call_count == 0
async def test_set_webhooks(
hass: HomeAssistant,
mock_webhooks_config_entry: MockConfigEntry,
mock_external_calls: None,
mock_register_webhook: None,
mock_generate_secret_token,
) -> None:
"""Test set webhooks success."""
mock_webhooks_config_entry.add_to_hass(hass)
with patch(
"homeassistant.components.telegram_bot.webhooks.Application.start", AsyncMock()
) as mock_start:
await hass.config_entries.async_setup(mock_webhooks_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_webhooks_config_entry.state is ConfigEntryState.LOADED
mock_start.assert_called_once()
async def test_set_webhooks_allowed_updates(
hass: HomeAssistant,
mock_webhooks_config_entry: MockConfigEntry,
mock_external_calls: None,
mock_register_webhook: None,
mock_generate_secret_token: str,
) -> None:
"""Test the webhook is registered for the updates the integration handles.
Telegram keeps the setting per bot and reuses the last one it was given
when it is omitted, so it has to be sent on every registration.
"""
mock_webhooks_config_entry.add_to_hass(hass)
with (
patch(
"homeassistant.components.telegram_bot.webhooks.Application.start",
AsyncMock(),
),
patch(
"homeassistant.components.telegram_bot.webhooks.Bot.set_webhook",
return_value=True,
) as mock_set_webhook,
):
await hass.config_entries.async_setup(mock_webhooks_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_webhooks_config_entry.state is ConfigEntryState.LOADED
assert mock_set_webhook.call_args.kwargs["allowed_updates"] == ALLOWED_UPDATES
async def test_webhooks_update_invalid_json(
hass: HomeAssistant,
webhook_bot,
hass_client: ClientSessionGenerator,
mock_generate_secret_token,
) -> None:
"""Test update with invalid json."""
client = await hass_client()
response = await client.post(
f"{TELEGRAM_WEBHOOK_URL}_123456",
headers={"X-Telegram-Bot-Api-Secret-Token": mock_generate_secret_token},
)
assert response.status == 400
await hass.async_block_till_done()
async def test_webhooks_unauthorized_network(
hass: HomeAssistant,
webhook_bot,
mock_generate_secret_token,
hass_client: ClientSessionGenerator,
) -> None:
"""Test update with request outside of trusted networks."""
client = await hass_client()
with patch(
"homeassistant.components.telegram_bot.webhooks.ip_address",
return_value=IPv4Network("1.2.3.4"),
) as mock_remote:
response = await client.post(
f"{TELEGRAM_WEBHOOK_URL}_123456",
json="mock json",
headers={"X-Telegram-Bot-Api-Secret-Token": mock_generate_secret_token},
)
assert response.status == 401
await hass.async_block_till_done()
mock_remote.assert_called_once()
async def test_webhooks_deregister_failed(
hass: HomeAssistant,
webhook_bot,
) -> None:
"""Test deregister webhooks."""
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
assert config_entry.state is ConfigEntryState.LOADED
with patch(
"homeassistant.components.telegram_bot.webhooks.Bot.delete_webhook",
) as mock_delete_webhook:
mock_delete_webhook.side_effect = TimedOut("mock timeout")
await hass.config_entries.async_unload(config_entry.entry_id)
mock_delete_webhook.assert_called_once()
assert config_entry.state is ConfigEntryState.NOT_LOADED