feat: complete CMS v2 with Docker, Fischerei, Meetings, Verband modules + UX audit fixes
Major changes: - Docker Compose: full Supabase stack (11 services) equivalent to supabase CLI - Fischerei module: 16 DB tables, waters/species/stocking/catch books/competitions - Sitzungsprotokolle module: meeting protocols, agenda items, task tracking - Verbandsverwaltung module: federation management, member clubs, contacts, fees - Per-account module activation via Modules page toggle - Site Builder: live CMS data in Puck blocks (courses, events, membership registration) - Public registration APIs: course signup, event registration, membership application - Document generation: PDF member cards, Excel reports, HTML labels - Landing page: real Com.BISS content (no filler text) - UX audit fixes: AccountNotFound component, shared status badges, confirm dialog, pagination, duplicate heading removal, emoji→badge replacement, a11y fixes - QA: healthcheck fix, API auth fix, enum mismatch fix, password required attribute
This commit is contained in:
501
QA_TEST_PLAN.md
Normal file
501
QA_TEST_PLAN.md
Normal file
@@ -0,0 +1,501 @@
|
||||
# MyEasyCMS v2 — Comprehensive QA Test Plan
|
||||
|
||||
## Test Environment
|
||||
- App: localhost:3000 (Docker)
|
||||
- Supabase: localhost:8000 (Kong gateway)
|
||||
- Studio: localhost:54323
|
||||
- DB: supabase/postgres:15.8.1.060
|
||||
|
||||
## Test Accounts
|
||||
| Email | Password | Role | Team |
|
||||
|-------|----------|------|------|
|
||||
| super-admin@makerkit.dev | testingpassword | Super Admin | - |
|
||||
| test@makerkit.dev | testingpassword | Owner | Makerkit |
|
||||
| owner@makerkit.dev | testingpassword | Owner | Makerkit |
|
||||
| member@makerkit.dev | testingpassword | Member | Makerkit |
|
||||
| custom@makerkit.dev | testingpassword | Custom | Makerkit |
|
||||
|
||||
## Test Categories
|
||||
|
||||
### A. Authentication & Authorization (12 tests)
|
||||
### B. Public Pages (8 tests)
|
||||
### C. Team Dashboard & Navigation (10 tests)
|
||||
### D. Member Management CRUD (15 tests)
|
||||
### E. Course Management CRUD (10 tests)
|
||||
### F. Event Management CRUD (8 tests)
|
||||
### G. Document Generation (8 tests)
|
||||
### H. Newsletter System (6 tests)
|
||||
### I. Site Builder & Public Club Pages (12 tests)
|
||||
### J. Finance / SEPA (6 tests)
|
||||
### K. Fischerei Module (12 tests)
|
||||
### L. Sitzungsprotokolle Module (8 tests)
|
||||
### M. Verbandsverwaltung Module (8 tests)
|
||||
### N. Module Activation System (6 tests)
|
||||
### O. Admin Panel (8 tests)
|
||||
### P. Public Registration APIs (9 tests)
|
||||
### Q. Edge Cases & Error Handling (10 tests)
|
||||
### R. Permission Boundaries (8 tests)
|
||||
|
||||
Total: ~156 test cases
|
||||
|
||||
---
|
||||
|
||||
## A. AUTHENTICATION & AUTHORIZATION
|
||||
|
||||
### A1. Login — Valid credentials
|
||||
- Setup: Logged out
|
||||
- Steps: Navigate /auth/sign-in, enter test@makerkit.dev / testingpassword, submit
|
||||
- Expected: Redirect to /home, user avatar visible
|
||||
- Pass: URL contains /home, no error toast
|
||||
|
||||
### A2. Login — Invalid password
|
||||
- Setup: Logged out
|
||||
- Steps: Enter test@makerkit.dev / wrongpassword, submit
|
||||
- Expected: Error message, stays on sign-in page
|
||||
- Pass: Error alert visible, URL still /auth/sign-in
|
||||
|
||||
### A3. Login — Empty fields
|
||||
- Steps: Click submit without entering anything
|
||||
- Expected: Client-side validation prevents submit
|
||||
- Pass: Form doesn't submit, validation indicators shown
|
||||
|
||||
### A4. Login — SQL injection attempt
|
||||
- Steps: Enter ' OR 1=1-- as email
|
||||
- Expected: Validation error (not valid email format)
|
||||
- Pass: No crash, proper error message
|
||||
|
||||
### A5. Registration — Valid
|
||||
- Steps: Navigate /auth/sign-up, enter unique email, password >= 6 chars, matching repeat
|
||||
- Expected: Account created, redirect to /home
|
||||
- Pass: User exists in DB, logged in
|
||||
|
||||
### A6. Registration — Duplicate email
|
||||
- Steps: Try registering with test@makerkit.dev
|
||||
- Expected: "Diese Anmeldedaten werden bereits verwendet"
|
||||
- Pass: Error shown, no crash
|
||||
|
||||
### A7. Registration — Weak password
|
||||
- Steps: Enter password "123"
|
||||
- Expected: Validation error (too short)
|
||||
- Pass: Form doesn't submit
|
||||
|
||||
### A8. Registration — Mismatched passwords
|
||||
- Steps: Enter different passwords in password and repeat fields
|
||||
- Expected: Validation error
|
||||
- Pass: Form shows mismatch error
|
||||
|
||||
### A9. Session persistence
|
||||
- Steps: Login, close tab, open new tab to /home
|
||||
- Expected: Still logged in
|
||||
- Pass: Dashboard loads, not redirected to sign-in
|
||||
|
||||
### A10. Logout
|
||||
- Steps: Click account dropdown > "Abmelden"
|
||||
- Expected: Session cleared, redirect to sign-in
|
||||
- Pass: Accessing /home redirects to /auth/sign-in
|
||||
|
||||
### A11. Protected route — unauthenticated access
|
||||
- Steps: Clear cookies, navigate to /home/makerkit
|
||||
- Expected: Redirect to /auth/sign-in
|
||||
- Pass: URL changes to sign-in
|
||||
|
||||
### A12. Admin route — non-admin access
|
||||
- Steps: Login as member@makerkit.dev, navigate to /admin
|
||||
- Expected: 404 (AdminGuard returns notFound)
|
||||
- Pass: 404 page shown
|
||||
|
||||
---
|
||||
|
||||
## B. PUBLIC PAGES
|
||||
|
||||
### B1. Landing page loads with real content
|
||||
- Expected: "Vereinsverwaltung, die mitwächst", "69.000", "SEPA"
|
||||
- Pass: No placeholder/filler text
|
||||
|
||||
### B2. Pricing page
|
||||
- Navigate /pricing
|
||||
- Expected: Pricing table renders
|
||||
|
||||
### B3. FAQ page
|
||||
- Navigate /faq
|
||||
- Expected: FAQ items render
|
||||
|
||||
### B4. Contact page
|
||||
- Navigate /contact
|
||||
- Expected: Contact form with name/email/message fields
|
||||
|
||||
### B5. Blog page
|
||||
- Navigate /blog
|
||||
- Expected: Blog listing (may be empty)
|
||||
|
||||
### B6. Legal pages (privacy, terms, cookies)
|
||||
- Navigate /privacy-policy, /terms-of-service, /cookie-policy
|
||||
- Expected: Each loads without error
|
||||
|
||||
### B7. Public club page
|
||||
- Navigate /club/makerkit
|
||||
- Expected: Club homepage with Puck content
|
||||
- Pass: Real data (courses, events) shown, not placeholders
|
||||
|
||||
### B8. Non-existent club page
|
||||
- Navigate /club/nonexistent
|
||||
- Expected: 404 page
|
||||
- Pass: Proper 404, no crash
|
||||
|
||||
---
|
||||
|
||||
## C. TEAM DASHBOARD & NAVIGATION
|
||||
|
||||
### C1. Team dashboard loads with stats
|
||||
- Login as test@makerkit.dev, navigate /home/makerkit
|
||||
- Expected: 4 stat cards, quick actions, activity feed
|
||||
- Pass: Numbers render (even if 0)
|
||||
|
||||
### C2. All sidebar links work
|
||||
- Click each sidebar item: Dashboard, Module, Mitglieder, Kurse, Veranstaltungen, Finanzen, Dokumente, Newsletter, Website
|
||||
- Expected: Each page loads without error
|
||||
|
||||
### C3. Account switcher
|
||||
- Click account dropdown > "Arbeitsbereich wechseln"
|
||||
- Expected: Shows list of accounts
|
||||
|
||||
### C4. Team settings — rename
|
||||
- Navigate /home/makerkit/settings
|
||||
- Expected: Team name editable, save works
|
||||
|
||||
### C5. Team members list
|
||||
- Navigate /home/makerkit/members
|
||||
- Expected: Shows 4 members with roles
|
||||
|
||||
### C6. Non-existent team slug
|
||||
- Navigate /home/nonexistent
|
||||
- Expected: Redirect or error page
|
||||
|
||||
### C7. Profile settings
|
||||
- Navigate /home/settings (personal)
|
||||
- Expected: Name, language, email change form
|
||||
|
||||
### C8. Theme toggle
|
||||
- Click theme toggle in nav
|
||||
- Expected: Dark/light theme switches
|
||||
|
||||
### C9. Breadcrumb navigation
|
||||
- Navigate to nested page, click breadcrumb links
|
||||
- Expected: Navigate back correctly
|
||||
|
||||
### C10. Mobile responsive (viewport 375px)
|
||||
- Resize to mobile
|
||||
- Expected: Sidebar collapses, hamburger menu works
|
||||
|
||||
---
|
||||
|
||||
## D. MEMBER MANAGEMENT CRUD
|
||||
|
||||
### D1. List members — empty state
|
||||
- Navigate /home/makerkit/members-cms
|
||||
- Expected: Shows "1 Mitglieder insgesamt" (Max Mustermann from earlier test)
|
||||
|
||||
### D2. Create member — all fields
|
||||
- Navigate /home/makerkit/members-cms/new
|
||||
- Fill: Vorname=Anna, Nachname=Schmidt, Email=anna@test.de, PLZ=93047, Ort=Regensburg
|
||||
- Expected: Member created, redirect to list
|
||||
|
||||
### D3. Create member — required fields only
|
||||
- Fill: Vorname=Test, Nachname=Minimal
|
||||
- Expected: Created successfully
|
||||
|
||||
### D4. Create member — empty required fields
|
||||
- Submit with empty Vorname
|
||||
- Expected: Validation error
|
||||
|
||||
### D5. Create member — invalid email format
|
||||
- Enter email "notanemail"
|
||||
- Expected: Validation error
|
||||
|
||||
### D6. Create member — duplicate email
|
||||
- Create member with same email as existing
|
||||
- Expected: DB constraint error or validation
|
||||
|
||||
### D7. View member detail
|
||||
- Click on member name in list
|
||||
- Expected: Detail page with all fields
|
||||
|
||||
### D8. Edit member
|
||||
- Navigate to member edit page
|
||||
- Change Vorname, save
|
||||
- Expected: Updated in DB and UI
|
||||
|
||||
### D9. Search members
|
||||
- Type in search box
|
||||
- Expected: List filters in real-time or on submit
|
||||
|
||||
### D10. Filter by status
|
||||
- Use status dropdown
|
||||
- Expected: Only matching members shown
|
||||
|
||||
### D11. Member with SEPA mandate
|
||||
- Create member with IBAN field filled
|
||||
- Expected: IBAN saved correctly
|
||||
|
||||
### D12. Member import
|
||||
- Navigate /home/makerkit/members-cms/import
|
||||
- Expected: Import wizard loads
|
||||
|
||||
### D13. Member statistics
|
||||
- Navigate /home/makerkit/members-cms/statistics
|
||||
- Expected: Statistics page loads
|
||||
|
||||
### D14. Member departments
|
||||
- Navigate /home/makerkit/members-cms/departments
|
||||
- Expected: Department management page
|
||||
|
||||
### D15. Pagination
|
||||
- With many members, verify pagination controls work
|
||||
|
||||
---
|
||||
|
||||
## E. COURSE MANAGEMENT
|
||||
|
||||
### E1. Course list — shows existing course
|
||||
- Navigate /home/makerkit/courses
|
||||
- Expected: "Schwimmkurs Anfänger" visible
|
||||
|
||||
### E2. Create course — valid
|
||||
- Navigate /home/makerkit/courses/new
|
||||
- Fill required fields, submit
|
||||
- Expected: Created, redirect to courses list
|
||||
|
||||
### E3. Course detail
|
||||
- Click on course name
|
||||
- Expected: Detail page with participants, schedule
|
||||
|
||||
### E4. Course calendar
|
||||
- Navigate /home/makerkit/courses/calendar
|
||||
- Expected: Calendar view loads
|
||||
|
||||
### E5. Course categories
|
||||
- Navigate /home/makerkit/courses/categories
|
||||
- Expected: Category management page
|
||||
|
||||
### E6. Course instructors
|
||||
- Navigate /home/makerkit/courses/instructors
|
||||
- Expected: Instructor list
|
||||
|
||||
### E7. Course locations
|
||||
- Navigate /home/makerkit/courses/locations
|
||||
- Expected: Location management
|
||||
|
||||
### E8. Course statistics
|
||||
- Navigate /home/makerkit/courses/statistics
|
||||
- Expected: Statistics page loads
|
||||
|
||||
### E9. Course participants
|
||||
- Navigate to course > participants tab
|
||||
- Expected: Participant list (may be empty)
|
||||
|
||||
### E10. Course attendance
|
||||
- Navigate to course > attendance tab
|
||||
- Expected: Attendance tracking page
|
||||
|
||||
---
|
||||
|
||||
## G. DOCUMENT GENERATION
|
||||
|
||||
### G1. Document type selection page
|
||||
- Navigate /home/makerkit/documents
|
||||
- Expected: 6 document types shown
|
||||
|
||||
### G2. Generate member cards (PDF)
|
||||
- Select Mitgliedsausweis, fill title, click Generieren
|
||||
- Expected: PDF downloads with .pdf extension
|
||||
- Pass: File downloads, success banner shown
|
||||
|
||||
### G3. Generate labels (HTML)
|
||||
- Select Etiketten, fill title, click Generieren
|
||||
- Expected: HTML file downloads with .html extension
|
||||
|
||||
### G4. Generate report (Excel)
|
||||
- Select Bericht, fill title, click Generieren
|
||||
- Expected: XLSX downloads with .xlsx extension
|
||||
|
||||
### G5. Coming soon types (invoice, letter, certificate)
|
||||
- Select Rechnung
|
||||
- Expected: "Demnächst verfügbar" banner, button disabled
|
||||
|
||||
### G6. Generate with empty title
|
||||
- Leave title blank, try to submit
|
||||
- Expected: Validation prevents submit (required field)
|
||||
|
||||
### G7. Generate with no members
|
||||
- Create new account with no members, try generating
|
||||
- Expected: Error "Keine aktiven Mitglieder"
|
||||
|
||||
### G8. Document templates page
|
||||
- Navigate /home/makerkit/documents/templates
|
||||
- Expected: Page loads, shows empty state
|
||||
|
||||
---
|
||||
|
||||
## I. SITE BUILDER & PUBLIC CLUB PAGES
|
||||
|
||||
### I1. Site builder list
|
||||
- Navigate /home/makerkit/site-builder
|
||||
- Expected: Shows pages list (hello, Über uns)
|
||||
|
||||
### I2. Create new page
|
||||
- Navigate /home/makerkit/site-builder/new
|
||||
- Fill title + slug, submit
|
||||
- Expected: Page created, Puck editor opens
|
||||
|
||||
### I3. Site builder settings
|
||||
- Navigate /home/makerkit/site-builder/settings
|
||||
- Expected: Design settings (name, colors, font, publish toggle)
|
||||
|
||||
### I4. Public page — published
|
||||
- Navigate /club/makerkit/hello
|
||||
- Expected: Puck content renders
|
||||
|
||||
### I5. Public page — unpublished
|
||||
- Navigate /club/makerkit/ueber-uns
|
||||
- Expected: 404 (not published)
|
||||
|
||||
### I6. Public page — non-existent
|
||||
- Navigate /club/makerkit/nonexistent
|
||||
- Expected: 404
|
||||
|
||||
### I7. Course data on public page
|
||||
- /club/makerkit should show "Schwimmkurs Anfänger"
|
||||
- Expected: Real course data, not placeholders
|
||||
|
||||
### I8. Course registration form
|
||||
- Click "Anmelden" on a course on the public page
|
||||
- Fill form, submit
|
||||
- Expected: "Anmeldung erfolgreich!" message
|
||||
|
||||
### I9. Event registration (no events)
|
||||
- EventList block should show "Keine anstehenden Veranstaltungen"
|
||||
|
||||
### I10. Membership application form
|
||||
- Fill "Mitglied werden" form on public page
|
||||
- Submit with valid data
|
||||
- Expected: Application saved in DB
|
||||
|
||||
### I11. Membership application — invalid email
|
||||
- Submit with invalid email
|
||||
- Expected: Client-side validation error
|
||||
|
||||
### I12. Newsletter signup
|
||||
- Use newsletter signup block
|
||||
- Expected: Subscription created or error
|
||||
|
||||
---
|
||||
|
||||
## N. MODULE ACTIVATION SYSTEM
|
||||
|
||||
### N1. Module toggles page shows all modules
|
||||
- Navigate /home/makerkit/modules
|
||||
- Expected: Fischerei, Sitzungsprotokolle, Verbandsverwaltung toggles visible
|
||||
|
||||
### N2. Activate Fischerei
|
||||
- Toggle Fischerei ON
|
||||
- Expected: "Fischerei" appears in sidebar
|
||||
|
||||
### N3. Deactivate Fischerei
|
||||
- Toggle Fischerei OFF
|
||||
- Expected: "Fischerei" disappears from sidebar
|
||||
|
||||
### N4. Activate Sitzungsprotokolle
|
||||
- Toggle ON
|
||||
- Expected: "Sitzungsprotokolle" appears in sidebar
|
||||
|
||||
### N5. Activate Verbandsverwaltung
|
||||
- Toggle ON
|
||||
- Expected: "Verbandsverwaltung" appears in sidebar
|
||||
|
||||
### N6. Direct URL access to deactivated module
|
||||
- Deactivate Fischerei, navigate /home/makerkit/fischerei
|
||||
- Expected: Page still loads (data exists) but not in sidebar
|
||||
|
||||
---
|
||||
|
||||
## P. PUBLIC REGISTRATION APIS
|
||||
|
||||
### P1. Course registration — valid
|
||||
- POST /api/club/course-register with valid courseId, name, email
|
||||
- Expected: 200 { success: true }
|
||||
|
||||
### P2. Course registration — missing fields
|
||||
- POST without email
|
||||
- Expected: 400 error
|
||||
|
||||
### P3. Course registration — invalid courseId
|
||||
- POST with random UUID
|
||||
- Expected: DB error or 500
|
||||
|
||||
### P4. Event registration — valid
|
||||
- POST /api/club/event-register with valid data
|
||||
- Expected: 200 success (need an event first)
|
||||
|
||||
### P5. Membership application — valid
|
||||
- POST /api/club/membership-apply with all fields
|
||||
- Expected: Row inserted in membership_applications
|
||||
|
||||
### P6. Membership application — invalid email
|
||||
- POST with email "notanemail"
|
||||
- Expected: 400 validation error
|
||||
|
||||
### P7. Membership application — missing accountId
|
||||
- POST without accountId
|
||||
- Expected: Error
|
||||
|
||||
### P8. Rate limiting (if any)
|
||||
- Send 100 rapid POSTs
|
||||
- Expected: No crash (may or may not rate limit)
|
||||
|
||||
### P9. XSS in form fields
|
||||
- Submit <script>alert(1)</script> as firstName
|
||||
- Expected: Stored as text, not executed on render
|
||||
|
||||
---
|
||||
|
||||
## Q. EDGE CASES & ERROR HANDLING
|
||||
|
||||
### Q1. API healthcheck
|
||||
- GET /api/healthcheck
|
||||
- Expected: { services: { database: true } }
|
||||
|
||||
### Q2. 404 for unknown route
|
||||
- Navigate /nonexistent
|
||||
- Expected: 404 page with "Seite nicht gefunden"
|
||||
|
||||
### Q3. Direct DB access via PostgREST (anon)
|
||||
- GET localhost:8000/rest/v1/members (anon key, no auth)
|
||||
- Expected: Empty array (RLS blocks anon)
|
||||
|
||||
### Q4. JWT expiration handling
|
||||
- Login, wait for token expiry (3600s), try action
|
||||
- Expected: Auto-refresh or redirect to login
|
||||
|
||||
### Q5. Concurrent writes
|
||||
- Two users edit same member simultaneously
|
||||
- Expected: Last write wins, no crash
|
||||
|
||||
### Q6. Very long text input
|
||||
- Enter 10000 char string in a text field
|
||||
- Expected: Validation limits or graceful handling
|
||||
|
||||
### Q7. Unicode/emoji in names
|
||||
- Create member with name "Müller-Lüdenscheidt 🎣"
|
||||
- Expected: Saved and displayed correctly
|
||||
|
||||
### Q8. Browser back button
|
||||
- Navigate deep, press back
|
||||
- Expected: Previous page loads correctly
|
||||
|
||||
### Q9. Double form submission
|
||||
- Click submit twice rapidly
|
||||
- Expected: Only one record created (isPending disables button)
|
||||
|
||||
### Q10. Network disconnect during submit
|
||||
- Submit form, disconnect network mid-request
|
||||
- Expected: Error message, no partial data corruption
|
||||
Reference in New Issue
Block a user