Notifications — QA Plan
1. Cron gating
| # | Scenario | Expected |
|---|---|---|
| 1.1 | Dev env, CRONS_ENABLED=false | Cron methods early-return |
| 1.2 | Prod env, enabled | Job runs |
2. Class reminders
| # | Scenario | Expected |
|---|---|---|
| 2.1 | 5 confirmed bookings for a class tomorrow at 09:00 | 5 emails sent at the 08:00 UTC tick |
| 2.2 | Class in 18h (outside 20–28h window) | No emails |
| 2.3 | Class in 30h | No emails |
| 2.4 | Cancelled booking | No email |
| 2.5 | Member with missing first name | ”Hi there” fallback used in template |
| 2.6 | Class has no location | Template omits location section |
| 2.7 | Resend rate-limited / error | Other recipients still get sent; failure count logged |
| 2.8 | Cron re-runs (same window) | Recipients receive duplicate — known behavior; document |
3. Expiration warnings
| # | Scenario | Expected |
|---|---|---|
| 3.1 | Subscription expires in 7 days | Email sent at 09:00 UTC |
| 3.2 | Subscription expires in 5 days | No email (outside window) |
| 3.3 | Subscription status='cancelled' | No email |
4. Cancellation notifications
| # | Scenario | Expected |
|---|---|---|
| 4.1 | Member cancels booking | Cancellation email sent immediately (not cron’d) |
| 4.2 | Staff cancels session — fans out to all booked members | One email each |
5. Test mode
| # | Scenario | Expected |
|---|---|---|
| 5.1 | Spec calls EmailService.send | No network call; entry recorded in in-memory log |
| 5.2 | getSentEmails() returns entries | Spec assertions pass |
6. Localization
| # | Scenario | Expected |
|---|---|---|
| 6.1 | Hebrew member receives class reminder | Known gap — template renders in English. Flag for fix. |
7. Smoke
- Manually trigger reminder cron (or stub time) → email lands in test inbox.
- Resend dashboard shows the send.
- Cancellation flow triggers an email immediately.