# 1. User Login — Test Cases

User Type: **Super Administrator**
Source: *Mi Digital Academy - Education CRM Features Document*
Spec: user_login.md — every feature, sub-feature, and rule covered

---

## Test Execution Policy
- Zero tolerance: any deviation from documented behavior = FAILED = bug
- Every bug is immediately logged/reported (Bug ID, feature, sub-feature, expected vs actual, severity) and fixed 100% before the group passes
- Feature group passes only at 100% test pass rate

## Coverage Matrix
| Feature | Sub-feature / Rule | Test IDs |
|---------|--------------------|----------|
| 1.1 Email and Password Login | Login screen fields, input validation, inline errors | TC-SA-01-01-001, TC-SA-01-01-002, TC-SA-01-01-003 |
| 1.1 Email and Password Login | Show/hide password toggle, auto-fill support | TC-SA-01-01-004, TC-SA-01-01-005 |
| 1.1 Email and Password Login | Forgot password link routing | TC-SA-01-01-006 |
| 1.1 Email and Password Login | Remember me checkbox | TC-SA-01-01-007, TC-SA-01-01-008 |
| 1.1 Email and Password Login | Rate limiting per account and per IP | TC-SA-01-01-009, TC-SA-01-01-010 |
| 1.1 Email and Password Login | Progressive failure feedback (generic message) | TC-SA-01-01-011 |
| 1.1 Email and Password Login | Pre-authentication checks in order | TC-SA-01-01-012, TC-SA-01-01-013, TC-SA-01-01-014, TC-SA-01-01-015, TC-SA-01-01-016 |
| 1.1 Email and Password Login | Post-verification 2FA challenge | TC-SA-01-01-017 |
| 1.1 Email and Password Login | Session establishment on success | TC-SA-01-01-018 |
| 1.1 Email and Password Login | Role-aware landing | TC-SA-01-01-019 |
| 1.1 Email and Password Login | Login attempt logging | TC-SA-01-01-020, TC-SA-01-01-021 |
| 1.1 Email and Password Login | Mobile app parity | TC-SA-01-01-022 |
| 1.1 Email and Password Login | Rule: no account enumeration via error message | TC-SA-01-01-023 |
| 1.1 Email and Password Login | Rule: email case-insensitive, password case-sensitive | TC-SA-01-01-024, TC-SA-01-01-025 |
| 1.1 Email and Password Login | Rule: suspended vs deactivated messages differ | TC-SA-01-01-026 |
| 1.1 Email and Password Login | Rule: locked account shows lockout time + support contact | TC-SA-01-01-027 |
| 1.1 Email and Password Login | Rule: IP deny list rejects before verification, IP-block logged | TC-SA-01-01-028 |
| 1.1 Email and Password Login | Rule: mandatory 2FA without enrollment → guided enrollment | TC-SA-01-01-029 |
| 1.1 Email and Password Login | Rule: every attempt logged with full context | TC-SA-01-01-030 |
| 1.1 Email and Password Login | Rule: session subject to all session policies | TC-SA-01-01-031 |
| 1.2 OTP-Based Login Verification | Policy configuration global / per role | TC-SA-01-01-032, TC-SA-01-01-033 |
| 1.2 OTP-Based Login Verification | Delivery channel selection with fallback | TC-SA-01-01-034, TC-SA-01-01-035, TC-SA-01-01-036 |
| 1.2 OTP-Based Login Verification | OTP generation (6-digit, random, single-use) | TC-SA-01-01-037, TC-SA-01-01-038 |
| 1.2 OTP-Based Login Verification | Validity window with countdown | TC-SA-01-01-039, TC-SA-01-01-040 |
| 1.2 OTP-Based Login Verification | Entry screen auto-advance and paste | TC-SA-01-01-041, TC-SA-01-01-042 |
| 1.2 OTP-Based Login Verification | Resend cooldown and maximum resend count | TC-SA-01-01-043, TC-SA-01-01-044 |
| 1.2 OTP-Based Login Verification | Attempt limit invalidates OTP | TC-SA-01-01-045 |
| 1.2 OTP-Based Login Verification | Login completion on valid OTP | TC-SA-01-01-046 |
| 1.2 OTP-Based Login Verification | Distinct failure messages | TC-SA-01-01-047, TC-SA-01-01-048, TC-SA-01-01-049 |
| 1.2 OTP-Based Login Verification | Delivery failure fallback | TC-SA-01-01-050 |
| 1.2 OTP-Based Login Verification | Full logging of OTP events | TC-SA-01-01-051 |
| 1.2 OTP-Based Login Verification | Rule: OTP single-use | TC-SA-01-01-052 |
| 1.2 OTP-Based Login Verification | Rule: expired code → expired message + resend | TC-SA-01-01-053 |
| 1.2 OTP-Based Login Verification | Rule: wrong attempts counted per issued code | TC-SA-01-01-054 |
| 1.2 OTP-Based Login Verification | Rule: resends rate-limited | TC-SA-01-01-055 |
| 1.2 OTP-Based Login Verification | Rule: unreachable phone → email or support path | TC-SA-01-01-056 |
| 1.2 OTP-Based Login Verification | Rule: OTP never logged in full | TC-SA-01-01-057 |
| 1.2 OTP-Based Login Verification | Rule: coexistence with 2FA, policy defines challenge | TC-SA-01-01-058 |
| 1.2 OTP-Based Login Verification | Rule: UI always shows expiry countdown | TC-SA-01-01-059 |
| 1.3 Social Login | Provider enable/disable per provider and user type | TC-SA-01-01-060, TC-SA-01-01-061 |
| 1.3 Social Login | First-login account creation | TC-SA-01-01-062 |
| 1.3 Social Login | Account matching on email | TC-SA-01-01-063 |
| 1.3 Social Login | Account linking with password verification | TC-SA-01-01-064, TC-SA-01-01-065 |
| 1.3 Social Login | Unlinking, blocked if last method | TC-SA-01-01-066, TC-SA-01-01-067 |
| 1.3 Social Login | Consent capture at first login | TC-SA-01-01-068 |
| 1.3 Social Login | Session behavior identical to password login | TC-SA-01-01-069 |
| 1.3 Social Login | Provider outage handling | TC-SA-01-01-070 |
| 1.3 Social Login | Admin monitoring of social logins | TC-SA-01-01-071 |
| 1.3 Social Login | Rule: never sole method for privileged roles | TC-SA-01-01-072 |
| 1.3 Social Login | Rule: linking requires existing password verification | TC-SA-01-01-073 |
| 1.3 Social Login | Rule: unlink blocked when no other method remains | TC-SA-01-01-074 |
| 1.3 Social Login | Rule: no silent duplicates, link/merge review | TC-SA-01-01-075 |
| 1.3 Social Login | Rule: graceful degradation on outage | TC-SA-01-01-076 |
| 1.3 Social Login | Rule: logged, subject to lockout and IP policies | TC-SA-01-01-077, TC-SA-01-01-078 |
| 1.3 Social Login | Rule: provider data per privacy policy, visible in export | TC-SA-01-01-079 |
| 1.4 Single Sign-On (SSO) | Integration setup with test-connection validation | TC-SA-01-01-080, TC-SA-01-01-081 |
| 1.4 Single Sign-On (SSO) | Organization scoping | TC-SA-01-01-082 |
| 1.4 Single Sign-On (SSO) | Role mapping | TC-SA-01-01-083 |
| 1.4 Single Sign-On (SSO) | Just-in-time provisioning | TC-SA-01-01-084 |
| 1.4 Single Sign-On (SSO) | De-provisioning | TC-SA-01-01-085 |
| 1.4 Single Sign-On (SSO) | Session behavior, local and federated logout | TC-SA-01-01-086, TC-SA-01-01-087 |
| 1.4 Single Sign-On (SSO) | Fallback policy on provider outage | TC-SA-01-01-088, TC-SA-01-01-089 |
| 1.4 Single Sign-On (SSO) | Admin monitoring | TC-SA-01-01-090 |
| 1.4 Single Sign-On (SSO) | Audit logging of configuration and provisioning | TC-SA-01-01-091 |
| 1.4 Single Sign-On (SSO) | Rule: no cross-organization or staff-role access | TC-SA-01-01-092 |
| 1.4 Single Sign-On (SSO) | Rule: platform staff never via organization SSO | TC-SA-01-01-093 |
| 1.4 Single Sign-On (SSO) | Rule: unmapped group → denied/restricted + flagged | TC-SA-01-01-094 |
| 1.4 Single Sign-On (SSO) | Rule: de-provisioning suspends, not deletes | TC-SA-01-01-095 |
| 1.4 Single Sign-On (SSO) | Rule: fail closed unless fallback opted in | TC-SA-01-01-096 |
| 1.4 Single Sign-On (SSO) | Rule: audit log carries actor and timestamp | TC-SA-01-01-097 |
| 1.4 Single Sign-On (SSO) | Rule: SSO sessions subject to session policies | TC-SA-01-01-098 |

