Skip to content

test(channels): add Telethon-based E2E test suite for Telegram channel using Telegram Test DC #2122

@bug-ops

Description

@bug-ops

Problem

TelegramChannel is the only production-facing channel that has never been live-tested in CI sessions. All journal entries are "Build verified" only. Bugs in MarkdownV2 escaping, streaming state, attachment handling, or allowed_users enforcement are invisible in unit tests and only surface with real users.

A "2-bot-in-group" approach is non-functional: Telegram Bot API never delivers messages from one bot to another, even with privacy mode disabled — this is a hard platform constraint.

Proposed Solution

Add a scripted E2E test suite using Telethon (Python MTProto client) with a user account on the Telegram Test DC (isolated from production, test phone numbers in +99966XXXXX format, no real SIM needed).

Components

1. Test runner script.local/testing/telegram_e2e.py

A Telethon client that connects to Test DC, sends scripted prompts to the Zeph bot, and asserts on bot replies. Scenarios:

  • /start → welcome message present
  • Math prompt 347 * 89 → reply contains 30,883
  • /reset → agent resets conversation
  • /skills → skills list returned without MarkdownV2 parse error
  • Unauthorized user → no reply, WARN logged
  • Long response (>4096 chars) → multiple messages received in order
  • confirm() timeout → denied after 30s
  • Empty message (sticker) → no reply

2. Fixture bot — a dedicated @ZephTestBot token stored as ZEPH_TELEGRAM_TEST_TOKEN in vault, connected to Telegram Test DC. Separate from any production bot token.

3. Test DC account sessiontest_session.session stored in .local/testing/ (gitignored). One-time setup via python3 .local/testing/setup_tg_test_account.py.

4. CI integration (optional) — gated by ZEPH_TELEGRAM_TEST_TOKEN and TELEGRAM_TEST_SESSION GitHub secrets, runs on push to main only (not PRs, to avoid flakiness on external service).

Key scripts

# .local/testing/setup_tg_test_account.py — run once
from telethon.sync import TelegramClient
API_ID = ...
API_HASH = "..."
client = TelegramClient('test_session', API_ID, API_HASH,
                        server=('149.154.167.40', 443))  # Test DC server
client.start(phone='+99966XXXXX')  # OTP = XXXXX
# .local/testing/telegram_e2e.py — run each CI session
import asyncio, sys
from telethon import TelegramClient, events

async def run_scenarios(client, bot):
    results = []
    # ... per-scenario send + assert pattern ...
    return results

Zeph config for Test DC

# .local/config/telegram-test.toml
[telegram]
token = { vault = "ZEPH_TELEGRAM_TEST_TOKEN" }
allowed_users = ["zeph_test_user"]

[llm]
provider = "openai"  # or router

Zeph itself does not need Test DC awareness — only the Telethon client connects to Test DC. The bot token for Test DC is obtained from @BotFather on the test server.

Acceptance Criteria

  • setup_tg_test_account.py creates a persistent session file for Test DC
  • telegram_e2e.py runs all 8 scenarios without manual interaction
  • Each scenario prints [PASS] / [FAIL] with reply excerpt
  • Script exits non-zero on any failure
  • Playbook .local/testing/playbooks/telegram-channel.md (Approach 2) updated with exact run instructions
  • Sessions are ephemeral: no persistent chat history between runs (/reset at start)
  • test_session.session added to .gitignore

Test Scenarios

Scenario Prompt / Action Assert
startup /start reply contains "Welcome"
math What is 347 * 89? reply contains 30,883
reset /reset any reply OR next message starts fresh context
skills /skills reply received, no MarkdownV2 error in log
unauthorized message from non-listed account no reply within 10s
long output prompt triggering >4096 char response ≥2 messages received
empty msg sticker (no text/attachment) no reply within 5s
streaming long-form explanation prompt first message appears before completion (intermediate edit visible)

Priority

Medium — enables automated regression detection for the Telegram channel. Current state (manual only, never tested in CI) means bugs in this channel can persist across dozens of CI cycles undetected.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    channelszeph-channels crate (Telegram)enhancementNew feature or requesttestingTests and quality

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions