Campaigns Recently Changed
Campaign List & Filtering
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-001 | View campaigns list on initial load | Logged in as Agent, organization has 3 campaigns in various statuses (draft, running, completed) | 1. Navigate to /campaigns 2. Wait for page to load | Campaigns list displays with name, WhatsApp account, status, recipient counts, and timestamps. Default tab is 'campaigns'. | High |
| CAM-002 | Filter campaigns by status | Logged in as Agent, campaigns list loaded with mix of statuses | 1. Click status dropdown filter 2. Select 'running' | Only campaigns with 'running' status display. Other statuses are hidden. | High |
| CAM-003 | Pagination of campaigns list | Logged in as Agent, organization has 75 campaigns | 1. Navigate to /campaigns 2. Scroll to bottom 3. Observe pagination controls | Default page size is 50. Next page button appears. Page 2 shows campaigns 51-75. | Medium |
| CAM-004 | Empty campaigns list state | Logged in as Agent, no campaigns exist in organization | 1. Navigate to /campaigns | Empty state message displays: "No campaigns yet. Create your first campaign." Create button is visible. | Medium |
| CAM-005 | Search/filter campaigns (future enhancement placeholder) | Logged in as Agent, campaigns list loaded | 1. Navigate to /campaigns | List displays campaigns; search box present in UI for future use | Low |
Campaign Creation - Setup Step
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-006 | Open create campaign wizard | Logged in as Agent, at least one WhatsApp account connected, at least one template available | 1. Navigate to /campaigns 2. Click 'New Campaign' button (Plus icon) | Wizard opens at Step 1/3 (Setup). Modal title shows "Create Campaign". Form fields visible: Name, WhatsApp Account, Template. | High |
| CAM-007 | Campaign name validation - required field | In campaign wizard Step 1 | 1. Leave Name field empty 2. Try to proceed to next step | Error message displays under Name field: "Campaign name is required." Next button is disabled or shows error. | High |
| CAM-008 | Campaign name validation - max length | In campaign wizard Step 1 | 1. Enter 256+ character string in Name field 2. Blur field | Error message displays: "Campaign name must be 255 characters or less." | Medium |
| CAM-009 | Select WhatsApp account - required field | In campaign wizard Step 1, multiple accounts available | 1. Leave WhatsApp Account dropdown unselected 2. Try to proceed | Error message displays: "WhatsApp account is required." Next button disabled. | High |
| CAM-010 | Select template - required field | In campaign wizard Step 1, templates available | 1. Leave Template dropdown unselected 2. Try to proceed | Error message displays: "Template is required." Next button disabled. | High |
| CAM-011 | Populate campaign setup form - happy path | In campaign wizard Step 1, one account and one template available | 1. Enter Name: "Q2 Product Launch" 2. Select WhatsApp Account from dropdown 3. Select Template from dropdown 4. Click Next | Form validation passes. Wizard advances to Step 2 (Recipients). Selected values remain in memory if user returns. | High |
| CAM-012 | Template selector shows only templates for selected account | In campaign wizard Step 1, Account A has 2 templates, Account B has 1 template | 1. Select Account A in dropdown 2. Open Template dropdown 3. Count templates 4. Switch to Account B 5. Open Template dropdown again | Template dropdown initially shows templates for Account A. After switching accounts, only Account B's template appears. | Medium |
| CAM-013 | Navigation - back from Step 1 | In campaign wizard Step 1 with form partially filled | 1. Click X or Back button | Wizard closes. User returns to campaigns list. Form data is discarded (new attempt starts fresh). | Medium |
Campaign Creation - Recipients Step
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-014 | Recipients step loads with source selection | In campaign wizard Step 2, setup step completed | 1. Arrive at Step 2/3 2. Observe recipient source options | Radio buttons or tabs display three options: "Contacts", "Tags", "CSV Upload". Default selection is "Contacts". | High |
| CAM-015 | Recipients source - Contacts | In campaign wizard Step 2, at least 5 contacts exist | 1. Ensure "Contacts" source is selected 2. Observe contacts list | Contact list displays with checkboxes, name, and phone number. "Select All" checkbox available. Can multi-select contacts. | High |
| CAM-016 | Recipients source - Tags | In campaign wizard Step 2, at least 3 tags exist with contacts tagged | 1. Click "Tags" radio button 2. Observe tags list | Tag list displays. Clicking a tag shows count of contacts with that tag. Multi-select tags available. Preview shows "X contacts will be targeted." | High |
| CAM-017 | Recipients source - CSV upload | In campaign wizard Step 2 | 1. Click "CSV Upload" radio button 2. Observe upload UI | Upload area displays with drag-and-drop or file picker. Instructions show: "Upload CSV with columns: phone, name, param1, param2, etc." | High |
| CAM-018 | CSV upload validation - valid file | In campaign wizard Step 2, CSV source selected | 1. Prepare valid CSV: "phone,name,param1\n+1234567890,John,value1\n+9876543210,Jane,value2" 2. Upload file | File is parsed successfully. Preview table displays 2 rows with phone, name, and param1. "Next" button enabled. | High |
| CAM-019 | CSV upload validation - missing phone column | In campaign wizard Step 2, CSV source selected | 1. Prepare CSV without phone column: "name,email\nJohn,john@example.com" 2. Upload file | Error message displays: "CSV must contain 'phone' and 'name' columns." File is rejected. Upload area remains empty. | High |
| CAM-020 | CSV upload validation - invalid phone format | In campaign wizard Step 2, CSV source selected | 1. Prepare CSV with invalid phone: "phone,name\ninvalid123,John" 2. Upload file | Warning displays: "Row 1: Invalid phone number 'invalid123'. Only rows with valid E.164 format will be included." Processing continues with valid rows. | Medium |
| CAM-021 | CSV upload validation - duplicate phones | In campaign wizard Step 2, CSV source selected | 1. Prepare CSV with duplicate: "phone,name\n+1234567890,John\n+1234567890,John2" 2. Upload file | Duplicate rows shown in preview. Notice: "1 duplicate phone number excluded. 1 unique recipient." File uploads; duplicates removed. | Medium |
| CAM-022 | Recipients validation - no recipients selected | In campaign wizard Step 2 | 1. Select "Contacts" source 2. Don't select any contacts 3. Try to proceed to Step 3 | Error message displays: "Please select at least one recipient." Next button disabled. | High |
| CAM-023 | Recipients validation - no tags selected | In campaign wizard Step 2 | 1. Select "Tags" source 2. Don't check any tags 3. Try to proceed | Error message displays: "Please select at least one tag." Next button disabled. | High |
| CAM-024 | Recipient count summary updates | In campaign wizard Step 2, Contacts source, 10 contacts available | 1. Select 3 contacts 2. Observe summary counter | Summary text displays: "Recipients selected: 3" or "Will send to 3 contacts." Counter updates as selection changes. | Medium |
| CAM-025 | Navigation - back from Step 2 | In campaign wizard Step 2 with recipients selected | 1. Click Back button | Wizard returns to Step 1. Setup form values retained (name, account, template). | Medium |
| CAM-026 | Navigation - back to Step 2 after review | In campaign wizard Step 3 (Review) | 1. Click Back button | Wizard returns to Step 2. Recipient selections retained. | Medium |
Campaign Creation - Review & Preflight Check Step
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-027 | Review step displays campaign summary | In campaign wizard Step 3, all prior steps completed | 1. Arrive at Step 3/3 2. Observe summary | Summary shows: Campaign Name, WhatsApp Account, Template name, Recipient source type, recipient count, scheduled send time (if set). | High |
| CAM-028 | Preflight check - success | In campaign wizard Step 3, 100 recipients selected, account tier allows 1000/day | 1. Arrive at Step 3 (preflight runs automatically) 2. Observe preflight result | Green checkmark displays. Message: "Campaign is ready to send. No issues detected." Create button enabled. | High |
| CAM-029 | Preflight check - warning - low quality rating | In campaign wizard Step 3, account has quality rating below threshold | 1. Arrive at Step 3 2. Observe preflight result | Yellow warning badge displays. Message: "Account quality rating is below recommended level. Delivery may be affected." Create button still enabled (warning, not blocking). | Medium |
| CAM-030 | Preflight check - error - account tier limit exceeded | In campaign wizard Step 3, 500 recipients selected, account tier only allows 100/day | 1. Arrive at Step 3 2. Observe preflight result | Red error badge displays. Message: "Your WhatsApp tier allows 100 messages/day. You selected 500 recipients. Please reduce recipients or upgrade." Create button disabled. | High |
| CAM-031 | Preflight check - error - token invalid | In campaign wizard Step 3, WhatsApp account token expired | 1. Arrive at Step 3 2. Observe preflight result | Red error badge. Message: "WhatsApp account token is invalid or expired. Please re-authenticate in Settings." Create button disabled. | High |
| CAM-032 | Schedule campaign - optional scheduling | In campaign wizard Step 3 | 1. Click "Schedule for later" toggle or date/time picker 2. Select future date and time 3. Click Create | Campaign is created with status "scheduled". scheduled_at field stores the datetime. Campaign does not send until scheduled time. | High |
| CAM-033 | Schedule campaign - past datetime validation | In campaign wizard Step 3, scheduling enabled | 1. Attempt to select a past date/time 2. Try to create | Error displays: "Scheduled time must be in the future." Past dates are disabled in picker. | Medium |
| CAM-034 | Create campaign - save to database | In campaign wizard Step 3, preflight passed, all validation complete | 1. Click "Create Campaign" button 2. Wait for save | Campaign is created and saved. Success toast displays: "Campaign 'Q2 Product Launch' created successfully." Wizard closes. New campaign appears in campaigns list with status "draft". | High |
| CAM-035 | Create campaign - server error handling | In campaign wizard Step 3, clicking Create triggers server error | 1. Click "Create Campaign" 2. Server returns 500 error | Error message displays: "Failed to create campaign. Please try again." Save button remains available for retry. Wizard does not close. | Medium |
Campaign Detail View
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-036 | Open campaign detail view | Logged in as Agent, campaign "Q2 Launch" exists with status "draft" | 1. Navigate to /campaigns 2. Click on campaign row "Q2 Launch" | Detail modal/panel opens. Shows campaign name, status badge (draft), WhatsApp account, template, recipient count (total_recipients), and metrics (sent, delivered, read, failed). | High |
| CAM-037 | Campaign detail - draft status | Campaign exists with status "draft" | 1. Open campaign detail 2. Observe action buttons | Buttons visible: "Edit", "Delete", "Launch Now". Edit and Delete are enabled. Launch Now is enabled. | High |
| CAM-038 | Campaign detail - running status | Campaign exists with status "running" | 1. Open campaign detail | Status badge shows "running" in blue. Buttons visible: "Pause", "Cancel". No Edit button. Delete disabled. | High |
| CAM-039 | Campaign detail - paused status | Campaign exists with status "paused" | 1. Open campaign detail | Status badge shows "paused" in yellow. Buttons visible: "Resume", "Cancel", "Delete" (disabled). | Medium |
| CAM-040 | Campaign detail - completed status | Campaign exists with status "completed" (all recipients processed) | 1. Open campaign detail | Status badge shows "completed" in green. Buttons visible: "Delete", "Archive", "Duplicate". Launch/Pause/Cancel buttons hidden. Metrics show final counts. | Medium |
| CAM-041 | Campaign detail - failed status with error | Campaign exists with status "failed" (fatal error like invalid token) | 1. Open campaign detail | Status badge shows "failed" in red. Error message displayed: specific error reason (e.g., "Access token expired. Re-authenticate the WhatsApp account."). Delete button visible. | Medium |
Campaign Recipients Tab
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-042 | Recipients list in campaign detail | Campaign "Q2 Launch" has 10 recipients with various statuses | 1. Open campaign detail 2. Click "Recipients" tab 3. Wait for list load | Recipients table displays: contact name, phone, status badge (pending/sent/delivered/read/failed), error message (if failed), sent timestamp, retry count. | High |
| CAM-043 | Recipients status filter | Campaign with 20 recipients: 10 sent, 5 delivered, 5 failed | 1. Open campaign detail, Recipients tab 2. Click status filter 3. Select "delivered" | Only 5 delivered recipients display. Other statuses hidden. Filter badge shows count. | Medium |
| CAM-044 | Recipients pagination | Campaign with 150 recipients | 1. Open campaign detail, Recipients tab 2. Scroll to bottom | Default page size 50. Pages 1-3 available. "Next" and "Previous" buttons functional. | Medium |
| CAM-045 | Recipient detail - failed with error message | Campaign with one recipient, status "failed", error_message: "Invalid phone number" | 1. Open campaign detail, Recipients tab 2. Find failed recipient row | Failed row shows error message tooltip/detail: "Invalid phone number". Retry count > 0 displayed. | Medium |
| CAM-046 | Empty recipients list (CSV with no valid rows) | Campaign created from CSV with no valid phones | 1. Open campaign detail, Recipients tab | Empty state: "No recipients found." Campaign status may be "draft" or show warning. | Low |
Campaign Edit
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-047 | Edit campaign - draft status | Campaign "Q2 Launch" exists with status "draft" | 1. Open campaign detail 2. Click "Edit" button | Edit modal opens. Form fields pre-filled: Name, Scheduled Time. Recipient source and template are read-only (info only). | High |
| CAM-048 | Edit campaign - name change | Campaign edit modal open, current name "Q2 Launch" | 1. Clear name field 2. Type "Q2 Product Launch 2.0" 3. Click Save | Name updated successfully. Success toast: "Campaign updated." Detail view refreshes with new name. | High |
| CAM-049 | Edit campaign - scheduled time change | Campaign edit modal open, currently scheduled for 2026-04-20 | 1. Click scheduled_at date picker 2. Select 2026-04-25 3. Click Save | Scheduled time updated. Campaign still has status "draft" (not yet started). Success message displays. | Medium |
| CAM-050 | Edit campaign - validation error on name | Campaign edit modal open | 1. Clear name field 2. Try to save | Error: "Campaign name is required." Save button disabled. | Medium |
| CAM-051 | Edit campaign - running/completed campaign | Campaign with status "running" or "completed" | 1. Open campaign detail 2. Look for Edit button | Edit button is hidden or disabled. Only Delete/Pause/Cancel buttons available. Campaign cannot be edited mid-flight. | High |
| CAM-052 | Edit campaign - cancel | Campaign edit modal open with changes | 1. Click X or Cancel button | Modal closes without saving. Original values retained. Campaign list unchanged. | Medium |
Campaign Launch & Status Transitions
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-053 | Launch campaign - draft to running | Campaign "Q2 Launch" exists with status "draft", not scheduled, preflight passed | 1. Open campaign detail 2. Click "Launch Now" button | Confirmation modal displays: "Ready to send to 100 recipients. Continue?" 2. Click "Confirm" | Campaign status changes to "running". started_at timestamp is set. Success toast: "Campaign launched." UI updates with "Pause" and "Cancel" buttons. |
| CAM-054 | Launch scheduled campaign | Campaign exists with status "draft", scheduled_at is future date | 1. Open campaign detail | Status shows "Scheduled for [date/time]". "Launch Now" button still available to send immediately. | Medium |
| CAM-055 | Launch campaign - confirmation cancel | Campaign edit modal with Launch confirmation displayed | 1. Click "Cancel" on confirmation | Modal closes. Campaign remains in draft status. No action taken. | Medium |
| CAM-056 | Pause campaign - running to paused | Campaign with status "running", 50 messages already sent | 1. Open campaign detail 2. Click "Pause" button | Confirmation: "Pause campaign? Pending messages will not be sent." 2. Click "Confirm" | Campaign status changes to "paused". UI updates with "Resume" button. Paused message displays worker does not process further recipients. |
| CAM-057 | Resume campaign - paused to running | Campaign with status "paused" | 1. Open campaign detail 2. Click "Resume" button | Confirmation: "Resume campaign? Remaining recipients will be sent." 2. Click "Confirm" | Campaign status changes back to "running". Worker resumes processing. Success toast displayed. |
| CAM-058 | Cancel campaign - running/draft/paused to cancelled | Campaign with any active status | 1. Open campaign detail 2. Click "Cancel" button | Confirmation: "Cancel campaign? This cannot be undone." 2. Click "Confirm" | Campaign status changes to "cancelled". No further messages sent. "Delete" button becomes available. UI shows final metrics (some messages may have been sent). |
| CAM-059 | Campaign auto-complete when all recipients processed | Campaign running, last recipient is processed | Background: Campaign is running. Worker finishes sending to final recipient. | Status automatically changes to "completed". started_at and completed_at both populated. Metrics show final counts. UI shows completion message: "Campaign completed. All messages sent." | High |
Campaign Deletion
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-060 | Delete campaign - draft status | Campaign "Q2 Launch" exists with status "draft" | 1. Open campaign detail 2. Click "Delete" button | Confirmation modal: "Delete this campaign? This cannot be undone." 2. Click "Confirm" | Campaign deleted from database. Campaigns list refreshes. Deleted campaign no longer appears. Success toast: "Campaign deleted." |
| CAM-061 | Delete campaign - completed status | Campaign with status "completed" | 1. Open campaign detail 2. Click "Delete" button | Confirmation modal displays. 2. Click "Confirm" | Campaign is deleted (soft delete or hard delete per business rules). Campaigns list updates. |
| CAM-062 | Delete campaign - running status | Campaign with status "running" | 1. Open campaign detail 2. Look for Delete button | Delete button is hidden/disabled. Message: "Cannot delete a running campaign. Pause or cancel it first." | High |
| CAM-063 | Delete campaign - cancel confirmation | Campaign detail, delete confirmation modal open | 1. Click Cancel or X button | Modal closes. Campaign remains in list unchanged. | Medium |
Campaign Message Sending - Template Variables & Media Headers
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-064 | Messages send with template text variables substituted | Campaign running with template "Hello {{1}}, your code is {{2}}", CSV has param1="John", param2="12345" | Background: Worker processes campaign. | Message sent to recipient: "Hello John, your code is 12345". TemplateObject built with parameters in correct order. Text parameters extracted and included. No blank variables sent (skipped per logic). | High |
| CAM-065 | Messages send with media HEADER (IMAGE) | Campaign running with template having IMAGE header, CSV has header_media_id="image_id_123" | Background: Worker processes campaign. Worker extracts header_media_id from recipient params. | MESSAGE sent with IMAGE media component in header. MediaObject with id="image_id_123" included in TemplateParameter. Header component added to TemplateObject. | High |
| CAM-066 | Messages send with media HEADER (VIDEO) | Campaign running with template having VIDEO header, CSV has header_media_id="video_id_456" | Background: Worker processes campaign. | MESSAGE sent with VIDEO media component in header. MediaObject with id="video_id_456" included. TemplateComponent type="header" with video parameter. | High |
| CAM-067 | Messages send with media HEADER (DOCUMENT) | Campaign running with template having DOCUMENT header, CSV has header_media_id="doc_id_789" | Background: Worker processes campaign. | MESSAGE sent with DOCUMENT media component in header. MediaObject with id="doc_id_789" included. TemplateComponent built correctly for document type. | High |
| CAM-068 | Media header skipped when media_id missing | Campaign running with template having IMAGE header, CSV has empty/missing header_media_id | Background: Worker processes campaign. recipient_params["header_media_id"] is empty or absent. | Header component not included. Message sent without media header (body/buttons only). No error; gracefully skips unsupported component. Recipient marked "sent" (not failed). | Medium |
| CAM-069 | Text parameters skipped when all values are blank | Campaign running with template "Code: {{1}}", CSV has param1="" (empty) | Background: Worker builds TemplateObject. All text parameters for a component are empty strings. | Text component skipped entirely (not added to components list). Message sent without that body section. Recipient marked "sent". | Medium |
| CAM-070 | URL button CTA - single dynamic URL ({{1}}) substitution | Campaign running with template "Click {{1}}" button URL "https://example.com/?code={{1}}", CSV has url_suffix="ABC123" | Background: Worker processes campaign. Detects {{1}} in URL button text. | TemplateComponent type="button", sub_type="url", index=0 added with parameter text="ABC123". URL becomes "https://example.com/?code=ABC123" at Meta end. Message sent with dynamic link. | High |
| CAM-071 | URL button CTA - multiple dynamic URLs (first button) | Campaign running with template having 2 URL buttons: button1="https://site1.com/?id={{1}}", button2="https://site2.com/?code={{1}}", CSV has url_suffix="val1", url_button_1="val2" | Background: Worker iterates buttons, processes first URL button with url_suffix, second with url_button_1. | First button gets parameter text="val1" (index=0). Second button gets parameter text="val2" (index=1). Both TemplateComponent buttons added. | Medium |
| CAM-072 | URL button CTA - url_suffix_N fallback logic | Campaign running with 2 URL buttons, CSV has url_button_0="first", url_button_1="second" (no url_suffix) | Background: Worker checks params for url_suffix (not found), falls back to url_button_0 for first button. | First button uses url_button_0="first". Second button uses url_button_1="second". Both dynamic URLs substituted correctly. | Medium |
| CAM-073 | URL button skipped when suffix missing | Campaign running with template "Click {{1}}" URL button, CSV has no url_suffix, no url_button_0 | Background: Worker detects {{1}} in URL but params["url_suffix"] and params["url_button_0"] are empty. | URL button component not added to template. Message sent without this button. No error. Recipient marked "sent". | Medium |
Campaign Message Sending - Worker & Rate Limiting
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-074 | Rate limiting - 80 msg/sec per account tier | Campaign running on standard tier account with 150 recipients | Background: Worker processes 150 messages at rate limit. | Messages batch-send at max 80/sec. Batches of 50 processed sequentially. No message loss. sent_count increments correctly. Worker does not exceed rate limit. | High |
| CAM-075 | Retry logic - transient error (recipient temporarily unavailable) | Campaign running, one recipient triggers transient WhatsApp error | Background: Worker retries recipient on transient error (not fatal). | Recipient retried up to MAX_RETRIES (3). If succeeds on retry 2, recipient marked "delivered" and retry_count=2. If all retries fail, recipient marked "failed" with error_message. | High |
| CAM-076 | Fatal error handling - invalid token (code 190) | Campaign running, WhatsApp account token expired | Background: Worker attempts to send, receives Meta error code 190 (invalid token). | Campaign immediately pauses/aborts. Status changes to "failed". error_message set: "Access token is invalid or expired. Re-authenticate the WhatsApp account in Settings." No further messages attempted. | High |
| CAM-077 | Fatal error handling - permission denied (code 200) | Campaign running, WhatsApp token lacks required scopes | Background: Worker receives Meta error code 200 (permission denied). | Campaign halts. Status set to "failed". error_message: "Insufficient permissions on the access token. Check the token scopes." Admin notified or error logged. | High |
| CAM-078 | Fatal error handling - hourly quota exhausted (code 4) | Campaign running, account hits Meta hourly limit | Background: Worker receives Meta error code 4 (app quota exhausted). | Campaign pauses. Status set to "paused" (not permanently failed). error_message: "WhatsApp API hourly rate limit reached. The campaign will need to be restarted." User can resume after quota resets. | Medium |
| CAM-079 | Batch processing - 50 messages per batch | Campaign running with 150 recipients | Background: Worker processes campaign. | Messages processed in 3 batches: batch 1 (50), batch 2 (50), batch 3 (50). Between batches, pause for rate limiting. Batches do not overlap. | Medium |
Preflight Check API Endpoint
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-080 | Preflight check - estimate recipient count (contacts source) | Logged in as Agent, 10 contacts exist | 1. POST /campaigns/preflight with recipient_source="contacts", contact_ids=[id1, id2, id3] | Response includes planned_recipients: 3. | High |
| CAM-081 | Preflight check - estimate recipient count (tags source) | Logged in as Agent, tag "vip" has 5 contacts, tag "leads" has 3 contacts | 1. POST /campaigns/preflight with recipient_source="tags", tags=["vip"] | Response includes planned_recipients: 5. | High |
| CAM-082 | Preflight check - estimate recipient count (CSV) | Logged in as Agent | 1. POST /campaigns/preflight with recipient_source="csv", csv_data=[{phone: "+1234567890", name: "John"}, ...] (5 rows) | Response includes planned_recipients: 5. | High |
| CAM-083 | Preflight check - assess account limits | Logged in as Agent, WhatsApp account tier: "standard" (1000 msg/day cap) | 1. POST /campaigns/preflight with whatsapp_account_id=acc1, planned_recipients=500 | Response: can_proceed=true, severity="none", reasons=[], tier_cap=1000. | High |
| CAM-084 | Preflight check - warning on quality rating | Logged in as Agent, account quality_rating="medium" (below optimal) | 1. POST /campaigns/preflight with whatsapp_account_id=acc1, planned_recipients=100 | Response: can_proceed=true, severity="warning", reasons include "Quality rating below recommended level", quality_rating="medium". | Medium |
| CAM-085 | Preflight check - error on tier cap exceeded | Logged in as Agent, account tier "standard" (100 msg/day cap), planned 200 recipients | 1. POST /campaigns/preflight with whatsapp_account_id=acc1, planned_recipients=200 | Response: can_proceed=false, severity="error", reasons include "Tier limit exceeded". tier_cap=100. | High |
| CAM-086 | Preflight check - error on invalid/expired token | Logged in as Agent, WhatsApp account has invalid token | 1. POST /campaigns/preflight with whatsapp_account_id=acc_invalid, planned_recipients=50 | HTTP 400 response. Detail: "Access token is invalid or expired." or similar. | Medium |
WhatsApp Templates Tab
| ID | Test Case | Preconditions | Steps | Expected Result | Priority |
|---|---|---|---|---|---|
| CAM-087 | View WhatsApp templates list | Logged in as Agent, organization has 2 accounts with 5 templates total | 1. Navigate to /campaigns 2. Click "WhatsApp Templates" tab | Templates list displays with: Template Name, Account Name, Language, Category, Status (approved/pending/rejected). Accounts dropdown and status filters present. | High |
| CAM-088 | Filter templates by account | WhatsApp Templates tab open, Account A has 2 templates, Account B has 3 | 1. Click Account filter dropdown 2. Select "Account A" | Only 2 templates for Account A display. Unrelated templates hidden. | Medium |
| CAM-089 | Filter templates by status | Templates list has mix of approved, pending, rejected | 1. Click Status filter 2. Select "pending" | Only pending templates display. Others hidden. | Medium |
| CAM-090 | Filter templates by category | Templates exist with MARKETING, UTILITY, AUTHENTICATION categories | 1. Click Category filter 2. Select "UTILITY" | Only UTILITY templates display. | Medium |
| CAM-091 | Search templates by name | Templates tab open, templates include "Welcome", "Confirmation", "Reminder" | 1. Type "Welcome" in search box 2. Wait for filter | Only "Welcome" template displays. Search is case-insensitive. | Medium |
| CAM-092 | Create template - form validation | In WhatsApp Templates tab, create form open | 1. Leave Account blank 2. Try to save | Error: "WhatsApp account is required." Save button disabled. | Medium |
| CAM-093 | Create template - minimum fields | In WhatsApp Templates tab, create form open | 1. Select Account "Account A" 2. Enter Name "Hello Template" 3. Select Language "en_US" 4. Select Category "MARKETING" 5. Enter Body "Hello {{1}}" 6. Click Save | Template created. Success toast: "Template created." Form resets. New template appears in list with status "pending" (awaiting Meta approval). | High |
| CAM-094 | Create template - with IMAGE header (media) | In WhatsApp Templates tab, create form open | 1. Select Account 2. Enter Name "Welcome with Image" 3. Select Language 4. Select Category 5. Click "Add Header" 6. Select Header Format "IMAGE" 7. Enter Header text or note "Welcome image" 8. Enter Body "Hello {{1}}" 9. Click Save | Template created with IMAGE header. Success toast displayed. Template saved with header format "IMAGE" in Meta. Appears in list. | High |