## 1.1 Email and Password Login

### TC-SA-01-01-001 — Login screen renders with all required elements
**Type:** Positive
**Covers:** 1.1 → Login screen with email and password fields, input validation, and clear inline error messages
**Preconditions:** A valid active Super Admin account exists; browser has no active session or stored credentials.
**Steps:**
1. Open the platform URL in a fresh browser session.
2. Observe the login screen layout and every visible element.
3. Verify each element's label and placement against the documented screen.
**Expected Result:** The screen shows exactly: email field, password field, "Remember me" checkbox, "Forgot password?" link, and "Sign in" button — no element missing, no extra undocumented element, labels exactly as documented.
**Priority:** Critical

### TC-SA-01-01-002 — Invalid email format shows inline error
**Type:** Negative
**Covers:** 1.1 → Login screen input validation (format check)
**Preconditions:** Login screen is displayed.
**Steps:**
1. Type "notanemail" into the email field and move focus out of the field.
2. Observe the validation feedback.
3. Repeat with "user@domain" (missing TLD) and "user @domain.com" (space).
**Expected Result:** Each invalid entry produces a clear inline error message beneath the email field describing the format problem; no submission is possible with an invalid format; the error clears when the input becomes valid.
**Priority:** High

### TC-SA-01-01-003 — Email trimming and case handling on input
**Type:** Edge
**Covers:** 1.1 → Login screen input validation (trimming, case handling for email)
**Preconditions:** A valid account exists for email "admin@school.com".
**Steps:**
1. Type "  admin@school.com  " (leading and trailing spaces) into the email field.
2. Enter the correct password and click "Sign in".
3. Log out, then repeat using "ADMIN@SCHOOL.COM" (uppercase).
**Expected Result:** In both cases the system trims whitespace and matches the email case-insensitively; login succeeds in both attempts; the stored account email remains in its original form.
**Priority:** High

### TC-SA-01-01-004 — Show/hide password toggle works
**Type:** Positive
**Covers:** 1.1 → "Show/hide password" toggle
**Preconditions:** Login screen is displayed.
**Steps:**
1. Type a password into the password field; observe the masked display.
2. Click the show/hide toggle.
3. Observe the field, then click the toggle again.
**Expected Result:** Initially the password is masked; after the first click the full password is visible exactly as typed; after the second click it is masked again; the toggle does not alter the entered value or move the cursor in a way that loses characters.
**Priority:** Medium

### TC-SA-01-01-005 — Password manager auto-fill support
**Type:** Positive
**Covers:** 1.1 → Auto-fill support for password managers
**Preconditions:** A password manager is installed with saved credentials for the platform URL.
**Steps:**
1. Open the login screen.
2. Trigger the password manager's auto-fill for the platform entry.
3. Observe which fields are populated.
**Expected Result:** The email and password fields are correctly identified and auto-filled by the password manager (fields expose standard autocomplete semantics); clicking "Sign in" after auto-fill submits the filled values without modification.
**Priority:** Medium

### TC-SA-01-01-006 — Forgot password link routes to reset flow
**Type:** Positive
**Covers:** 1.1 → "Forgot password" link routing to the reset flow
**Preconditions:** Login screen is displayed.
**Steps:**
1. Click the "Forgot password?" link on the login screen.
2. Observe the destination screen.
**Expected Result:** The user is routed to the password reset flow (the reset screen of feature 4.2) with the reset instructions displayed; the login screen state (typed values) is not lost if the user navigates back.
**Priority:** High

### TC-SA-01-01-007 — Remember me extends session persistence
**Type:** Positive
**Covers:** 1.1 → "Remember me" checkbox
**Preconditions:** A valid active account; session policy defines a normal (non-remembered) timeout shorter than the test window.
**Steps:**
1. Log in with "Remember me" ticked.
2. Close the browser completely and wait longer than the normal session timeout.
3. Reopen the browser and navigate to the platform URL.
**Expected Result:** The session is still valid after the browser restart (the remembered session persists beyond the normal timeout per the remember-me policy); the user lands directly on their panel without re-entering credentials.
**Priority:** High

### TC-SA-01-01-008 — Without remember me, session ends with browser
**Type:** Negative
**Covers:** 1.1 → "Remember me" checkbox (unchecked behavior)
**Preconditions:** A valid active account.
**Steps:**
1. Log in with "Remember me" left unticked.
2. Close the browser completely.
3. Reopen the browser and navigate to the platform URL.
**Expected Result:** The session is not persisted; the user is redirected to the login screen and must authenticate again.
**Priority:** High

### TC-SA-01-01-009 — Rate limiting per account on login attempts
**Type:** Negative
**Covers:** 1.1 → Rate limiting on login attempts per account
**Preconditions:** A valid account; the documented per-account attempt threshold is known (e.g., 5 attempts).
**Steps:**
1. Submit the correct email with a wrong password repeatedly, one attempt at a time, from a single IP.
2. Count attempts until the per-account limit is reached.
3. Observe the screen and the account state after the limit.
**Expected Result:** After the documented number of failures the account is temporarily locked/rate-limited; the screen shows the remaining-attempt warning before the limit and the lockout state after it; further attempts with the correct password are rejected until the limit window elapses.
**Priority:** Critical

### TC-SA-01-01-010 — Rate limiting per IP on login attempts
**Type:** Negative
**Covers:** 1.1 → Rate limiting on login attempts per IP
**Preconditions:** A test IP address; multiple valid accounts; the documented per-IP threshold is known.
**Steps:**
1. From the same IP, submit login attempts against different accounts (mix of valid and invalid credentials) until the per-IP threshold is exceeded.
2. Attempt a login with a known-good account from the same IP.
3. Attempt the same login from a different IP.
**Expected Result:** The per-IP limit triggers throttling/blocking for that IP (the known-good account is rejected from the limited IP with a rate-limit notice); the identical login from a different IP succeeds; the IP-level event is logged.
**Priority:** Critical

### TC-SA-01-01-011 — Progressive failure feedback with generic message
**Type:** Negative
**Covers:** 1.1 → Progressive failure feedback: generic "invalid email or password" message
**Preconditions:** A valid account; no prior failed attempts in the current window.
**Steps:**
1. Enter the correct email and a wrong password; click "Sign in".
2. Read the error message exactly.
3. Repeat one more time and read the message again.
**Expected Result:** Both failures show the identical generic message "Invalid email or password" (never revealing which field was wrong) plus the remaining-attempt count before a temporary lock (e.g., "3 more attempts before a temporary lock"); the count decreases correctly between attempts.
**Priority:** Critical

### TC-SA-01-01-012 — Suspended account cannot log in
**Type:** Edge
**Covers:** 1.1 → Pre-authentication checks: account status (suspended)
**Preconditions:** An account set to suspended status with valid credentials.
**Steps:**
1. Attempt login with the suspended account's correct email and password.
2. Read the message shown.
3. Attempt again to confirm the state is enforced consistently.
**Expected Result:** Login is rejected before credential verification completes into a session; the message is "Your account is suspended. Please contact support" with support contact details; no session is created; the attempt is logged.
**Priority:** Critical

### TC-SA-01-01-013 — Deactivated account cannot log in
**Type:** Edge
**Covers:** 1.1 → Pre-authentication checks: account status (deactivated)
**Preconditions:** An account set to deactivated (permanent closure) status.
**Steps:**
1. Attempt login with the deactivated account's correct credentials.
2. Read the message shown.
**Expected Result:** Login is rejected; the message is the permanent closure notice (distinct from the suspended message, with no appeal path); no session is created; the attempt is logged.
**Priority:** Critical

