您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

test_dataset_permission.py 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. from unittest.mock import Mock, patch
  2. import pytest
  3. from models.account import Account, TenantAccountRole
  4. from models.dataset import Dataset, DatasetPermission, DatasetPermissionEnum
  5. from services.dataset_service import DatasetService
  6. from services.errors.account import NoPermissionError
  7. class TestDatasetPermissionService:
  8. """Test cases for dataset permission checking functionality"""
  9. def setup_method(self):
  10. """Set up test fixtures"""
  11. # Mock tenant and user
  12. self.tenant_id = "test-tenant-123"
  13. self.creator_id = "creator-456"
  14. self.normal_user_id = "normal-789"
  15. self.owner_user_id = "owner-999"
  16. # Mock dataset
  17. self.dataset = Mock(spec=Dataset)
  18. self.dataset.id = "dataset-123"
  19. self.dataset.tenant_id = self.tenant_id
  20. self.dataset.created_by = self.creator_id
  21. # Mock users
  22. self.creator_user = Mock(spec=Account)
  23. self.creator_user.id = self.creator_id
  24. self.creator_user.current_tenant_id = self.tenant_id
  25. self.creator_user.current_role = TenantAccountRole.EDITOR
  26. self.normal_user = Mock(spec=Account)
  27. self.normal_user.id = self.normal_user_id
  28. self.normal_user.current_tenant_id = self.tenant_id
  29. self.normal_user.current_role = TenantAccountRole.NORMAL
  30. self.owner_user = Mock(spec=Account)
  31. self.owner_user.id = self.owner_user_id
  32. self.owner_user.current_tenant_id = self.tenant_id
  33. self.owner_user.current_role = TenantAccountRole.OWNER
  34. def test_permission_check_different_tenant_should_fail(self):
  35. """Test that users from different tenants cannot access dataset"""
  36. self.normal_user.current_tenant_id = "different-tenant"
  37. with pytest.raises(NoPermissionError, match="You do not have permission to access this dataset."):
  38. DatasetService.check_dataset_permission(self.dataset, self.normal_user)
  39. def test_owner_can_access_any_dataset(self):
  40. """Test that tenant owners can access any dataset regardless of permission"""
  41. self.dataset.permission = DatasetPermissionEnum.ONLY_ME
  42. # Should not raise any exception
  43. DatasetService.check_dataset_permission(self.dataset, self.owner_user)
  44. def test_only_me_permission_creator_can_access(self):
  45. """Test ONLY_ME permission allows only creator to access"""
  46. self.dataset.permission = DatasetPermissionEnum.ONLY_ME
  47. # Creator should be able to access
  48. DatasetService.check_dataset_permission(self.dataset, self.creator_user)
  49. def test_only_me_permission_others_cannot_access(self):
  50. """Test ONLY_ME permission denies access to non-creators"""
  51. self.dataset.permission = DatasetPermissionEnum.ONLY_ME
  52. with pytest.raises(NoPermissionError, match="You do not have permission to access this dataset."):
  53. DatasetService.check_dataset_permission(self.dataset, self.normal_user)
  54. def test_all_team_permission_allows_access(self):
  55. """Test ALL_TEAM permission allows any team member to access"""
  56. self.dataset.permission = DatasetPermissionEnum.ALL_TEAM
  57. # Should not raise any exception for team members
  58. DatasetService.check_dataset_permission(self.dataset, self.normal_user)
  59. DatasetService.check_dataset_permission(self.dataset, self.creator_user)
  60. @patch("services.dataset_service.db.session")
  61. def test_partial_team_permission_creator_can_access(self, mock_session):
  62. """Test PARTIAL_TEAM permission allows creator to access"""
  63. self.dataset.permission = DatasetPermissionEnum.PARTIAL_TEAM
  64. # Should not raise any exception for creator
  65. DatasetService.check_dataset_permission(self.dataset, self.creator_user)
  66. # Should not query database for creator
  67. mock_session.query.assert_not_called()
  68. @patch("services.dataset_service.db.session")
  69. def test_partial_team_permission_with_explicit_permission(self, mock_session):
  70. """Test PARTIAL_TEAM permission allows users with explicit permission"""
  71. self.dataset.permission = DatasetPermissionEnum.PARTIAL_TEAM
  72. # Mock database query to return a permission record
  73. mock_permission = Mock(spec=DatasetPermission)
  74. mock_session.query().filter_by().first.return_value = mock_permission
  75. # Should not raise any exception
  76. DatasetService.check_dataset_permission(self.dataset, self.normal_user)
  77. # Verify database was queried correctly
  78. mock_session.query().filter_by.assert_called_with(dataset_id=self.dataset.id, account_id=self.normal_user.id)
  79. @patch("services.dataset_service.db.session")
  80. def test_partial_team_permission_without_explicit_permission(self, mock_session):
  81. """Test PARTIAL_TEAM permission denies users without explicit permission"""
  82. self.dataset.permission = DatasetPermissionEnum.PARTIAL_TEAM
  83. # Mock database query to return None (no permission record)
  84. mock_session.query().filter_by().first.return_value = None
  85. with pytest.raises(NoPermissionError, match="You do not have permission to access this dataset."):
  86. DatasetService.check_dataset_permission(self.dataset, self.normal_user)
  87. # Verify database was queried correctly
  88. mock_session.query().filter_by.assert_called_with(dataset_id=self.dataset.id, account_id=self.normal_user.id)
  89. @patch("services.dataset_service.db.session")
  90. def test_partial_team_permission_non_creator_without_permission_fails(self, mock_session):
  91. """Test that non-creators without explicit permission are denied access"""
  92. self.dataset.permission = DatasetPermissionEnum.PARTIAL_TEAM
  93. # Create a different user (not the creator)
  94. other_user = Mock(spec=Account)
  95. other_user.id = "other-user-123"
  96. other_user.current_tenant_id = self.tenant_id
  97. other_user.current_role = TenantAccountRole.NORMAL
  98. # Mock database query to return None (no permission record)
  99. mock_session.query().filter_by().first.return_value = None
  100. with pytest.raises(NoPermissionError, match="You do not have permission to access this dataset."):
  101. DatasetService.check_dataset_permission(self.dataset, other_user)
  102. def test_partial_team_permission_uses_correct_enum(self):
  103. """Test that the method correctly uses DatasetPermissionEnum.PARTIAL_TEAM"""
  104. # This test ensures we're using the enum instead of string literals
  105. self.dataset.permission = DatasetPermissionEnum.PARTIAL_TEAM
  106. # Creator should always have access
  107. DatasetService.check_dataset_permission(self.dataset, self.creator_user)
  108. @patch("services.dataset_service.logging")
  109. @patch("services.dataset_service.db.session")
  110. def test_permission_denied_logs_debug_message(self, mock_session, mock_logging):
  111. """Test that permission denied events are logged"""
  112. self.dataset.permission = DatasetPermissionEnum.PARTIAL_TEAM
  113. mock_session.query().filter_by().first.return_value = None
  114. with pytest.raises(NoPermissionError):
  115. DatasetService.check_dataset_permission(self.dataset, self.normal_user)
  116. # Verify debug message was logged
  117. mock_logging.debug.assert_called_with(
  118. f"User {self.normal_user.id} does not have permission to access dataset {self.dataset.id}"
  119. )