# 5. License & Seat Management — Test Cases

User Type: **Super Administrator**
Source: *Mi Digital Academy - Education CRM Features Document*
Spec: license_seat_management.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 |
|---------|--------------------|----------|
| 5.1 Allocate Student Seats Under Institute Licenses | License seat tracking: total seats, allocated, available per institute license | TC-SA-03-05-001 |
| 5.1 Allocate Student Seats Under Institute Licenses | Seat allocation on student-institute linking (a linked student with a seat occupies one) | TC-SA-03-05-002 |
| 5.1 Allocate Student Seats Under Institute Licenses | Allocation cap enforcement: a seat cannot be allocated beyond the licensed count | TC-SA-03-05-003 |
| 5.1 Allocate Student Seats Under Institute Licenses | Seat list per institute: which students hold seats, allocation dates | TC-SA-03-05-004 |
| 5.1 Allocate Student Seats Under Institute Licenses | Availability view: remaining seats, projected usage | TC-SA-03-05-005 |
| 5.1 Allocate Student Seats Under Institute Licenses | Over-allocation prevention with a clear block message | TC-SA-03-05-003 |
| 5.1 Allocate Student Seats Under Institute Licenses | Audit logging of allocations | TC-SA-03-05-006 |
| 5.1 Allocate Student Seats Under Institute Licenses | Rule: allocation cannot exceed the licensed seat count; the cap is enforced at link time with a clear block | TC-SA-03-05-003 |
| 5.1 Allocate Student Seats Under Institute Licenses | Rule: a seat is allocated when a student is linked with a seat; released when unlinked or re-linked elsewhere | TC-SA-03-05-007 |
| 5.1 Allocate Student Seats Under Institute Licenses | Rule: license upgrades increase available seats immediately; downgrades are handled with a plan for excess seats | TC-SA-03-05-008 |
| 5.1 Allocate Student Seats Under Institute Licenses | Rule: the seat list is the source of truth for usage; consistent with the student-institute links | TC-SA-03-05-009 |
| 5.1 Allocate Student Seats Under Institute Licenses | Rule: allocation and release are audit-logged with the student, institute, and timestamp | TC-SA-03-05-006 |
| 5.1 Allocate Student Seats Under Institute Licenses | Rule: availability is always visible so enrollment decisions are made against real capacity | TC-SA-03-05-005 |
| 5.2 Transfer Licenses Between Students | Transfer a seat from one student to another within the same institute | TC-SA-03-05-010 |
| 5.2 Transfer Licenses Between Students | Outgoing student's seat released; incoming student's seat allocated in one operation | TC-SA-03-05-011 |
| 5.2 Transfer Licenses Between Students | License usage unchanged by a transfer (one seat moves, not added) | TC-SA-03-05-012 |
| 5.2 Transfer Licenses Between Students | Incoming student eligibility check (valid account, correct institute, no existing seat) | TC-SA-03-05-013 |
| 5.2 Transfer Licenses Between Students | Outgoing student handling (unlink, or retain account without the seat) | TC-SA-03-05-014 |
| 5.2 Transfer Licenses Between Students | Audit logging of the transfer (from student, to student, institute, timestamp) | TC-SA-03-05-015 |
| 5.2 Transfer Licenses Between Students | Rule: a transfer is atomic: the release and the allocation happen together; no gap or double-count | TC-SA-03-05-011 |
| 5.2 Transfer Licenses Between Students | Rule: the incoming student must be eligible; ineligible transfers are blocked with the reason | TC-SA-03-05-013 |
| 5.2 Transfer Licenses Between Students | Rule: a transfer does not change the license total; it moves one seat | TC-SA-03-05-012 |
| 5.2 Transfer Licenses Between Students | Rule: the outgoing student's account handling is explicit (retain without seat, or deactivate) — not implicit | TC-SA-03-05-014 |
| 5.2 Transfer Licenses Between Students | Rule: transfers are audit-logged with both students, the institute, and the timestamp | TC-SA-03-05-015 |
| 5.2 Transfer Licenses Between Students | Rule: a transfer to a student who already holds a seat is blocked (one seat per student per institute) | TC-SA-03-05-016 |
| 5.3 Remove Student Accounts from Licenses | Remove a student from the license (release the seat) with a reason | TC-SA-03-05-017 |
| 5.3 Remove Student Accounts from Licenses | Seat returns to the institute's available pool immediately | TC-SA-03-05-018 |
| 5.3 Remove Student Accounts from Licenses | Student account handling options: retain (unlinked), move to another institute, or deactivate | TC-SA-03-05-019 |
| 5.3 Remove Student Accounts from Licenses | Bulk removal for a set of students (e.g., a graduating cohort) | TC-SA-03-05-020 |
| 5.3 Remove Student Accounts from Licenses | License downgrade support: plan and execute seat reduction when a license shrinks | TC-SA-03-05-021 |
| 5.3 Remove Student Accounts from Licenses | Audit logging of removals with the reason and account handling | TC-SA-03-05-022 |
| 5.3 Remove Student Accounts from Licenses | Rule: removal releases the seat immediately; the account handling is a separate, explicit choice | TC-SA-03-05-019 |
| 5.3 Remove Student Accounts from Licenses | Rule: bulk removal requires a confirmed preview (count, reason, account handling) before execution | TC-SA-03-05-020 |
| 5.3 Remove Student Accounts from Licenses | Rule: a license downgrade cannot leave usage above the new count; excess seats must be freed first | TC-SA-03-05-023 |
| 5.3 Remove Student Accounts from Licenses | Rule: removed students' accounts are never silently deleted; the handling is explicit | TC-SA-03-05-019 |
| 5.3 Remove Student Accounts from Licenses | Rule: removals are audit-logged with the reason and the account handling | TC-SA-03-05-022 |
| 5.3 Remove Student Accounts from Licenses | Rule: the seat pool reflects removals immediately, so availability is always accurate | TC-SA-03-05-018 |