### TC-SA-01-01-014 — Locked account shows lockout state, not credential prompt
**Type:** Edge
**Covers:** 1.1 → Pre-authentication checks: lockout state
**Preconditions:** An account currently in temporary lockout from repeated failures.
**Steps:**
1. Attempt login with the locked account's correct credentials.
2. Read the screen content.
**Expected Result:** The screen shows the remaining lockout time and the support contact instead of accepting credentials; even the correct password is rejected during the lockout window; the attempt is logged as a blocked-during-lockout event.
**Priority:** Critical

### TC-SA-01-01-015 — IP deny list blocks before credential verification
**Type:** Edge
**Covers:** 1.1 → Pre-authentication checks: IP allow/deny lists
**Preconditions:** A valid account; the source IP added to the deny list by the Super Admin.
**Steps:**
1. From the deny-listed IP, attempt login with the account's correct credentials.
2. Observe the rejection and the security log.
**Expected Result:** The attempt is rejected before credential verification (the correct password makes no difference); the rejection is logged specifically as an IP-block event (distinguishable from a wrong-password failure); no session is created.
**Priority:** Critical

### TC-SA-01-01-016 — Location policy enforced at login
**Type:** Edge
**Covers:** 1.1 → Pre-authentication checks: location policy
**Preconditions:** A location policy restricting logins to defined regions; a test source outside the allowed region.
**Steps:**
1. Attempt login from a location outside the allowed region with correct credentials.
2. Observe the rejection and the security log.
3. Attempt login from an allowed location with the same credentials.
**Expected Result:** The out-of-region attempt is rejected by the location policy with a policy-denied message and logged as a location-policy event; the in-region attempt proceeds normally; the policy check occurs in the documented pre-authentication order.
**Priority:** High

### TC-SA-01-01-017 — 2FA challenge presented after password verification
**Type:** Positive
**Covers:** 1.1 → Post-verification checks: 2FA challenge if enabled
**Preconditions:** 2FA enabled for the account/role; valid credentials.
**Steps:**
1. Enter correct email and password; click "Sign in".
2. Observe the screen transition after password verification.
**Expected Result:** The password verifies, then the screen transitions to the second-factor step (e.g., "Enter the 6-digit code sent to your registered phone" with a 60-second resend countdown); no session is established until the second factor is verified.
**Priority:** Critical

### TC-SA-01-01-018 — Session established and event logged on success
**Type:** Positive
**Covers:** 1.1 → Session establishment on success
**Preconditions:** Valid credentials; all pre- and post-verification checks passable.
**Steps:**
1. Complete a full successful login (including any second factor).
2. Inspect the session record for the account.
3. Inspect the login activity log for the event.
**Expected Result:** A session record is created with the correct account, timestamp, IP, and device; a login event is written to the security/login log with full context; the user is redirected to their default landing screen.
**Priority:** Critical

### TC-SA-01-01-019 — Role-aware landing after login
**Type:** Positive
**Covers:** 1.1 → Role-aware landing
**Preconditions:** Accounts of different user types (Super Admin, Student, and at least one other role) with valid credentials.
**Steps:**
1. Log in as the Super Admin and record the landing screen.
2. Log in as the Student and record the landing screen.
3. Log in as the third role and record the landing screen.
**Expected Result:** Each user type lands on their own panel home (Super Admin → Super Admin Dashboard, Student → Student Dashboard, etc.); no user type is ever landed on another type's panel; the dashboard shows the user's name, role badge, and standard navigation.
**Priority:** High

### TC-SA-01-01-020 — Successful login attempt logged with full context
**Type:** Positive
**Covers:** 1.1 → Login attempt logging (success)
**Preconditions:** Login activity log accessible to the Super Admin; a successful login to perform.
**Steps:**
1. Perform a successful login from a known IP and device.
2. Open Security Monitoring → Login Activity.
3. Locate the event and inspect its fields.
**Expected Result:** The successful attempt is recorded with timestamp, IP address, device, and outcome = success; the fields match the actual attempt exactly.
**Priority:** High

### TC-SA-01-01-021 — Failed login attempt logged with failure reason
**Type:** Positive
**Covers:** 1.1 → Login attempt logging (failure)
**Preconditions:** Login activity log accessible; a failed login to perform.
**Steps:**
1. Attempt a login with a wrong password from a known IP and device.
2. Open Security Monitoring → Login Activity.
3. Locate the event and inspect its fields.
**Expected Result:** The failed attempt is recorded with timestamp, IP, device, outcome = failure, and the failure reason (e.g., invalid credentials); the log entry is distinguishable from success entries.
**Priority:** High

### TC-SA-01-01-022 — Mobile app login parity with device-bound tokens
**Type:** Positive
**Covers:** 1.1 → Mobile app parity
**Preconditions:** The mobile app installed on a test device; a valid account.
**Steps:**
1. Launch the mobile app and log in with the same credentials used on web.
2. Verify credential verification behaves identically (same validations, same error messages, same 2FA step if enabled).
3. Inspect the session record for the mobile login.
**Expected Result:** The mobile app performs identical credential verification (same checks, same messages, same second-factor behavior); the session is device-bound (a device-bound session token is issued); the login event is logged with the mobile device identified.
**Priority:** High

### TC-SA-01-01-023 — Error message prevents account enumeration
**Type:** Negative
**Covers:** 1.1 → Rule: error never distinguishes "email not found" from "wrong password"
**Preconditions:** One valid account; one email address known not to exist.
**Steps:**
1. Attempt login with the non-existent email and any password; record the exact message.
2. Attempt login with the valid email and a wrong password; record the exact message.
3. Compare the two messages character for character.
**Expected Result:** Both messages are identical ("Invalid email or password"); no wording, timing indicator, or additional detail reveals whether the email exists; an attacker cannot enumerate valid accounts from the login screen.
**Priority:** Critical

### TC-SA-01-01-024 — Email matched case-insensitively
**Type:** Edge
**Covers:** 1.1 → Rule: email addresses matched case-insensitively
**Preconditions:** A valid account for "Admin@School.COM".
**Steps:**
1. Log in using "aDmIn@ScHoOl.CoM" with the correct password.
2. Verify the session belongs to the correct account.
**Expected Result:** Login succeeds; the session is for the single existing account (no duplicate created, no "not found" error); case variation in the email never creates ambiguity.
**Priority:** High

### TC-SA-01-01-025 — Password is case-sensitive
**Type:** Negative
**Covers:** 1.1 → Rule: passwords are case-sensitive
**Preconditions:** A valid account whose password contains mixed case (e.g., "Passw0rd!").
**Steps:**
1. Attempt login with the password in different case ("password!" or "PASSWORD!").
2. Observe the result.
**Expected Result:** Login fails with the generic invalid-credentials message; case variation in the password is never accepted; the failure is counted toward the attempt limit like any other failure.
**Priority:** High

### TC-SA-01-01-026 — Suspended and deactivated messages differ by state
**Type:** Edge
**Covers:** 1.1 → Rule: message differs by state (suspended = temporary with appeal path; deactivated = permanent)
**Preconditions:** One suspended account and one deactivated account.
**Steps:**
1. Attempt login with the suspended account; record the exact message.
2. Attempt login with the deactivated account; record the exact message.
3. Compare the two messages.
**Expected Result:** The suspended message states the suspension is temporary and provides the appeal/support path; the deactivated message states permanent closure; the two messages are clearly different and each matches its documented state.
**Priority:** High

### TC-SA-01-01-027 — Locked screen shows remaining lockout time and support contact
**Type:** Edge
**Covers:** 1.1 → Rule: locked account shows remaining lockout time and support contact instead of accepting credentials
**Preconditions:** An account in active temporary lockout.
**Steps:**
1. Open the login screen and submit the locked account's credentials.
2. Read the displayed lockout information.
3. Wait until the lockout elapses and attempt login again with correct credentials.
**Expected Result:** During lockout: the screen shows the remaining lockout time and the support contact, and credentials are not accepted; after the lockout elapses: login with correct credentials succeeds and the attempt counter resets.
**Priority:** Critical

### TC-SA-01-01-028 — Deny-listed IP rejection logged as IP-block event
**Type:** Negative
**Covers:** 1.1 → Rule: deny-listed IP rejected before verification and logged as IP-block event
**Preconditions:** Source IP on the deny list; valid credentials for the account.
**Steps:**
1. Attempt login from the deny-listed IP with correct credentials.
2. Open the security log and locate the event.
3. Verify the event type and its context fields.
**Expected Result:** The rejection occurs before credential verification; the log entry is typed as an IP-block event (not a credential failure) and carries timestamp, IP, and account context; the event is visible in Security Monitoring.
**Priority:** Critical

