| 
                        123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 | 
                        - from unittest.mock import Mock, patch
 - 
 - import pytest
 - 
 - from models.account import Account, TenantAccountRole
 - from models.dataset import Dataset, DatasetPermission, DatasetPermissionEnum
 - from services.dataset_service import DatasetService
 - from services.errors.account import NoPermissionError
 - 
 - 
 - class DatasetPermissionTestDataFactory:
 -     """Factory class for creating test data and mock objects for dataset permission tests."""
 - 
 -     @staticmethod
 -     def create_dataset_mock(
 -         dataset_id: str = "dataset-123",
 -         tenant_id: str = "test-tenant-123",
 -         created_by: str = "creator-456",
 -         permission: DatasetPermissionEnum = DatasetPermissionEnum.ONLY_ME,
 -         **kwargs,
 -     ) -> Mock:
 -         """Create a mock dataset with specified attributes."""
 -         dataset = Mock(spec=Dataset)
 -         dataset.id = dataset_id
 -         dataset.tenant_id = tenant_id
 -         dataset.created_by = created_by
 -         dataset.permission = permission
 -         for key, value in kwargs.items():
 -             setattr(dataset, key, value)
 -         return dataset
 - 
 -     @staticmethod
 -     def create_user_mock(
 -         user_id: str = "user-789",
 -         tenant_id: str = "test-tenant-123",
 -         role: TenantAccountRole = TenantAccountRole.NORMAL,
 -         **kwargs,
 -     ) -> Mock:
 -         """Create a mock user with specified attributes."""
 -         user = Mock(spec=Account)
 -         user.id = user_id
 -         user.current_tenant_id = tenant_id
 -         user.current_role = role
 -         for key, value in kwargs.items():
 -             setattr(user, key, value)
 -         return user
 - 
 -     @staticmethod
 -     def create_dataset_permission_mock(
 -         dataset_id: str = "dataset-123",
 -         account_id: str = "user-789",
 -         **kwargs,
 -     ) -> Mock:
 -         """Create a mock dataset permission record."""
 -         permission = Mock(spec=DatasetPermission)
 -         permission.dataset_id = dataset_id
 -         permission.account_id = account_id
 -         for key, value in kwargs.items():
 -             setattr(permission, key, value)
 -         return permission
 - 
 - 
 - class TestDatasetPermissionService:
 -     """
 -     Comprehensive unit tests for DatasetService.check_dataset_permission method.
 - 
 -     This test suite covers all permission scenarios including:
 -     - Cross-tenant access restrictions
 -     - Owner privilege checks
 -     - Different permission levels (ONLY_ME, ALL_TEAM, PARTIAL_TEAM)
 -     - Explicit permission checks for PARTIAL_TEAM
 -     - Error conditions and logging
 -     """
 - 
 -     @pytest.fixture
 -     def mock_dataset_service_dependencies(self):
 -         """Common mock setup for dataset service dependencies."""
 -         with patch("services.dataset_service.db.session") as mock_session:
 -             yield {
 -                 "db_session": mock_session,
 -             }
 - 
 -     @pytest.fixture
 -     def mock_logging_dependencies(self):
 -         """Mock setup for logging tests."""
 -         with patch("services.dataset_service.logger") as mock_logging:
 -             yield {
 -                 "logging": mock_logging,
 -             }
 - 
 -     def _assert_permission_check_passes(self, dataset: Mock, user: Mock):
 -         """Helper method to verify that permission check passes without raising exceptions."""
 -         # Should not raise any exception
 -         DatasetService.check_dataset_permission(dataset, user)
 - 
 -     def _assert_permission_check_fails(
 -         self, dataset: Mock, user: Mock, expected_message: str = "You do not have permission to access this dataset."
 -     ):
 -         """Helper method to verify that permission check fails with expected error."""
 -         with pytest.raises(NoPermissionError, match=expected_message):
 -             DatasetService.check_dataset_permission(dataset, user)
 - 
 -     def _assert_database_query_called(self, mock_session: Mock, dataset_id: str, account_id: str):
 -         """Helper method to verify database query calls for permission checks."""
 -         mock_session.query().filter_by.assert_called_with(dataset_id=dataset_id, account_id=account_id)
 - 
 -     def _assert_database_query_not_called(self, mock_session: Mock):
 -         """Helper method to verify that database query was not called."""
 -         mock_session.query.assert_not_called()
 - 
 -     # ==================== Cross-Tenant Access Tests ====================
 - 
 -     def test_permission_check_different_tenant_should_fail(self):
 -         """Test that users from different tenants cannot access dataset regardless of other permissions."""
 -         # Create dataset and user from different tenants
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(
 -             tenant_id="tenant-123", permission=DatasetPermissionEnum.ALL_TEAM
 -         )
 -         user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="user-789", tenant_id="different-tenant-456", role=TenantAccountRole.EDITOR
 -         )
 - 
 -         # Should fail due to different tenant
 -         self._assert_permission_check_fails(dataset, user)
 - 
 -     # ==================== Owner Privilege Tests ====================
 - 
 -     def test_owner_can_access_any_dataset(self):
 -         """Test that tenant owners can access any dataset regardless of permission level."""
 -         # Create dataset with restrictive permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(permission=DatasetPermissionEnum.ONLY_ME)
 - 
 -         # Create owner user
 -         owner_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="owner-999", role=TenantAccountRole.OWNER
 -         )
 - 
 -         # Owner should have access regardless of dataset permission
 -         self._assert_permission_check_passes(dataset, owner_user)
 - 
 -     # ==================== ONLY_ME Permission Tests ====================
 - 
 -     def test_only_me_permission_creator_can_access(self):
 -         """Test ONLY_ME permission allows only the dataset creator to access."""
 -         # Create dataset with ONLY_ME permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(
 -             created_by="creator-456", permission=DatasetPermissionEnum.ONLY_ME
 -         )
 - 
 -         # Create creator user
 -         creator_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="creator-456", role=TenantAccountRole.EDITOR
 -         )
 - 
 -         # Creator should be able to access
 -         self._assert_permission_check_passes(dataset, creator_user)
 - 
 -     def test_only_me_permission_others_cannot_access(self):
 -         """Test ONLY_ME permission denies access to non-creators."""
 -         # Create dataset with ONLY_ME permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(
 -             created_by="creator-456", permission=DatasetPermissionEnum.ONLY_ME
 -         )
 - 
 -         # Create normal user (not the creator)
 -         normal_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="normal-789", role=TenantAccountRole.NORMAL
 -         )
 - 
 -         # Non-creator should be denied access
 -         self._assert_permission_check_fails(dataset, normal_user)
 - 
 -     # ==================== ALL_TEAM Permission Tests ====================
 - 
 -     def test_all_team_permission_allows_access(self):
 -         """Test ALL_TEAM permission allows any team member to access the dataset."""
 -         # Create dataset with ALL_TEAM permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(permission=DatasetPermissionEnum.ALL_TEAM)
 - 
 -         # Create different types of team members
 -         normal_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="normal-789", role=TenantAccountRole.NORMAL
 -         )
 -         editor_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="editor-456", role=TenantAccountRole.EDITOR
 -         )
 - 
 -         # All team members should have access
 -         self._assert_permission_check_passes(dataset, normal_user)
 -         self._assert_permission_check_passes(dataset, editor_user)
 - 
 -     # ==================== PARTIAL_TEAM Permission Tests ====================
 - 
 -     def test_partial_team_permission_creator_can_access(self, mock_dataset_service_dependencies):
 -         """Test PARTIAL_TEAM permission allows creator to access without database query."""
 -         # Create dataset with PARTIAL_TEAM permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(
 -             created_by="creator-456", permission=DatasetPermissionEnum.PARTIAL_TEAM
 -         )
 - 
 -         # Create creator user
 -         creator_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="creator-456", role=TenantAccountRole.EDITOR
 -         )
 - 
 -         # Creator should have access without database query
 -         self._assert_permission_check_passes(dataset, creator_user)
 -         self._assert_database_query_not_called(mock_dataset_service_dependencies["db_session"])
 - 
 -     def test_partial_team_permission_with_explicit_permission(self, mock_dataset_service_dependencies):
 -         """Test PARTIAL_TEAM permission allows users with explicit permission records."""
 -         # Create dataset with PARTIAL_TEAM permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(permission=DatasetPermissionEnum.PARTIAL_TEAM)
 - 
 -         # Create normal user (not the creator)
 -         normal_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="normal-789", role=TenantAccountRole.NORMAL
 -         )
 - 
 -         # Mock database query to return a permission record
 -         mock_permission = DatasetPermissionTestDataFactory.create_dataset_permission_mock(
 -             dataset_id=dataset.id, account_id=normal_user.id
 -         )
 -         mock_dataset_service_dependencies["db_session"].query().filter_by().first.return_value = mock_permission
 - 
 -         # User with explicit permission should have access
 -         self._assert_permission_check_passes(dataset, normal_user)
 -         self._assert_database_query_called(mock_dataset_service_dependencies["db_session"], dataset.id, normal_user.id)
 - 
 -     def test_partial_team_permission_without_explicit_permission(self, mock_dataset_service_dependencies):
 -         """Test PARTIAL_TEAM permission denies users without explicit permission records."""
 -         # Create dataset with PARTIAL_TEAM permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(permission=DatasetPermissionEnum.PARTIAL_TEAM)
 - 
 -         # Create normal user (not the creator)
 -         normal_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="normal-789", role=TenantAccountRole.NORMAL
 -         )
 - 
 -         # Mock database query to return None (no permission record)
 -         mock_dataset_service_dependencies["db_session"].query().filter_by().first.return_value = None
 - 
 -         # User without explicit permission should be denied access
 -         self._assert_permission_check_fails(dataset, normal_user)
 -         self._assert_database_query_called(mock_dataset_service_dependencies["db_session"], dataset.id, normal_user.id)
 - 
 -     def test_partial_team_permission_non_creator_without_permission_fails(self, mock_dataset_service_dependencies):
 -         """Test that non-creators without explicit permission are denied access to PARTIAL_TEAM datasets."""
 -         # Create dataset with PARTIAL_TEAM permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(
 -             created_by="creator-456", permission=DatasetPermissionEnum.PARTIAL_TEAM
 -         )
 - 
 -         # Create a different user (not the creator)
 -         other_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="other-user-123", role=TenantAccountRole.NORMAL
 -         )
 - 
 -         # Mock database query to return None (no permission record)
 -         mock_dataset_service_dependencies["db_session"].query().filter_by().first.return_value = None
 - 
 -         # Non-creator without explicit permission should be denied access
 -         self._assert_permission_check_fails(dataset, other_user)
 -         self._assert_database_query_called(mock_dataset_service_dependencies["db_session"], dataset.id, other_user.id)
 - 
 -     # ==================== Enum Usage Tests ====================
 - 
 -     def test_partial_team_permission_uses_correct_enum(self):
 -         """Test that the method correctly uses DatasetPermissionEnum.PARTIAL_TEAM instead of string literals."""
 -         # Create dataset with PARTIAL_TEAM permission using enum
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(
 -             created_by="creator-456", permission=DatasetPermissionEnum.PARTIAL_TEAM
 -         )
 - 
 -         # Create creator user
 -         creator_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="creator-456", role=TenantAccountRole.EDITOR
 -         )
 - 
 -         # Creator should always have access regardless of permission level
 -         self._assert_permission_check_passes(dataset, creator_user)
 - 
 -     # ==================== Logging Tests ====================
 - 
 -     def test_permission_denied_logs_debug_message(self, mock_dataset_service_dependencies, mock_logging_dependencies):
 -         """Test that permission denied events are properly logged for debugging purposes."""
 -         # Create dataset with PARTIAL_TEAM permission
 -         dataset = DatasetPermissionTestDataFactory.create_dataset_mock(permission=DatasetPermissionEnum.PARTIAL_TEAM)
 - 
 -         # Create normal user (not the creator)
 -         normal_user = DatasetPermissionTestDataFactory.create_user_mock(
 -             user_id="normal-789", role=TenantAccountRole.NORMAL
 -         )
 - 
 -         # Mock database query to return None (no permission record)
 -         mock_dataset_service_dependencies["db_session"].query().filter_by().first.return_value = None
 - 
 -         # Attempt permission check (should fail)
 -         with pytest.raises(NoPermissionError):
 -             DatasetService.check_dataset_permission(dataset, normal_user)
 - 
 -         # Verify debug message was logged with correct user and dataset information
 -         mock_logging_dependencies["logging"].debug.assert_called_with(
 -             "User %s does not have permission to access dataset %s", normal_user.id, dataset.id
 -         )
 
 
  |