## 5.1 Allocate Student Seats Under Institute Licenses

### TC-SA-03-05-001 — License seat tracking shows total, allocated, and available per institute license
**Type:** Positive
**Covers:** 5.1 → License seat tracking: total seats, allocated, available per institute license
**Preconditions:** An institute with a 100-seat license and 95 linked students.
**Steps:**
1. Open the institute's license view.
2. Verify the total (100), allocated (95), and available (5) counts.
**Expected Result:** The license view shows total=100, allocated=95, available=5 — the counts are accurate and consistent.
**Priority:** Critical

### TC-SA-03-05-002 — Seat allocation happens on student-institute linking
**Type:** Positive
**Covers:** 5.1 → Seat allocation on student-institute linking (a linked student with a seat occupies one)
**Preconditions:** An institute with 5 available seats; a new student is to be linked.
**Steps:**
1. Link the student to the institute with a seat.
2. Verify the license view updates (allocated increases by 1, available decreases by 1).
**Expected Result:** The seat is allocated on linking — the license view reflects the new allocation immediately.
**Priority:** Critical

### TC-SA-03-05-003 — Allocation cap enforcement: a seat cannot be allocated beyond the licensed count; over-allocation is blocked with a clear message
**Type:** Negative
**Covers:** 5.1 → Allocation cap enforcement: a seat cannot be allocated beyond the licensed count; Over-allocation prevention with a clear block message; Rule: the cap is enforced at link time with a clear block
**Preconditions:** An institute with a 100-seat license and 100 allocated seats (0 available).
**Steps:**
1. Attempt to link a 101st student with a seat.
**Expected Result:** The allocation is blocked with a clear message: "No available seats under this license" — the cap is enforced at link time.
**Priority:** Critical

