""" Unit tests for permission classes Tests IsAuthenticatedAndActive, HasTenantAccess, IsViewerOrAbove, IsEditorOrAbove, IsAdminOrOwner """ from django.test import TestCase from rest_framework.test import APIRequestFactory from rest_framework.views import APIView from igny8_core.api.permissions import ( IsAuthenticatedAndActive, HasTenantAccess, IsViewerOrAbove, IsEditorOrAbove, IsAdminOrOwner ) from igny8_core.auth.models import User, Account, Plan class PermissionsTestCase(TestCase): """Test cases for permission classes""" def setUp(self): """Set up test fixtures""" self.factory = APIRequestFactory() self.view = APIView() # Create test plan self.plan = Plan.objects.create( name="Test Plan", slug="test-plan", price=0, credits_per_month=1000 ) # Create owner user first (Account needs owner) self.owner_user = User.objects.create_user( username='owner', email='owner@test.com', password='testpass123', role='owner' ) # Create test account with owner self.account = Account.objects.create( name="Test Account", slug="test-account", plan=self.plan, owner=self.owner_user ) # Update owner user to have account self.owner_user.account = self.account self.owner_user.save() self.admin_user = User.objects.create_user( username='admin', email='admin@test.com', password='testpass123', role='admin', account=self.account ) self.editor_user = User.objects.create_user( username='editor', email='editor@test.com', password='testpass123', role='editor', account=self.account ) self.viewer_user = User.objects.create_user( username='viewer', email='viewer@test.com', password='testpass123', role='viewer', account=self.account ) # Create another account for tenant isolation testing self.other_owner = User.objects.create_user( username='other_owner', email='other_owner@test.com', password='testpass123', role='owner' ) self.other_account = Account.objects.create( name="Other Account", slug="other-account", plan=self.plan, owner=self.other_owner ) self.other_owner.account = self.other_account self.other_owner.save() self.other_user = User.objects.create_user( username='other', email='other@test.com', password='testpass123', role='owner', account=self.other_account ) def test_is_authenticated_and_active_authenticated(self): """Test IsAuthenticatedAndActive allows authenticated users""" permission = IsAuthenticatedAndActive() request = self.factory.get('/test/') request.user = self.owner_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_authenticated_and_active_unauthenticated(self): """Test IsAuthenticatedAndActive denies unauthenticated users""" permission = IsAuthenticatedAndActive() request = self.factory.get('/test/') request.user = None result = permission.has_permission(request, self.view) self.assertFalse(result) def test_is_authenticated_and_active_inactive_user(self): """Test IsAuthenticatedAndActive denies inactive users""" permission = IsAuthenticatedAndActive() self.owner_user.is_active = False self.owner_user.save() request = self.factory.get('/test/') request.user = self.owner_user result = permission.has_permission(request, self.view) self.assertFalse(result) def test_has_tenant_access_same_account(self): """Test HasTenantAccess allows users from same account""" permission = HasTenantAccess() request = self.factory.get('/test/') request.user = self.owner_user request.account = self.account result = permission.has_permission(request, self.view) self.assertTrue(result) def test_has_tenant_access_different_account(self): """Test HasTenantAccess denies users from different account""" permission = HasTenantAccess() request = self.factory.get('/test/') request.user = self.owner_user request.account = self.other_account result = permission.has_permission(request, self.view) self.assertFalse(result) def test_has_tenant_access_admin_bypass(self): """Test HasTenantAccess allows admin/developer to bypass""" permission = HasTenantAccess() request = self.factory.get('/test/') request.user = self.admin_user request.account = self.other_account # Different account result = permission.has_permission(request, self.view) self.assertTrue(result) # Admin should bypass def test_has_tenant_access_system_account(self): """Test HasTenantAccess allows system account users to bypass""" # Create system account owner system_owner = User.objects.create_user( username='system_owner_test', email='system_owner_test@test.com', password='testpass123', role='owner' ) # Create system account system_account = Account.objects.create( name="AWS Admin", slug="aws-admin", plan=self.plan, owner=system_owner ) system_owner.account = system_account system_owner.save() system_user = User.objects.create_user( username='system', email='system@test.com', password='testpass123', role='viewer', account=system_account ) permission = HasTenantAccess() request = self.factory.get('/test/') request.user = system_user request.account = self.account # Different account result = permission.has_permission(request, self.view) self.assertTrue(result) # System account user should bypass def test_is_viewer_or_above_viewer(self): """Test IsViewerOrAbove allows viewer role""" permission = IsViewerOrAbove() request = self.factory.get('/test/') request.user = self.viewer_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_viewer_or_above_editor(self): """Test IsViewerOrAbove allows editor role""" permission = IsViewerOrAbove() request = self.factory.get('/test/') request.user = self.editor_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_viewer_or_above_admin(self): """Test IsViewerOrAbove allows admin role""" permission = IsViewerOrAbove() request = self.factory.get('/test/') request.user = self.admin_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_viewer_or_above_owner(self): """Test IsViewerOrAbove allows owner role""" permission = IsViewerOrAbove() request = self.factory.get('/test/') request.user = self.owner_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_editor_or_above_viewer_denied(self): """Test IsEditorOrAbove denies viewer role""" permission = IsEditorOrAbove() request = self.factory.get('/test/') request.user = self.viewer_user result = permission.has_permission(request, self.view) self.assertFalse(result) def test_is_editor_or_above_editor_allowed(self): """Test IsEditorOrAbove allows editor role""" permission = IsEditorOrAbove() request = self.factory.get('/test/') request.user = self.editor_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_editor_or_above_admin_allowed(self): """Test IsEditorOrAbove allows admin role""" permission = IsEditorOrAbove() request = self.factory.get('/test/') request.user = self.admin_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_admin_or_owner_viewer_denied(self): """Test IsAdminOrOwner denies viewer role""" permission = IsAdminOrOwner() request = self.factory.get('/test/') request.user = self.viewer_user result = permission.has_permission(request, self.view) self.assertFalse(result) def test_is_admin_or_owner_editor_denied(self): """Test IsAdminOrOwner denies editor role""" permission = IsAdminOrOwner() request = self.factory.get('/test/') request.user = self.editor_user result = permission.has_permission(request, self.view) self.assertFalse(result) def test_is_admin_or_owner_admin_allowed(self): """Test IsAdminOrOwner allows admin role""" permission = IsAdminOrOwner() request = self.factory.get('/test/') request.user = self.admin_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_is_admin_or_owner_owner_allowed(self): """Test IsAdminOrOwner allows owner role""" permission = IsAdminOrOwner() request = self.factory.get('/test/') request.user = self.owner_user result = permission.has_permission(request, self.view) self.assertTrue(result) def test_all_permissions_unauthenticated_denied(self): """Test all permissions deny unauthenticated users""" permissions = [ IsAuthenticatedAndActive(), HasTenantAccess(), IsViewerOrAbove(), IsEditorOrAbove(), IsAdminOrOwner() ] request = self.factory.get('/test/') request.user = None for permission in permissions: result = permission.has_permission(request, self.view) self.assertFalse(result, f"{permission.__class__.__name__} should deny unauthenticated users")