mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:11:13 -05:00
502 lines
11 KiB
Markdown
502 lines
11 KiB
Markdown
# 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
|