### TC-SA-03-05-004 — Seat list per institute shows which students hold seats and allocation dates
**Type:** Positive
**Covers:** 5.1 → Seat list per institute: which students hold seats, allocation dates
**Preconditions:** An institute with 95 allocated seats.
**Steps:**
1. Open the institute's seat list.
2. Verify each allocated seat shows the student, allocation date, and status.
**Expected Result:** The seat list shows all 95 students with their allocation dates and status — complete and accurate.
**Priority:** High

### TC-SA-03-05-005 — Availability view shows remaining seats and projected usage
**Type:** Positive
**Covers:** 5.1 → Availability view: remaining seats, projected usage; Rule: availability is always visible so enrollment decisions are made against real capacity
**Preconditions:** An institute with 5 available seats and pending enrollment requests.
**Steps:**
1. Open the availability view.
2. Verify the remaining seats (5) and the projected usage.
**Expected Result:** The availability view shows the remaining seats and projected usage — enrollment decisions can be made against real capacity.
**Priority:** Medium

### TC-SA-03-05-006 — Allocation and release are audit-logged with the student, institute, and timestamp
**Type:** Positive
**Covers:** 5.1 → Audit logging of allocations; Rule: allocation and release are audit-logged with the student, institute, and timestamp
**Preconditions:** A seat allocation and a seat release have occurred.
**Steps:**
1. Open the audit trail and filter by "seat".
2. Verify each entry.
**Expected Result:** Both the allocation and the release are audit-logged with the student, the institute, and the timestamp.
**Priority:** Critical

### TC-SA-03-05-007 — A seat is released when a student is unlinked or re-linked elsewhere
**Type:** Positive
**Covers:** 5.1 → Rule: a seat is allocated when a student is linked to the institute with a seat; it is released when the student is unlinked or re-linked elsewhere
**Preconditions:** A student holds a seat under Institute A.
**Steps:**
1. Unlink the student from Institute A — verify the seat is released.
2. Re-link a second student from Institute A to Institute B — verify the seat is released under A.
**Expected Result:** In both cases, the seat is released — the license view reflects the release immediately.
**Priority:** High

### TC-SA-03-05-008 — License upgrades increase available seats immediately; downgrades are handled with a plan for excess seats
**Type:** Positive
**Covers:** 5.1 → Rule: license upgrades increase available seats immediately; downgrades are handled with a plan for excess seats (see 5.3)
**Preconditions:** An institute with a 100-seat license (100 allocated) upgrades to 150 seats.
**Steps:**
1. Confirm the upgrade to 150 seats.
2. Verify the available seats increase immediately (50 available).
3. For a downgrade scenario, verify a plan for excess seats is required.
**Expected Result:** The upgrade increases available seats immediately (50); the downgrade requires a plan for excess seats before it can proceed.
**Priority:** High

### TC-SA-03-05-009 — The seat list is the source of truth for usage; consistent with the student-institute links
**Type:** Positive
**Covers:** 5.1 → Rule: the seat list is the source of truth for usage; it is consistent with the student-institute links
**Preconditions:** An institute with 95 linked students with seats.
**Steps:**
1. Open the seat list and count the allocated seats.
2. Open the student-institute links and count the linked students with seats.
**Expected Result:** The seat list count matches the student-institute link count exactly — the seat list is the source of truth and is consistent.
**Priority:** High

## 5.2 Transfer Licenses Between Students

### TC-SA-03-05-010 — A seat can be transferred from one student to another within the same institute
**Type:** Positive
**Covers:** 5.2 → Transfer a seat from one student to another within the same institute
**Preconditions:** An institute with a student who is withdrawing and a new student ready to take the place.
**Steps:**
1. Open the institute's license view and select the outgoing student's seat.
2. Choose "Transfer to another student" and select the incoming student.
3. Confirm the transfer.
**Expected Result:** The seat is transferred from the outgoing student to the incoming student within the same institute.
**Priority:** Critical

