Comprehensive Testing Guide
This guide walks you through testing every feature of PacBoiler, from setup to payments and emails.
1. Prerequisites
Ensure your .env.local is configured with credentials for:
- Supabase (URL and Anon Key)
- Supabase Service Role Key (for admin operations)
- LemonSqueezy (Test Mode)
- Resend
Required Environment Variables
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# LemonSqueezy
LEMONSQUEEZY_API_KEY=your_api_key
LEMONSQUEEZY_STORE_ID=your_store_id
LEMONSQUEEZY_WEBHOOK_SECRET=your_webhook_secret
NEXT_PUBLIC_LEMONSQUEEZY_PRO_VARIANT_ID=your_pro_variant_id
NEXT_PUBLIC_LEMONSQUEEZY_ENTERPRISE_VARIANT_ID=your_enterprise_variant_id
# Resend
RESEND_API_KEY=your_resend_api_key2. Database Setup (Supabase)
- Login to Supabase Dashboard.
- Select Project → SQL Editor.
- Run Migrations (In Order):
- 001_initial_schema.sql: Core tables (profiles, subscriptions, webhooks) and functions.
- 002_rbac.sql: Admin policies and role management.
- 003_waitlist.sql: Waitlist and conversion tracking.
- 004_notifications.sql: In-app notification system.
- Verify: Go to Table Editor. You should see the following tables:
profilessubscriptionswebhook_eventswaitlistwaitlist_conversionsnotifications
3. Authentication Setup
Enable Auth Providers
-
Go to Authentication → Providers in Supabase Dashboard
-
Enable the following:
- ✅ Email (Magic Link)
- ✅ GitHub (follow setup in main docs)
-
Configure URL Configuration:
- Site URL:
http://localhost:3000 - Redirect URLs: Add these:
- Site URL:
http://localhost:3000/auth/callback
http://localhost:3000/dashboard
http://localhost:3000/admin
4. Authentication & User Profile
Sign Up (Magic Link)
- Go to
http://localhost:3000/signup. - Enter an email (e.g.,
test@example.com) and click "Send Magic Link". - Check Email:
- Check the inbox of
test@example.com. - Click the Magic Link.
- Check the inbox of
- Verify: You should be redirected to
/dashboard. - DB Verify: Check
profilestable in Supabase - user should haverole = 'user'.
Sign Up (GitHub OAuth)
- Go to
http://localhost:3000/signup. - Click "Continue with GitHub".
- Authorize the application.
- Verify: You should be redirected to
/dashboard.
Update Profile
- Go to
/dashboard/settings. - Enter a Full Name (e.g., "Test User") and Avatar URL (e.g.,
https://github.com/shadcn.png). - Click Save Changes.
- Verify: Refresh the page. The name and avatar in the sidebar/header should update.
- DB Verify: Check
profilestable in Supabase -full_nameandavatar_urlshould be updated.
Delete Account
- Go to
/dashboard/settings. - Click Delete Account → Confirm in the dialog.
- Verify: You are redirected to
/and logged out. - DB Verify: User should be gone from
auth.usersandpublic.profiles(cascades to subscriptions).
5. Admin Panel & RBAC
Promote to Super Admin
- Sign up a new user (e.g.,
admin@example.com). - Go to Supabase SQL Editor and run:
UPDATE public.profiles
SET role = 'super_admin'
WHERE email = 'admin@example.com';- Important: Sign out and sign back in as
admin@example.comfor the role to take effect.
Test Admin Redirect
- Log in as
admin@example.com. - Verify: You should be automatically redirected to
/admininstead of/dashboard.
Admin Dashboard Features
- View Dashboard: At
/admin, you should see admin statistics and overview. - User Management: Go to
/admin/users. You should see:- List of all users with their roles, plans, and join dates
- Ability to change roles (dropdown for each user)
- Three-dot menu with delete option
Role Management (Super Admin Only)
- As
super_admin, try to change another user's role toadmin. - Verify:
- Confirmation dialog appears
- Role updates successfully
- Page refreshes showing new role
- Test Protection: Try to change your own role (should show error: "You cannot change your own role").
Admin vs Super Admin Permissions
- Create a regular admin:
UPDATE public.profiles
SET role = 'admin'
WHERE email = 'regularadmin@example.com';- Log in as the regular admin.
- Verify Read-Only Access:
- Can view
/adminand/admin/users - Cannot change roles (dropdown is disabled)
- Cannot delete users (delete option is hidden)
- Can view
Delete User (Super Admin Only)
- Log in as
super_admin. - Go to
/admin/users. - Click the three-dot menu on a user → Delete user.
- Verify:
- Confirmation dialog appears with warning
- User is deleted from database
- Cannot delete your own account (option disabled)
6. Payments (LemonSqueezy)
Prerequisite: Enable "Test Mode" in LemonSqueezy Store Settings.
Setup Products
- Create two products in LemonSqueezy (Pro, Enterprise).
- Create variants for each product.
- Copy their Variant IDs to
.env.local:
NEXT_PUBLIC_LEMONSQUEEZY_PRO_VARIANT_ID=123456
NEXT_PUBLIC_LEMONSQUEEZY_ENTERPRISE_VARIANT_ID=789012Checkout Flow
- Login as a user (not admin).
- Go to
/dashboard/billing. - Verify Current Plan: Should show "Free" plan by default.
- Click Upgrade on the "Pro" plan.
- LemonSqueezy Checkout: You should be redirected to a test checkout page.
- Use a Test Card:
- Card:
4242 4242 4242 4242 - Expiry: Any future date
- CVC: Any 3 digits
- Card:
- Complete purchase.
- Verify: You are redirected back to
/dashboard/billing?success=true.
Webhooks (Critical for Updating Database)
To test that the database updates after payment:
- Install ngrok (if not already):
npm install -g ngrok- Start your Next.js app:
npm run dev- Start ngrok in another terminal:
ngrok http 3000-
Copy HTTPS URL: From ngrok output (e.g.,
https://xxxx.ngrok-free.app). -
Configure LemonSqueezy Webhook:
- Go to LemonSqueezy Dashboard → Settings → Webhooks
- Click "+" to add new webhook
- URL:
https://xxxx.ngrok-free.app/api/webhooks/lemonsqueezy - Events: Select all subscription events:
subscription_createdsubscription_updatedsubscription_cancelledsubscription_resumedsubscription_expiredsubscription_pausedsubscription_unpaused
- Signing Secret: Copy this and add to
.env.localasLEMONSQUEEZY_WEBHOOK_SECRET - Save webhook
-
Test Complete Flow:
- Perform a test checkout again
- Watch Terminal: You should see "Processing webhook" logs
- Check Database:
- Go to Supabase → Table Editor →
subscriptions - Find your user's subscription
- Verify:
status = 'active',plan_type = 'pro'
- Go to Supabase → Table Editor →
- Check UI:
- Refresh
/dashboard/billing - Should show "Current Plan: Pro" with active status
- Refresh
-
Test Cancellation:
- Go to LemonSqueezy Dashboard → Subscriptions
- Find the test subscription and cancel it
- Verify: Webhook fires, database updates, UI reflects cancellation
7. Emails (Resend)
Setup
- Ensure
RESEND_API_KEYis set in.env.local. - Verify your domain in Resend Dashboard (or use test domain for development).
Test Welcome Email
- The
sendWelcomeEmailfunction is ready insrc/lib/resend/index.ts. - Manual Test - Create a test route:
// src/app/test-email/route.ts
import { sendWelcomeEmail } from "@/lib/resend";
import { NextResponse } from "next/server";
export async function GET() {
try {
await sendWelcomeEmail("your@email.com", "Test User");
return NextResponse.json({ success: true });
} catch (error) {
return NextResponse.json({ error: "Failed to send" }, { status: 500 });
}
}- Visit
http://localhost:3000/test-email. - Check your inbox for the welcome email.
Transactional Emails (Optional)
- Subscription Emails: Can be triggered inside the Webhook handler (
src/app/api/webhooks/lemonsqueezy/route.ts). - You can add email notifications for:
- New subscription
- Subscription cancelled
- Payment failed
- Subscription renewed
8. Waitlist Testing
Signup Flow
- Go to the landing page (
/). - Locate the Waitlist section.
- Enter an email (e.g.,
waitlist@example.com) and click "Join Waitlist". - Verify: A success message should appear.
- DB Verify: Check the
waitlisttable in Supabase. The email should be present withstatus = 'active'.
Conversion Tracking
- Sign up for a full account using the same email used for the waitlist (
waitlist@example.com). - Complete the signup flow (Magic Link or OAuth).
- Verify: Log in and go to
/dashboard. - DB Verify:
- Check the
waitlisttable; the status forwaitlist@example.comshould now beconverted. - Check the
waitlist_conversionstable; a new entry should link the waitlist ID to the new profile ID.
- Check the
Admin View
- Log in as a
super_admin. - Go to
/admin/waitlist(if implemented) or check stats. - Verify: The new signup should be reflected in the waitlist statistics.
9. Rate Limiting Testing
Prerequisite: Ensure Upstash Redis variables are set in .env.local.
Trigger Rate Limit
- Go to the Waitlist form or Login page.
- Rapidly submit the form multiple times (e.g., 10+ times within a few seconds).
- Verify:
- The server should return a
429 Too Many Requestsstatus. - A toast notification or error message should appear: "Too many requests. Please try again later."
- The server should return a
Verification
- Wait for the duration specified in your rate limit configuration (e.g., 1 minute).
- Try submitting again.
- Verify: The request should now succeed.
10. Notifications Testing
Triggering Notifications
- Welcome Notification: Sign up as a new user.
- Admin Actions: (If implemented) Have an admin perform an action that triggers a notification for a user.
UI Verification
- Log in as the user.
- Look for the notification icon in the header/sidebar.
- Verify: A red dot or counter should indicate unread notifications.
- Click the icon to open the notifications panel.
- Verify: The notification (e.g., "Welcome to PacBoiler! 🎉") should be visible.
Mark as Read
- Click on a notification or the "Mark all as read" button.
- Verify: The unread indicator should disappear.
- DB Verify: Check the
notificationstable in Supabase;readshould betrue.
11. End-to-End User Journey
Test the complete flow:
- Waitlist: User joins waitlist → status is 'active'
- Signup: User signs up with same email → waitlist status becomes 'converted' → receives welcome notification
- Profile: User updates their profile with name and avatar
- Upgrade: User upgrades to Pro plan → completes checkout
- Webhook: Webhook fires → database updates → UI shows Pro plan
- Admin: Super admin can view the user and waitlist stats in admin panel
- Delete: User deletes their account → all data is removed via cascade
12. Common Issues & Troubleshooting
Magic Link Not Working
- Check spam folder
- Verify Site URL in Supabase matches
http://localhost:3000 - Check redirect URLs are whitelisted
- Ensure email provider is enabled
Admin Panel Access Denied
- Verify role is set to
adminorsuper_adminin database - Sign out and sign back in after role change
- Check that admin policies are created in database
Webhook Not Firing
- Ensure ngrok is running and HTTPS URL is correct
- Verify webhook secret matches in both LemonSqueezy and
.env.local - Check terminal for any error logs
- Test webhook manually in LemonSqueezy dashboard
Role Changes Not Working
- Ensure
SUPABASE_SERVICE_ROLE_KEYis set in.env.local - Verify the API route at
/api/admin/users/roleexists - Check browser console for errors
- Ensure you're logged in as
super_admin
Delete Not Working
- Ensure
SUPABASE_SERVICE_ROLE_KEYis set - Verify you're not trying to delete your own account
- Check that
createAdminClientis properly configured - Look for errors in terminal logs
Rate Limiting Not Working
- Verify Upstash Redis URL and Token are correct
- Check if you are testing from a whitelisted IP (if any)
- Ensure the middleware or API route is correctly applying the rate limiter
13. Next Steps
After testing:
- Remove test email route if created
- Clean up test users from database
- Document any custom modifications
- Prepare for production deployment