# 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!**