### TC-SA-03-05-011 — The transfer is atomic: release and allocation happen together; no gap or double-count
**Type:** Positive
**Covers:** 5.2 → Outgoing student's seat released; incoming student's seat allocated in one operation; Rule: a transfer is atomic: the release and the allocation happen together, so usage never shows a gap or a double-count
**Preconditions:** An institute at 100/100 seats; a transfer is initiated.
**Steps:**
1. Initiate the transfer.
2. Monitor the license usage during and after the operation.
**Expected Result:** The release and allocation happen in one atomic operation — the license usage never shows a gap (99) or a double-count (101); it stays at 100/100.
**Priority:** Critical

### TC-SA-03-05-012 — License usage is unchanged by a transfer (one seat moves, not added)
**Type:** Positive
**Covers:** 5.2 → License usage unchanged by a transfer (one seat moves, not added); Rule: a transfer does not change the license total; it moves one seat
**Preconditions:** An institute at 100/100 seats; a transfer is completed.
**Steps:**
1. Complete the transfer.
2. Verify the license total and usage.
**Expected Result:** The license total is unchanged (100) and the usage is unchanged (100/100) — one seat moved, none added.
**Priority:** High

### TC-SA-03-05-013 — Incoming student eligibility check: valid account, correct institute, no existing seat; ineligible transfers are blocked with the reason
**Type:** Negative
**Covers:** 5.2 → Incoming student eligibility check (valid account, correct institute, no existing seat); Rule: the incoming student must be eligible; ineligible transfers are blocked with the reason
**Preconditions:** Three incoming students: one with an invalid account, one linked to a different institute, one with an existing seat.
**Steps:**
1. Attempt a transfer to the student with an invalid account.
2. Attempt a transfer to the student linked to a different institute.
3. Attempt a transfer to the student with an existing seat.
**Expected Result:** All three transfers are blocked with the specific reason: invalid account, wrong institute, or existing seat.
**Priority:** Critical

### TC-SA-03-05-014 — Outgoing student handling is explicit: retain without seat, or deactivate
**Type:** Positive
**Covers:** 5.2 → Outgoing student handling (unlink, or retain account without the seat); Rule: the outgoing student's account handling is explicit (retain without seat, or deactivate) — not implicit
**Preconditions:** A transfer is initiated; the outgoing student is leaving the institute.
**Steps:**
1. Initiate the transfer.
2. Select the outgoing student's handling: "Retain account, unlink from institute".
3. For a second transfer, select "Deactivate" (routed to the deactivation flow).
**Expected Result:** The outgoing student's handling is an explicit choice — "retain without seat" or "deactivate" — never implicit.
**Priority:** High

### TC-SA-03-05-015 — Transfers are audit-logged with both students, the institute, and the timestamp
**Type:** Positive
**Covers:** 5.2 → Audit logging of the transfer (from student, to student, institute, timestamp); Rule: transfers are audit-logged with both students, the institute, and the timestamp
**Preconditions:** A seat transfer has been completed.
**Steps:**
1. Open the audit trail and locate the transfer entry.
2. Verify the entry's fields.
**Expected Result:** The transfer is audit-logged with the from student, the to student, the institute, and the timestamp.
**Priority:** Critical

### TC-SA-03-05-016 — A transfer to a student who already holds a seat is blocked
**Type:** Negative
**Covers:** 5.2 → Rule: a transfer to a student who already holds a seat is blocked (one seat per student per institute)
**Preconditions:** An incoming student already holds a seat under the institute.
**Steps:**
1. Attempt to transfer a seat to the student who already holds one.
**Expected Result:** The transfer is blocked — one seat per student per institute; the student already holds a seat.
**Priority:** Critical

## 5.3 Remove Student Accounts from Licenses

### TC-SA-03-05-017 — A student can be removed from the license (seat released) with a reason
**Type:** Positive
**Covers:** 5.3 → Remove a student from the license (release the seat) with a reason
**Preconditions:** A student holds a seat under an institute; the student is graduating.
**Steps:**
1. Select the student in the seat list and choose "Remove from license".
2. Enter the reason "Graduated — [year]".
3. Confirm.
**Expected Result:** The student is removed from the license; the seat is released; the reason is recorded.
**Priority:** Critical

