Automations — QA Plan
Run locally with AUTOMATIONS_ENABLED=true on the API; the engine is off without it. Join-link purchases complete without a real card when the org uses the test payment provider and the API runs with TEST_HOOKS_ENABLED=true.
1. Editor
| # | Scenario | Expected |
|---|---|---|
| 1.1 | Type text, put the caret mid-sentence, pick “insert variable” | Token lands at the caret; typing continues in the editor |
| 1.2 | Bold, italic, underline, H2/H3, bullet and numbered lists | Shown in the editor and the preview |
| 1.3 | Add an https:// link, then a mailto: link | Both saved; links styled in the editor and preview |
| 1.4 | Try javascript:alert(1) | Refused in the popover; API rejects it with 400 if sent directly |
| 1.5 | Link popover → “Book a class — opens the app” | Saved as /schedule; delivered email links to ${FRONTEND_URL}/schedule |
| 1.6 | Save, activate, reload | Formatting, links and variables come back intact |
| 1.7 | Open an automation saved with only a plain body | Loads as paragraphs; saving keeps the text |
| 1.8 | new_member step: open “insert variable” | Only {first_name}, {last_name}, {org_name} |
| 1.9 | Paste {plan_name} into a new_member body | Inline warning; Save/Activate disabled; API returns 400 automation_unsupported_variables |
| 1.10 | Preview in Hebrew / Russian | Sample name דנה / Дана |
2. Email rendering
| # | Scenario | Expected |
|---|---|---|
| 2.1 | Hebrew member receives an automation email | Org letterhead and footer, right-to-left, name interpolated |
| 2.2 | English lead receives an automation email | Left-to-right, lead consent footer + List-Unsubscribe |
| 2.3 | Step with an empty subject | Subject is the org name, never the automation’s name |
| 2.4 | Body with a long URL, viewed at 390px | Link wraps; no horizontal overflow |
| 2.5 | Plain body containing <b> and & | Rendered as text, escaped |
| 2.6 | Same step on push / WhatsApp | Plain text, links as text (url) |
3. Unsubscribe
| # | Scenario | Expected |
|---|---|---|
| 3.1 | Promotional automation (e.g. absent) to a member | Body unsubscribe line + List-Unsubscribe / List-Unsubscribe-Post headers |
| 3.2 | Transactional automation (e.g. new_member, subscription_started) | No unsubscribe line or headers |
| 3.3 | Click the link → confirm on /{lang}/automation-emails/unsubscribe | automation.email = false; announcement pref untouched |
| 3.4 | One-click POST /email-unsubscribe?token=… | Same result; 200 |
| 3.4b | After unsubscribing, follow “Manage notification preferences” | Lands on /{lang}/profile/notifications (via sign-in); turning “automatic messages” email back on re-enables automation email |
| 3.5 | Tampered token | 200 with status: invalid; nothing written |
| 3.6 | Announcement link mailed before this release (/announcements/unsubscribe, old web page) | Still opts out of announcement email only |
| 3.7 | Opted-out member hits another automation | Step run skipped / member_opted_out |
4. New-member welcome
| # | Scenario | Expected |
|---|---|---|
| 4.1 | Desk-created member | One welcome email |
| 4.2 | Join link without a plan | One welcome email |
| 4.3 | Join link with a plan, paid online | Fixed “purchase confirmed” system email + the welcome after the payment lands |
| 4.4 | Join link with a plan, presale | Presale confirmation + the welcome right away (not ~70 min later) |
| 4.5 | Join link with a plan, checkout abandoned | No welcome; hold dropped after 24h or released |
| 4.6 | Join-link signup settled at the desk (cash or free plan) | Welcome once the plan starts |
| 4.7 | Existing member buys another plan, or renews | No second welcome |
| 4.8 | Member under 18 joins | Welcome sent |
| 4.9 | Staff create a managed child; guardian accepts the link | One welcome to the guardian’s email, subject “Regarding |
| 4.10 | Promotional automation (e.g. birthday) for a managed child | Skipped promotional_to_minor_blocked |
| 4.11 | Erase a member who received an automation | Erasure succeeds; their enrollments and step runs are gone |
5. Push
| # | Scenario | Expected |
|---|---|---|
| 5.1 | Tap an automation push in the member app | Opens the home tab |
| 5.2 | Push step with email fallback, member has no app installed | Step run skipped no_device; fallback email sent |
6. Counters
| # | Scenario | Expected |
|---|---|---|
| 6.1 | After a welcome is sent | List shows “Sent (30d)” 1; “In progress” 0 once the enrollment completes |