0eb899afb9
Notifications: - Add shared http_base, redact, and SSRF hardening modules - Refactor dispatcher, queue, receiver and per-provider clients (telegram, discord, email, matrix, ntfy, slack, webhook) to use the shared base, with bounded queue and redacted error logs - Tests for ssrf, redact, http_base, queue bounds, dispatcher aggregation, telegram media partition, email and matrix clients Frontend: - Settings: log level / log format selectors now use IconGridSelect with per-option icons and i18n descriptions - Minor providers page and entity-cache store updates Tooling: - Document code-review-graph MCP usage in CLAUDE.md - Ignore .code-review-graph/, register .mcp.json
57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
"""Telegram media-group mixed-type partitioning regression test.
|
|
|
|
Telegram rejects sendMediaGroup payloads that mix ``document`` with
|
|
``photo``/``video``. The client must partition before chunking so a
|
|
mixed input list still delivers all assets.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from notify_bridge_core.notifications.telegram.client import TelegramClient
|
|
|
|
|
|
def test_partition_keeps_photo_video_together() -> None:
|
|
parts = TelegramClient._partition_media_by_kind([
|
|
{"type": "photo", "url": "p1"},
|
|
{"type": "video", "url": "v1"},
|
|
{"type": "photo", "url": "p2"},
|
|
])
|
|
assert len(parts) == 1
|
|
assert [a["url"] for a in parts[0]] == ["p1", "v1", "p2"]
|
|
|
|
|
|
def test_partition_separates_documents_from_media() -> None:
|
|
parts = TelegramClient._partition_media_by_kind([
|
|
{"type": "photo", "url": "p1"},
|
|
{"type": "document", "url": "d1"},
|
|
{"type": "video", "url": "v1"},
|
|
])
|
|
assert len(parts) == 3
|
|
assert parts[0][0]["url"] == "p1"
|
|
assert parts[1][0]["url"] == "d1"
|
|
assert parts[2][0]["url"] == "v1"
|
|
|
|
|
|
def test_partition_groups_consecutive_documents() -> None:
|
|
parts = TelegramClient._partition_media_by_kind([
|
|
{"type": "document", "url": "d1"},
|
|
{"type": "document", "url": "d2"},
|
|
{"type": "photo", "url": "p1"},
|
|
])
|
|
assert len(parts) == 2
|
|
assert [a["url"] for a in parts[0]] == ["d1", "d2"]
|
|
assert parts[1][0]["url"] == "p1"
|
|
|
|
|
|
def test_partition_empty() -> None:
|
|
assert TelegramClient._partition_media_by_kind([]) == []
|
|
|
|
|
|
def test_partition_defaults_missing_type_to_photo() -> None:
|
|
"""Items without an explicit type are treated as photos for grouping."""
|
|
parts = TelegramClient._partition_media_by_kind([
|
|
{"url": "x"}, # no type
|
|
{"type": "video", "url": "v"},
|
|
])
|
|
assert len(parts) == 1
|