Change-detectors, tautologies, source-reading tests, redundant duplicates, mock-echo tests and dead/unrunnable tests. Per-test rationale in the lane ledger (category + reason for every removal).
107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
"""Cold-boot pending-queue knob for the Telegram adapter.
|
|
|
|
Contract: a cold boot drops Telegram's server-side pending updates unless
|
|
``extra.drop_pending_on_cold_boot`` is false; a watcher reconnect always
|
|
preserves them. Conflict recovery is a separate path and is not covered here.
|
|
"""
|
|
|
|
import logging
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock
|
|
|
|
import pytest
|
|
|
|
from gateway.config import PlatformConfig
|
|
from plugins.platforms.telegram.adapter import TelegramAdapter
|
|
|
|
|
|
def _make_adapter(extra=None) -> TelegramAdapter:
|
|
return TelegramAdapter(PlatformConfig(enabled=True, token="test-token", extra=extra or {}))
|
|
|
|
|
|
async def _capture_drop_pending(adapter: TelegramAdapter, *, is_reconnect: bool):
|
|
"""Run _start_polling_mode with staging mocked; return the forwarded flag."""
|
|
captured = {}
|
|
adapter._delete_webhook_best_effort = AsyncMock()
|
|
|
|
async def _fake_resilient(*, drop_pending_updates, error_callback, require_progress=False):
|
|
captured["drop_pending_updates"] = drop_pending_updates
|
|
captured["require_progress"] = require_progress
|
|
return True
|
|
|
|
adapter._start_polling_resilient = _fake_resilient
|
|
await adapter._start_polling_mode(is_reconnect=is_reconnect)
|
|
return captured
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_cold_boot_drops_queue_by_default():
|
|
"""Default config: cold boot drops, reconnect preserves."""
|
|
adapter = _make_adapter()
|
|
assert adapter._drop_pending_on_cold_boot is True
|
|
|
|
cold = await _capture_drop_pending(adapter, is_reconnect=False)
|
|
assert cold["drop_pending_updates"] is True
|
|
|
|
warm = await _capture_drop_pending(adapter, is_reconnect=True)
|
|
assert warm["drop_pending_updates"] is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_cold_boot_preserves_queue_when_opted_out():
|
|
"""extra.drop_pending_on_cold_boot=false: cold boot preserves the backlog."""
|
|
adapter = _make_adapter(extra={"drop_pending_on_cold_boot": False})
|
|
assert adapter._drop_pending_on_cold_boot is False
|
|
|
|
cold = await _capture_drop_pending(adapter, is_reconnect=False)
|
|
assert cold["drop_pending_updates"] is False
|
|
|
|
warm = await _capture_drop_pending(adapter, is_reconnect=True)
|
|
assert warm["drop_pending_updates"] is False
|
|
|
|
|
|
async def _capture_webhook_drop_pending(
|
|
adapter: TelegramAdapter, monkeypatch, *, is_reconnect: bool
|
|
):
|
|
"""Run _start_webhook_mode against a stub updater; return the forwarded flag."""
|
|
captured = {}
|
|
|
|
async def _fake_start_webhook(**kwargs):
|
|
captured.update(kwargs)
|
|
|
|
adapter._app = SimpleNamespace(
|
|
updater=SimpleNamespace(start_webhook=AsyncMock(side_effect=_fake_start_webhook))
|
|
)
|
|
monkeypatch.setenv("TELEGRAM_WEBHOOK_URL", "https://example.test/telegram")
|
|
monkeypatch.setenv("TELEGRAM_WEBHOOK_SECRET", "test-secret")
|
|
await adapter._start_webhook_mode(
|
|
"https://example.test/telegram", is_reconnect=is_reconnect
|
|
)
|
|
return captured
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_webhook_cold_boot_honors_the_knob_and_logs_the_decision(monkeypatch, caplog):
|
|
"""The webhook start path forwards the same policy as polling, and says which one
|
|
it applied. The flag is not a no-op there: PTB feeds it to delete_webhook /
|
|
set_webhook, which drop Telegram's stored updates."""
|
|
adapter = _make_adapter(extra={"drop_pending_on_cold_boot": False})
|
|
|
|
with caplog.at_level(logging.INFO, logger="plugins.platforms.telegram.adapter"):
|
|
captured = await _capture_webhook_drop_pending(
|
|
adapter, monkeypatch, is_reconnect=False
|
|
)
|
|
|
|
assert captured["drop_pending_updates"] is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_webhook_reconnect_preserves_queue_regardless_of_the_knob(monkeypatch):
|
|
"""A watcher reconnect keeps #46621's guarantee even when the knob asks cold
|
|
boots to drop."""
|
|
adapter = _make_adapter()
|
|
|
|
captured = await _capture_webhook_drop_pending(adapter, monkeypatch, is_reconnect=True)
|
|
|
|
assert captured["drop_pending_updates"] is False
|