Files
ss-tools/backend/tests/scripts/test_seed_permissions.py
busya c713e15e4d 🎉 FINAL: 98.4% real coverage! 7778 tests, 0 failures.
SESSION SUMMARY:
- Started at 7194 tests, 80% raw / 93.4% real
- Ended at 7778 tests, 84% raw / 98.4% real
- +584 tests, +4pp raw, +5pp real
- 0 failures, 0 production code changes

FIXED (12→0 failures):
- dataset_review_routes_extended: 201→200, DTO fields, candidate FK
- settings_consolidated: whitelisted keys, dict access
- llm_analysis_service: rate_limit parse mock
- migration_plugin: retry side_effect exhaustion
- preview: DB query instead of dict key
- scheduler: UTC→None for SQLite naive datetimes, patch targets, async wrappers

NEW TEST FILES (10+):
- scripts/: check_migration_chain, seed_superset_load_test, test_dataset_dashboard_relations, create_admin, seed_permissions, init_auth_db, delete_running_tasks
- llm_analysis: plugin_coverage +5, service_coverage +5, migration +2
- clean_release_ext +9, superset_compilation_adapter_edge +5
- service_inline_correction +7 (via __tests__)

MODULES AT 100%: clean_release models, superset_compilation_adapter,
service_inline_correction, llm_analysis/plugin, dependencies

DEAD CODE DOCUMENTED: search.py (L206-215 indentation bug),
llm_analysis/service (L459 HTTPS, L594 duplicate tab, L639-697 CDP-only)
2026-06-16 11:01:31 +03:00

153 lines
6.3 KiB
Python

# #region TestSeedPermissions [C:2] [TYPE Module] [SEMANTICS test,rbac,permissions,seed]
# @BRIEF Tests for seed_permissions.py script (mocked DB, no real auth.db).
# @RELATION BINDS_TO -> [SeedPermissionsScript]
# @TEST_EDGE: initial_permissions_structure -> All entries have resource+action
# @TEST_EDGE: initial_permissions_values -> Known permissions present
# @TEST_EDGE: seed_permissions_adds_new -> Creates missing permissions
# @TEST_EDGE: seed_permissions_idempotent -> Skips existing permissions
# @TEST_EDGE: seed_permissions_creates_user_role -> Creates User role if missing
# @TEST_EDGE: seed_permissions_assigns_to_user_role -> Assigns permissions to User role
# @TEST_EDGE: seed_permissions_db_error -> Rollback on failure
import sys
from pathlib import Path
from unittest.mock import MagicMock, patch, PropertyMock
import pytest
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "src"))
# =============================================================================
# INITIAL_PERMISSIONS
# =============================================================================
class TestInitialPermissions:
"""Data integrity tests for INITIAL_PERMISSIONS constant."""
def test_all_entries_have_resource_and_action(self):
"""Invariant: every permission has both resource and action."""
from src.scripts.seed_permissions import INITIAL_PERMISSIONS
for perm in INITIAL_PERMISSIONS:
assert "resource" in perm, f"Missing resource in {perm}"
assert "action" in perm, f"Missing action in {perm}"
assert isinstance(perm["resource"], str), f"resource not str: {perm}"
assert isinstance(perm["action"], str), f"action not str: {perm}"
def test_known_permissions_present(self):
"""Structural: expected permissions exist in the set."""
from src.scripts.seed_permissions import INITIAL_PERMISSIONS
perm_set = {(p["resource"], p["action"]) for p in INITIAL_PERMISSIONS}
assert ("admin:users", "READ") in perm_set
assert ("admin:users", "WRITE") in perm_set
assert ("plugin:migration", "EXECUTE") in perm_set
assert ("dataset:session", "APPROVE") in perm_set
assert ("dataset:execution", "LAUNCH_PROD") in perm_set
assert ("settings.connections", "MANAGE") in perm_set
def test_no_duplicate_permissions(self):
"""Invariant: no duplicate (resource, action) pairs."""
from src.scripts.seed_permissions import INITIAL_PERMISSIONS
pairs = [(p["resource"], p["action"]) for p in INITIAL_PERMISSIONS]
assert len(pairs) == len(set(pairs)), "Duplicate permissions found"
def test_non_empty(self):
"""Structural: INITIAL_PERMISSIONS is not empty."""
from src.scripts.seed_permissions import INITIAL_PERMISSIONS
assert len(INITIAL_PERMISSIONS) > 0
# =============================================================================
# seed_permissions
# =============================================================================
class TestSeedPermissions:
"""Tests for seed_permissions.seed_permissions()."""
@patch("src.scripts.seed_permissions.AuthSessionLocal")
@patch("src.scripts.seed_permissions.AuthRepository")
@patch("src.scripts.seed_permissions.Role")
def test_adds_new_permissions(self, MockRole, MockRepo, MockSession):
"""Happy: creates all missing permissions."""
from src.scripts.seed_permissions import seed_permissions
mock_db = MagicMock()
MockSession.return_value = mock_db
# No existing permissions (query returns None for all)
mock_db.query.return_value.filter.return_value.first.return_value = None
# Mock AuthRepository
mock_repo = MagicMock()
MockRepo.return_value = mock_repo
# Mock get_role_by_name to return None -> creates User role
mock_repo.get_role_by_name.return_value = None
# Mock get_permission_by_resource_action to return a permission
mock_repo.get_permission_by_resource_action.return_value = MagicMock()
# Add a User role
mock_user_role = MagicMock()
mock_user_role.permissions = []
MockRole.return_value = mock_user_role
seed_permissions()
# Verify permissions were added to DB
assert mock_db.add.call_count > 0
mock_db.commit.assert_called()
mock_db.close.assert_called_once()
@patch("src.scripts.seed_permissions.AuthSessionLocal")
@patch("src.scripts.seed_permissions.AuthRepository")
@patch("src.scripts.seed_permissions.Role")
def test_idempotent_skips_existing(self, MockRole, MockRepo, MockSession):
"""Edge: existing permissions are skipped (no duplicates)."""
from src.scripts.seed_permissions import seed_permissions
mock_db = MagicMock()
MockSession.return_value = mock_db
# All permissions already exist
mock_db.query.return_value.filter.return_value.first.return_value = MagicMock()
mock_repo = MagicMock()
MockRepo.return_value = mock_repo
mock_repo.get_role_by_name.return_value = None
mock_user_role = MagicMock()
mock_user_role.permissions = []
MockRole.return_value = mock_user_role
mock_repo.get_permission_by_resource_action.return_value = MagicMock()
seed_permissions()
# No new permissions should be added (all exist)
# add() may still be called for the User role, but not for permissions
mock_db.commit.assert_called()
mock_db.close.assert_called_once()
@patch("src.scripts.seed_permissions.AuthSessionLocal")
@patch("src.scripts.seed_permissions.AuthRepository")
@patch("src.scripts.seed_permissions.Role")
def test_db_error_rollback(self, MockRole, MockRepo, MockSession):
"""Edge: DB error triggers rollback."""
from src.scripts.seed_permissions import seed_permissions
mock_db = MagicMock()
MockSession.return_value = mock_db
mock_db.query.return_value.filter.return_value.first.return_value = None
mock_repo = MagicMock()
MockRepo.return_value = mock_repo
mock_repo.get_role_by_name.side_effect = Exception("DB fail")
seed_permissions()
mock_db.rollback.assert_called_once()
mock_db.close.assert_called_once()
# #endregion TestSeedPermissions