### TC-SA-01-01-029 — Mandatory 2FA without enrollment pauses at guided enrollment
**Type:** Edge
**Covers:** 1.1 → Rule: mandatory 2FA with no enrollment → guided enrollment step, not failure
**Preconditions:** A role with mandatory 2FA; an account in that role that has not enrolled in 2FA; valid credentials.
**Steps:**
1. Attempt login with the account's correct credentials.
2. Observe the screen after password verification.
3. Complete the guided enrollment flow and finish the login.
**Expected Result:** Login does not fail; it pauses at a guided 2FA enrollment step (per feature 3.1) with clear instructions; after enrollment completes, the login continues and the session is established; the enrollment and login are both logged.
**Priority:** Critical

### TC-SA-01-01-030 — Blocked attempts logged with full context
**Type:** Positive
**Covers:** 1.1 → Rule: every attempt (success, failure, block) written to the login activity log with full context
**Preconditions:** Scenarios available to produce a success, a failure, and a block (deny-listed IP or lockout).
**Steps:**
1. Produce one successful, one failed, and one blocked login attempt.
2. Open the login activity log and locate all three events.
3. Inspect each event's context fields.
**Expected Result:** All three events are present; each carries timestamp, IP, device, outcome, and reason/context appropriate to its type; no attempt type is missing from the log.
**Priority:** High

### TC-SA-01-01-031 — Login-created session obeys session policies
**Type:** Edge
**Covers:** 1.1 → Rule: sessions subject to all session policies (timeouts, concurrency, remember-me)
**Preconditions:** Session policies configured (idle timeout, max concurrent sessions); a valid account.
**Steps:**
1. Log in and remain idle beyond the configured idle timeout; attempt an action.
2. Log in from a second device beyond the concurrency limit.
3. Observe enforcement in both cases.
**Expected Result:** The idle session is terminated per the timeout policy (the action triggers re-authentication); the concurrent-session limit is enforced (the excess session is blocked or the oldest is terminated per policy); enforcement is consistent with the documented session policies.
**Priority:** High

## 1.2 OTP-Based Login Verification (Password + OTP)

### TC-SA-01-01-032 — Enable password+OTP login per role
**Type:** Positive
**Covers:** 1.2 → Policy configuration: per role
**Preconditions:** Super Admin access to System Settings → Security Policy → Login Methods.
**Steps:**
1. Open the Login Methods screen.
2. Enable "Password + OTP" for a single selected role only.
3. Save, then log in as a user of that role and as a user of a role without the policy.
**Expected Result:** The selected role's login presents the OTP step after password verification; the other role's login does not present the OTP step; the policy state is visible on the configuration screen.
**Priority:** Critical

### TC-SA-01-01-033 — Enable password+OTP login globally
**Type:** Positive
**Covers:** 1.2 → Policy configuration: globally
**Preconditions:** Super Admin access to the Login Methods screen.
**Steps:**
1. Enable "Password + OTP" globally (all roles).
2. Save, then log in as users of three different roles.
**Expected Result:** Every role's login now presents the OTP step after password verification; the global state is reflected on the configuration screen; reverting the setting removes the step for all roles.
**Priority:** Critical

### TC-SA-01-01-034 — OTP delivered via SMS to registered phone
**Type:** Positive
**Covers:** 1.2 → OTP delivery channel: SMS
**Preconditions:** Password+OTP enabled; the account has a registered phone; SMS delivery available.
**Steps:**
1. Complete the password step of login.
2. Observe the OTP step screen and the SMS delivery to the registered phone.
**Expected Result:** The screen states the code was sent to the registered (masked) phone number; a 6-digit code arrives by SMS to that exact number; the code on the screen flow matches the delivery channel shown.
**Priority:** Critical

### TC-SA-01-01-035 — OTP delivered via email
**Type:** Positive
**Covers:** 1.2 → OTP delivery channel: email
**Preconditions:** Password+OTP enabled; the account has a registered email; email channel selected/available.
**Steps:**
1. Complete the password step of login.
2. Observe the OTP step screen and the email delivery.
**Expected Result:** The screen states the code was sent to the registered email; an email containing the 6-digit code arrives at that address; the code is usable to complete login.
**Priority:** High

### TC-SA-01-01-036 — Fallback channel when primary delivery fails
**Type:** Edge
**Covers:** 1.2 → Fallback channel if the primary fails
**Preconditions:** Password+OTP enabled; primary channel (SMS) made to fail (unreachable number); email channel registered.
**Steps:**
1. Complete the password step of login.
2. Wait for the primary delivery to fail.
3. Observe the fallback offer and use it.
**Expected Result:** On primary failure the system offers the fallback channel (email) or the support-assisted path; using the fallback delivers a working OTP; the delivery failure and fallback are logged.
**Priority:** High

### TC-SA-01-01-037 — OTP is a 6-digit numeric code
**Type:** Positive
**Covers:** 1.2 → OTP generation: 6-digit numeric code
**Preconditions:** Password+OTP enabled; delivery channel observable.
**Steps:**
1. Trigger an OTP issuance during login.
2. Inspect the delivered code's format.
3. Repeat for three separate issuances.
**Expected Result:** Every issued code is exactly 6 numeric digits (no letters, no longer/shorter); the entry screen provides exactly 6 digit fields.
**Priority:** High

### TC-SA-01-01-038 — OTP codes are random and non-repeating in sequence
**Type:** Edge
**Covers:** 1.2 → OTP generation: cryptographically random
**Preconditions:** Password+OTP enabled; ability to observe multiple issuances.
**Steps:**
1. Trigger 10 separate OTP issuances (via resend where allowed, or repeated logins).
2. Record each code.
3. Analyze the sequence for predictability (sequential increments, fixed values, short cycles).
**Expected Result:** The codes show no predictable pattern (no fixed value, no simple increment, no short cycle); each issuance is independent; no code is derivable from previous codes.
**Priority:** High

### TC-SA-01-01-039 — Validity window countdown shown on entry screen
**Type:** Positive
**Covers:** 1.2 → OTP validity window with countdown shown
**Preconditions:** Password+OTP enabled; a fresh OTP issued.
**Steps:**
1. Complete the password step and observe the OTP entry screen.
2. Read the countdown display and watch it tick.
**Expected Result:** The screen shows the validity countdown (e.g., "It expires in 04:59") starting from the documented window (e.g., 5 minutes); the countdown ticks down in real time; the displayed window matches the configured validity.
**Priority:** High

### TC-SA-01-01-040 — OTP expires at end of validity window
**Type:** Edge
**Covers:** 1.2 → OTP validity window (expiry)
**Preconditions:** A fresh OTP issued; the validity window known.
**Steps:**
1. Complete the password step and receive the OTP.
2. Wait until the validity window elapses without entering the code.
3. Enter the (now expired) code and submit.
**Expected Result:** After expiry the code is rejected with the specific "expired" message and a resend option (not a generic error); the expired code cannot be used even though it was valid when issued.
**Priority:** Critical

### TC-SA-01-01-041 — OTP entry fields auto-advance
**Type:** Positive
**Covers:** 1.2 → OTP entry screen with auto-advance digit fields
**Preconditions:** A fresh OTP issued; the OTP entry screen displayed.
**Steps:**
1. Type digits one at a time into the first field.
2. Observe focus movement after each digit.
3. Use backspace to correct a digit and re-enter it.
**Expected Result:** Focus automatically advances to the next field after each digit; backspace moves focus back and clears the digit; all 6 digits can be entered without manual tabbing; the Verify button becomes active when all 6 fields are filled.
**Priority:** Medium

### TC-SA-01-01-042 — OTP paste support
**Type:** Positive
**Covers:** 1.2 → OTP entry screen paste support
**Preconditions:** A fresh OTP issued; the code available on the clipboard.
**Steps:**
1. Copy the 6-digit code to the clipboard.
2. Click the first OTP field and paste.
3. Observe field population and submit.
**Expected Result:** Pasting distributes the 6 digits across the fields correctly (no truncation, no reordering); the code verifies successfully; pasting a malformed value (wrong length/characters) is rejected with a clear inline error.
**Priority:** Medium

