125 lines
4.5 KiB
Markdown
125 lines
4.5 KiB
Markdown
# Telegram Bridge Multi-Tenant — Test Results
|
|
|
|
**Date:** 2026-04-09
|
|
**Broker Commit:** `e3fa6e6`
|
|
**Feature:** Multi-tenant Telegram bridge (4 entry points)
|
|
**Tester:** Mou (Claude Opus 4.6) + Playwright automation
|
|
**Bot:** `@claudemeshbot`
|
|
|
|
---
|
|
|
|
## Test Results: 27/30 PASS
|
|
|
|
### 1. Broker Deploy + Bridge Boot
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T1 | Broker deploys with telegram env vars | **PASS** | Deploy `n55iiz489hkr` finished |
|
|
| T2 | Bridge boots on startup | **PASS** | `[tg-bridge] bot running — 0 mesh(es), 0 chat(s)` |
|
|
| T3 | Health check | **PASS** | `{"status":"ok","db":"up","uptime":55}` |
|
|
|
|
### 2. Token Endpoint
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T4 | POST /tg/token returns JWT + deep link | **PASS** | 703-char JWT |
|
|
| T5a | Token sub=telegram-connect | **PASS** | |
|
|
| T5b | Token iss=claudemesh-broker | **PASS** | |
|
|
| T5c | Token has exp (15min TTL) | **PASS** | 900s from iat |
|
|
| T5d | Token has meshId | **PASS** | |
|
|
| T6 | Deep link format | **PASS** | `https://t.me/claudemeshbot?start=<jwt>` |
|
|
| T7 | Missing fields rejected | **PASS** | 400 error |
|
|
|
|
### 3. Entry Point A: Deep Link /start (Playwright)
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T8 | Generate token via API | **PASS** | |
|
|
| T9 | /start connects | **PASS** | "Connected to mesh alexis-mou!" |
|
|
| T10 | Bridge row in DB | **PASS** | chatId=845184042, active=true |
|
|
| T11 | Peer in list_peers | **PASS** | `tg:Alejandro [idle] {type:bridge, channel:telegram}` |
|
|
|
|
### 4. Message Routing (Playwright)
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T12 | Telegram -> Mesh broadcast | **PASS** | Received as `<channel>` in Claude Code |
|
|
| T13 | Mesh -> Telegram | **PASS** | `send_message(to: "tg:Alejandro")` appeared in bot chat |
|
|
| T14 | /dm Mou | **PASS** | DM delivered, peer responded |
|
|
| T15 | Peer picker (multi-match) | **PASS** | Inline keyboard: Mou (idle), Mou (all), Mou (Desktop), Send to ALL |
|
|
| T16 | @mention DM | **PASS** | `@Mou` triggered peer picker |
|
|
|
|
### 5. File Sharing
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T17 | Send photo from Telegram | **DEFERRED** | Playwright can't trigger native file dialog in Telegram Web |
|
|
| T18 | /file download | **DEFERRED** | Requires T17 |
|
|
| T19 | File download proxy | **DEFERRED** | Requires T17 |
|
|
|
|
### 6. Bot Commands (Playwright)
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T20 | /peers | **PASS** | Full peer list with bridge peer |
|
|
| T21 | /meshes | **PASS** | Connected meshes listed |
|
|
| T22 | /status | **PASS** | Bridge status info shown |
|
|
| T23 | /help | **PASS** | All 10 commands listed |
|
|
| T24 | /broadcast | **PASS** | Message received by mesh peers |
|
|
|
|
### 7. Disconnect + Reconnect
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T25 | /disconnect | **PASS** | DB: active=false, disconnected_at set |
|
|
| T26 | Peer gone from list_peers | **KNOWN LIMITATION** | WS stays open (TTL sweep needed) |
|
|
| T27 | Reconnect via /start | **PASS** | "Already connected" — upsert works |
|
|
|
|
### 8. Entry Point D: Invite URL Detection
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T28 | Paste invite URL in bot chat | **PASS** | "Detected invite link" with token extraction |
|
|
|
|
### 9. Entry Point B: CLI QR Code
|
|
|
|
| # | Test | Result | Notes |
|
|
|---|---|---|---|
|
|
| T29 | `claudemesh connect telegram` | **PASS** | QR code rendered in terminal |
|
|
| T30 | `claudemesh connect telegram --link` | **PASS** | Plain deep link URL output |
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
| Category | Pass | Deferred | Known Limitation |
|
|
|---|---|---|---|
|
|
| Infra + Deploy | 3 | 0 | 0 |
|
|
| Token Endpoint | 7 | 0 | 0 |
|
|
| Entry Point A (/start) | 4 | 0 | 0 |
|
|
| Message Routing | 5 | 0 | 0 |
|
|
| File Sharing | 0 | 3 | 0 |
|
|
| Bot Commands | 5 | 0 | 0 |
|
|
| Disconnect/Reconnect | 2 | 0 | 1 |
|
|
| Entry Point D (URL) | 1 | 0 | 0 |
|
|
| Entry Point B (CLI) | 2 | 0 | 0 |
|
|
| **Total** | **27** | **3** | **1** |
|
|
|
|
---
|
|
|
|
## Bugs Found & Fixed During Testing
|
|
|
|
1. **Lockfile mismatch** — `pnpm-lock.yaml` not updated for telegram deps
|
|
2. **Grammy not in broker deps** — added to broker `package.json`
|
|
3. **Bot username** — `claudemeshbot` not `claudemesh_bot`
|
|
4. **Wire agent missed** — Wave 2 edits lost, rewired manually
|
|
5. **Healthcheck too short** — 10s start-period → 30s, 3 retries → 5
|
|
6. **Grammy crash guard** — `.catch()` on `bot.start()` promise
|
|
7. **Duplicate key on reconnect** — `INSERT` → `onConflictDoUpdate` upsert
|
|
|
|
## Screenshots
|
|
|
|
All screenshots saved to `/tmp/tg-tests/`:
|
|
- 01-telegram-home.png through 27-file-upload.png
|
|
- Key screenshots: 10-start-sent.png (T9), 15-broadcast.png (T24), 17-dm.png (T14), 18-dm-picked.png (T15)
|