# 6. IP-Based Access Control — Test Cases

User Type: **Super Administrator**
Source: *Mi Digital Academy - Education CRM Features Document*
Spec: ip_based_access_control.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 |
|---------|--------------------|----------|
| 6.1 IP Allow/Deny Lists | Create allow lists and deny lists | TC-SA-01-06-001 |
| 6.1 IP Allow/Deny Lists | Single IPs and CIDR ranges | TC-SA-01-06-002 |
| 6.1 IP Allow/Deny Lists | Scope per list: global or per role | TC-SA-01-06-003 |
| 6.1 IP Allow/Deny Lists | Entry management: add, edit, remove with description and optional expiry | TC-SA-01-06-004 |
| 6.1 IP Allow/Deny Lists | Precedence: deny over allow when both match | TC-SA-01-06-005 |
| 6.1 IP Allow/Deny Lists | Immediate effect on new logins; optional enforcement on existing sessions | TC-SA-01-06-006 |
| 6.1 IP Allow/Deny Lists | Hit logging | TC-SA-01-06-007 |
| 6.1 IP Allow/Deny Lists | List health view | TC-SA-01-06-008 |
| 6.1 IP Allow/Deny Lists | Audit logging of all list changes | TC-SA-01-06-009 |
| 6.1 IP Allow/Deny Lists | Rule: a deny always wins | TC-SA-01-06-010 |
| 6.1 IP Allow/Deny Lists | Rule: role-scoped allow-list lockout surfaced in the block message | TC-SA-01-06-011 |
| 6.1 IP Allow/Deny Lists | Rule: every block logged with IP, user (if known), and triggering entry | TC-SA-01-06-012 |
| 6.1 IP Allow/Deny Lists | Rule: optional expiry so temporary allowances do not become permanent | TC-SA-01-06-013 |
| 6.1 IP Allow/Deny Lists | Rule: list changes audit-logged with acting admin and entry details | TC-SA-01-06-014 |
| 6.1 IP Allow/Deny Lists | Rule: enforcement on existing sessions is optional (default: new logins only) | TC-SA-01-06-015 |
| 6.2 Location-Based Access Restrictions | Block or allow access by country/region | TC-SA-01-06-016 |
| 6.2 Location-Based Access Restrictions | Per-role location policies | TC-SA-01-06-017 |
| 6.2 Location-Based Access Restrictions | Velocity checks (impossible travel) | TC-SA-01-06-018 |
| 6.2 Location-Based Access Restrictions | User notification when a login is blocked by location policy | TC-SA-01-06-019 |
| 6.2 Location-Based Access Restrictions | Admin review queue of blocked and velocity-flagged attempts | TC-SA-01-06-020 |
| 6.2 Location-Based Access Restrictions | Configurable: velocity alerts as review items or automatic blocks | TC-SA-01-06-021 |
| 6.2 Location-Based Access Restrictions | Logging of all location-based blocks and velocity flags | TC-SA-01-06-022 |
| 6.2 Location-Based Access Restrictions | Rule: country/region level, not city level | TC-SA-01-06-023 |
| 6.2 Location-Based Access Restrictions | Rule: velocity alerts are review items by default, not automatic blocks | TC-SA-01-06-024 |
| 6.2 Location-Based Access Restrictions | Rule: a location block is always communicated with reason and support path | TC-SA-01-06-025 |
| 6.2 Location-Based Access Restrictions | Rule: temporary exceptions time-boxed, audit-logged, auto-expiring | TC-SA-01-06-026 |
| 6.2 Location-Based Access Restrictions | Rule: blocks and flags logged and visible in the admin security dashboard | TC-SA-01-06-027 |
| 6.2 Location-Based Access Restrictions | Rule: policy changes apply to new logins; no retroactive termination | TC-SA-01-06-028 |
| 6.3 Geo-Restrictions | Platform-level geo availability | TC-SA-01-06-029 |
| 6.3 Geo-Restrictions | Content-level geo-restrictions | TC-SA-01-06-030 |
| 6.3 Geo-Restrictions | Enforcement at access time based on current IP (server-side) | TC-SA-01-06-031 |
| 6.3 Geo-Restrictions | Clear messaging when access is geo-blocked | TC-SA-01-06-032 |
| 6.3 Geo-Restrictions | Admin configuration of restriction lists per item or category | TC-SA-01-06-033 |
| 6.3 Geo-Restrictions | Geo-block hit statistics | TC-SA-01-06-034 |
| 6.3 Geo-Restrictions | Logging of all geo-block events for licensing compliance | TC-SA-01-06-035 |
| 6.3 Geo-Restrictions | Integration with content management | TC-SA-01-06-036 |
| 6.3 Geo-Restrictions | Rule: checks at access time; availability changes as the user's region changes | TC-SA-01-06-037 |
| 6.3 Geo-Restrictions | Rule: server-side enforcement; no client-side bypass or URL guessing | TC-SA-01-06-038 |
| 6.3 Geo-Restrictions | Rule: a geo-block affects only the restricted content, not the account | TC-SA-01-06-039 |
| 6.3 Geo-Restrictions | Rule: geo-block events logged with item, user, region, timestamp | TC-SA-01-06-040 |
| 6.3 Geo-Restrictions | Rule: restriction changes audit-logged with acting admin and licensing reference | TC-SA-01-06-041 |
| 6.3 Geo-Restrictions | Rule: category + item restrictions → the stricter (union) applies | TC-SA-01-06-042 |

