# Logout Tracking System - Testing Checklist **Purpose:** Verify the logout tracking system works correctly for all scenarios --- ## Pre-Testing Setup - [ ] Backend container restarted - [ ] Frontend container restarted - [ ] Browser DevTools console open - [ ] Backend logs accessible (`docker logs -f igny8_backend`) --- ## Test 1: Manual Logout **Steps:** 1. Login to the app 2. Navigate to any page (e.g., `/dashboard`) 3. Click the logout button **Expected Results:** - [ ] Console shows: `đŸšĒ LOGOUT - User Action:` - [ ] Redirected to `/signin` - [ ] Yellow alert box appears on signin page - [ ] Alert shows: "User manually logged out" - [ ] Original page shown in alert: `/dashboard` - [ ] Click â„šī¸ icon shows technical details - [ ] Technical details show: - Code: `MANUAL_LOGOUT` - Source: `manual_user_action` - Path: `/dashboard` (or whatever page you were on) - User email in context - Timestamp - [ ] After refresh, alert is gone (single display) --- ## Test 2: Token Expiration (401) **Steps:** 1. Login to the app 2. Get the access token from localStorage 3. In browser console, manually expire it: ```javascript localStorage.setItem('access_token', 'invalid_token') ``` 4. Navigate to a protected page or make an API call **Expected Results:** - [ ] Console shows: `🚨 LOGOUT TRIGGERED - Token Refresh Failed` or `🚨 LOGOUT TRIGGERED - No Refresh Token` - [ ] Redirected to `/signin` - [ ] Yellow alert box appears - [ ] Alert shows token-related message - [ ] Original page shown in alert - [ ] Technical details show correct error code --- ## Test 3: Session Contamination (Account Mismatch) **Steps:** 1. Login with a user account 2. In Django admin or shell, create session contamination: ```python # Get a session and modify _account_id to wrong value from django.contrib.sessions.models import Session session = Session.objects.first() data = session.get_decoded() data['_account_id'] = 99999 # Non-existent account session.session_data = session.encode(data) session.save() ``` 3. Refresh the app or make an API call **Expected Results:** - [ ] Backend logs show: `[AUTO-LOGOUT] SESSION_ACCOUNT_MISMATCH` - [ ] Console shows: `🚨 LOGOUT TRIGGERED - Backend Validation Failed` - [ ] Redirected to `/signin` - [ ] Yellow alert shows: "Session contamination: account ID mismatch" - [ ] Technical details show: - Code: `SESSION_ACCOUNT_MISMATCH` - Source: `backend_middleware` - Context: stored vs current account IDs - [ ] Backend logs include IP, path, user ID, timestamp --- ## Test 4: Missing Account **Steps:** 1. In Django admin, remove account from a user: ```python user = User.objects.get(email='test@example.com') user.account = None user.save() ``` 2. Try to login with that user **Expected Results:** - [ ] Backend logs show: `[AUTO-LOGOUT] ACCOUNT_MISSING` - [ ] Console shows: `🚨 LOGOUT TRIGGERED` - [ ] Alert shows: "Account not configured for this user" - [ ] Technical details show: - Code: `ACCOUNT_MISSING` - Source: `backend_middleware` or `refresh_user_validation` --- ## Test 5: Inactive Plan **Steps:** 1. In Django admin, deactivate user's plan: ```python plan = Plan.objects.get(slug='starter') plan.is_active = False plan.save() ``` 2. User makes an API call or refreshes page **Expected Results:** - [ ] Backend logs show: `[AUTO-LOGOUT] PLAN_INACTIVE` - [ ] Console shows: `🚨 LOGOUT TRIGGERED` - [ ] Alert shows: "Subscription plan is inactive" - [ ] Technical details show: - Code: `PLAN_INACTIVE` - HTTP status 402 in context --- ## Test 6: Suspended Account **Steps:** 1. In Django admin, suspend an account: ```python account = Account.objects.get(id=1) account.status = 'suspended' account.save() ``` 2. User tries to access protected page **Expected Results:** - [ ] Backend logs show: `[AUTO-LOGOUT] ACCOUNT_SUSPENDED` - [ ] Alert shows: "Account is suspended" - [ ] Technical details show: - Code: `ACCOUNT_SUSPENDED` - HTTP status 403 --- ## Test 7: 403 Auth Credentials Error **Steps:** 1. Login to the app 2. In browser console, corrupt the token: ```javascript localStorage.setItem('access_token', 'Bearer corrupted') ``` 3. Make an API call **Expected Results:** - [ ] Console shows: `🚨 LOGOUT TRIGGERED - Authentication Credentials Missing` - [ ] Alert shows authentication credentials error - [ ] Technical details show: - Code: `AUTH_CREDENTIALS_MISSING` - Source: `api_403_auth_error` --- ## Test 8: Page Path Accuracy **Steps:** 1. Login and navigate through multiple pages 2. Trigger logout from different pages: - From `/dashboard` → Check logout shows `/dashboard` - From `/planner/keywords` → Check logout shows `/planner/keywords` - From `/writer/articles` → Check logout shows `/writer/articles` **Expected Results:** - [ ] Every logout shows **exact page** where logout occurred - [ ] **Never** shows `/signin` as logout path - [ ] Path captured BEFORE redirect --- ## Test 9: Console Logging Format **Expected in Browser Console:** - [ ] 🚨 emoji for automatic logouts - [ ] đŸšĒ emoji for manual logout - [ ] Grouped logs with expandable details - [ ] Full JSON context logged - [ ] Timestamps present - [ ] Error codes visible **Expected in Backend Logs:** ```bash [AUTO-LOGOUT] ERROR_CODE: Message. User=123, Account=456, Path=/page, IP=..., Timestamp=... ``` - [ ] `[AUTO-LOGOUT]` prefix present - [ ] Error code included - [ ] All context fields present - [ ] Grep-friendly format --- ## Test 10: Alert Box UI **Visual Checks:** - [ ] Yellow background (not red) - [ ] Clear heading: "Session Ended" - [ ] User-friendly message displayed - [ ] Original page path shown (if not /signin) - [ ] Info icon (â„šī¸) present - [ ] Click info icon expands technical details - [ ] Technical details show: - Error code - Source - Timestamp (formatted) - Context JSON (formatted with indentation) - [ ] Click info icon again collapses details - [ ] Alert disappears after page refresh --- ## Test 11: Multiple Logouts **Steps:** 1. Trigger logout (any method) 2. See alert on signin page 3. Login again 4. Trigger different logout (different error) 5. Return to signin page **Expected Results:** - [ ] First logout reason cleared after first display - [ ] Second logout shows new reason (not old one) - [ ] No accumulation of old logout reasons - [ ] Each logout tracked separately --- ## Test 12: Edge Cases ### No Logout Reason **Steps:** Navigate directly to `/signin` without logout **Expected:** - [ ] No alert box shown - [ ] No console errors - [ ] No localStorage pollution ### localStorage Disabled **Steps:** Disable localStorage in browser, trigger logout **Expected:** - [ ] Console warning about failed storage - [ ] App still functions - [ ] No crash ### Malformed Logout Reason **Steps:** Manually corrupt logout_reason in localStorage ```javascript localStorage.setItem('logout_reason', 'invalid json') ``` **Expected:** - [ ] Console warning about parsing failure - [ ] No alert shown - [ ] No crash --- ## Test 13: Cross-Browser Testing Test in multiple browsers: - [ ] Chrome - [ ] Firefox - [ ] Safari - [ ] Edge **All features should work identically** --- ## Test 14: Mobile Responsiveness Test on mobile devices/emulator: - [ ] Alert box displays correctly - [ ] Technical details expand/collapse works - [ ] Text is readable - [ ] No horizontal scroll --- ## Success Criteria ✅ **All tests pass** ✅ **Every logout has visible reason** ✅ **Exact page tracking works** ✅ **Console logs are clear** ✅ **Backend logs are searchable** ✅ **User sees helpful message** ✅ **Developers can debug easily** --- ## Troubleshooting ### Alert not showing - Check browser console for logout reason object - Check if localStorage.getItem('logout_reason') returns data - Verify SignInForm component mounted ### Wrong page shown - Verify `window.location.pathname` captured BEFORE redirect - Check logout trigger happens before navigation - Ensure logout_reason stored BEFORE logout() call ### Backend logs missing - Check logger level is WARNING or INFO - Verify logger name: 'auth.middleware' - Check LOGGING config in settings.py ### Console logs missing - Check browser console filters (show all levels) - Verify emoji not filtered out - Check if code throwing before log statement --- ## Maintenance **When adding new logout causes:** 1. Add error code to `LOGOUT_REASONS` dict 2. Update logout trigger to create structured reason 3. Store in localStorage before logout 4. Log to console with 🚨 5. Update this testing checklist 6. Update LOGOUT-CAUSES-COMPLETE-REFERENCE.md **Keep documentation in sync with implementation!**