### TC-SA-01-01-043 — Resend available after cooldown
**Type:** Positive
**Covers:** 1.2 → Resend with cooldown
**Preconditions:** A fresh OTP issued; the resend cooldown known (e.g., 60 seconds).
**Steps:**
1. Observe the "Resend code" link state immediately after issuance.
2. Wait for the cooldown to elapse.
3. Click "Resend code" and observe the new delivery.
**Expected Result:** During the cooldown the link is disabled with a visible countdown; after the cooldown it becomes active; clicking it issues a fresh OTP to the registered channel; the old code's state is handled per policy (invalidated or superseded) and the new countdown restarts.
**Priority:** High

### TC-SA-01-01-044 — Maximum resend count per login attempt enforced
**Type:** Edge
**Covers:** 1.2 → Maximum resend count per login attempt
**Preconditions:** A login in progress; the documented maximum resend count known.
**Steps:**
1. Resend the OTP repeatedly, waiting out each cooldown, until the maximum count is reached.
2. Attempt one more resend.
3. Observe the screen state.
**Expected Result:** Resends are allowed up to the documented maximum; beyond it, no further resend is offered for this login attempt (the user must restart the login or use the support-assisted path); the limit and each resend are logged.
**Priority:** High

### TC-SA-01-01-045 — Five wrong OTP entries invalidate the code
**Type:** Negative
**Covers:** 1.2 → Attempt limit: fixed number of wrong entries invalidates the OTP
**Preconditions:** A fresh OTP issued; the documented wrong-entry limit known (e.g., 5).
**Steps:**
1. Enter a wrong 6-digit code and submit; read the message.
2. Repeat wrong entries until the limit is reached.
3. Enter the correct (originally issued) code and submit.
**Expected Result:** Each wrong entry shows the remaining attempts ("Incorrect code. 4 attempts remaining."); after the limit the message changes to "This code is no longer valid. Request a new code."; the originally correct code is now rejected (the code is invalidated); a fresh issuance is required.
**Priority:** Critical

### TC-SA-01-01-046 — Valid OTP completes login and establishes session
**Type:** Positive
**Covers:** 1.2 → Login completion on valid OTP
**Preconditions:** A fresh, unexpired OTP; all prior steps passed.
**Steps:**
1. Enter the valid OTP and click "Verify".
2. Observe the transition and the session state.
3. Check the login log entry for this login.
**Expected Result:** The session is established immediately on valid OTP; the user is redirected to their panel home; the login is logged as "password + OTP — success" with timestamp, IP, and device.
**Priority:** Critical

### TC-SA-01-01-047 — Expired OTP produces distinct expired message
**Type:** Negative
**Covers:** 1.2 → Failure handling: expired OTP message
**Preconditions:** An OTP that has passed its validity window.
**Steps:**
1. Enter the expired code and submit.
2. Read the exact message and available actions.
**Expected Result:** The message is specifically about expiry (not the generic wrong-code message) and offers a resend action; the failure is logged as an expiry event.
**Priority:** High

### TC-SA-01-01-048 — Wrong OTP produces distinct wrong-code message with attempts remaining
**Type:** Negative
**Covers:** 1.2 → Failure handling: wrong OTP message
**Preconditions:** A fresh, unexpired OTP; a different valid-format 6-digit code available.
**Steps:**
1. Enter the wrong code and submit.
2. Read the exact message.
**Expected Result:** The message is specifically "Incorrect code" with the remaining attempt count; it is distinct from the expired and delivery-failure messages; the failure is logged as a wrong-OTP event.
**Priority:** High

### TC-SA-01-01-049 — Delivery failure produces distinct actionable message
**Type:** Negative
**Covers:** 1.2 → Failure handling: delivery failure message
**Preconditions:** OTP delivery made to fail (channel unreachable).
**Steps:**
1. Complete the password step with delivery failing.
2. Read the message and available actions.
**Expected Result:** The message clearly indicates the code could not be delivered and offers actionable options (retry, switch channel if registered, or support-assisted path); the delivery failure is logged with the channel.
**Priority:** High

### TC-SA-01-01-050 — SMS failure offers email or support-assisted path
**Type:** Edge
**Covers:** 1.2 → Delivery failure fallback
**Preconditions:** Primary channel SMS failing; email registered on the account.
**Steps:**
1. Trigger an OTP issuance with SMS failing.
2. Select the email fallback and complete delivery.
3. With email also unavailable, observe the support-assisted path.
**Expected Result:** When SMS fails, email delivery is offered (if registered) and works end-to-end; when no channel is available, the support-assisted recovery path is offered with clear instructions; both fallbacks are logged.
**Priority:** High

### TC-SA-01-01-051 — All OTP events logged (issued, verified, failed, expired)
**Type:** Positive
**Covers:** 1.2 → Full logging of each OTP issuance, verification, failure, and expiry
**Preconditions:** Login activity log accessible; scenarios to produce all four event types.
**Steps:**
1. Produce one issuance, one successful verification, one wrong-entry failure, and one expiry.
2. Open the login activity log and locate all four events.
3. Inspect each event's fields.
**Expected Result:** All four event types are present with timestamps, channel, and outcome; events are distinguishable by type; the sequence matches the actual order of operations.
**Priority:** High

### TC-SA-01-01-052 — Verified OTP cannot be reused
**Type:** Negative
**Covers:** 1.2 → Rule: OTP is single-use
**Preconditions:** An OTP that has been successfully verified once (login completed, then logged out).
**Steps:**
1. Start a new login with the same account.
2. Enter the previously verified code and submit.
**Expected Result:** The code is rejected (single-use enforced) even though it is within its original validity window; the rejection is logged as a reuse attempt; a fresh issuance is required.
**Priority:** Critical

### TC-SA-01-01-053 — Expired code message offers resend, not generic error
**Type:** Edge
**Covers:** 1.2 → Rule: expired code produces "expired" message with resend option
**Preconditions:** An expired OTP.
**Steps:**
1. Submit the expired code.
2. Verify the message wording and the presence of a working resend action.
3. Use the resend action and complete login with the new code.
**Expected Result:** The message explicitly indicates expiry (wording distinct from wrong-code and delivery-failure); a resend action is present and functional; login completes with the fresh code.
**Priority:** High

### TC-SA-01-01-054 — Wrong-attempt counter is per issued code
**Type:** Edge
**Covers:** 1.2 → Rule: wrong-OTP attempts counted per issued code
**Preconditions:** A login in progress with a fresh OTP.
**Steps:**
1. Enter 3 wrong codes (counter now at 3 of 5).
2. Request a fresh code via resend.
3. Enter 2 more wrong codes against the new code and read the counter.
**Expected Result:** The counter resets with the new code (the new code shows its own full attempt budget, e.g., "3 attempts remaining" after 2 wrong entries, not "0 remaining" carried over); each code's attempts are tracked independently.
**Priority:** High

### TC-SA-01-01-055 — Resend rate limiting prevents SMS abuse
**Type:** Edge
**Covers:** 1.2 → Rule: resends rate-limited (cooldown + maximum per login session)
**Preconditions:** A login in progress; cooldown and maximum known.
**Steps:**
1. Attempt to click "Resend code" during the cooldown window.
2. Attempt rapid successive resends after each cooldown until the per-session maximum.
3. Observe enforcement and logging.
**Expected Result:** Resend during cooldown is blocked (link disabled with countdown); the per-session maximum caps total resends; no burst of deliveries can be triggered; all resend attempts (allowed and blocked) are logged.
**Priority:** High

### TC-SA-01-01-056 — Unreachable phone routes to email or support path
**Type:** Edge
**Covers:** 1.2 → Rule: unreachable phone → email delivery if registered, or support-assisted recovery
**Preconditions:** Account with an unreachable registered phone and a registered email.
**Steps:**
1. Start login; primary SMS delivery fails (unreachable number).
2. Switch to email delivery and complete login.
3. Repeat with no registered email and observe the support-assisted path.
**Expected Result:** With email registered: the switch is offered and login completes via email; without any reachable channel: the support-assisted recovery path is presented with clear steps; both paths are logged with the channels attempted.
**Priority:** High

### TC-SA-01-01-057 — OTP value never appears in logs
**Type:** Positive
**Covers:** 1.2 → Rule: OTPs never logged in full; only event and channel recorded
**Preconditions:** Multiple OTP events produced; log access available.
**Steps:**
1. Produce several OTP events (issuance, verification, failure, expiry).
2. Search the full text of the login/security logs for any 6-digit code values.
3. Inspect the recorded fields of each OTP event.
**Expected Result:** No log entry contains the actual OTP value; each entry records only the event type, the channel, the outcome, and context (timestamp, IP, device); a full log review reveals zero code values.
**Priority:** Critical

