Merge branch 'workstream-i'
This commit is contained in:
@@ -2302,10 +2302,10 @@ _Depends on: D1-D9, E1-E4, C3_
|
||||
_Depends on: F1-F7, C3_
|
||||
_Can run parallel to H after F1 is done_
|
||||
|
||||
- [ ] **I1**: Create `/account` page (profile settings, avatar upload)
|
||||
- [ ] **I2**: Create `/account/auth` page (password, passkeys management)
|
||||
- [ ] **I3**: Create `/account/devices` page (trusted devices)
|
||||
- [ ] **I4**: Create `/account/sessions` page (session history)
|
||||
- [x] **I1**: Create `/account` page (profile settings, avatar upload)
|
||||
- [x] **I2**: Create `/account/auth` page (password, passkeys management)
|
||||
- [x] **I3**: Create `/account/devices` page (trusted devices)
|
||||
- [x] **I4**: Create `/account/sessions` page (session history)
|
||||
|
||||
---
|
||||
|
||||
|
||||
287
docs/test-plans/account.md
Normal file
287
docs/test-plans/account.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# Test Plan: Account Pages (Workstream I)
|
||||
|
||||
## Overview
|
||||
Manual test plan for the account management pages: Profile, Authentication, Devices, and Sessions.
|
||||
|
||||
## Prerequisites
|
||||
- Dev server running: `bun run --cwd apps/publisher-dashboard dev`
|
||||
- Logged-in user account
|
||||
- Access to multiple devices/browsers for session testing
|
||||
|
||||
---
|
||||
|
||||
## 1. Account Navigation
|
||||
|
||||
### 1.1 Navigation Tabs
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Navigate to `/account` | Profile tab is highlighted |
|
||||
| 2 | Click "Authentication" tab | Navigate to `/account/auth`, tab highlighted |
|
||||
| 3 | Click "Devices" tab | Navigate to `/account/devices`, tab highlighted |
|
||||
| 4 | Click "Sessions" tab | Navigate to `/account/sessions`, tab highlighted |
|
||||
| 5 | Resize to mobile width | Tab labels hidden, only icons visible |
|
||||
|
||||
---
|
||||
|
||||
## 2. Profile Page (`/account`)
|
||||
|
||||
### 2.1 Profile Loading
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Navigate to `/account` | Loading spinner shown briefly |
|
||||
| 2 | Wait for data | Form populated with current user data |
|
||||
| 3 | Refresh page | Data persists correctly |
|
||||
|
||||
### 2.2 Avatar URL
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Enter valid image URL | Avatar preview updates |
|
||||
| 2 | Enter invalid URL (e.g., "not-a-url") | Error: "Please enter a valid URL" on blur |
|
||||
| 3 | Enter URL without http/https | Error shown |
|
||||
| 4 | Clear URL | Avatar shows initials fallback |
|
||||
| 5 | Enter URL to non-image | Preview attempts to load, falls back gracefully |
|
||||
|
||||
### 2.3 Display Name (Required)
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Clear display name | Save button disabled |
|
||||
| 2 | Enter valid name (1-100 chars) | Save button enabled |
|
||||
| 3 | Enter name > 100 chars | Input enforces maxlength |
|
||||
|
||||
### 2.4 Full Name (Optional)
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Leave empty | Form valid |
|
||||
| 2 | Enter value | Form valid |
|
||||
| 3 | Save with value | Value persists after refresh |
|
||||
|
||||
### 2.5 Phone Number
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Enter valid phone: "+1 555 123 4567" | Auto-formats to E.164 on blur |
|
||||
| 2 | Enter invalid phone: "abc123" | Error: "Please enter a valid phone number" |
|
||||
| 3 | Leave empty | Form valid (optional field) |
|
||||
| 4 | Enter international number | Formats correctly |
|
||||
|
||||
### 2.6 Save Profile
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Make no changes | Save button disabled |
|
||||
| 2 | Change any field | Save button enabled |
|
||||
| 3 | Click Save | Loading state, success toast |
|
||||
| 4 | Refresh page | Changes persisted |
|
||||
| 5 | Save with validation error | Button disabled, cannot submit |
|
||||
|
||||
### 2.7 Delete Account
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Click "Delete account" button | Confirmation dialog opens |
|
||||
| 2 | Dialog shows warning icon | Red/destructive styling |
|
||||
| 3 | Enter wrong password | Error message shown |
|
||||
| 4 | Enter correct password | Account deleted, redirected to login |
|
||||
| 5 | Click Cancel | Dialog closes, no action |
|
||||
|
||||
---
|
||||
|
||||
## 3. Authentication Page (`/account/auth`)
|
||||
|
||||
### 3.1 Email Display
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | View email section | Email displayed (read-only) |
|
||||
| 2 | Verified user | "Verified" badge shown |
|
||||
| 3 | Unverified user | No badge (or "Unverified" indicator) |
|
||||
|
||||
### 3.2 Password - No Existing Password
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | User without password | Shows "No password set" |
|
||||
| 2 | Click "Set password" | Dialog opens |
|
||||
| 3 | No "Current password" field | Only new password fields shown |
|
||||
| 4 | Enter weak password (<8 chars) | Submit disabled |
|
||||
| 5 | Enter mismatched passwords | Submit disabled |
|
||||
| 6 | Enter valid matching passwords | Submit enabled |
|
||||
| 7 | Submit | Success toast, status updates to "Password is set" |
|
||||
|
||||
### 3.3 Password - Existing Password
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | User with password | Shows "Password is set" |
|
||||
| 2 | Click "Change password" | Dialog opens with current password field |
|
||||
| 3 | Leave current password empty | Submit disabled |
|
||||
| 4 | Enter wrong current password | Error message on submit |
|
||||
| 5 | Enter correct current + valid new | Success toast |
|
||||
|
||||
### 3.4 Passkeys List
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | No passkeys | Empty state message |
|
||||
| 2 | Has passkeys | List with name, created date, last used |
|
||||
| 3 | Each passkey | Rename and Delete buttons visible |
|
||||
|
||||
### 3.5 Add Passkey
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Click "+ Add passkey" | Dialog opens |
|
||||
| 2 | Browser doesn't support WebAuthn | Message shown, form disabled |
|
||||
| 3 | Enter passkey name | Create button enabled |
|
||||
| 4 | Click Create | Browser WebAuthn prompt appears |
|
||||
| 5 | Complete WebAuthn ceremony | Success toast, passkey appears in list |
|
||||
| 6 | Cancel WebAuthn prompt | Error: "Passkey creation was cancelled" |
|
||||
| 7 | Verify passkey name | Name matches what user entered |
|
||||
|
||||
### 3.6 Rename Passkey
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Click rename icon | Dialog opens with current name |
|
||||
| 2 | Enter same name | Save disabled |
|
||||
| 3 | Enter new name | Save enabled |
|
||||
| 4 | Save | Success toast, list updates |
|
||||
|
||||
### 3.7 Delete Passkey
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Click delete icon | Confirmation dialog |
|
||||
| 2 | Confirm deletion | Success toast, passkey removed |
|
||||
| 3 | Only 1 passkey, no password | Delete button disabled with tooltip |
|
||||
| 4 | Has password or 2+ passkeys | Delete enabled |
|
||||
|
||||
---
|
||||
|
||||
## 4. Devices Page (`/account/devices`)
|
||||
|
||||
### 4.1 Trusted Devices List
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Navigate to page | List of trusted devices shown |
|
||||
| 2 | Current device | Marked with "Current" badge |
|
||||
| 3 | Each device shows | Name, location, last used date |
|
||||
| 4 | No trusted devices | Empty state message |
|
||||
|
||||
### 4.2 Remove Trust
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Click "Remove trust" on any device | Confirmation dialog |
|
||||
| 2 | Confirm | Success toast, device removed from list |
|
||||
| 3 | Cancel | Dialog closes, no change |
|
||||
|
||||
### 4.3 Remove All Trusted Devices
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Only 1 device | "Remove all" button not shown |
|
||||
| 2 | 2+ devices | "Remove all trusted devices" button shown |
|
||||
| 3 | Click remove all | Confirmation dialog |
|
||||
| 4 | Confirm | All devices removed, empty state shown |
|
||||
|
||||
---
|
||||
|
||||
## 5. Sessions Page (`/account/sessions`)
|
||||
|
||||
### 5.1 Active Sessions
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Navigate to page | Active sessions listed |
|
||||
| 2 | Current session | Marked with "Current" badge |
|
||||
| 3 | Each session shows | Browser/OS, location, auth method, start date |
|
||||
| 4 | Passkey session | Shows "via passkey" with key icon |
|
||||
| 5 | Password session | Shows "via password" |
|
||||
|
||||
### 5.2 Revoke Session
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Current session | No revoke button |
|
||||
| 2 | Other session | Revoke button visible |
|
||||
| 3 | Click Revoke | Confirmation dialog |
|
||||
| 4 | Confirm | Session moved to past sessions |
|
||||
|
||||
### 5.3 Revoke All Sessions
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | Only current session | "Revoke all" button not shown |
|
||||
| 2 | Multiple sessions | "Revoke all other sessions" shown |
|
||||
| 3 | Confirm revoke all | All other sessions revoked |
|
||||
|
||||
### 5.4 Past Sessions
|
||||
| Step | Action | Expected Result |
|
||||
|------|--------|-----------------|
|
||||
| 1 | No past sessions | Section not shown |
|
||||
| 2 | Has past sessions | Section shows with grayed styling |
|
||||
| 3 | Past session shows | Browser/OS, location, date range, "Logged out" |
|
||||
| 4 | More than 10 | Shows "Showing 10 of X" message |
|
||||
|
||||
---
|
||||
|
||||
## 6. Cross-Cutting Concerns
|
||||
|
||||
### 6.1 Loading States
|
||||
| Page | Expected |
|
||||
|------|----------|
|
||||
| All pages | Spinner while loading data |
|
||||
| Form submissions | Button shows loading state |
|
||||
| Dialogs | Buttons disabled during submission |
|
||||
|
||||
### 6.2 Error Handling
|
||||
| Scenario | Expected |
|
||||
|----------|----------|
|
||||
| Network error | Error alert shown |
|
||||
| API error | Error message from server displayed |
|
||||
| Validation error | Inline error message |
|
||||
|
||||
### 6.3 Accessibility
|
||||
| Test | Expected |
|
||||
|------|----------|
|
||||
| Keyboard navigation | All interactive elements focusable |
|
||||
| Screen reader | ARIA labels present on icons/buttons |
|
||||
| Dialog close button | Has aria-label="Close dialog" |
|
||||
| Navigation tabs | Has aria-current="page" on active |
|
||||
|
||||
### 6.4 Mobile Responsiveness
|
||||
| Breakpoint | Expected |
|
||||
|------------|----------|
|
||||
| Desktop (>640px) | Full navigation labels |
|
||||
| Mobile (<640px) | Icon-only navigation |
|
||||
| All sizes | Forms remain usable |
|
||||
|
||||
---
|
||||
|
||||
## 7. Integration Tests
|
||||
|
||||
### 7.1 Full Passkey Flow
|
||||
1. Navigate to `/account/auth`
|
||||
2. Add new passkey with custom name
|
||||
3. Verify passkey appears in list with correct name
|
||||
4. Rename passkey
|
||||
5. Delete passkey (if not last auth method)
|
||||
|
||||
### 7.2 Password Change Flow
|
||||
1. Set initial password (if none)
|
||||
2. Change password with correct current password
|
||||
3. Verify can log in with new password
|
||||
|
||||
### 7.3 Multi-Device Session Test
|
||||
1. Log in on Device A
|
||||
2. Log in on Device B
|
||||
3. On Device A, view sessions - see both
|
||||
4. Revoke Device B session
|
||||
5. Verify Device B is logged out
|
||||
|
||||
---
|
||||
|
||||
## 8. Edge Cases
|
||||
|
||||
| Scenario | Expected Behavior |
|
||||
|----------|-------------------|
|
||||
| Last auth method | Cannot delete (button disabled) |
|
||||
| Very long passkey name | Truncated in UI, full in tooltip |
|
||||
| Many sessions (>10 past) | Pagination/truncation message |
|
||||
| Slow network | Loading states visible |
|
||||
| Session expired mid-action | Redirected to login |
|
||||
| Concurrent passkey creation | Correct passkey gets renamed (race condition fixed) |
|
||||
|
||||
---
|
||||
|
||||
## Sign-Off
|
||||
|
||||
| Tester | Date | Status |
|
||||
|--------|------|--------|
|
||||
| | | |
|
||||
Reference in New Issue
Block a user