Test Plan & Coverage - bounswe/bounswe2026group11 GitHub Wiki
Test Plan & Coverage
Testing Strategy
The project uses four layers of testing aligned with the MVP delivery goals:
Unit Tests — test business logic in isolation using in-memory fakes. No database, no network. Cover the
application layer (app/auth, app/event) and HTTP adapter layer (adapter/driving/httpapi). Every service method
and handler is tested against success paths, validation failures, and edge cases. Run with go test ./....
Integration Tests — test the full stack against a real PostgreSQL instance via testcontainers-go. Verify that
SQL queries, transactions, DB triggers, and constraints work correctly end to end. Run with go test -tags=integration ./tests/integration/.
Manual / API Testing — endpoints are exercised against the live local stack (Docker Compose) using Swagger UI at
http://localhost/api/docs/. The mock OTP mailer logs codes to the server console for verification during
development.
Manual UI Testing (Mobile) — the React Native / Expo application is tested manually on a real device or emulator (Android/iOS). Core user flows — registration, login, event creation, event discovery, and participation — are exercised screen by screen to verify correct rendering, navigation, form validation feedback, and API integration.
| Feature | Unit | Backend Integration | Frontend | Mobile Manual | Status |
|---|---|---|---|---|---|
| 1. Authentication & User Accounts | |||||
| Registration via email OTP — success path | ✅ | ✅ | ✅ | ✅ | Done |
| Registration — invalid email format | ✅ | — | ✅ | ✅ | Done |
| Registration — OTP expired | ✅ | — | ✅ | ✅ | Done |
| Registration — OTP wrong code (attempt tracking) | ✅ | — | ✅ | ✅ | Done |
| Registration — OTP attempt exhaustion | ✅ | — | ✅ | ✅ | Done |
| Registration — duplicate email / username | ✅ | ✅ | ✅ | ✅ | Done |
| Username / email availability check | ✅ | ✅ | ✅ | ✅ | Done |
| Login with username + password — success | ✅ | ✅ | ✅ | ✅ | Done |
| Login — wrong password | ✅ | ✅ | ✅ | ✅ | Done |
| Login — user not found | 🔲 | 🔲 | ✅ | ✅ | Done |
| Token refresh & rotation | ✅ | ✅ | ✅ | ✅ | Done |
| Refresh token reuse detection | ✅ | ✅ | — | — | Done |
| Absolute session limit (60 days) | ✅ | — | — | — | Done |
| Logout | ✅ | ✅ | ✅ | ✅ | Done |
| JWT auth middleware — valid token | ✅ | — | — | — | Done |
| JWT auth middleware — missing / expired / malformed token | ✅ | — | — | — | Done |
| Forgot password flow (request OTP, verify, reset) | ✅ | ✅ | ✅ | ✅ | Done |
| 2. User Profile & History | |||||
| View user profile | 🔲 | 🔲 | ✅ | ✅ | Done |
| Edit profile (display name, bio, photo) | 🔲 | 🔲 | ✅ | ✅ | Done |
| Avatar upload via CDN | 🔲 | 🔲 | ✅ | ✅ | Done |
| View host / participant / final scores | 🔲 | 🔲 | ✅ | 🔲 | Done |
| View created events | 🔲 | 🔲 | ✅ | ✅ | Done |
| View participation history | 🔲 | 🔲 | ✅ | ✅ | Done |
| 3. Event Creation & Lifecycle | |||||
| Create event — success path (with location, tags, constraints) | ✅ | ✅ | ✅ | ✅ | Done |
| Create event — optional end time | ✅ | ✅ | ✅ | ✅ | Done |
| Create event — empty title rejected | ✅ | ✅ | ✅ | ✅ | Done |
| Create event — too many tags rejected | ✅ | ✅ | 🔲 | ✅ | Done |
| Create event — invalid privacy level rejected | ✅ | ✅ | 🔲 | 🔲 | Done |
| Create event — end time before start time rejected | ✅ | ✅ | ✅ | ✅ | Done |
| Create event — unauthenticated request rejected (401) | ✅ | — | ✅ | ✅ | Done |
| Cancel event as host | ✅ | ✅ | ✅ | ✅ | Done |
| Event status: Active → IN_PROGRESS (after start time) | ✅ | ✅ | ✅ | ✅ | Done |
| Event status: Active → Completed (after end time / manual) | ✅ | ✅ | ✅ | ✅ | Done |
| Event status: Active → Canceled | ✅ | ✅ | ✅ | ✅ | Done |
| Auto-expiry background job (stale & max-duration events) | ✅ | 🔲 | — | — | Done |
| 4. Event Discovery | |||||
| List events with pagination | 🔲 | 🔲 | ✅ | ✅ | Done |
| Search by title, description, tags | 🔲 | 🔲 | ✅ | ✅ | Done |
| Filter by location radius (PostGIS) | 🔲 | 🔲 | ✅ | ✅ | Done |
| Filter by time range | 🔲 | 🔲 | ✅ | ✅ | Done |
| Filter by category | 🔲 | 🔲 | ✅ | ✅ | Done |
| IN_PROGRESS events excluded from discovery | 🔲 | 🔲 | ✅ | ✅ | Done |
| Private events hidden from discovery | 🔲 | 🔲 | ✅ | ✅ | Done |
| 5. Privacy & Participation Flows | |||||
| Public event — direct join | 🔲 | 🔲 | ✅ | ✅ | Done |
| Public event — participant count increment | 🔲 | 🔲 | ✅ | ✅ | Done |
| Protected event — join request creation | 🔲 | 🔲 | ✅ | ✅ | Done |
| Protected event — host approves join request | 🔲 | 🔲 | ✅ | ✅ | Done |
| Protected event — host rejects join request | 🔲 | 🔲 | ✅ | ✅ | Done |
| Leave event | 🔲 | 🔲 | ✅ | ✅ | Done |
| Rejoin after pre-start leave | ✅ | 🔲 | 🔲 | 🔲 | Done |
| Private event — host invites user by username | 🔲 | 🔲 | 🔲 | 🔲 | In Progress |
| Private event — user accepts invitation | 🔲 | 🔲 | 🔲 | 🔲 | In Progress |
| Private event — user declines invitation | 🔲 | 🔲 | 🔲 | 🔲 | In Progress |
| Participant count tracked for approved users only | 🔲 | 🔲 | ✅ | ✅ | Done |
| 6. Event Details & Engagement | |||||
| View event detail | 🔲 | 🔲 | ✅ | ✅ | Done |
| Save / favorite an event | 🔲 | 🔲 | ✅ | ✅ | Done |
| View favorite events list | 🔲 | 🔲 | ✅ | ✅ | Done |
| Save / view favorite locations | 🔲 | 🔲 | ✅ | ✅ | Done |
| Event metrics (participant count, pending count, save count) | 🔲 | 🔲 | ✅ | ✅ | Done |
| Post-event ratings (host rates participant, participant rates event) | 🔲 | 🔲 | ✅ | 🔲 | Done |
| Expiry warning banner (53–60 days) | 🔲 | — | ✅ | ✅ | Done |
| 7. Request & Invitation Tracking | |||||
| Host views pending join requests | 🔲 | 🔲 | ✅ | ✅ | Done |
| User views invitation status | 🔲 | 🔲 | 🔲 | 🔲 | In Progress |
| 8. Basic Event Consistency | |||||
| Participation count sync via DB triggers | 🔲 | 🔲 | — | — | Done |
| Favorite count sync via DB triggers | 🔲 | 🔲 | — | — | Done |
| Access control enforced consistently across privacy types | 🔲 | 🔲 | ✅ | ✅ | Done |
User Acceptance Criteria
The MVP is acceptable from a user perspective when the following scenarios work correctly end to end:
1. Authentication and User Accounts
- A new user can register with email OTP verification and receive a valid session
- A registered user can log in with username or email and password
- Invalid credentials are rejected with clear error messages
- Sessions expire correctly; refresh token rotation works without requiring re-login
- A user can check if a username or email is already taken before completing registration
- A user can reset their password via email OTP
2. Event Creation and Lifecycle
- An authenticated host can create a public, protected, or private event with mandatory fields: title, location, start time, privacy type, and capacity
- Up to 5 custom tags and optional participation constraints can be attached
- Events with invalid data are rejected with clear field-level error messages (empty title, too many tags, end time before start time, invalid privacy level)
- Event, location, tags, and constraints are always persisted atomically — partial writes never occur
- A host can cancel an event
- Events automatically transition to IN_PROGRESS and COMPLETED based on time
3. Event Discovery
- Users can discover public and protected events through list view, search, and filters
- Events can be filtered by location radius, time range, category, and tags
- Private and IN_PROGRESS events do not appear in public discovery
4. Privacy and Participation Flows
- Public events: any user can join immediately
- Protected events: users submit a join request; host approves or rejects
- Private events: host invites users by username; users accept or decline
- Participant counts are tracked correctly for approved participants only
5. Event Details and Engagement
- Users can view event details and save events to favorites
- Users can save up to 3 favorite locations
- Hosts can view pending join requests and manage approvals
- Post-event ratings can be submitted within the 7-day rating window
Acceptance Threshold
The MVP is considered shippable when:
- All unit and integration tests pass (
go test ./...andgo test -tags=integration) - The full registration → login → create event flow works on the deployed server
- All three participation flows (public, protected, private) behave consistently with the visibility rules defined in the MVP scope
- Event lifecycle transitions (Active → IN_PROGRESS → Completed, Active → Canceled) work correctly
- The core user flows (registration, login, event creation, and event discovery) work end to end on the mobile application running on a real device or emulator without crashes or broken navigation