### TC-SA-01-01-058 — Coexistence with 2FA: policy defines the challenge
**Type:** Edge
**Covers:** 1.2 → Rule: both modes can be active; policy defines which challenge is presented
**Preconditions:** An account enrolled in 2FA (section 3) with password+OTP also enabled for its role.
**Steps:**
1. Log in with the account and observe which second-factor challenge is presented.
2. Compare with the documented precedence (2FA enrollment state takes precedence once enrolled).
3. Check the configuration screen for the precedence setting.
**Expected Result:** Exactly one second-factor challenge is presented per the policy (the enrolled 2FA challenge takes precedence); the user is never asked to complete both in one login; the behavior matches the configured precedence.
**Priority:** High

### TC-SA-01-01-059 — Expiry countdown always visible regardless of delivery latency
**Type:** Edge
**Covers:** 1.2 → Rule: UI always shows the expiry countdown
**Preconditions:** A login in progress; simulate/observe slow delivery latency.
**Steps:**
1. Complete the password step and observe the OTP screen from the moment it appears.
2. Keep the screen open through the full validity window.
3. Verify the countdown is continuously visible and accurate.
**Expected Result:** The countdown is visible from the moment the OTP screen appears (even before the user receives the code), ticks continuously, and reaches zero exactly at the validity window end; the user can always tell when to resend.
**Priority:** Medium

## 1.3 Social Login (Google, Facebook)

### TC-SA-01-01-060 — Enable a provider for selected user types
**Type:** Positive
**Covers:** 1.3 → Provider enable/disable per provider and per user type
**Preconditions:** Super Admin access to System Settings → Security Policy → Login Methods → Social Login; Facebook currently disabled.
**Steps:**
1. Enable Facebook for students and parents only.
2. Save and open the login screen as a student-type session context.
3. Verify the button appears for eligible types and not for excluded ones.
**Expected Result:** The "Continue with Facebook" button appears for students and parents; it does not appear for excluded user types; the enable/disable state per provider and per user type is visible and editable on the configuration screen.
**Priority:** High

### TC-SA-01-01-061 — Privileged roles excluded from social login
**Type:** Negative
**Covers:** 1.3 → Provider enable/disable per user type (admin roles excluded)
**Preconditions:** Social login enabled for general user types; privileged roles (Super Admin, Billing Administrator) on the exclusion list.
**Steps:**
1. Attempt to reach the login screen in the context of a privileged role.
2. Verify no social login buttons are presented for that role.
3. Attempt to configure social login as the only method for a privileged role.
**Expected Result:** No social login button is shown to privileged roles; the configuration prevents social login from being the only authentication method for a privileged role (the save is blocked or the exclusion is enforced); the exclusion list is visible on the configuration screen.
**Priority:** Critical

### TC-SA-01-01-062 — First social login creates account and prompts required fields
**Type:** Positive
**Covers:** 1.3 → First-login account creation
**Preconditions:** A social identity (Google) whose email does not exist on the platform; provider enabled.
**Steps:**
1. Click "Continue with Google" and complete the provider consent.
2. Observe the account creation and the post-login prompt.
3. Inspect the created account's profile data.
**Expected Result:** A platform account is created using the social profile (name, email, profile picture); required fields not provided by the provider (e.g., phone) are prompted immediately afterwards; the account is active and lands on the correct panel for its user type.
**Priority:** High

### TC-SA-01-01-063 — Social email matching existing account offers linking
**Type:** Edge
**Covers:** 1.3 → Account matching on email
**Preconditions:** An existing email/password account; a social identity with the same email; provider enabled.
**Steps:**
1. Click the social login button with the matching social identity.
2. Observe the system's response to the email match.
**Expected Result:** The system does not create a duplicate; it offers to link the social identity to the existing account (with the required verification); the user can complete linking and then log in via the provider; the match event is logged.
**Priority:** Critical

### TC-SA-01-01-064 — Link a social provider from profile settings
**Type:** Positive
**Covers:** 1.3 → Account linking from profile settings with password verification
**Preconditions:** An existing email/password account; the user logged in.
**Steps:**
1. Open profile settings → connected accounts.
2. Select "Add Google" and complete the provider consent.
3. Verify the account's existing password when prompted.
4. Log out and log in via Google.
**Expected Result:** The provider is linked after password verification; subsequent logins via Google succeed and land on the same account; the linked provider is visible in profile settings; the linking is audit-logged.
**Priority:** High

