# Testing Guide

Comprehensive testing procedures and checklists for ThrillWiki.

---

## Testing Philosophy

1. **Manual testing first** - Critical user flows tested manually
2. **Database validation** - Verify data integrity with SQL queries
3. **Error monitoring** - Watch logs during testing
4. **Real-world scenarios** - Test with realistic data
5. **Edge cases** - Test boundary conditions and error states

---

## Manual Testing Checklist

### Authentication Flow

**Password Sign In:**
- [ ] Sign in with valid credentials
- [ ] Sign in with invalid password
- [ ] Sign in with non-existent email
- [ ] Session persists after page refresh
- [ ] Sign out works correctly

**OAuth Sign In:**
- [ ] Google OAuth flow completes
- [ ] Discord OAuth flow completes
- [ ] Profile created after first OAuth sign-in
- [ ] OAuth profile data synced correctly

**MFA Enrollment:**
- [ ] Enroll TOTP factor successfully
- [ ] QR code displays correctly
- [ ] Backup codes generated
- [ ] Verify code works
- [ ] Invalid code rejected

**MFA Challenge:**
- [ ] MFA-enrolled user prompted for code on sign in
- [ ] Valid code accepted, session upgraded to AAL2
- [ ] Invalid code rejected
- [ ] Step-up required for admin actions
- [ ] Lock warning shows when AAL2 about to expire

### Submission Flow

**Park Creation:**
- [ ] Form validation works (required fields, slug format)
- [ ] Image upload works (banner, card, gallery)
- [ ] Date precision selector works (day, month, year)
- [ ] Location search and selection works
- [ ] Operator/property owner selection works
- [ ] Submission created in moderation queue
- [ ] Toast confirmation shows
- [ ] No direct write to parks table

**Park Editing:**
- [ ] Existing park loads in form
- [ ] Change detection works (only changed fields submitted)
- [ ] Image replacement works
- [ ] Submission created with original_data
- [ ] Edit appears in moderation queue

**Ride Creation:**
- [ ] All ride categories work
- [ ] Coaster stats editor works (metric only)
- [ ] Technical specs editor works
- [ ] Former names editor works
- [ ] Unit conversion helper displays
- [ ] Submission created successfully

**Company Creation:**
- [ ] Company type selection works
- [ ] Person type selection works
- [ ] Founded date with precision works
- [ ] Logo upload works
- [ ] Submission created successfully

**Ride Model Creation:**
- [ ] Manufacturer required validation works
- [ ] Category selection works
- [ ] Submission created successfully

### Moderation Queue

**Queue Display:**
- [ ] All pending submissions show
- [ ] Filters work (entity type, status, search)
- [ ] Sort options work
- [ ] Pagination works
- [ ] Stats display correctly

**Claiming:**
- [ ] Claim submission button works
- [ ] Lock acquired (15 minutes)
- [ ] Lock status displays
- [ ] Another moderator cannot claim
- [ ] Lock expires after 15 minutes

**Lock Management:**
- [ ] Lock timer displays correctly
- [ ] Warning shows at 2 minutes remaining
- [ ] Extend lock button works
- [ ] Lock auto-expires if not extended
- [ ] Expired lock shows error state

**Review:**
- [ ] Submission items display correctly
- [ ] Change comparison shows (for edits)
- [ ] Dependency visualization works
- [ ] Individual item approval works
- [ ] Individual item rejection works

**Approval:**
- [ ] Approve all works
- [ ] Selective approval works
- [ ] Edge function called successfully
- [ ] Entity created/updated in database
- [ ] Version created with correct attribution
- [ ] Submission status updated to 'approved'
- [ ] Lock released
- [ ] Notification sent to submitter

**Rejection:**
- [ ] Rejection reason required
- [ ] Reject all works
- [ ] Submission status updated to 'rejected'
- [ ] Lock released
- [ ] Notification sent to submitter

### Versioning System

**Version Creation:**
- [ ] Version created on entity INSERT
- [ ] Version created on entity UPDATE
- [ ] Version number increments
- [ ] is_current flag set correctly
- [ ] created_by set from session variable
- [ ] submission_id linked correctly

