Test Cases: Admin Fundraising Console (#623)

Module: Fundraising & Campaigns — Admin Console

Endpoints: GET /api/campaigns/admin/donations/pending (queue) · approve/reject (see TC-FUND-001) · POST /api/billing/admin/campaigns/:id/close-out · GET .../close-out/donors.csv · POST .../close-out/thank-you.

Frontend: /admin/campaigns (list), /admin/campaigns/new (create), /admin/campaigns/donations/pending (pending-proof queue), /admin/campaigns/:id (detail), /admin/campaigns/:id/updates. Roles: ADMIN / TREASURER / FINANCE_MANAGER / SUPER_ADMIN.

Prerequisites

Test Cases

TC-FUND-ADMIN-01: Pending-Proof Queue Lists Oldest-First

StepActionExpected Result
1Open Proof Review (/admin/campaigns/donations/pending).GET /api/campaigns/admin/donations/pending — lists all tenant PENDING donations across all campaigns, oldest first, each row showing the donor, amount, and the uploaded proof image.
2Approve or reject a row inline (no page navigation).The row disappears from the queue immediately; the same approve/reject endpoints from TC-FUND-001 are used.

TC-FUND-ADMIN-02: Nav Badge Tracks Pending Count

StepActionExpected Result
1Note the current "Proof Review" sidebar badge count. Create a new donation + proof upload (as donor, in a second session/tab).Badge count increments by 1 (backed by listPendingDonations().total, key pendingProofDonations).
2Approve or reject the new donation.Badge count decrements by 1.
3Log in as a role WITHOUT finance permissions and check the badge.The badge shows 0 — a 403 on the underlying fetch is treated as 0, not surfaced as an error.

TC-FUND-ADMIN-03: Campaign Close-Out — Final Totals

StepActionExpected Result
1On an ACTIVE campaign with a mix of APPROVED/PENDING/REJECTED donations, trigger Close-Out from the campaign detail page.POST /api/billing/admin/campaigns/:id/close-out. FundraisingCampaign.status ACTIVE → CLOSED. Response finalTotal = SUM(Donation.amount WHERE approvalStatus = APPROVED) only — PENDING/REJECTED excluded. donationCount matches the number of APPROVED donations.
2Re-trigger Close-Out on the now-CLOSED campaign.Idempotent 200 no-op (NOT a 400) — same finalTotal/donationCount returned.

TC-FUND-ADMIN-04: Close-Out Donor CSV Export

StepActionExpected Result
1Download GET .../close-out/donors.csv for the closed campaign.CSV contains only APPROVED donations. Anonymous donation rows have name/email redacted to "Anonymous"/empty string.

TC-FUND-ADMIN-05: Close-Out Bulk Thank-You Email

StepActionExpected Result
1Trigger POST .../close-out/thank-you.Response shape {total,sent,skipped,failed}. Only APPROVED donors are emailed; anonymous donors with no linked member are skipped, not failed.
2Check MailHog.One thank-you email per non-anonymous APPROVED donor.

TC-FUND-ADMIN-06: Auto-Close on Deadline Does NOT Auto-Run Close-Out

StepActionExpected Result
1Let (or force via a past endsAt) a campaign's deadline pass.A sweep auto-transitions ACTIVE → CLOSED; the public donate button goes dark/disabled.
2Check any donations that were PENDING near the deadline.Close-out is NOT auto-run — those PENDING donations remain in the Proof Review queue and are still approvable by admin after auto-close.