### TC-SA-01-01-065 — Linking without password verification is blocked
**Type:** Negative
**Covers:** 1.3 → Account linking requires password verification
**Preconditions:** An existing email/password account; a session where the password has not been recently verified.
**Steps:**
1. Attempt to add a social provider from profile settings.
2. Decline/fail the password verification step.
3. Observe the linking outcome.
**Expected Result:** The linking is blocked until the existing password is verified; no provider is added on verification failure; the blocked attempt is logged; the attacker scenario (linking one's own social identity to a victim account without the password) is impossible.
**Priority:** Critical

### TC-SA-01-01-066 — Unlink a provider when other methods remain
**Type:** Positive
**Covers:** 1.3 → Unlinking a social provider
**Preconditions:** An account with a working password AND a linked social provider.
**Steps:**
1. Open profile settings → connected accounts.
2. Remove the linked provider (with any required verification).
3. Log out and log in via password.
**Expected Result:** The provider is unlinked successfully because another working method (password) remains; password login continues to work; the unlink is audit-logged.
**Priority:** Medium

### TC-SA-01-01-067 — Unlinking blocked when it would remove the last method
**Type:** Negative
**Covers:** 1.3 → Unlinking blocked if it would leave no authentication method
**Preconditions:** An account whose only working authentication method is a linked social provider (password disabled, no other provider).
**Steps:**
1. Open profile settings → connected accounts.
2. Attempt to remove the only linked provider.
**Expected Result:** The unlink is blocked with a clear message explaining that the account would be left with no authentication method; the provider remains linked; the blocked attempt is logged.
**Priority:** Critical

### TC-SA-01-01-068 — Consent captured at first social login
**Type:** Positive
**Covers:** 1.3 → Consent capture at first login
**Preconditions:** A first-time social login (new account or first use of the provider).
**Steps:**
1. Perform the first social login.
2. Observe the consent presentation regarding the provider's data usage.
3. Inspect the stored consent record.
**Expected Result:** At first login the platform privacy policy covering the social provider's data usage is presented and accepted (click-through); the consent record (what, when, which policy version) is stored with the account; subsequent logins do not re-prompt unless the policy changes.
**Priority:** High

### TC-SA-01-01-069 — Social login session behaves identically to password login
**Type:** Positive
**Covers:** 1.3 → Session behavior identical to password login
**Preconditions:** A linked social account; 2FA and session policies configured for the role.
**Steps:**
1. Log in via the social provider.
2. Verify the 2FA policy is applied (if enabled for the role).
3. Verify session policies (timeout, concurrency) apply to the social session.
4. Verify the login is logged like any other.
**Expected Result:** The social session is subject to the same 2FA policy, the same session policies, and the same logging as a password login; no session behavior differs by login method.
**Priority:** High

### TC-SA-01-01-070 — Provider outage hides button and preserves password login
**Type:** Edge
**Covers:** 1.3 → Provider outage handling
**Preconditions:** A provider made unreachable (simulated outage); the provider enabled.
**Steps:**
1. Open the login screen during the outage.
2. Observe the social button state and any notice.
3. Complete a password login.
**Expected Result:** The affected provider's button is hidden or shows "temporarily unavailable — use email and password"; the other provider (if healthy) and password login remain fully functional; the outage is reflected in the provider health view.
**Priority:** High

### TC-SA-01-01-071 — Admin monitoring shows social login usage and failures
**Type:** Positive
**Covers:** 1.3 → Admin monitoring: usage statistics and failure rates per provider
**Preconditions:** Social logins have occurred (successes, new accounts, failures) for at least one provider.
**Steps:**
1. Open Security Monitoring → Login Activity filtered by method "Social".
2. Review the per-provider statistics.
3. Verify each metric against known activity.
**Expected Result:** The view shows successful logins, new accounts created, and failures per provider; the numbers match the actual activity; failures are inspectable with context (provider, outcome, account).
**Priority:** Medium

### TC-SA-01-01-072 — Social login can never be the only method for privileged roles
**Type:** Negative
**Covers:** 1.3 → Rule: privileged roles must always have email/password
**Preconditions:** A privileged role account; configuration access.
**Steps:**
1. Attempt to disable the password for a privileged role account that has a linked social provider.
2. Attempt to configure a privileged role with social login only.
3. Attempt a social-only login as a privileged role.
**Expected Result:** All three are prevented: the password cannot be disabled for a privileged role, the configuration cannot reduce a privileged role to social-only, and a social-only login is rejected for privileged roles; the enforcement is logged.
**Priority:** Critical

### TC-SA-01-01-073 — Attacker cannot link own social identity to a victim account
**Type:** Negative
**Covers:** 1.3 → Rule: linking requires verifying the account's existing password first
**Preconditions:** A victim account with a known password (test fixture); an attacker social identity; a session on the victim account without recent password verification.
**Steps:**
1. In the victim account's profile settings, attempt to add the attacker's social provider.
2. At the password verification prompt, enter a wrong password.
3. Observe the linking outcome and the log.
**Expected Result:** The linking fails at password verification; the attacker's provider is not added; the failed verification is logged; the victim account's connected accounts are unchanged.
**Priority:** Critical

### TC-SA-01-01-074 — Unlink blocked when password disabled and no other provider
**Type:** Edge
**Covers:** 1.3 → Rule: unlink blocked when no other working method remains
**Preconditions:** An account with password disabled and exactly one linked provider.
**Steps:**
1. Attempt to unlink the sole provider via profile settings.
2. Attempt the same via any admin action available.
**Expected Result:** Both attempts are blocked with the no-remaining-method message; the account retains its only working authentication method; the blocked attempts are logged.
**Priority:** Critical

### TC-SA-01-01-075 — Duplicate account prevention with merge review
**Type:** Edge
**Covers:** 1.3 → Rule: provider email used by another account → linking/merge review, no silent duplicate
**Preconditions:** An existing account for email X; a social identity with email X that was previously used to create a second account (duplicate fixture).
**Steps:**
1. Attempt a social login with the identity.
2. Observe the system's duplicate handling.
3. As Super Admin, open the user directory, find both accounts, and run the account-merge support process.
4. Verify data preservation and the audit log.
**Expected Result:** The system offers linking/merge review rather than silently using/creating a duplicate; the merge preserves the older account's data into the primary account; the merge is audit-logged with actor and timestamp; post-merge, both login methods reach the single primary account.
**Priority:** Critical

### TC-SA-01-01-076 — Partial provider degradation shows unavailable notice
**Type:** Edge
**Covers:** 1.3 → Rule: outages degrade gracefully (button hidden or unavailable notice)
**Preconditions:** A provider in a degraded state (slow/failing but not fully down).
**Steps:**
1. Open the login screen during the degradation.
2. Observe the button state and notice text.
3. Attempt the social login and observe the failure handling.
**Expected Result:** The button shows the unavailable notice (or is hidden) with the "use email and password" guidance; any attempted social login fails with a clear provider-unavailable message (not a generic error); password login is unaffected; the degradation is visible in provider health monitoring.
**Priority:** Medium

### TC-SA-01-01-077 — Social logins logged with provider, outcome, and account
**Type:** Positive
**Covers:** 1.3 → Rule: all social logins logged with provider, outcome, and account
**Preconditions:** Social logins produced (success and failure); log access available.
**Steps:**
1. Produce one successful and one failed social login.
2. Locate both events in the login activity log.
3. Inspect the recorded fields.
**Expected Result:** Each event records the provider (Google/Facebook), the outcome (success/failure), and the account; the events are filterable by method "Social"; the context (timestamp, IP, device) is present.
**Priority:** High

### TC-SA-01-01-078 — Social logins subject to lockout and IP policies
**Type:** Negative
**Covers:** 1.3 → Rule: social logins subject to the same lockout and IP policies
**Preconditions:** A social-enabled account; a deny-listed IP; the lockout threshold known.
**Steps:**
1. Attempt repeated failed social logins until the lockout threshold.
2. Observe the lockout applying to the social method.
3. Attempt a social login from the deny-listed IP.
**Expected Result:** The lockout applies to social logins exactly as to password logins (the account locks after the threshold); the deny-listed IP is rejected for social logins and logged as an IP-block event; no login method bypasses the access-control policies.
**Priority:** Critical

### TC-SA-01-01-079 — Provider data stored per privacy policy and visible in export
**Type:** Positive
**Covers:** 1.3 → Rule: provider data stored per privacy policy, visible in profile data export
**Preconditions:** An account created/linked via a social provider (name, email, picture received).
**Steps:**
1. Open the account's profile data.
2. Run the user's data export (portability).
3. Inspect the export for the provider-sourced fields.
**Expected Result:** The provider-sourced data (name, email, picture) is stored and is visible in the profile data export; the stored data matches what the provider supplied; the storage and export comply with the privacy policy (only the documented fields, no excess provider data retained).
**Priority:** Medium

## 1.4 Single Sign-On (SSO) for Enterprise and Institute Integrations

### TC-SA-01-01-080 — Configure an SSO integration and pass test connection
**Type:** Positive
**Covers:** 1.4 → SSO integration setup with test-connection validation
**Preconditions:** Super Admin access to System Settings → Integrations → SSO; a test identity provider available.
**Steps:**
1. Select "New SSO integration".
2. Enter the organization name and the identity provider's connection details.
3. Run the test-connection check.
4. Save and activate the integration.
**Expected Result:** The test-connection check validates the configuration and shows a success result; the integration is saved and activated; the organization's users see "Continue with [Institute]" at the login entry; the configuration change is audit-logged.
**Priority:** Critical

### TC-SA-01-01-081 — Failed test connection is reported clearly
**Type:** Negative
**Covers:** 1.4 → Test-connection validation (failure path)
**Preconditions:** An SSO integration form with deliberately invalid connection details.
**Steps:**
1. Enter invalid identity provider connection details.
2. Run the test-connection check.
3. Observe the result and the ability to activate.
**Expected Result:** The check shows a failure result with a clear indication of what failed; the integration cannot be activated while the test connection fails; the failed test is logged.
**Priority:** High

### TC-SA-01-01-082 — SSO identity scoped to its own organization
**Type:** Negative
**Covers:** 1.4 → Organization scoping
**Preconditions:** Two organizations (A and B) each with their own SSO integration; a user identity from organization A.
**Steps:**
1. Attempt to use organization A's identity to access organization B's portal entry.
2. Attempt to use organization A's identity to reach platform staff areas.
**Expected Result:** Both are denied: an identity from one organization's provider can never authenticate into another organization's users or into platform staff roles; the denials are logged with the organization context.
**Priority:** Critical

### TC-SA-01-01-083 — Role mapping applied to SSO users
**Type:** Positive
**Covers:** 1.4 → Role mapping
**Preconditions:** An active SSO integration with role mapping configured (staff group → Teacher, admin contact → Institute Administrator, students → Student).
**Steps:**
1. Log in via SSO as a member of the staff group; record the assigned role.
2. Log in via SSO as the admin contact; record the assigned role.
3. Log in via SSO as a student; record the assigned role.
**Expected Result:** Each user receives exactly the mapped role (Teacher, Institute Administrator, Student respectively); the mapping is visible on the integration configuration screen; role assignment events are logged.
**Priority:** Critical

### TC-SA-01-01-084 — Just-in-time provisioning on first SSO login
**Type:** Positive
**Covers:** 1.4 → Just-in-time provisioning
**Preconditions:** An active SSO integration with JIT creation enabled; a user who has never logged in.
**Steps:**
1. Have the user perform their first SSO login.
2. Observe the account creation and role assignment.
3. Observe the required-field prompt (e.g., phone) on first login.
4. Inspect the provisioning event in the SSO activity view.
**Expected Result:** The platform account is created automatically using the mapped attributes; the mapped role is assigned; required fields are prompted on first login; the user lands on their panel; the provisioning event is visible in the SSO activity view and audit-logged.
**Priority:** Critical

### TC-SA-01-01-085 — De-provisioning suspends the account on removal
**Type:** Edge
**Covers:** 1.4 → De-provisioning
**Preconditions:** An SSO-provisioned account; the organization removes the user from its directory; de-provisioning policy = suspend on removal.
**Steps:**
1. Remove the user from the organization's directory.
2. Have the user attempt an SSO login.
3. Inspect the platform account state and the activity view.
**Expected Result:** The SSO login fails; per policy the platform account is suspended; the de-provisioning event appears in the SSO activity view; the suspension is confirmable in the user directory; the event is audit-logged.
**Priority:** Critical

### TC-SA-01-01-086 — SSO sessions follow standard session policies
**Type:** Positive
**Covers:** 1.4 → Session behavior: same session policies
**Preconditions:** An active SSO integration; session policies configured (timeout, concurrency).
**Steps:**
1. Log in via SSO and remain idle beyond the idle timeout; attempt an action.
2. Log in via SSO from a second device beyond the concurrency limit.
**Expected Result:** The idle SSO session terminates per the timeout policy; the concurrency limit is enforced for SSO sessions exactly as for other sessions; no session policy is bypassed by the SSO method.
**Priority:** High

### TC-SA-01-01-087 — Federated logout ends the organizational session too
**Type:** Positive
**Covers:** 1.4 → Logout can be local or federated
**Preconditions:** An active SSO session; federated logout configured for the integration.
**Steps:**
1. Log in via SSO.
2. Log out from the platform.
3. Attempt to access the organization's identity provider session directly.
**Expected Result:** The federated logout ends both the platform session and the organizational session; the direct access to the provider session is denied (re-authentication required); the logout is logged. With local-only logout configured, only the platform session ends (verified as the alternate configuration).
**Priority:** High

### TC-SA-01-01-088 — Provider outage blocks SSO login with clear notice
**Type:** Edge
**Covers:** 1.4 → Fallback policy: provider unreachable → blocked with notice
**Preconditions:** An active SSO integration; the identity provider made unreachable; the organization has NOT opted into password fallback.
**Steps:**
1. Attempt an SSO login during the outage.
2. Read the notice shown.
3. Check the provider-health alert in the SSO monitoring view.
**Expected Result:** The SSO login is blocked (fail closed) with the notice "Single sign-on is temporarily unavailable. Please try again later."; no fallback login is offered (the organization did not opt in); the provider-health alert is visible to the Super Admin; the blocked attempts are logged.
**Priority:** Critical

### TC-SA-01-01-089 — Opted-in organization gets password fallback during outage
**Type:** Edge
**Covers:** 1.4 → Fallback policy: platform password fallback only if opted in
**Preconditions:** An active SSO integration whose organization opted into platform-password fallback; the identity provider unreachable; the users have platform passwords.
**Steps:**
1. Attempt an SSO login during the outage.
2. Observe the fallback offer.
3. Complete a platform-password login for the organization's user.
**Expected Result:** The SSO attempt shows the outage notice plus the fallback option; the platform-password login succeeds for the opted-in organization's users; the fallback usage is logged and distinguishable from normal SSO logins.
**Priority:** High

### TC-SA-01-01-090 — Admin monitoring shows SSO activity, provisioning, and health
**Type:** Positive
**Covers:** 1.4 → Admin monitoring per integration
**Preconditions:** SSO logins, provisioning events, and a provider health change have occurred.
**Steps:**
1. Open the SSO monitoring view for the integration.
2. Review login activity, provisioning events, and provider health.
3. Verify each against known events.
**Expected Result:** The view shows SSO login activity, provisioning/de-provisioning events, and provider health per integration; the data matches the actual events; the view supports the quarterly-review export.
**Priority:** Medium

### TC-SA-01-01-091 — All SSO configuration changes and provisioning events audit-logged
**Type:** Positive
**Covers:** 1.4 → Audit logging of all SSO configuration changes and provisioning events
**Preconditions:** SSO configuration changes and provisioning/de-provisioning events produced; audit log access.
**Steps:**
1. Make a configuration change (e.g., edit role mapping).
2. Produce a provisioning event and a de-provisioning event.
3. Locate all three in the audit log and inspect their fields.
**Expected Result:** All three events are audit-logged with actor and timestamp; configuration changes show what changed and who changed it; provisioning/de-provisioning events show the user, organization, and outcome; the log is exportable.
**Priority:** High

### TC-SA-01-01-092 — Organization identity cannot reach platform staff roles
**Type:** Negative
**Covers:** 1.4 → Rule: SSO identity never authenticates into platform staff roles
**Preconditions:** An active SSO integration; an organization user identity.
**Steps:**
1. Attempt to use the organization identity to access any platform staff role or area.
2. Attempt to craft/impersonate a staff-role assertion from the organization provider.
**Expected Result:** All attempts are denied: organization SSO covers the organization's own users only; no staff role is reachable via an organization provider; the denials are logged with the organization and role context.
**Priority:** Critical

### TC-SA-01-01-093 — Platform staff cannot authenticate via organization SSO
**Type:** Negative
**Covers:** 1.4 → Rule: platform staff never authenticate via an organization's SSO
**Preconditions:** A Super Admin (platform staff) account; an active organization SSO integration.
**Steps:**
1. Attempt to log in as the Super Admin using the organization's SSO entry.
2. Observe the result.
**Expected Result:** The attempt is denied: platform staff (Super Admin and internal roles) never authenticate via an organization's SSO; the Super Admin must use the platform's own authentication (email/password + 2FA); the denied attempt is logged.
**Priority:** Critical

### TC-SA-01-01-094 — Unmapped organizational group yields restricted account flagged for review
**Type:** Edge
**Covers:** 1.4 → Rule: unmapped group → denied or default-restricted account flagged for admin review
**Preconditions:** An active SSO integration; an organizational group with no role mapping.
**Steps:**
1. Have a user in the unmapped group perform an SSO login.
2. Observe the account state and role.
3. Check the admin review queue for the flag.
**Expected Result:** The user does not receive a silent grant of access: the account is denied or created with default-restricted permissions; the case is flagged for admin review in the queue; the event is audit-logged; after the admin maps the group, subsequent logins receive the mapped role.
**Priority:** Critical

### TC-SA-01-01-095 — De-provisioning suspends (not deletes) and is reversible
**Type:** Edge
**Covers:** 1.4 → Rule: de-provisioning suspends so data is retained and reversible
**Preconditions:** An SSO-provisioned account with data; the organization removes then re-adds the user.
**Steps:**
1. Remove the user from the organization directory; confirm the platform account is suspended.
2. Verify the account's data is retained (not deleted).
3. Re-add the user to the organization directory and have them log in via SSO.
**Expected Result:** The suspension retains all account data; after re-addition the SSO login succeeds and the account is re-activated with its prior data intact; both the suspension and re-activation are audit-logged; no data loss occurs at any point.
**Priority:** High

### TC-SA-01-01-096 — Non-opted-in organization fails closed on provider outage
**Type:** Edge
**Covers:** 1.4 → Rule: fail closed unless the organization explicitly opted into fallback
**Preconditions:** Two organizations: one opted into fallback, one not; the provider outage affects both.
**Steps:**
1. During the outage, attempt SSO login for a user of the non-opted-in organization.
2. During the same outage, attempt SSO login for a user of the opted-in organization.
3. Compare the two outcomes.
**Expected Result:** The non-opted-in user is hard-blocked with the unavailable notice and no fallback; the opted-in user is offered the platform-password fallback; the distinction is enforced strictly per organization and logged.
**Priority:** Critical

### TC-SA-01-01-097 — SSO audit entries carry actor and timestamp
**Type:** Positive
**Covers:** 1.4 → Rule: all SSO events audit-logged with actor and timestamp
**Preconditions:** SSO events produced by a known admin actor at known times.
**Steps:**
1. Produce a configuration change, a provisioning event, and a de-provisioning event.
2. Inspect each audit entry's actor and timestamp fields.
**Expected Result:** Every entry records the actor (the admin or system process responsible) and an accurate timestamp; system-initiated events (e.g., automatic de-provisioning) are attributed to the system with the triggering context; no entry lacks either field.
**Priority:** High

### TC-SA-01-01-098 — SSO sessions subject to timeouts and concurrency
**Type:** Edge
**Covers:** 1.4 → Rule: SSO sessions subject to the same session policies
**Preconditions:** An active SSO integration; idle timeout and concurrency limits configured.
**Steps:**
1. Create an SSO session and let it idle past the timeout; attempt an action.
2. Create SSO sessions on two devices for the same user beyond the concurrency limit.
**Expected Result:** The idle SSO session is terminated per policy (re-authentication required); the concurrency limit is enforced for SSO sessions; enforcement is identical to non-SSO sessions; the terminations are logged.
**Priority:** High
