mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Add event entities to Overseerr (#134975)
This commit is contained in:
parent
c4ac648a2b
commit
d7315f4500
@ -17,14 +17,15 @@ from homeassistant.components.webhook import (
|
|||||||
from homeassistant.const import CONF_WEBHOOK_ID, Platform
|
from homeassistant.const import CONF_WEBHOOK_ID, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.helpers.http import HomeAssistantView
|
from homeassistant.helpers.http import HomeAssistantView
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
from .const import DOMAIN, JSON_PAYLOAD, LOGGER, REGISTERED_NOTIFICATIONS
|
from .const import DOMAIN, EVENT_KEY, JSON_PAYLOAD, LOGGER, REGISTERED_NOTIFICATIONS
|
||||||
from .coordinator import OverseerrConfigEntry, OverseerrCoordinator
|
from .coordinator import OverseerrConfigEntry, OverseerrCoordinator
|
||||||
from .services import setup_services
|
from .services import setup_services
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
PLATFORMS: list[Platform] = [Platform.EVENT, Platform.SENSOR]
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
||||||
|
|
||||||
@ -129,6 +130,7 @@ class OverseerrWebhookManager:
|
|||||||
LOGGER.debug("Received webhook payload: %s", data)
|
LOGGER.debug("Received webhook payload: %s", data)
|
||||||
if data["notification_type"].startswith("MEDIA"):
|
if data["notification_type"].startswith("MEDIA"):
|
||||||
await self.entry.runtime_data.async_refresh()
|
await self.entry.runtime_data.async_refresh()
|
||||||
|
async_dispatcher_send(hass, EVENT_KEY, data)
|
||||||
return HomeAssistantView.json({"message": "ok"})
|
return HomeAssistantView.json({"message": "ok"})
|
||||||
|
|
||||||
async def unregister_webhook(self) -> None:
|
async def unregister_webhook(self) -> None:
|
||||||
|
@ -14,6 +14,8 @@ ATTR_STATUS = "status"
|
|||||||
ATTR_SORT_ORDER = "sort_order"
|
ATTR_SORT_ORDER = "sort_order"
|
||||||
ATTR_REQUESTED_BY = "requested_by"
|
ATTR_REQUESTED_BY = "requested_by"
|
||||||
|
|
||||||
|
EVENT_KEY = f"{DOMAIN}_event"
|
||||||
|
|
||||||
REGISTERED_NOTIFICATIONS = (
|
REGISTERED_NOTIFICATIONS = (
|
||||||
NotificationType.REQUEST_PENDING_APPROVAL
|
NotificationType.REQUEST_PENDING_APPROVAL
|
||||||
| NotificationType.REQUEST_APPROVED
|
| NotificationType.REQUEST_APPROVED
|
||||||
@ -23,28 +25,24 @@ REGISTERED_NOTIFICATIONS = (
|
|||||||
| NotificationType.REQUEST_AUTOMATICALLY_APPROVED
|
| NotificationType.REQUEST_AUTOMATICALLY_APPROVED
|
||||||
)
|
)
|
||||||
JSON_PAYLOAD = (
|
JSON_PAYLOAD = (
|
||||||
'"{\\"notification_type\\":\\"{{notification_type}}\\",\\"event\\":\\"'
|
'"{\\"notification_type\\":\\"{{notification_type}}\\",\\"subject\\":\\"{{subject}'
|
||||||
'{{event}}\\",\\"subject\\":\\"{{subject}}\\",\\"message\\":\\"{{messa'
|
'}\\",\\"message\\":\\"{{message}}\\",\\"image\\":\\"{{image}}\\",\\"{{media}}\\":'
|
||||||
'ge}}\\",\\"image\\":\\"{{image}}\\",\\"{{media}}\\":{\\"media_type\\"'
|
'{\\"media_type\\":\\"{{media_type}}\\",\\"tmdb_idd\\":\\"{{media_tmdbid}}\\",\\"t'
|
||||||
':\\"{{media_type}}\\",\\"tmdbId\\":\\"{{media_tmdbid}}\\",\\"tvdbId\\'
|
'vdb_id\\":\\"{{media_tvdbid}}\\",\\"status\\":\\"{{media_status}}\\",\\"status4k'
|
||||||
'":\\"{{media_tvdbid}}\\",\\"status\\":\\"{{media_status}}\\",\\"statu'
|
'\\":\\"{{media_status4k}}\\"},\\"{{request}}\\":{\\"request_id\\":\\"{{request_id'
|
||||||
's4k\\":\\"{{media_status4k}}\\"},\\"{{request}}\\":{\\"request_id\\":'
|
'}}\\",\\"requested_by_email\\":\\"{{requestedBy_email}}\\",\\"requested_by_userna'
|
||||||
'\\"{{request_id}}\\",\\"requestedBy_email\\":\\"{{requestedBy_email}}'
|
'me\\":\\"{{requestedBy_username}}\\",\\"requested_by_avatar\\":\\"{{requestedBy_a'
|
||||||
'\\",\\"requestedBy_username\\":\\"{{requestedBy_username}}\\",\\"requ'
|
'vatar}}\\",\\"requested_by_settings_discord_id\\":\\"{{requestedBy_settings_disco'
|
||||||
'estedBy_avatar\\":\\"{{requestedBy_avatar}}\\",\\"requestedBy_setting'
|
'rdId}}\\",\\"requested_by_settings_telegram_chat_id\\":\\"{{requestedBy_settings_'
|
||||||
's_discordId\\":\\"{{requestedBy_settings_discordId}}\\",\\"requestedB'
|
'telegramChatId}}\\"},\\"{{issue}}\\":{\\"issue_id\\":\\"{{issue_id}}\\",\\"issue_'
|
||||||
'y_settings_telegramChatId\\":\\"{{requestedBy_settings_telegramChatId'
|
'type\\":\\"{{issue_type}}\\",\\"issue_status\\":\\"{{issue_status}}\\",\\"reporte'
|
||||||
'}}\\"},\\"{{issue}}\\":{\\"issue_id\\":\\"{{issue_id}}\\",\\"issue_ty'
|
'd_by_email\\":\\"{{reportedBy_email}}\\",\\"reported_by_username\\":\\"{{reported'
|
||||||
'pe\\":\\"{{issue_type}}\\",\\"issue_status\\":\\"{{issue_status}}\\",'
|
'By_username}}\\",\\"reported_by_avatar\\":\\"{{reportedBy_avatar}}\\",\\"reported'
|
||||||
'\\"reportedBy_email\\":\\"{{reportedBy_email}}\\",\\"reportedBy_usern'
|
'_by_settings_discord_id\\":\\"{{reportedBy_settings_discordId}}\\",\\"reported_by'
|
||||||
'ame\\":\\"{{reportedBy_username}}\\",\\"reportedBy_avatar\\":\\"{{rep'
|
'_settings_telegram_chat_id\\":\\"{{reportedBy_settings_telegramChatId}}\\"},\\"{{'
|
||||||
'ortedBy_avatar}}\\",\\"reportedBy_settings_discordId\\":\\"{{reported'
|
'comment}}\\":{\\"comment_message\\":\\"{{comment_message}}\\",\\"commented_by_ema'
|
||||||
'By_settings_discordId}}\\",\\"reportedBy_settings_telegramChatId\\":'
|
'il\\":\\"{{commentedBy_email}}\\",\\"commented_by_username\\":\\"{{commentedBy_us'
|
||||||
'\\"{{reportedBy_settings_telegramChatId}}\\"},\\"{{comment}}\\":{\\"c'
|
'ername}}\\",\\"commented_by_avatar\\":\\"{{commentedBy_avatar}}\\",\\"commented_b'
|
||||||
'omment_message\\":\\"{{comment_message}}\\",\\"commentedBy_email\\":'
|
'y_settings_discord_id\\":\\"{{commentedBy_settings_discordId}}\\",\\"commented_by'
|
||||||
'\\"{{commentedBy_email}}\\",\\"commentedBy_username\\":\\"{{commented'
|
'_settings_telegram_chat_id\\":\\"{{commentedBy_settings_telegramChatId}}\\"}}"'
|
||||||
'By_username}}\\",\\"commentedBy_avatar\\":\\"{{commentedBy_avatar}}'
|
|
||||||
'\\",\\"commentedBy_settings_discordId\\":\\"{{commentedBy_settings_di'
|
|
||||||
'scordId}}\\",\\"commentedBy_settings_telegramChatId\\":\\"{{commented'
|
|
||||||
'By_settings_telegramChatId}}\\"},\\"{{extra}}\\":[]\\n}"'
|
|
||||||
)
|
)
|
||||||
|
99
homeassistant/components/overseerr/event.py
Normal file
99
homeassistant/components/overseerr/event.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
"""Support for Overseerr events."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from homeassistant.components.event import EventEntity, EventEntityDescription
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import EVENT_KEY
|
||||||
|
from .coordinator import OverseerrConfigEntry, OverseerrCoordinator
|
||||||
|
from .entity import OverseerrEntity
|
||||||
|
|
||||||
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class OverseerrEventEntityDescription(EventEntityDescription):
|
||||||
|
"""Describes Overseerr config event entity."""
|
||||||
|
|
||||||
|
nullable_fields: list[str]
|
||||||
|
|
||||||
|
|
||||||
|
EVENTS: tuple[OverseerrEventEntityDescription, ...] = (
|
||||||
|
OverseerrEventEntityDescription(
|
||||||
|
key="media",
|
||||||
|
translation_key="last_media_event",
|
||||||
|
event_types=[
|
||||||
|
"pending",
|
||||||
|
"approved",
|
||||||
|
"available",
|
||||||
|
"failed",
|
||||||
|
"declined",
|
||||||
|
"auto_approved",
|
||||||
|
],
|
||||||
|
nullable_fields=["comment", "issue"],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: OverseerrConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up Overseerr sensor entities based on a config entry."""
|
||||||
|
|
||||||
|
coordinator = entry.runtime_data
|
||||||
|
async_add_entities(
|
||||||
|
OverseerrEvent(coordinator, description) for description in EVENTS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class OverseerrEvent(OverseerrEntity, EventEntity):
|
||||||
|
"""Defines a Overseerr event entity."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator: OverseerrCoordinator,
|
||||||
|
description: OverseerrEventEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize Overseerr event entity."""
|
||||||
|
super().__init__(coordinator, description.key)
|
||||||
|
self.entity_description = description
|
||||||
|
self._attr_available = True
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Subscribe to updates."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
self.async_on_remove(
|
||||||
|
async_dispatcher_connect(self.hass, EVENT_KEY, self._handle_update)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _handle_update(self, event: dict[str, Any]) -> None:
|
||||||
|
"""Handle incoming event."""
|
||||||
|
event_type = event["notification_type"].lower()
|
||||||
|
if event_type.split("_")[0] == self.entity_description.key:
|
||||||
|
self._trigger_event(event_type[6:], event)
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
if super().available != self._attr_available:
|
||||||
|
self._attr_available = super().available
|
||||||
|
super()._handle_coordinator_update()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return True if entity is available."""
|
||||||
|
return self._attr_available
|
||||||
|
|
||||||
|
|
||||||
|
def parse_event(event: dict[str, Any], nullable_fields: list[str]) -> dict[str, Any]:
|
||||||
|
"""Parse event."""
|
||||||
|
event.pop("notification_type")
|
||||||
|
for field in nullable_fields:
|
||||||
|
event.pop(field)
|
||||||
|
return event
|
@ -21,6 +21,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
|
"event": {
|
||||||
|
"last_media_event": {
|
||||||
|
"name": "Last media event",
|
||||||
|
"state": {
|
||||||
|
"pending": "Pending",
|
||||||
|
"approved": "Approved",
|
||||||
|
"available": "Available",
|
||||||
|
"failed": "Failed",
|
||||||
|
"declined": "Declined",
|
||||||
|
"auto_approved": "Auto-approved"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"sensor": {
|
"sensor": {
|
||||||
"total_requests": {
|
"total_requests": {
|
||||||
"name": "Total requests"
|
"name": "Total requests"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"enabled": true,
|
"enabled": true,
|
||||||
"types": 222,
|
"types": 222,
|
||||||
"options": {
|
"options": {
|
||||||
"jsonPayload": "{\"notification_type\":\"{{notification_type}}\",\"event\":\"{{event}}\",\"subject\":\"{{subject}}\",\"message\":\"{{message}}\",\"image\":\"{{image}}\",\"{{media}}\":{\"media_type\":\"{{media_type}}\",\"tmdbId\":\"{{media_tmdbid}}\",\"tvdbId\":\"{{media_tvdbid}}\",\"status\":\"{{media_status}}\",\"status4k\":\"{{media_status4k}}\"},\"{{request}}\":{\"request_id\":\"{{request_id}}\",\"requestedBy_email\":\"{{requestedBy_email}}\",\"requestedBy_username\":\"{{requestedBy_username}}\",\"requestedBy_avatar\":\"{{requestedBy_avatar}}\",\"requestedBy_settings_discordId\":\"{{requestedBy_settings_discordId}}\",\"requestedBy_settings_telegramChatId\":\"{{requestedBy_settings_telegramChatId}}\"},\"{{issue}}\":{\"issue_id\":\"{{issue_id}}\",\"issue_type\":\"{{issue_type}}\",\"issue_status\":\"{{issue_status}}\",\"reportedBy_email\":\"{{reportedBy_email}}\",\"reportedBy_username\":\"{{reportedBy_username}}\",\"reportedBy_avatar\":\"{{reportedBy_avatar}}\",\"reportedBy_settings_discordId\":\"{{reportedBy_settings_discordId}}\",\"reportedBy_settings_telegramChatId\":\"{{reportedBy_settings_telegramChatId}}\"},\"{{comment}}\":{\"comment_message\":\"{{comment_message}}\",\"commentedBy_email\":\"{{commentedBy_email}}\",\"commentedBy_username\":\"{{commentedBy_username}}\",\"commentedBy_avatar\":\"{{commentedBy_avatar}}\",\"commentedBy_settings_discordId\":\"{{commentedBy_settings_discordId}}\",\"commentedBy_settings_telegramChatId\":\"{{commentedBy_settings_telegramChatId}}\"},\"{{extra}}\":[]\n}",
|
"jsonPayload": "{\"notification_type\":\"{{notification_type}}\",\"subject\":\"{{subject}}\",\"message\":\"{{message}}\",\"image\":\"{{image}}\",\"{{media}}\":{\"media_type\":\"{{media_type}}\",\"tmdb_idd\":\"{{media_tmdbid}}\",\"tvdb_id\":\"{{media_tvdbid}}\",\"status\":\"{{media_status}}\",\"status4k\":\"{{media_status4k}}\"},\"{{request}}\":{\"request_id\":\"{{request_id}}\",\"requested_by_email\":\"{{requestedBy_email}}\",\"requested_by_username\":\"{{requestedBy_username}}\",\"requested_by_avatar\":\"{{requestedBy_avatar}}\",\"requested_by_settings_discord_id\":\"{{requestedBy_settings_discordId}}\",\"requested_by_settings_telegram_chat_id\":\"{{requestedBy_settings_telegramChatId}}\"},\"{{issue}}\":{\"issue_id\":\"{{issue_id}}\",\"issue_type\":\"{{issue_type}}\",\"issue_status\":\"{{issue_status}}\",\"reported_by_email\":\"{{reportedBy_email}}\",\"reported_by_username\":\"{{reportedBy_username}}\",\"reported_by_avatar\":\"{{reportedBy_avatar}}\",\"reported_by_settings_discord_id\":\"{{reportedBy_settings_discordId}}\",\"reported_by_settings_telegram_chat_id\":\"{{reportedBy_settings_telegramChatId}}\"},\"{{comment}}\":{\"comment_message\":\"{{comment_message}}\",\"commented_by_email\":\"{{commentedBy_email}}\",\"commented_by_username\":\"{{commentedBy_username}}\",\"commented_by_avatar\":\"{{commentedBy_avatar}}\",\"commented_by_settings_discord_id\":\"{{commentedBy_settings_discordId}}\",\"commented_by_settings_telegram_chat_id\":\"{{commentedBy_settings_telegramChatId}}\"}}",
|
||||||
"webhookUrl": "http://10.10.10.10:8123/api/webhook/test-webhook-id"
|
"webhookUrl": "http://10.10.10.10:8123/api/webhook/test-webhook-id"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,23 @@
|
|||||||
{
|
{
|
||||||
"notification_type": "MEDIA_AUTO_APPROVED",
|
"notification_type": "MEDIA_AUTO_APPROVED",
|
||||||
"event": "Movie Request Automatically Approved",
|
|
||||||
"subject": "Something (2024)",
|
"subject": "Something (2024)",
|
||||||
"message": "Here is an interesting Linux ISO that was automatically approved.",
|
"message": "Here is an interesting Linux ISO that was automatically approved.",
|
||||||
"image": "https://image.tmdb.org/t/p/w600_and_h900_bestv2/something.jpg",
|
"image": "https://image.tmdb.org/t/p/w600_and_h900_bestv2/something.jpg",
|
||||||
"media": {
|
"media": {
|
||||||
"media_type": "movie",
|
"media_type": "movie",
|
||||||
"tmdbId": "123",
|
"tmdb_id": "123",
|
||||||
"tvdbId": "",
|
"tvdb_id": "",
|
||||||
"status": "PENDING",
|
"status": "PENDING",
|
||||||
"status4k": "UNKNOWN"
|
"status4k": "UNKNOWN"
|
||||||
},
|
},
|
||||||
"request": {
|
"request": {
|
||||||
"request_id": "16",
|
"request_id": "16",
|
||||||
"requestedBy_email": "my@email.com",
|
"requested_by_email": "my@email.com",
|
||||||
"requestedBy_username": "henk",
|
"requested_by_username": "henk",
|
||||||
"requestedBy_avatar": "https://plex.tv/users/abc/avatar?c=123",
|
"requested_by_avatar": "https://plex.tv/users/abc/avatar?c=123",
|
||||||
"requestedBy_settings_discordId": "123",
|
"requested_by_settings_discord_id": "123",
|
||||||
"requestedBy_settings_telegramChatId": ""
|
"requested_by_settings_telegram_chat_id": ""
|
||||||
},
|
},
|
||||||
"issue": null,
|
"issue": null,
|
||||||
"comment": null,
|
"comment": null
|
||||||
"extra": []
|
|
||||||
}
|
}
|
||||||
|
86
tests/components/overseerr/snapshots/test_event.ambr
Normal file
86
tests/components/overseerr/snapshots/test_event.ambr
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_entities[event.overseerr_last_media_event-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'event_types': list([
|
||||||
|
'pending',
|
||||||
|
'approved',
|
||||||
|
'available',
|
||||||
|
'failed',
|
||||||
|
'declined',
|
||||||
|
'auto_approved',
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'event',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'event.overseerr_last_media_event',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Last media event',
|
||||||
|
'platform': 'overseerr',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'last_media_event',
|
||||||
|
'unique_id': '01JG00V55WEVTJ0CJHM0GAD7PC-media',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_entities[event.overseerr_last_media_event-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'comment': None,
|
||||||
|
'event_type': 'auto_approved',
|
||||||
|
'event_types': list([
|
||||||
|
'pending',
|
||||||
|
'approved',
|
||||||
|
'available',
|
||||||
|
'failed',
|
||||||
|
'declined',
|
||||||
|
'auto_approved',
|
||||||
|
]),
|
||||||
|
'friendly_name': 'Overseerr Last media event',
|
||||||
|
'image': 'https://image.tmdb.org/t/p/w600_and_h900_bestv2/something.jpg',
|
||||||
|
'issue': None,
|
||||||
|
'media': dict({
|
||||||
|
'media_type': 'movie',
|
||||||
|
'status': 'PENDING',
|
||||||
|
'status4k': 'UNKNOWN',
|
||||||
|
'tmdb_id': '123',
|
||||||
|
'tvdb_id': '',
|
||||||
|
}),
|
||||||
|
'message': 'Here is an interesting Linux ISO that was automatically approved.',
|
||||||
|
'notification_type': 'MEDIA_AUTO_APPROVED',
|
||||||
|
'request': dict({
|
||||||
|
'request_id': '16',
|
||||||
|
'requested_by_avatar': 'https://plex.tv/users/abc/avatar?c=123',
|
||||||
|
'requested_by_email': 'my@email.com',
|
||||||
|
'requested_by_settings_discord_id': '123',
|
||||||
|
'requested_by_settings_telegram_chat_id': '',
|
||||||
|
'requested_by_username': 'henk',
|
||||||
|
}),
|
||||||
|
'subject': 'Something (2024)',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'event.overseerr_last_media_event',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '2023-10-21T00:00:00.000+00:00',
|
||||||
|
})
|
||||||
|
# ---
|
109
tests/components/overseerr/test_event.py
Normal file
109
tests/components/overseerr/test_event.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
"""Tests for the Overseerr event platform."""
|
||||||
|
|
||||||
|
from datetime import UTC, datetime
|
||||||
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
|
from future.backports.datetime import timedelta
|
||||||
|
import pytest
|
||||||
|
from python_overseerr import OverseerrConnectionError
|
||||||
|
from syrupy import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.components.overseerr import DOMAIN
|
||||||
|
from homeassistant.const import STATE_UNAVAILABLE, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from . import call_webhook, setup_integration
|
||||||
|
|
||||||
|
from tests.common import (
|
||||||
|
MockConfigEntry,
|
||||||
|
async_fire_time_changed,
|
||||||
|
load_json_object_fixture,
|
||||||
|
snapshot_platform,
|
||||||
|
)
|
||||||
|
from tests.typing import ClientSessionGenerator
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.freeze_time("2023-10-21")
|
||||||
|
async def test_entities(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_overseerr_client: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
hass_client_no_auth: ClientSessionGenerator,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
) -> None:
|
||||||
|
"""Test all entities."""
|
||||||
|
with patch("homeassistant.components.overseerr.PLATFORMS", [Platform.EVENT]):
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
client = await hass_client_no_auth()
|
||||||
|
|
||||||
|
await call_webhook(
|
||||||
|
hass,
|
||||||
|
load_json_object_fixture("webhook_request_automatically_approved.json", DOMAIN),
|
||||||
|
client,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.freeze_time("2023-10-21")
|
||||||
|
async def test_event_does_not_write_state(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_overseerr_client: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
hass_client_no_auth: ClientSessionGenerator,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test event entities don't write state on coordinator update."""
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
client = await hass_client_no_auth()
|
||||||
|
|
||||||
|
await call_webhook(
|
||||||
|
hass,
|
||||||
|
load_json_object_fixture("webhook_request_automatically_approved.json", DOMAIN),
|
||||||
|
client,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get(
|
||||||
|
"event.overseerr_last_media_event"
|
||||||
|
).last_reported == datetime(2023, 10, 21, 0, 0, 0, tzinfo=UTC)
|
||||||
|
|
||||||
|
freezer.tick(timedelta(minutes=5))
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get(
|
||||||
|
"event.overseerr_last_media_event"
|
||||||
|
).last_reported == datetime(2023, 10, 21, 0, 0, 0, tzinfo=UTC)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_event_goes_unavailable(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_overseerr_client: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test event entities go unavailable when we can't fetch data."""
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("event.overseerr_last_media_event").state != STATE_UNAVAILABLE
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_overseerr_client.get_request_count.side_effect = OverseerrConnectionError(
|
||||||
|
"Boom"
|
||||||
|
)
|
||||||
|
|
||||||
|
freezer.tick(timedelta(minutes=5))
|
||||||
|
async_fire_time_changed(hass)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("event.overseerr_last_media_event").state == STATE_UNAVAILABLE
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user