Structured test cases for user acceptance testing of the AstraDial editor and PBX platform.
1. Authentication
TC-1.1: Organisation Login
| Step | Action | Expected |
| 1 | Go to editor.astradial.com/dashboard | Login page with Organisation/Admin tabs |
| 2 | Select Organisation tab | Email + password fields shown |
| 3 | Enter systems@grandestancia.com + password | Firebase login succeeds |
| 4 | Verify redirect | Lands on /dashboard/{orgId}/overview |
| 5 | Check sidebar | Shows org name, profile at bottom, no "Switch Organisation" |
| - | Result | [ ] Pass / [ ] Fail |
TC-1.2: Admin Login
| Step | Action | Expected |
| 1 | Select Admin tab | Email + password fields shown |
| 2 | Enter admin@astradial.com + password | Firebase login succeeds |
| 3 | Verify org list | Shows all organisations (GrandEstancia, etc.) |
| 4 | Click on GrandEstancia | Lands on org dashboard |
| 5 | Check sidebar | Shows "Switch Organisation" link |
| 6 | Click "Switch Organisation" | Returns to org list |
| - | Result | [ ] Pass / [ ] Fail |
TC-1.3: Admin vs Org Permissions
| Step | Action | Expected |
| 1 | Login as org user | Trunks page: read-only, no Add/Delete |
| 2 | Login as admin | Trunks page: full CRUD (Add, Edit, Delete) |
| 3 | Verify DIDs | Org user: can edit routing. Admin: full control |
| - | Result | [ ] Pass / [ ] Fail |
TC-1.4: Logout
| Step | Action | Expected |
| 1 | Click profile at bottom of sidebar | Dropdown opens |
| 2 | Click "Log out" | Redirects to login page |
| 3 | Try accessing /dashboard/{orgId} directly | Redirects to login |
| - | Result | [ ] Pass / [ ] Fail |
2. Dashboard Overview
TC-2.1: Stats Cards
| Step | Action | Expected |
| 1 | Navigate to Home | 4 stat cards visible |
| 2 | Check "Total Calls" | Shows count from last 7 days (not capped at 50) |
| 3 | Check "Active Users" | Matches user count in Users page |
| 4 | Check "Open Tickets" | Matches open tickets in Tickets page |
| 5 | Check "Avg Duration" | Reasonable duration shown |
| - | Result | [ ] Pass / [ ] Fail |
TC-2.2: Call Volume Chart
| Step | Action | Expected |
| 1 | Check chart | Shows 7 days (Mon-Sun) |
| 2 | Verify data | Inbound + outbound bars match actual call logs |
| - | Result | [ ] Pass / [ ] Fail |
3. Users
TC-3.1: User CRUD
| Step | Action | Expected |
| 1 | Navigate to Users | List of all users with extensions |
| 2 | Create a new user | User appears in list with extension |
| 3 | Check SIP QR code | QR code displays with correct credentials |
| - | Result | [ ] Pass / [ ] Fail |
4. Queues
TC-4.1: Queue Management
| Step | Action | Expected |
| 1 | Navigate to Queues | Queue list with MOH column |
| 2 | Click ... → Edit on a queue | Edit dialog opens with MOH + Greeting dropdowns |
| 3 | Change MOH to a custom class | Saves, MOH column updates |
| 4 | Assign a greeting | Saves, greeting links to queue |
| - | Result | [ ] Pass / [ ] Fail |
TC-4.2: Music on Hold
| Step | Action | Expected |
| 1 | Scroll to MOH section | System default files shown with play buttons |
| 2 | Click play on a default music file | Audio player bar appears, music plays |
| 3 | Click "Upload Audio" | Upload dialog opens |
| 4 | Upload an MP3 file | File appears in custom class, playable |
| 5 | Delete custom file | File removed |
| - | Result | [ ] Pass / [ ] Fail |
TC-4.3: TTS Greetings
| Step | Action | Expected |
| 1 | Scroll to Greetings section | List of greetings shown |
| 2 | Click "Create Greeting" | Dialog opens |
| 3 | Enter name + text + select voice | Click Create |
| 4 | Verify greeting appears | Shows in list with Enabled badge |
| 5 | Click play button | Audio plays the TTS greeting |
| 6 | Click Enabled badge | Toggles to Disabled |
| 7 | Delete greeting | Removed from list |
| - | Result | [ ] Pass / [ ] Fail |
5. DID Routing
TC-5.1: Edit DID Routing
| Step | Action | Expected |
| 1 | Navigate to DIDs | DID list shown |
| 2 | Click ... → Edit Routing | Edit dialog opens |
| 3 | Change routing to Extension | Dropdown shows user extensions |
| 4 | Select extension 1014 | Save |
| 5 | Call the DID number from phone | Call routes to extension 1014 |
| 6 | Change routing to Queue 5001 | Save |
| 7 | Call again | Call routes to queue |
| - | Result | [ ] Pass / [ ] Fail |
6. Trunks (Admin Only)
TC-6.1: Trunk Configuration
| Step | Action | Expected |
| 1 | Login as admin, navigate to Trunks | Trunk list with Edit option |
| 2 | Click ... → Edit | Edit dialog with channel limit field |
| 3 | Change max channels to 5 | Saves |
| 4 | Verify in Asterisk | pjsip show endpoint reflects change |
| - | Result | [ ] Pass / [ ] Fail |
7. SuperHuman (AI Bots)
TC-7.1: Bot Management
| Step | Action | Expected |
| 1 | Navigate to SuperHuman | Bot list shown |
| 2 | Verify bot details | Extension, model, voice shown |
| 3 | Click Edit Flow | Flow editor opens |
| - | Result | [ ] Pass / [ ] Fail |
TC-7.2: Bot Call (Zoiper)
| Step | Action | Expected |
| 1 | Call bot extension from Zoiper | Bot answers, plays greeting |
| 2 | Speak to bot | Bot hears and responds |
| 3 | Request a ticket | Bot creates ticket (check Tickets page) |
| 4 | Say goodbye | Bot ends call |
| - | Result | [ ] Pass / [ ] Fail |
TC-7.3: Bot Call (PSTN)
| Step | Action | Expected |
| 1 | Call DID from mobile phone | Bot answers, plays greeting |
| 2 | Speak to bot (first greeting) | Bot hears after greeting finishes |
| 3 | Full conversation | Bot responds correctly |
| 4 | Verify ticket creation | Ticket appears in Tickets page |
| - | Result | [ ] Pass / [ ] Fail |
8. Workflows
TC-8.1: Workflow CRUD
| Step | Action | Expected |
| 1 | Navigate to Workflows | Workflow list with IDs |
| 2 | Click "Templates" → Hotel Check-in | Template workflow created |
| 3 | Click on workflow | Visual editor opens |
| 4 | Add a node, connect edges | Saves correctly |
| 5 | Copy Trigger URL from ... menu | URL in clipboard |
| - | Result | [ ] Pass / [ ] Fail |
TC-8.2: Webhook Trigger
| Step | Action | Expected |
| 1 | Copy workflow trigger URL | URL copied |
| 2 | Create API key in Webhooks page | Key created, visible |
| 3 | Trigger via curl with API key | Returns execution_id, status queued |
| 4 | Check execution history (Runs) | Execution shows as completed |
| - | Result | [ ] Pass / [ ] Fail |
TC-8.3: Workflow Survives Restart
| Step | Action | Expected |
| 1 | Create a scheduled workflow | Confirm in DB |
| 2 | Restart workflow engine (pm2 restart workflow-engine) | Service comes back |
| 3 | Check health endpoint | Returns OK |
| 4 | Verify scheduled jobs recovered | Jobs re-queued in Bull |
| - | Result | [ ] Pass / [ ] Fail |
9. API Keys (Webhooks Page)
TC-9.1: API Key CRUD
| Step | Action | Expected |
| 1 | Navigate to Webhooks | API Keys section shown |
| 2 | Click "Create Key" | Key created, shown with reveal/copy |
| 3 | Click eye icon | Key revealed |
| 4 | Click copy icon | Key copied to clipboard |
| 5 | Click status badge | Toggles active/inactive |
| 6 | Delete key | Removed from list |
| - | Result | [ ] Pass / [ ] Fail |
TC-9.2: API Key Auth on Trigger
| Step | Action | Expected |
| 1 | Create an API key | Key created |
| 2 | Trigger workflow WITHOUT key | Returns 401 "API key required" |
| 3 | Trigger workflow WITH key in X-API-Key header | Returns 200, execution queued |
| 4 | Deactivate key, trigger again | Returns 403 "Invalid or inactive" |
| - | Result | [ ] Pass / [ ] Fail |
10. Security
TC-10.1: Firewall
| Step | Action | Expected |
| 1 | Check UFW status | Default deny, internal ports blocked |
| 2 | Try accessing port 3002 externally | Connection refused |
| 3 | Try accessing port 7860 externally | Connection refused |
| - | Result | [ ] Pass / [ ] Fail |
TC-10.2: SIP GeoIP Blocking
| Step | Action | Expected |
| 1 | Check iptables rules | india_sip ipset + DROP rules exist |
| 2 | Check ipset entries | 7000+ Indian CIDR blocks loaded |
| 3 | Verify SIP from India works | Registered phones stay connected |
| 4 | Check dropped packets counter | Non-zero (attackers blocked) |
| - | Result | [ ] Pass / [ ] Fail |
TC-10.3: fail2ban
| Step | Action | Expected |
| 1 | Check jail status | 4 jails active |
| 2 | Check asterisk jail | maxretry=3, bantime=86400 |
| 3 | Check banned IPs | Non-zero banned count |
| - | Result | [ ] Pass / [ ] Fail |
TC-10.4: Secret Rotation
| Step | Action | Expected |
| 1 | Check JWT_SECRET | Not default value |
| 2 | Check env file permissions | All 600 |
| 3 | Check Firebase password | Not "123456" |
| - | Result | [ ] Pass / [ ] Fail |
11. UI/UX
TC-11.1: Theme Toggle
| Step | Action | Expected |
| 1 | Click profile → Light/Dark mode | Theme switches |
| 2 | Refresh page | Theme persists |
| - | Result | [ ] Pass / [ ] Fail |
| Step | Action | Expected |
| 1 | Click each sidebar item | Correct page loads |
| 2 | Check Request Feature | Opens email compose |
| 3 | Check Raise Issue | Shows phone number |
| 4 | Check Guide | Opens docs.astradial.com |
| - | Result | [ ] Pass / [ ] Fail |
TC-11.3: Workflow Editor Resize
| Step | Action | Expected |
| 1 | Open workflow editor, click a node | Inspector panel opens |
| 2 | Drag the resize handle left/right | Panel resizes smoothly |
| 3 | Click collapse button | Panel collapses |
| 4 | Click expand button | Panel re-opens |
| - | Result | [ ] Pass / [ ] Fail |
12. WhatsApp (MSG91)
TC-12.1: API Key Configuration
| Step | Action | Expected |
| 1 | Navigate to WhatsApp | Page shows "MSG91 Not Configured" |
| 2 | Enter MSG91 authkey and click Save | Status changes to "MSG91 Connected" with masked key |
| 3 | Click "Fetch Numbers" in Phone Numbers tab | Available WhatsApp sender numbers listed |
| - | Result | [ ] Pass / [ ] Fail |
TC-12.2: Templates
| Step | Action | Expected |
| 1 | Click Templates tab | Empty table with "Fetch Templates" button |
| 2 | Click "Fetch Templates" | Templates listed with name, status (APPROVED), language, variables |
| 3 | Verify template variables | Shows body_1, body_2 etc. for templates with placeholders |
| - | Result | [ ] Pass / [ ] Fail |
TC-12.3: Message Logs
| Step | Action | Expected |
| 1 | Click Message Logs tab | Date picker + "Fetch Logs" button |
| 2 | Select today's date and fetch | Delivery reports shown (customer number, template, status, time) |
| 3 | Check status badges | read=green, delivered=light green, sent=blue, failed=grey |
| - | Result | [ ] Pass / [ ] Fail |
TC-12.4: Workflow WhatsApp Node
| Step | Action | Expected |
| 1 | Add send_whatsapp node in workflow | Config panel shows Phone, Mode |
| 2 | Select "Template (MSG91)" mode | Sender Number, Template Name dropdowns appear |
| 3 | Select a template | Language auto-fills, variable mappings appear (body_1, body_2) |
| 4 | Map variables to trigger fields | Dropdowns show {trigger.name}, {trigger.phone} etc. |
| 5 | Trigger workflow with webhook | WhatsApp message sent via MSG91 |
| - | Result | [ ] Pass / [ ] Fail |
13. Ticket System — Zero Missed Calls
TC-13.1: Auto-Ticket on Missed Call
| Step | Action | Expected |
| 1 | Call DID number from phone, don't answer | Call shows as "NO ANSWER" in Call History |
| 2 | Check Tickets page | New ticket appears with source "missed call", priority "high" |
| 3 | Check sidebar | Tickets badge count increments |
| 4 | Verify ticket details | Phone number correct, summary shows "Missed call from..." |
| - | Result | [ ] Pass / [ ] Fail |
TC-13.2: Repeat Caller Escalation
| Step | Action | Expected |
| 1 | Call again from same number (don't answer) | NO duplicate ticket created |
| 2 | Check existing ticket | Summary appended with "Also called at {time}" |
| 3 | Check priority | Escalated to "urgent" |
| - | Result | [ ] Pass / [ ] Fail |
TC-13.3: Bot Call Without Ticket
| Step | Action | Expected |
| 1 | Call bot, chat briefly but don't provide ticket info, hang up | Call ends without bot creating ticket |
| 2 | Wait 10 seconds | Auto-ticket created with source "bot_dropped" |
| 3 | Verify details | Shows "Call ended without ticket ({duration}s)" |
| - | Result | [ ] Pass / [ ] Fail |
TC-13.4: Bot Creates Ticket (No Duplicate)
| Step | Action | Expected |
| 1 | Call bot, provide full info (name, room, issue) | Bot creates ticket via function call |
| 2 | Check Tickets page | Ticket exists with source "bot", full details |
| 3 | Verify no duplicate | Only ONE ticket for this call (auto-ticket skipped) |
| - | Result | [ ] Pass / [ ] Fail |
TC-13.5: Human Agent Answers (No Ticket)
| Step | Action | Expected |
| 1 | Call DID, agent answers on their extension | Call answered by human |
| 2 | End call normally | NO auto-ticket created (human handled it) |
| - | Result | [ ] Pass / [ ] Fail |
TC-13.6: Queue Timeout
| Step | Action | Expected |
| 1 | Call queue, all agents busy/unavailable | Queue timeout fires |
| 2 | Check Tickets page | Ticket with source "queue_timeout" |
| - | Result | [ ] Pass / [ ] Fail |
TC-13.7: Click-to-Call from Ticket
| Step | Action | Expected |
| 1 | Open a ticket with phone number | Detail sheet shows Copy + Call Back buttons |
| 2 | Click Copy | Phone number copied to clipboard |
| 3 | Click "Call Back" | Dialog opens with From picker (extension/phone) |
| 4 | Select extension and click Call | Click-to-call initiates |
| - | Result | [ ] Pass / [ ] Fail |
TC-13.8: Ticket Scenarios Matrix
| Scenario | Disposition | answered_by | Auto-ticket? | Source |
| Call not picked | NO ANSWER | any | Yes | missed_call |
| Queue timeout | NO ANSWER | queue | Yes | queue_timeout |
| Bot answers, caller drops | ANSWERED | bot ext (per-org, see auto-ticket-system) | Yes (after 8s) | bot_dropped |
| Bot answers, creates ticket | ANSWERED | bot ext | No (bot handled) | bot |
| Human agent answers (incl. extensions like 1003/1012/1013 used by other orgs as humans) | ANSWERED | human ext | No (skipped) | — |
| Repeat caller | any | any | No (append to existing) | — |
| Internal call | any | any | No (skipped) | — |
| Outbound call | any | any | No (skipped) | — |
Sign-off
| Role | Name | Date | Status |
| Developer | | | |
| QA | | | |
| Client | | | |