Test Cases: Registration — Free Events (RSVP)
Module: Events & Registrations - Free Registration
Endpoints: POST /api/events/:id/register (member) · POST /api/public/:tenantSlug/events/:slug/register (guest) · DELETE /api/events/:id/register (cancel).
Frontend: register directly from the Registration card on /events/:slug (no checkout page for free events).
Prerequisites
- A free (
priceCents: 0, RSVP) upcoming event — e.g. the seed'sRCME Check-in Test Event(today). Login astestmember@rcme.membervu.com/Member123!.
Test Cases
TC-REG-FREE-01: Immediate RSVP
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open the free event → Registration card shows "Free" + a "Register" button. | Button visible (capacity available). |
| 2 | Click Register. | POST /api/events/:id/register. Toast "Successfully registered for event!"; auto-switches to the My Ticket(s) tab. Status → CONFIRMED / REGISTERED_PAID (free = no invoice). |
| 3 | Check the My Ticket tab. | QR code + ticket/check-in code shown (Print/Copy available). |
| 4 | Check MailHog (https://stg-webmail.membervu.com). | A confirmation email with the ticket (QR / .ics if enabled in event email settings). |
TC-REG-FREE-02: Full Event (Sold Out — no waitlist)
| Step | Action | Expected Result |
|---|---|---|
| 1 | Open an event at full capacity (or lower an event's capacity below its registration count to force it). | Card shows red "Sold Out"; detail card shows "Event is Full — Check back for cancellations", no Register button, no "Join Waitlist". |
| 2 | API bypass: POST /api/events/:id/register. | 400 — "Event capacity reached". |
TC-REG-FREE-03: Already Registered (idempotent)
| Step | Action | Expected Result |
|---|---|---|
| 1 | On an event you're already registered for, the card shows "Registered" + "View Ticket". | No duplicate register button. |
| 2 | Re-call POST /api/events/:id/register. | Idempotent — no duplicate registration created. |
TC-REG-FREE-04: Cancel Registration
| Step | Action | Expected Result |
|---|---|---|
| 1 | Cancel your registration (UI cancel / DELETE /api/events/:id/register). | Registration → CANCELLED; the spot frees up. (For paid+already-paid registrations, cancel is blocked.) |
TC-REG-FREE-05: Guest Public Registration + Referral (#172/#173)
| Step | Action | Expected Result |
|---|---|---|
| 1 | Logged out, open the public event landing page → register as a guest (name/email). | Guest registration form (POST /api/public/:tenantSlug/events/:slug/register); a guest Member record is created. |
| 2 | In the Referral section choose "Referred by a member", type a member's full name → click Verify. | Single match → green ✓ + a signed token stored (no member ID exposed); ambiguous → "be more specific"; not found → message. Token sent on submit; if it expires, you're asked to re-verify. |
TC-REG-FREE-06: Re-register After Cancel → Fresh Row + Fresh QR (#637)
| Step | Action | Expected Result |
|---|---|---|
| 1 | Register, note the check-in code/QR, then cancel (DELETE /api/events/:id/register) and register again for the same event. | The unique index is now partial / active-only (WHERE status <> 'CANCELLED') — re-registration inserts a new EventRegistration row rather than reactivating the cancelled one (reverses the #448 reactivate-in-place behavior). |
| 2 | Compare the new check-in code/QR to the one noted before cancelling. | They are different — the free-event check-in code is a hash of registration.id, so a new row means a new code/QR. |
| 3 | Check the cancelled registration's fate; then try registering again while already active. | The CANCELLED row is retained (audit history, not deleted); attempting a second active registration is blocked/idempotent — only one non-cancelled row per member+event. |