### TC-SA-03-05-018 — The seat returns to the institute's available pool immediately
**Type:** Positive
**Covers:** 5.3 → Seat returns to the institute's available pool immediately; Rule: the seat pool reflects removals immediately, so availability is always accurate
**Preconditions:** An institute with 5 available seats; a student is removed.
**Steps:**
1. Remove the student from the license.
2. Verify the available seats increase immediately (6).
**Expected Result:** The seat returns to the pool immediately — the availability view reflects the removal without delay.
**Priority:** High

### TC-SA-03-05-019 — Student account handling options: retain (unlinked), move to another institute, or deactivate; never silently deleted
**Type:** Positive
**Covers:** 5.3 → Student account handling options: retain (unlinked), move to another institute, or deactivate; Rule: removal releases the seat immediately; the account handling is a separate, explicit choice; Rule: removed students' accounts are never silently deleted; the handling is explicit
**Preconditions:** A student is removed from the license.
**Steps:**
1. Select the account handling: "Retain accounts, unlink from institute" — verify the account survives.
2. For a second student, select "Move to another institute" — verify the re-link.
3. For a third student, select "Deactivate" — verify the deactivation flow.
**Expected Result:** All three handling options work; the account handling is a separate, explicit choice — no account is silently deleted.
**Priority:** Critical

### TC-SA-03-05-020 — Bulk removal requires a confirmed preview (count, reason, account handling) before execution
**Type:** Positive
**Covers:** 5.3 → Bulk removal for a set of students (e.g., a graduating cohort); Rule: bulk removal requires a confirmed preview (count, reason, account handling) before execution
**Preconditions:** A cohort of 20 graduating students is selected.
**Steps:**
1. Select the 20 students and choose "Remove from license".
2. Verify the preview shows the count (20), a reason field, and the account handling.
3. Attempt to confirm without the reason.
4. Enter the reason and account handling, and confirm.
**Expected Result:** The preview shows the count, reason, and account handling; confirmation is blocked without them; with them, all 20 seats are released.
**Priority:** Critical

### TC-SA-03-05-021 — License downgrade support: plan and execute seat reduction when a license shrinks
**Type:** Positive
**Covers:** 5.3 → License downgrade support: plan and execute seat reduction when a license shrinks
**Preconditions:** An institute with a 100-seat license (90 allocated) is downgrading to 80 seats.
**Steps:**
1. Initiate the downgrade to 80 seats.
2. Verify the system identifies the 10 excess seats that must be freed.
3. Execute the removals until usage is within the new 80-seat count.
4. Confirm the downgrade.
**Expected Result:** The downgrade is planned (10 excess seats identified) and executed (removals until usage ≤ 80); the license is now 80 seats with usage within the count.
**Priority:** High

### TC-SA-03-05-022 — Removals are audit-logged with the reason and the account handling
**Type:** Positive
**Covers:** 5.3 → Audit logging of removals with the reason and account handling; Rule: removals are audit-logged with the reason and the account handling
**Preconditions:** An individual and a bulk removal have been performed.
**Steps:**
1. Open the audit trail and filter by "license removal".
2. Verify each entry.
**Expected Result:** Both removals are audit-logged with the reason and the account handling (retain/move/deactivate).
**Priority:** Critical

### TC-SA-03-05-023 — A license downgrade cannot leave usage above the new count; excess seats must be freed first
**Type:** Negative
**Covers:** 5.3 → Rule: a license downgrade cannot leave usage above the new count; excess seats must be freed first (the system blocks a downgrade that would over-allocate)
**Preconditions:** An institute with a 100-seat license (90 allocated) attempts to downgrade to 80 seats without freeing the 10 excess.
**Steps:**
1. Attempt to confirm the downgrade to 80 seats with 90 allocated.
**Expected Result:** The downgrade is blocked — usage (90) would exceed the new count (80); the 10 excess seats must be freed first.
**Priority:** Critical
