# Test Model: RBAC & Access Control Feature: Role-based access control and post visibility policies. Defines who can create, read, update, delete, and view posts based on role (GUEST, USER, ADMIN) and ownership. ## Unit Test Cases ### TC-UNIT-101: Role Enum Values - **Type:** Positive - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestRole::test_role_values` - **Expected:** `Role.ADMIN.value == "admin"`, `Role.USER.value == "user"`, `Role.GUEST.value == "guest"` - **Last Verified:** 2026-05-07 ### TC-UNIT-102: Permission Constants - **Type:** Positive - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestPermissions::test_permission_values` - **Expected:** All permission strings match definitions (`post:create`, `post:read`, etc.) - **Last Verified:** 2026-05-07 ### TC-UNIT-103: Admin Has All Permissions - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestRolePermissions::test_admin_has_all_permissions` - **Expected:** `ROLE_PERMISSIONS[Role.ADMIN]` contains all defined permissions - **Last Verified:** 2026-05-07 ### TC-UNIT-104: User Permissions — No Unpublished Read - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestRolePermissions::test_user_permissions` - **Expected:** User has `post:create`, `post:read`, `post:update`, `post:delete`, `post:publish` but **not** `post:read_unpublished` - **Last Verified:** 2026-05-07 ### TC-UNIT-105: Guest Permissions — Read Only - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestRolePermissions::test_guest_permissions` - **Expected:** Guest has only `post:read`; no create, update, delete, publish, or unpublished read - **Last Verified:** 2026-05-07 ### TC-UNIT-106: has_permission — Admin Check - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestHasPermission::test_admin_has_all_permissions_check` - **Expected:** `has_permission(Role.ADMIN, any_perm)` is `True`; unknown permission returns `False` - **Last Verified:** 2026-05-07 ### TC-UNIT-107: has_permission — User Cannot Read Unpublished - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestHasPermission::test_user_limited_permissions` - **Expected:** `has_permission(Role.USER, POST_READ_UNPUBLISHED)` is `False` - **Last Verified:** 2026-05-07 ### TC-UNIT-108: has_permission — Guest Read Only - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestHasPermission::test_guest_read_only` - **Expected:** `has_permission(Role.GUEST, POST_READ)` is `True`; all others `False` - **Last Verified:** 2026-05-07 ### TC-UNIT-109: get_effective_role — Admin Priority - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestGetEffectiveRole::test_admin_from_roles_list` - **Expected:** Any list containing `"admin"` resolves to `Role.ADMIN` - **Last Verified:** 2026-05-07 ### TC-UNIT-110: get_effective_role — User Priority - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestGetEffectiveRole::test_user_from_roles_list` - **Expected:** List with `"user"` (and no `"admin"`) resolves to `Role.USER` - **Last Verified:** 2026-05-07 ### TC-UNIT-111: get_effective_role — Guest Fallback - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestGetEffectiveRole::test_guest_from_roles_list` - **Expected:** Empty list or unknown roles resolve to `Role.GUEST` - **Last Verified:** 2026-05-07 ### TC-UNIT-112: get_effective_role — Priority Order - **Type:** Policy - **Layer:** Unit - **File:** `unit/domain/test_roles.py::TestGetEffectiveRole::test_role_priority` - **Expected:** Priority is `admin > user > guest` - **Last Verified:** 2026-05-07 ## E2E Test Cases ### TC-E2E-101: Draft Visibility Policy Across Roles - **Type:** Policy - **Layer:** E2E - **File:** `e2e/test_post_lifecycle.py::test_post_visibility_policies_across_users` - **Preconditions:** Four browser contexts: user, user2, guest, admin - **Steps:** 1. User creates a draft 2. User creates a published post 3. Verify home-page visibility for each role 4. Verify direct draft access by user2 returns 404 - **Expected:** - User sees both posts - User2 sees only published - Guest sees only published - Admin sees both - User2 gets 404 on direct draft URL - **Last Verified:** 2026-05-07 ## Web Route Policy Reference The following policies are implemented in `app/presentation/web/deps.py` and `app/presentation/web/routes.py`. They are covered via E2E but lack dedicated unit tests for the web layer. | Function | Rule | Covered By | |----------|------|------------| | `can_create_post` | USER or ADMIN | E2E-001 | | `can_edit_post` | ADMIN or own post author | Unit (use cases) | | `can_delete_post` | ADMIN or own post author | Unit (use cases) | | `can_see_draft` | ADMIN or own post author | E2E-101 | | `_get_visible_posts` | GUEST: published only; USER: published + own drafts; ADMIN: all | E2E-101 | ### TC-E2E-102: Admin Can Edit Any Post - **Type:** Positive - **Layer:** E2E - **File:** `e2e/test_post_ownership.py::test_admin_can_edit_any_post` - **Preconditions:** Two browser contexts: user (creates post), admin (edits post) - **Steps:** 1. User creates and publishes a post 2. Admin opens the post detail page 3. Admin clicks edit, changes title, and saves 4. Verify the post detail shows the updated title - **Expected:** Admin sees edit button, successfully updates post, detail page reflects new title - **Last Verified:** 2026-05-07 ### TC-E2E-103: User Cannot Edit Other User's Post - **Type:** Negative - **Layer:** E2E - **File:** `e2e/test_post_ownership.py::test_user_cannot_edit_other_users_post` - **Preconditions:** Two browser contexts: user (creates post), user2 (attempts edit) - **Steps:** 1. User creates and publishes a post 2. User2 opens the post detail page 3. Verify edit button is not visible 4. User2 attempts direct access to `/web/posts/{slug}/edit` - **Expected:** Edit button is hidden; direct access returns 403 error page - **Last Verified:** 2026-05-07 ## Coverage Summary | Aspect | Coverage | Notes | |--------|----------|-------| | Role definitions | Unit | Enum values and permission mapping fully tested | | Permission checks | Unit | `has_permission` and `get_effective_role` fully tested | | Web-level enforcement | E2E | Visibility and ownership rules tested via browser | | API-level enforcement | — | No API tests exist after refactor | ## Gaps (Not Yet Covered) - [ ] TC-UNIT-113: Web deps — `can_create_post` for each role - [ ] TC-UNIT-114: Web deps — `can_edit_post` for owner vs non-owner - [ ] TC-UNIT-115: Web deps — `can_delete_post` for owner vs non-owner - [ ] TC-UNIT-116: Web deps — `can_see_draft` for each role combination - [ ] TC-API-101: API POST create — unauthorized (no token) - [ ] TC-API-102: API POST create — forbidden (guest token) - [ ] TC-API-103: API GET unpublished post — forbidden (other user) - [ ] TC-E2E-104: Admin can delete any post via web UI - [ ] TC-E2E-105: User cannot delete other user's post via web UI