## 6.1 IP Allow/Deny Lists

### TC-SA-01-06-001 — Create allow lists and deny lists
**Type:** Positive
**Covers:** 6.1 → Create allow lists (only listed IPs may access) and deny lists (listed IPs are blocked)
**Preconditions:** Super Admin access to System Settings → Security Policy → IP Access Control; test IPs available.
**Steps:**
1. Create a deny list with a test IP and verify a login from that IP is blocked.
2. Create an allow list (global) with a single trusted IP and verify only that IP may access.
3. Verify both list types appear in the IP Access Control screen with their entries.
**Expected Result:** The deny list blocks the listed IP (login refused); the allow list restricts access to only the listed IPs (others refused); both list types are created, visible, and functional; the creation is audit-logged.
**Priority:** Critical

### TC-SA-01-06-002 — Single IPs and CIDR ranges supported
**Type:** Positive
**Covers:** 6.1 → Support for single IPs and CIDR ranges
**Preconditions:** The IP Access Control screen; a single test IP and a test CIDR range with multiple source IPs.
**Steps:**
1. Add a single-IP entry and verify a login from exactly that IP is affected.
2. Add a CIDR range entry and verify logins from multiple IPs within the range are affected.
3. Verify an IP just outside the range is not affected.
**Expected Result:** The single-IP entry matches exactly that IP; the CIDR entry matches all IPs within the range (and the boundary IP just outside is not matched); both entry types are validated on entry (malformed CIDR rejected); the matches are logged.
**Priority:** High

### TC-SA-01-06-003 — Scope per list: global or per role
**Type:** Positive
**Covers:** 6.1 → Scope per list: global, or restricted to specific roles
**Preconditions:** The IP Access Control screen; roles (e.g., Billing Administrator, Super Admin) and a standard user role.
**Steps:**
1. Create a global deny entry and verify it blocks all roles from that IP.
2. Create an allow list scoped to the Billing Administrator and Super Admin roles with an office range.
3. Log in from the office IP as a privileged role (allowed) and as a standard role (not scoped — verify behavior).
4. Log in from a non-office IP as a privileged role (blocked by the scoped allow list).
**Expected Result:** The global entry applies to all roles; the role-scoped allow list applies only to the scoped roles (privileged roles must be on a listed IP; non-scoped roles are unaffected by that list); the scoping matches the configuration exactly; the effects are logged.
**Priority:** High

### TC-SA-01-06-004 — Entry management: add, edit, remove with description and optional expiry
**Type:** Positive
**Covers:** 6.1 → Entry management: add, edit, remove entries, each with a description and optional expiry
**Preconditions:** The IP Access Control screen; an existing entry to edit/remove.
**Steps:**
1. Add an entry with a description and an expiry; verify both are stored.
2. Edit the entry (change the range, description, expiry); verify the edit applies.
3. Remove the entry; verify it no longer takes effect.
4. Add an entry with no expiry; verify it persists.
**Expected Result:** Add/edit/remove all work; the description and optional expiry are stored and displayed; the edited entry takes effect immediately; the removed entry stops taking effect; the no-expiry entry persists; all changes are audit-logged.
**Priority:** High

### TC-SA-01-06-005 — Precedence: deny lists take precedence over allow lists
**Type:** Negative
**Covers:** 6.1 → Precedence rule: deny lists take precedence over allow lists when both match
**Preconditions:** An IP that appears in both an allow list and a deny list.
**Steps:**
1. Configure an IP in both an allow list and a deny list.
2. Attempt a login from that IP.
3. Observe the outcome.
**Expected Result:** The login is blocked (the deny wins); the allow entry does not override the deny; the block is logged with the triggering deny entry; the precedence is consistent regardless of entry order or creation time.
**Priority:** Critical