**Version History:**
- [ ] All versions display in timeline
- [ ] Version details show correctly
- [ ] Created by user shows
- [ ] Change type badge displays
- [ ] Current version marked

**Version Comparison:**
- [ ] Select two versions
- [ ] Compare button enabled
- [ ] Diff shows changed fields only
- [ ] Old vs new values display
- [ ] Foreign key changes resolved to names

**Rollback:**
- [ ] Rollback button shows (not for current version)
- [ ] Rollback creates new submission
- [ ] Submission goes to moderation queue
- [ ] On approval, new version created

### Image Upload

**Upload Flow:**
- [ ] Drag & drop works
- [ ] File picker works
- [ ] Multiple files upload
- [ ] Progress indicator shows
- [ ] CloudFlare upload succeeds
- [ ] Image preview displays
- [ ] Caption editor works
- [ ] Set as banner works
- [ ] Set as card works
- [ ] Remove image works
- [ ] Blob URLs cleaned up

**Error Handling:**
- [ ] File too large rejected
- [ ] Invalid file type rejected
- [ ] Network error handled
- [ ] Partial upload failure handled
- [ ] Cleanup on error works

### Unit System

**Display Conversion:**
- [ ] Metric user sees km/h, m, cm
- [ ] Imperial user sees mph, ft, in
- [ ] Auto-detection sets correct system
- [ ] Manual preference change works
- [ ] Conversion accurate

**Input Validation:**
- [ ] Coaster stats only accept metric
- [ ] Technical specs enforce metric
- [ ] Conversion helper shows correct formula
- [ ] Invalid unit rejected

### Date Handling

**Date Input:**
- [ ] Date picker works (day precision)
- [ ] Month picker works (month precision)
- [ ] Year input works (year precision)
- [ ] Precision selector works
- [ ] Date stored as YYYY-MM-DD

**Date Display:**
- [ ] Day precision: "July 15, 2024"
- [ ] Month precision: "July 2024"
- [ ] Year precision: "2024"
- [ ] Empty date handled gracefully

### Notifications

**Subscriber Creation:**
- [ ] Novu subscriber created on sign up
- [ ] Subscriber ID stored in database
- [ ] Profile data synced to Novu

**Notification Triggering:**
- [ ] Submission approved notification sent
- [ ] Submission rejected notification sent
- [ ] Review reply notification sent
- [ ] Moderation alert sent to moderators

**Notification Center:**
- [ ] In-app center displays
- [ ] Unread count shows
- [ ] Mark as read works
- [ ] Notification click navigates correctly

### User Roles & Permissions

**Role Assignment:**
- [ ] Admin can grant moderator role
- [ ] Admin can grant admin role
- [ ] Only superuser can grant superuser role
- [ ] Role revocation works
- [ ] Audit log entry created

**Permission Checks:**
- [ ] User cannot access admin pages
- [ ] Moderator can access moderation queue
- [ ] Admin can access user management
- [ ] Superuser can access all admin features
- [ ] MFA required for sensitive actions

---

## Database Validation Queries

### Check Submission Flow

```sql
-- Verify no direct writes to entity tables (should be empty if moderation works)
SELECT * FROM parks 
WHERE created_at > NOW() - INTERVAL '1 hour'
  AND id NOT IN (
    SELECT (item_data->>'park_id')::UUID 
    FROM submission_items 
    WHERE item_type = 'park' AND status = 'approved'
  );
```

### Check Versioning

```sql
-- Verify version created for recent park update
SELECT 
  p.name,
  pv.version_number,
  pv.change_type,
  pv.created_by,
  pv.submission_id,
  pv.is_current
FROM parks p
JOIN park_versions pv ON pv.park_id = p.id
WHERE p.updated_at > NOW() - INTERVAL '1 hour'
ORDER BY p.id, pv.version_number DESC;
```

### Check Lock Status

```sql
-- Identify stuck locks
SELECT 
  id,
  submission_type,
  assigned_to,
  assigned_at,
  locked_until,
  status
FROM content_submissions
WHERE status = 'pending'
  AND locked_until IS NOT NULL
  AND locked_until < NOW();
```

### Check RLS Policies

