11 files updated to reflect current state (v0.0.22 → v0.0.46): ARCHITECTURE.md: - Ring tones, group calls, read receipts, markdown rendering sections - Bot API expanded (BotFather, numeric IDs, Telegram compat) - Admin commands, known issues, 155 tests TASK_PLAN.md: - All P1-P4 marked DONE with version numbers - Additional completed work section (bots, ETH, ring tones, group calls) - New FC-P7 (Voice & Transport): cpal, Sender Keys, WebTransport - FC-P6-T9/T10 added PROGRESS.md: - Full version history table v0.0.22 through v0.0.46 - Known issues section README.md: - Voice calls, ring tones, group calls, read receipts, markdown, 155 tests SECURITY.md: - Bot API security, voice call security, admin commands sections - Updated protection tables USAGE.md: - Group calls, read receipts, markdown formatting, admin commands CLIENT.md: - Call commands, read receipts, markdown rendering LLM_HELP.md + LLM_BOT_DEV.md: - Call/group call/admin commands, ring tones, per-bot numeric IDs TESTING_E2E.md: - Tests 16-18: ring tones, group calls, admin commands CLAUDE.md: - Ring tone notes, group signal endpoint, MLS roadmap Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
14 KiB
14 KiB
featherChat End-to-End Testing Guide
Version: 0.0.46
Prerequisites
Local Testing
# Build everything
cargo build --release --bin warzone-server --bin warzone-client
wasm-pack build crates/warzone-wasm --target web --out-dir ../../wasm-pkg
# Binaries
./target/release/warzone-server
./target/release/warzone-client
Two-Server Testing (Federation)
# Server Alpha
./warzone-server --bind 0.0.0.0:7700 --federation alpha.json --enable-bots --bots-config bots.json
# Server Bravo
./warzone-server --bind 0.0.0.0:7700 --federation bravo.json --enable-bots --bots-config bots.json
Voice Call Testing (requires WZP relay)
# Terminal A: WZP relay (QUIC audio SFU)
./wzp-relay --listen 0.0.0.0:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate
# Terminal B: WZP web bridge (browser WebSocket <-> QUIC)
./wzp-web --port 8080 --relay 127.0.0.1:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate
# Terminal C: featherChat server with relay address
export WZP_RELAY_ADDR=127.0.0.1:8080
./warzone-server
Test 1: Basic Messaging (TUI ↔ TUI)
Setup
# Terminal 1: Server
./target/release/warzone-server
# Terminal 2: User A
./target/release/warzone-client init
./target/release/warzone-client register --server http://localhost:7700
./target/release/warzone-client tui --server http://localhost:7700
# Terminal 3: User B
WARZONE_HOME=~/.warzone-b ./target/release/warzone-client init
WARZONE_HOME=~/.warzone-b ./target/release/warzone-client register --server http://localhost:7700
WARZONE_HOME=~/.warzone-b ./target/release/warzone-client tui --server http://localhost:7700
Steps
- User A: Note the ETH address shown at startup (e.g.,
0x85e3D8...) - User B:
/peer 0x85e3D8e4a6EEfc048fc80497773D440Bf3487D2b - User B: Type
Hello!and press Enter - User A: Should see the message with ✓ (sent) → ✓✓ (delivered)
- User A:
/r Hi back!(reply) - User B: Should see the reply
Verify
- Messages delivered in real-time (< 1 second)
- ✓ appears on send, ✓✓ on delivery
- Timestamps show [HH:MM]
- ETH address shown in header
/infoshows both ETH and fingerprint
Test 2: Basic Messaging (Web ↔ Web)
Setup
- Open browser tab 1:
http://localhost:7700 - Click "Generate Identity" → note the ETH address
- Open browser tab 2 (incognito):
http://localhost:7700 - Click "Generate Identity"
Steps
- Tab 2: Paste Tab 1's ETH address in the peer input box
- Tab 2: Type "Hello from web!" → Send
- Tab 1: Should see the message
- Tab 1:
/peer <tab2_eth_address>→ Type "Hi!" → Send - Tab 2: Should see the reply
Verify
- Messages show with 🔒 prefix (E2E encrypted)
- ETH address shown in header (click to copy)
- Markdown renders (bold,
code, etc.) - Scrollbar visible and working
Test 3: TUI ↔ Web Cross-Client
Steps
- Start TUI (User A) and Web (User B) as above
- Web:
/peer <TUI_eth_address>→ Send message - TUI: Should see the message with terminal bell
- TUI:
/r Hello from terminal! - Web: Should see the reply
Verify
- Cross-client encryption works (TUI encrypts, Web decrypts and vice versa)
- Receipts flow correctly between clients
Test 4: Group Messaging
Steps
- User A:
/gcreate testgroup - User A:
/g testgroup - User B:
/g testgroup(auto-joins) - User A: Type "Hello group!" → Send
- User B: Should see
UserA [#testgroup]: Hello group! - User B: Type "Reply!" → Send
- User A: Should see the reply
Verify
- Group creation works
- Auto-join on
/g - Messages fan-out to all members
/gmembersshows online status (● / ○)
Test 5: Federation (Two Servers)
Setup
# Server Alpha (Terminal 1)
./warzone-server --bind 0.0.0.0:7700 --federation alpha.json
# Server Bravo (Terminal 2)
./warzone-server --bind 0.0.0.0:7701 --data-dir ./data-bravo --federation bravo.json
alpha.json:
{"server_id":"alpha","shared_secret":"test123","peer":{"id":"bravo","url":"http://127.0.0.1:7701"}}
bravo.json:
{"server_id":"bravo","shared_secret":"test123","peer":{"id":"alpha","url":"http://127.0.0.1:7700"}}
Steps
- User A connects to Alpha (port 7700)
- User B connects to Bravo (port 7701)
- Wait 5 seconds for federation presence sync
- User A:
/peer <UserB_eth_address>→ Send message - User B: Should receive the message
Verify
- Server logs show "Federation: connected to peer"
GET /v1/federation/statusreturns"peer_connected": true- Messages route across servers transparently
- Key bundles proxy via federation (no "Peer not registered")
- Aliases resolve across servers
Test 6: File Transfer
Steps
- Set up two peers (TUI or Web)
- Sender:
/file /path/to/small-file.txt(must be < 10MB) - Receiver: Should see "Incoming file..." → chunk progress → "File saved: ..."
- Verify the file at
~/.warzone/downloads/small-file.txt
Verify
- SHA-256 integrity check passes
- File appears in downloads directory
- Progress shown per chunk
Test 7: Call Signaling
Steps (Web ↔ Web)
- User A: Set peer to User B
- User A: Click 📞 Call button (or
/call) - User B: Should see "📞 Incoming call" with Accept/Reject buttons
- User B: Click ✓ Accept
- Both: Should see "Call connected!" / "🔊 In call"
- Either: Click "End Call" (or
/hangup) - Both: Should see "Call ended"
Steps (TUI ↔ TUI)
- User A:
/call <peer_address> - User A: Header shows yellow "📞 Calling..."
- User B: "📞 Incoming call from ... — /accept or /reject"
- User B:
/accept - User A: Header shows green "🔊 0:00" timer
- User A or B:
/hangup
Verify
- Call bar appears in web when peer is set
- Incoming call notification (pulsing animation in web, bell in TUI)
- Call state updates in header (TUI) / call bar (web)
- Hangup/reject cleans up state on both sides
Test 8: Voice Call Audio (requires WZP relay)
Prerequisites
# Terminal 1: WZP relay (QUIC audio SFU)
./wzp-relay --listen 0.0.0.0:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate
# Terminal 2: WZP web bridge (browser WebSocket <-> QUIC)
./wzp-web --port 8080 --relay 127.0.0.1:4433 --auth-url http://127.0.0.1:7700/v1/auth/validate
# Terminal 3: featherChat server
WZP_RELAY_ADDR=127.0.0.1:8080 ./warzone-server
Steps
- Open two browser tabs to
http://localhost:7700 - Tab 1: Set peer to Tab 2
- Tab 1: Click 📞 Call
- Tab 2: Click ✓ Accept
- Both: Allow microphone access when prompted
- Speak into mic — other tab should hear audio
- End call
Verify
- "Audio: connecting to ..." message appears
- "Audio: connected — mic active" confirms WS to relay
- Audio flows bidirectionally
- Audio stops on hangup
- No audio leak after call ends
Test 9: Bot API
Setup
# Server with bots enabled
./warzone-server --enable-bots --bots-config bots.json
Create a bot via BotFather
- Open web client
/peer @botfather- Type
/newbot TestEchoBot - Note the token from BotFather's reply
Run echo bot
import requests, time
TOKEN = "YOUR_TOKEN_HERE"
API = f"http://localhost:7700/v1/bot/{TOKEN}"
offset = 0
while True:
r = requests.post(f"{API}/getUpdates", json={"offset": offset, "timeout": 30}).json()
for u in r.get("result", []):
offset = u["update_id"] + 1
msg = u.get("message", {})
text, cid = msg.get("text"), msg.get("chat", {}).get("id")
if text and cid:
requests.post(f"{API}/sendMessage", json={"chat_id": cid, "text": f"Echo: {text}"})
time.sleep(0.1)
Test messaging the bot
/peer @testechobot- Type "Hello bot!"
- Bot should reply "Echo: Hello bot!"
Verify
- BotFather creates bot and returns token
- Bot receives plaintext messages (not encrypted)
- Bot replies appear in chat
- Markdown in bot replies renders correctly
- Inline keyboards render as clickable buttons (if bot sends reply_markup)
Test 10: System Bots (from config)
Verify
- Start server with
--bots-config bots.json - Check
data/bot-tokens.txtexists with all tokens - Open web client — welcome screen shows "Available bots: @helpbot, @codebot, ..."
/peer @helpbot→ Send "hello" → Bot should respond (if bot process is running)
Test 11: Device Management
Steps
- Connect with TUI
- Open web client (same identity or different)
- TUI:
/devices— should list both sessions - TUI:
/kick <web_device_id> - Web: Connection should drop
Verify
/devicesshows device IDs and connection times/kickdisconnects the target device- Max 5 devices per identity enforced
Test 12: Friend List
Steps
- User A:
/friend <UserB_address> - User A:
/friend(no args) — should list User B with online/offline status - User A:
/unfriend <UserB_address> - User A:
/friend— should show empty
Verify
- Friend list persists across restarts (encrypted on server)
- Online/offline status shown
- Add/remove works
Test 13: Session Recovery
Steps
- Establish a session between two peers (exchange messages)
- Delete one peer's session DB:
rm -rf ~/.warzone/db/ - Restart that peer's TUI
- Other peer sends a message
- Should see "[session reset]" and then re-establish
Verify
- "[session reset]" message appears
- Subsequent messages work after re-X3DH
Test 14: Auto-Backup
Steps
- Start TUI client
- Wait 5 minutes (or use
/backupfor immediate) - Check
~/.warzone/backups/for.wzbkfiles - Only 3 most recent should exist
Verify
/backupcreates file immediately- Auto-backup runs every 5 minutes
- Old backups rotated (max 3)
Test 15: Protocol Versioning
Steps
- Send a message normally — raw bincode (legacy format)
- Check server logs — should accept it
- Upgrade client to send envelope format in the future
- Old server should still accept legacy
- New server accepts both
Verify
- Legacy (raw bincode) still works
- Envelope
[WZ][v1][len][payload]accepted - Future version envelope rejected with clear error
Test 16: Ring Tones
Steps (Web ↔ Web)
- User A: Set peer to User B
- User A: Click Call button (or
/call) - User A: Listen for outgoing ringback tone (repeating double beep)
- User B: Listen for incoming ring tone (classic ring pattern)
- User B: Click Accept
- Both: Ring tones should stop immediately
- Repeat: User A calls, User B rejects — tones should stop on reject
- Repeat: User A calls, User A hangs up before answer — tones should stop on hangup
Verify
- Outgoing ringback plays on caller side while waiting
- Incoming ring tone plays on callee side
- Both tones stop immediately on accept
- Both tones stop immediately on reject
- Both tones stop immediately on hangup (caller cancels)
- No residual audio after call ends (no oscillator leak)
Test 17: Group Calls
Prerequisites
- WZP relay running (see Test 8 prerequisites)
- At least 3 users in a group
Steps
- User A, B, C: All join group via
/g testgroup - User A:
/gcall— starts group voice call - User B: Should see group call notification
- User B:
/gjoin— joins the active group call - Both A and B: Should hear each other's audio
- User C:
/gjoin— joins, now 3 participants - Verify participant count shows 3
- User B:
/gleave-call— leaves call but stays in text group - User B: Can still send text messages in the group
- User A:
/hangup— ends call for remaining participants
Verify
/gcallsends notification to all group members/gjoinconnects to the group audio room- Participant count updates as members join/leave
/gleave-callleaves audio but keeps text group membership/gmutetoggles microphone mute- Audio flows between all participants in the room
- Call ends cleanly when last participant leaves
Test 18: Admin Commands
Prerequisites
- Server running with admin fingerprint configured
Steps
- Admin user:
/admin-help— should list available admin commands - Admin user: Start a call between two other users (or self-call for testing)
- Admin user:
/admin-calls— should list active calls with participants and duration - Non-admin user:
/admin-calls— should show "permission denied" or similar
Verify
/admin-helplists all admin commands/admin-callsshows active calls (caller, callee, duration, type)- Non-admin users cannot execute admin commands
- Admin commands do not expose message content
Quick Smoke Test (5 minutes)
If you only have 5 minutes, test these:
./warzone-server --enable-bots --bots-config bots.json- Open
http://localhost:7700in two browser tabs - Tab 1: Generate identity
- Tab 2: Generate identity,
/peer <tab1_eth_address> - Tab 2: Send "Hello!" → Tab 1 should see bold text
- Tab 1:
/peer @botfather→/newbot QuickBot→ Note token - Start echo bot with the token (Python script above)
- Tab 1:
/peer @quickbot→ "test" → Should get "Echo: test" - Tab 1:
/peer <tab2_address>→ Click 📞 Call → Tab 2: Accept - Both: Should see "Call connected!" (audio needs WZP relay running)
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| "Peer not registered" | Peer hasn't registered keys | Peer needs to open client first |
| "[message could not be decrypted]" | Stale session or cached bundle | Clear localStorage (web) or delete session DB |
| "alias not found" | Bot/alias doesn't exist on this server | Check --enable-bots, wipe data + restart |
| No audio | WZP relay not running | Start wzp-relay + wzp-web + set WZP_RELAY_ADDR |
| Federation not working | Peer server down or wrong config | Check GET /v1/federation/status on both |
| "connection limit reached" | 5 devices max | /devices → /kick old ones |
| Version mismatch (web) | Old service worker cached | Hard refresh (Cmd+Shift+R) |
| Bot not responding | Bot process not running | Check bot process is polling getUpdates |