### TC-SA-01-06-006 — Immediate effect on new logins; optional enforcement on existing sessions
**Type:** Positive
**Covers:** 6.1 → Immediate effect on new login attempts; optional enforcement on existing sessions
**Preconditions:** An active session from an IP to be denied; the IP Access Control screen.
**Steps:**
1. Add a deny entry for the IP (default enforcement — new logins only).
2. Attempt a new login from that IP (blocked).
3. Verify the existing session still works (default does not cut it off).
4. Re-configure with enforcement on existing sessions and verify the existing session is cut off.
**Expected Result:** The deny takes effect immediately for new login attempts; by default the existing session is not cut off; with the optional enforcement enabled, the existing session from the newly-denied IP is cut off; both behaviors match the configuration; the effects are logged.
**Priority:** High

### TC-SA-01-06-007 — Hit logging: which entries trigger, how often, by which IPs/users
**Type:** Positive
**Covers:** 6.1 → Hit logging: which list entries are being triggered, how often, by which IPs/users
**Preconditions:** Active list entries; traffic producing hits; the hit log view.
**Steps:**
1. Generate hits on several list entries (from known IPs, some with known users).
2. Open the hit log.
3. Verify per-entry hit counts, frequency, and the triggering IPs/users.
**Expected Result:** The hit log shows which entries are being triggered, how often, and by which IPs/users; the counts match the actual traffic; the data supports tuning (identifying over- or under-used entries); the log is refreshable.
**Priority:** Medium

### TC-SA-01-06-008 — List health view: zero-hit and heavily-hit entries
**Type:** Positive
**Covers:** 6.1 → List health view: entries with zero hits (removal candidates) and heavily-hit entries
**Preconditions:** Entries with zero hits and entries with many hits; the list health view.
**Steps:**
1. Open the list health view.
2. Verify zero-hit entries are surfaced as removal candidates.
3. Verify heavily-hit entries are surfaced.
4. Act on a zero-hit entry (remove) and a near-expiry entry (renew or let lapse).
**Expected Result:** The health view distinguishes zero-hit entries (candidates for removal) from heavily-hit entries; the data matches the hit log; the view supports the monthly review (remove stale, renew or lapse expiring); the actions are audit-logged.
**Priority:** Medium

### TC-SA-01-06-009 — Audit logging of all list changes
**Type:** Positive
**Covers:** 6.1 → Audit logging of all list changes
**Preconditions:** List changes (add/edit/remove) produced; audit log access.
**Steps:**
1. Produce add, edit, and remove changes across entries.
2. Locate all of them in the audit log.
3. Inspect the acting admin, entry details, and timestamp on each.
**Expected Result:** Every list change is audit-logged with the acting admin, the entry details (before/after where relevant), and the timestamp; no change is missing; the log is exportable for the security audit evidence package.
**Priority:** High

### TC-SA-01-06-010 — A deny always wins over an allow
**Type:** Negative
**Covers:** 6.1 → Rule: deny lists take precedence over allow lists — a deny always wins
**Preconditions:** Multiple IPs each present in both an allow and a deny entry (different lists, roles, and scopes).
**Steps:**
1. For each overlapping IP, attempt a login.
2. Observe the outcome in each case (global vs role-scoped overlaps).
**Expected Result:** In every overlap the deny wins (the login is blocked); the precedence holds across global and role-scoped lists and regardless of which list was created first; every block is logged with the triggering deny entry.
**Priority:** Critical