```sql
-- Test entity table RLS (should fail as non-service role)
BEGIN;
SET LOCAL ROLE authenticated;
INSERT INTO parks (name, slug, park_type) 
VALUES ('Test Park', 'test-park', 'theme_park');
-- Should fail with permission denied
ROLLBACK;
```

---

## Error Monitoring

### Console Logs

Watch browser console for:
- [ ] No React errors
- [ ] No TypeScript errors
- [ ] No 401 Unauthorized errors
- [ ] No 403 Forbidden errors
- [ ] No 500 Server errors

### Network Tab

Monitor API calls:
- [ ] All Supabase requests succeed
- [ ] Edge function calls return 200
- [ ] CloudFlare uploads succeed
- [ ] Realtime subscriptions connected
- [ ] No excessive requests (n+1 queries)

### Edge Function Logs

Check Supabase logs for:
- [ ] No unhandled exceptions
- [ ] Request/response logged
- [ ] Duration reasonable (<5s)
- [ ] No infinite loops

---

## Performance Testing

### Page Load Times

- [ ] Homepage loads < 2s
- [ ] Park detail loads < 3s
- [ ] Moderation queue loads < 3s
- [ ] Image heavy pages load < 5s

### Query Performance

```sql
-- Slow query detection
SELECT 
  query,
  calls,
  total_time,
  mean_time,
  max_time
FROM pg_stat_statements
WHERE mean_time > 100 -- Over 100ms average
ORDER BY mean_time DESC
LIMIT 20;
```

### Bundle Size

```bash
npm run build
# Check dist/ folder size
# Target: < 1MB initial bundle
```

---

## User Acceptance Testing

### New User Journey

1. [ ] Sign up with email/password
2. [ ] Verify email (if required)
3. [ ] Complete profile setup
4. [ ] Browse parks
5. [ ] Add ride credit
6. [ ] Write review
7. [ ] Submit new park (goes to moderation)

### Moderator Journey

1. [ ] Sign in with moderator account
2. [ ] View moderation queue
3. [ ] Claim submission
4. [ ] Review submission details
5. [ ] Approve submission
6. [ ] Verify entity live on site
7. [ ] Check version history

### Admin Journey

1. [ ] Sign in with admin account
2. [ ] Complete MFA challenge
3. [ ] View user management
4. [ ] Grant moderator role
5. [ ] View system activity log
6. [ ] Check admin settings

---

## Regression Testing

After major changes, re-test:

**Critical Paths:**
- [ ] Auth flow (sign in, sign up, sign out)
- [ ] Submission flow (create park, moderation, approval)
- [ ] Version system (create, compare, rollback)
- [ ] Image upload (upload, set variants, delete)

**Secondary Paths:**
- [ ] Search functionality
- [ ] Filters and sorting
- [ ] User profiles
- [ ] Reviews and ratings
- [ ] Lists management

---

## Test Data Generation

Use the built-in test data generator:

```typescript
// Navigate to /admin/settings
// Click "Test Data Generator" tab
// Select entities to generate
// Click "Generate Test Data"
```

Or use the edge function:

```bash
curl -X POST https://[project-ref].supabase.co/functions/v1/seed-test-data \
  -H "Authorization: Bearer [anon-key]" \
  -H "Content-Type: application/json" \
  -d '{
    "parks": 10,
    "rides": 50,
    "companies": 5,
    "users": 20
  }'
```

---

## Bug Reporting Template

```markdown
**Bug Description:**
Clear description of the issue

**Steps to Reproduce:**
1. Go to...
2. Click on...
3. Enter...
4. Observe...

**Expected Behavior:**
What should happen

**Actual Behavior:**
What actually happens

**Environment:**
- Browser: Chrome 120
- OS: macOS 14
- User Role: Moderator
- Device: Desktop

**Console Errors:**
```
[Paste console errors]
```

**Screenshots:**
[Attach screenshots if relevant]

**Database State:**
[Relevant database records if applicable]
```

---

**See Also:**
- [PHASE_5_TESTING.md](./PHASE_5_TESTING.md) - Original testing plan
- [TEST_DATA_GENERATOR.md](./TEST_DATA_GENERATOR.md) - Test data generation
- [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) - Common issues and solutions