### TC-SA-01-06-011 — Role-scoped allow-list lockout surfaced in the block message
**Type:** Edge
**Covers:** 6.1 → Rule: a role-scoped allow list that excludes the user's IP blocks the next login; surfaced in the block message
**Preconditions:** A privileged user working from a non-listed IP (e.g., remote from home); a role-scoped allow list for their role.
**Steps:**
1. Have the privileged user attempt a login from the non-listed IP.
2. Read the block message.
3. Verify the message explains the cause (role-scoped allow list) and the path to resolution.
**Expected Result:** The login is blocked (the user's IP is not on the role-scoped allow list); the block message surfaces the cause (not a generic failure) so the "why am I locked out?" case is explained; the message points to the resolution (be on a listed IP or contact support to adjust the rule); the block is logged.
**Priority:** High

### TC-SA-01-06-012 — Every block logged with IP, user (if known), and triggering entry
**Type:** Positive
**Covers:** 6.1 → Rule: every block event logged with the IP, the user (if known), and the specific list entry
**Preconditions:** Block events produced (some with known users, some anonymous); the block log.
**Steps:**
1. Generate blocks from known-user logins and anonymous attempts.
2. Locate all blocks in the log.
3. Verify IP, user (where known), and the specific triggering list entry on each.
**Expected Result:** Every block event is logged with the IP, the user (where the attempt identified one), and the specific list entry that triggered it; anonymous attempts show the IP and entry with no user; no block is missing; the log supports verifying the lists are working.
**Priority:** High

### TC-SA-01-06-013 — Optional expiry: temporary allowances do not become permanent
**Type:** Edge
**Covers:** 6.1 → Rule: entries support optional expiry so temporary allowances do not become permanent
**Preconditions:** A temporary allow entry with a short expiry (e.g., 7 days for remote work).
**Steps:**
1. Add the temporary allow entry with the expiry.
2. Verify the allowance works before the expiry.
3. Let the expiry elapse and verify the entry no longer takes effect.
4. Verify the expiry is visible in the entry and the health view.
**Expected Result:** The temporary allowance works until the expiry; after the expiry the entry automatically stops taking effect (the user is locked out again if off-list); the expiry is visible on the entry and in the list health view; the lapse is logged; no temporary allowance becomes permanent.
**Priority:** High

### TC-SA-01-06-014 — List changes audit-logged with acting admin and entry details
**Type:** Positive
**Covers:** 6.1 → Rule: changes to lists audit-logged with the acting admin and the entry details
**Preconditions:** Multiple list changes by different admins; audit log access.
**Steps:**
1. Produce add/edit/remove changes by two different admins.
2. Locate all entries in the audit log.
3. Verify the acting admin and the entry details on each.
**Expected Result:** Every change is audit-logged with the acting admin (distinguishing which admin made it) and the full entry details (IP/range, scope, description, expiry, before/after); no change lacks its actor or details; the log is exportable.
**Priority:** High

### TC-SA-01-06-015 — Enforcement on existing sessions is optional
**Type:** Edge
**Covers:** 6.1 → Rule: by default lists gate new logins; an admin can choose to also cut off existing sessions from a newly-denied IP
**Preconditions:** An active session from an IP to be denied; both enforcement settings to test.
**Steps:**
1. Deny the IP with default enforcement; verify the existing session persists and a new login is blocked.
2. Deny another IP (with an active session) with enforcement on existing sessions; verify the existing session is cut off.
3. Verify the setting is explicit per action (not a hidden global).
**Expected Result:** Default behavior gates only new logins (existing sessions persist); the optional enforcement, when chosen, also cuts off existing sessions from the newly-denied IP; the choice is explicit and visible; both behaviors are logged with the enforcement mode used.
**Priority:** High

## 6.2 Location-Based Access Restrictions

### TC-SA-01-06-016 — Block or allow access by country/region
**Type:** Positive
**Covers:** 6.2 → Block or allow access by country/region
**Preconditions:** Super Admin access to System Settings → Security Policy → Location Restrictions; test sources in allowed and disallowed countries.
**Steps:**
1. Configure an allowed-region policy (e.g., the operating country).
2. Attempt a login from within the allowed country (allowed).
3. Attempt a login from outside the allowed country (blocked).
4. Verify the boundary (a neighboring country is blocked).
**Expected Result:** Logins from within the allowed country/region succeed; logins from outside are blocked; the boundary is at country/region level; the block is communicated to the user and logged; the configuration is audit-logged.
**Priority:** Critical

### TC-SA-01-06-017 — Per-role location policies
**Type:** Positive
**Covers:** 6.2 → Per-role location policies (e.g., admin roles restricted to the operating country)
**Preconditions:** The Location Restrictions screen; privileged and standard roles; test sources in and out of the operating country.
**Steps:**
1. Restrict privileged roles (Super Admin, Billing Administrator, staff) to the operating country.
2. Log in from the operating country as a privileged role (allowed) and as a standard role (verify its policy).
3. Log in from abroad as a privileged role (blocked) and as a standard role (per its policy).
**Expected Result:** The privileged roles are restricted to the operating country (abroad logins blocked); standard roles follow their own (possibly looser) policy; the per-role scoping matches the configuration; the blocks are communicated and logged.
**Priority:** High

### TC-SA-01-06-018 — Velocity checks flag impossible-travel logins
**Type:** Positive
**Covers:** 6.2 → Velocity checks: flag logins from vastly different locations within a short window
**Preconditions:** Velocity checks enabled with a threshold (e.g., two continents in 60 minutes); an account to test.
**Steps:**
1. Log in successfully from location A (continent 1).
2. Within the window, log in successfully from location B (continent 2).
3. Observe the velocity flag/alert.
4. Verify the alert details (both events, devices, IPs, methods).
**Expected Result:** The two logins from vastly different locations within the window raise a velocity flag (a critical alert per the threshold); the alert shows both login events with devices, IPs, and methods; the flag is a review item (not a silent block by default); the flag is logged.
**Priority:** Critical

### TC-SA-01-06-019 — User notification when a login is blocked by location policy
**Type:** Positive
**Covers:** 6.2 → User notification when a login is blocked by location policy, with the reason and support contact
**Preconditions:** A location policy that will block a login; a user in a disallowed location.
**Steps:**
1. Have the user attempt a login from the disallowed location.
2. Read the block message.
3. Verify the reason and the support contact are present.
**Expected Result:** The user sees a clear message (e.g., "Access from your current location is not permitted for your role. Contact support if this is unexpected."); the reason (location policy) and a support contact/path are included; the block is not a dead-end; the block is logged.
**Priority:** High

### TC-SA-01-06-020 — Admin review queue of blocked and velocity-flagged attempts
**Type:** Positive
**Covers:** 6.2 → Admin review queue of location-blocked and velocity-flagged login attempts
**Preconditions:** Location-blocked and velocity-flagged attempts produced; the review queue.
**Steps:**
1. Generate several location blocks and velocity flags.
2. Open the admin review queue.
3. Verify each item is present with its details and an action path.
4. Action an item (e.g., grant a temporary exception, resolve a flag) and verify it is marked actioned.
**Expected Result:** The queue lists all location-blocked and velocity-flagged attempts with details (user, location, time, method); each item has an action path (exception, resolve, escalate); actioned items are marked; the queue supports the weekly review; the actions are logged.
**Priority:** High

### TC-SA-01-06-021 — Configurable: velocity alerts as review items or automatic blocks
**Type:** Positive
**Covers:** 6.2 → Configurable: velocity alerts as review items or (optionally) automatic blocks
**Preconditions:** The velocity configuration screen; an account to test.
**Steps:**
1. With the default (review items), trigger a velocity event and verify it is flagged, not blocked.
2. Switch to automatic blocks and trigger a velocity event; verify the login is blocked.
3. Verify the setting is explicit and the change is audit-logged.
**Expected Result:** In review-item mode the velocity event raises a flag (the login is not auto-blocked); in automatic-block mode the velocity event blocks the login; the setting is explicit and configurable; the mode change is audit-logged; the events are logged in both modes.
**Priority:** High

### TC-SA-01-06-022 — Logging of all location-based blocks and velocity flags
**Type:** Positive
**Covers:** 6.2 → Logging of all location-based blocks and velocity flags
**Preconditions:** Location blocks and velocity flags produced; log access.
**Steps:**
1. Produce several location blocks and velocity flags.
2. Locate all of them in the log.
3. Inspect user, location, time, and type on each.
**Expected Result:** Every location-based block and velocity flag is logged with user, location(s), timestamp, and type (block vs flag); no event is missing; the log is exportable and feeds the admin security dashboard.
**Priority:** High

### TC-SA-01-06-023 — Rules applied at country/region level, not city level
**Type:** Edge
**Covers:** 6.2 → Rule: location approximate; rules applied at country/region level, not city level
**Preconditions:** A location policy; a source whose IP geolocation is imprecise (city-level ambiguity within an allowed country).
**Steps:**
1. Attempt a login from a source whose IP resolves to a city within the allowed country but with imprecise geolocation.
2. Observe the outcome.
3. Verify no city-level rule exists or is applied.
**Expected Result:** The login is evaluated at country/region level (the imprecise city-level geolocation does not cause a false block within the allowed country); no city-level rule is applied; the approximation is consistent with the IP-derived location; the outcome is logged.
**Priority:** Medium

### TC-SA-01-06-024 — Velocity alerts are review items by default, not automatic blocks
**Type:** Negative
**Covers:** 6.2 → Rule: VPN/NAT can shift location; velocity alerts are review items by default, not automatic blocks
**Preconditions:** Velocity checks enabled in the default (review-item) mode; a user on a VPN/mobile NAT that shifts apparent location.
**Steps:**
1. Have the user log in via a VPN that shifts the apparent location, then again from their normal location within the window.
2. Observe the velocity flag.
3. Verify the login was NOT automatically blocked (default mode).
**Expected Result:** The shifted-location logins raise a velocity flag (a review item); the logins are not automatically blocked in the default mode (the VPN/NAT false-positive case is handled by review, not a hard block); the flag is logged and appears in the review queue; the admin can resolve it as a false positive.
**Priority:** High

### TC-SA-01-06-025 — A location block is always communicated with reason and support path
**Type:** Positive
**Covers:** 6.2 → Rule: a location block is always communicated to the user with the reason and a support path
**Preconditions:** Multiple location blocks produced (different roles, different disallowed locations).
**Steps:**
1. Generate several location blocks.
2. For each, read the user-facing message.
3. Verify the reason and support path are present in every case.
**Expected Result:** Every location block is communicated to the user with the reason (location policy for their role) and a support path; no block is silent or a dead-end; legitimate travel can be resolved via support (temporary exception); every block is logged.
**Priority:** High

### TC-SA-01-06-026 — Temporary location exceptions: time-boxed, audit-logged, auto-expiring
**Type:** Edge
**Covers:** 6.2 → Rule: temporary location exceptions are time-boxed and audit-logged; they expire automatically
**Preconditions:** A user traveling abroad (blocked by the location policy); a temporary exception to grant.
**Steps:**
1. Grant a temporary location exception for the user with an expiry matching the trip.
2. Verify the user can log in from abroad during the exception.
3. Let the expiry elapse and verify the exception no longer applies.
4. Inspect the audit entry for the exception.
**Expected Result:** The exception allows the abroad login while active; it expires automatically at the time-box (the user is blocked again afterward); the exception is audit-logged (user, location, expiry, acting admin); the lapse is logged; no exception persists beyond its time-box.
**Priority:** High

### TC-SA-01-06-027 — Blocks and flags logged and visible in the admin security dashboard
**Type:** Positive
**Covers:** 6.2 → Rule: all location-based blocks and velocity flags are logged and visible in the admin security dashboard
**Preconditions:** Location blocks and velocity flags produced; the admin security dashboard.
**Steps:**
1. Generate several blocks and flags.
2. Open the admin security dashboard.
3. Verify each is visible with its details.
4. Drill into one and verify the full event.
**Expected Result:** All location-based blocks and velocity flags are visible in the admin security dashboard; each shows its details (user, location, time, type); drilling in shows the full event; the dashboard data matches the log; the items support the weekly review.
**Priority:** Medium

### TC-SA-01-06-028 — Policy changes apply to new logins; no retroactive termination
**Type:** Edge
**Covers:** 6.2 → Rule: location policy changes apply to new login attempts; no retroactive termination of existing sessions
**Preconditions:** An active session from a location that will become disallowed; a policy change to make.
**Steps:**
1. Note the active session's location.
2. Change the location policy to disallow that location and save.
3. Verify the existing session is not terminated.
4. Attempt a new login from that location (blocked).
**Expected Result:** The existing session is not retroactively terminated (it continues until it ends naturally or an admin explicitly terminates it); the new login from the now-disallowed location is blocked; the policy change applies to new login attempts; the change is audit-logged.
**Priority:** High

## 6.3 Geo-Restrictions

### TC-SA-01-06-029 — Platform-level geo availability
**Type:** Positive
**Covers:** 6.3 → Platform-level geo availability: the set of countries/regions where the service operates
**Preconditions:** Super Admin access to the platform-level geo availability configuration; test sources in operating and non-operating countries.
**Steps:**
1. Review the operating-country list.
2. Attempt platform access from an operating country (available).
3. Attempt platform access from a non-operating country (unavailable).
4. Update the list to add a new country and verify access there.
**Expected Result:** The platform is available in the operating countries and unavailable in non-operating countries; the operating-country list is reviewable and updatable; adding a country makes the platform available there immediately; the change is audit-logged.
**Priority:** High

### TC-SA-01-06-030 — Content-level geo-restrictions
**Type:** Positive
**Covers:** 6.3 → Content-level geo-restrictions: specific content items or categories unavailable in certain regions
**Preconditions:** A content item to restrict; test sources in licensed and restricted regions.
**Steps:**
1. Set a geo-restriction on the content item (restricted regions).
2. Attempt to access the content from a licensed region (available).
3. Attempt to access it from a restricted region (blocked with the message).
4. Verify the rest of the platform remains usable in the restricted region.
**Expected Result:** The content is available in the licensed region and geo-blocked in the restricted regions; the block shows the clear message; the rest of the platform remains usable to the restricted-region user (only the content is affected); the restriction is logged.
**Priority:** Critical

### TC-SA-01-06-031 — Enforcement at access time based on current IP (server-side)
**Type:** Positive
**Covers:** 6.3 → Enforcement at access time based on the user's current IP (server-side)
**Preconditions:** A geo-restricted content item; a user whose IP region can change (travel).
**Steps:**
1. Access the content from a licensed region (available).
2. Change the user's IP region (travel) to a restricted region.
3. Access the content again (blocked).
4. Verify the check happened at access time (not at login time).
**Expected Result:** The availability is determined at content access time based on the current IP; the same user sees the content available in the licensed region and blocked in the restricted region; the check is server-side (not cached from login); the events are logged.
**Priority:** High

### TC-SA-01-06-032 — Clear messaging when access is geo-blocked
**Type:** Positive
**Covers:** 6.3 → Clear messaging when access is geo-blocked
**Preconditions:** A geo-restricted content item; a user in a restricted region.
**Steps:**
1. Attempt to access the geo-blocked content.
2. Read the message.
3. Verify it is clear and specific (not a generic error).
**Expected Result:** The user sees a clear message (e.g., "This content is not available in your region."); the message is specific to the geo-block (not a generic failure or 404); the rest of the platform remains usable; the block is logged.
**Priority:** Medium

### TC-SA-01-06-033 — Admin configuration of restriction lists per item or category
**Type:** Positive
**Covers:** 6.3 → Admin configuration of restriction lists per content item or category
**Preconditions:** Super Admin access to Content Management; a content item and a content category.
**Steps:**
1. Configure a restriction list on a specific content item.
2. Configure a restriction list on a content category.
3. Verify items in the category inherit the category restriction.
4. Edit both lists and verify the changes apply.
**Expected Result:** Restrictions can be set per content item and per category; category restrictions are inherited by the items in the category; edits to either list apply immediately; the configuration is available in Content Management; the changes are audit-logged.
**Priority:** High

### TC-SA-01-06-034 — Geo-block hit statistics: demand in restricted regions
**Type:** Positive
**Covers:** 6.3 → Geo-block hit statistics: demand in restricted regions, per content item
**Preconditions:** Geo-block events produced for several content items from restricted regions; the statistics view.
**Steps:**
1. Generate geo-block attempts for several items from known restricted regions.
2. Open the geo-block hit statistics.
3. Verify per-item and per-region demand counts.
4. Identify a region with meaningful demand for a licensed item.
**Expected Result:** The statistics show geo-block demand per content item and per restricted region; the counts match the actual attempts; the data supports licensing decisions (identifying demand for license expansion); the statistics are refreshable/exportable.
**Priority:** Medium

### TC-SA-01-06-035 — Logging of all geo-block events for licensing compliance
**Type:** Positive
**Covers:** 6.3 → Logging of all geo-block events for licensing compliance reporting
**Preconditions:** Geo-block events produced for licensed content; log access.
**Steps:**
1. Generate geo-block events for a licensed content item.
2. Locate all of them in the geo-block event log.
3. Verify content item, user (if authenticated), region, and timestamp on each.
4. Export the log for the licensing compliance report.
**Expected Result:** Every geo-block event is logged with content item, user (if authenticated), region, and timestamp; the log supports the licensing compliance report (showing no playback occurred in unlicensed regions); the export is complete and accurate.
**Priority:** High

### TC-SA-01-06-036 — Integration with content management: restrictions inherited by delivery
**Type:** Positive
**Covers:** 6.3 → Integration with content management: restrictions set on the content item and inherited by its delivery
**Preconditions:** A content item with a geo-restriction; the content's delivery (playback) surface.
**Steps:**
1. Set the geo-restriction on the content item in Content Management.
2. Access the content's delivery (playback) from a restricted region.
3. Verify the restriction is inherited by the delivery (blocked).
4. Access from a licensed region (available).
**Expected Result:** The restriction set on the content item is inherited by its delivery (playback is blocked in restricted regions without re-configuring the delivery); the licensed-region playback works; the integration is seamless (one configuration point); the events are logged.
**Priority:** High

### TC-SA-01-06-037 — Checks at access time; availability changes as the user's region changes
**Type:** Edge
**Covers:** 6.3 → Rule: geo-restriction checks happen at content access time; a traveling user may see availability change
**Preconditions:** A geo-restricted content item; a user traveling between a licensed and a restricted region.
**Steps:**
1. Access the content in the licensed region (available).
2. Travel to the restricted region and access the content (blocked).
3. Return to the licensed region and access the content (available again).
**Expected Result:** The availability changes as the user's IP region changes (checked at each access); the user sees the content available, then blocked, then available again as they move; no stale availability is cached; each access-time check is logged.
**Priority:** Medium

### TC-SA-01-06-038 — Server-side enforcement; no client-side bypass or URL guessing
**Type:** Negative
**Covers:** 6.3 → Rule: restrictions enforced server-side; cannot be bypassed by client-side manipulation or URL guessing
**Preconditions:** A geo-restricted content item; a user in a restricted region with access to the client and the content URL.
**Steps:**
1. From the restricted region, attempt to bypass the geo-block via client-side manipulation (disable the block UI, modify the request).
2. Attempt to access the content via direct URL guessing (the raw content URL).
3. Observe the outcomes.
**Expected Result:** The geo-block cannot be bypassed by client-side manipulation (the server enforces it); direct URL guessing is also blocked (the server checks the IP at access time); the content is not delivered in the restricted region by any path; the bypass attempts are logged.
**Priority:** Critical

### TC-SA-01-06-039 — A geo-block affects only the restricted content, not the account
**Type:** Edge
**Covers:** 6.3 → Rule: a geo-block affects only the restricted content (or platform); it does not log the user out or block their account
**Preconditions:** An authenticated user in a restricted region; a geo-restricted content item.
**Steps:**
1. As the authenticated user, attempt the geo-blocked content.
2. Observe the block.
3. Verify the user is still logged in and can use the rest of the platform.
4. Verify the account is not blocked/suspended.
**Expected Result:** The geo-block affects only the restricted content (the user sees the message); the user is NOT logged out; the rest of the platform remains usable; the account is not blocked or suspended; the block is logged as a content-level event.
**Priority:** High

### TC-SA-01-06-040 — Geo-block events logged with item, user, region, timestamp
**Type:** Positive
**Covers:** 6.3 → Rule: all geo-block events logged with content item, user (if authenticated), region, and timestamp
**Preconditions:** Geo-block events produced (authenticated and anonymous); log access.
**Steps:**
1. Generate geo-block events from authenticated and anonymous access.
2. Locate all of them in the log.
3. Verify content item, user (if authenticated), region, and timestamp on each.
**Expected Result:** Every geo-block event is logged with the content item, the user (where authenticated), the region, and the timestamp; anonymous events show the item and region with no user; no event is missing; the log supports the licensing compliance report.
**Priority:** High

### TC-SA-01-06-041 — Restriction changes audit-logged with acting admin and licensing reference
**Type:** Positive
**Covers:** 6.3 → Rule: restriction changes (add/remove regions) audit-logged with the acting admin and the licensing reference
**Preconditions:** Restriction changes to make (add and remove regions); a licensing reference; audit log access.
**Steps:**
1. Add a restricted region with the licensing reference note.
2. Remove a restricted region (license expansion) with the reference.
3. Locate both changes in the audit log.
4. Verify the acting admin and the licensing reference on each.
**Expected Result:** Both the add and remove changes are audit-logged with the acting admin and the licensing reference; the before/after region lists are captured; no change lacks its actor or reference; the log supports the licensing audit.
**Priority:** High

### TC-SA-01-06-042 — Category + item restrictions: the stricter (union) applies
**Type:** Edge
**Covers:** 6.3 → Rule: where an item has both category-level and item-level restrictions, the stricter (union of) restrictions applies
**Preconditions:** A content category with a restriction set; an item in it with an additional item-level restriction (a superset of regions).
**Steps:**
1. Configure the category restriction (e.g., regions A and B restricted).
2. Configure the item restriction (e.g., regions A, B, and C restricted).
3. Access the item from region C (item-only restriction).
4. Access the item from region A (both restrictions).
5. Access a sibling item (category only) from region C.
**Expected Result:** The item is blocked in regions A, B, and C (the union of category and item restrictions — the stricter applies); the sibling item is blocked only in A and B (category restriction); the union rule is applied correctly; the events are logged.
**Priority:** High
