import uuid import pytest from django.contrib.auth import get_user_model from django.contrib.auth.hashers import make_password from rest_framework.test import APIClient from infrasynth.tenancy.models import Tenant, TenantMembership UserModel = get_user_model() @pytest.fixture def tenant(db): return Tenant.objects.create(slug=f"t-{uuid.uuid4().hex[:8]}", name="Test Workspace") @pytest.fixture def membership_factory(db): def create_membership(user, tenant, role="member", is_owner=False, is_active=True): return TenantMembership.objects.create( tenant=tenant, user=user, role=role, is_owner=is_owner, is_active=is_active, ) return create_membership @pytest.fixture(autouse=True) def bind_tenant_context(tenant): """Binds ``current_tenant`` for the whole test so scoped managers work.""" from infrasynth.tenancy.context import tenant_context with tenant_context(tenant): yield tenant @pytest.fixture def api_client(db): return APIClient() @pytest.fixture def user(db, tenant): user = UserModel.objects.create_user( username="testuser", email="test@example.com", password="testpass123", ) TenantMembership.objects.create(tenant=tenant, user=user, role="owner", is_owner=True) return user @pytest.fixture def admin_user(db, tenant): user = UserModel.objects.create_superuser( username="admin", email="admin@example.com", password="adminpass123", ) TenantMembership.objects.create(tenant=tenant, user=user, role="owner", is_owner=True) return user @pytest.fixture def member_user(db, tenant): """A non-owner member of the current tenant (no implicit permissions).""" user = UserModel.objects.create_user( username="member", email="member@example.com", password="memberpass123", ) TenantMembership.objects.create(tenant=tenant, user=user, role="member", is_owner=False) return user @pytest.fixture def member_client(member_user, db): client = APIClient() client.force_authenticate(user=member_user) return client @pytest.fixture def authenticated_client(user, db): client = APIClient() client.force_authenticate(user=user) return client @pytest.fixture def admin_client(admin_user, db): client = APIClient() client.force_authenticate(user=admin_user) return client @pytest.fixture def user_factory(): def create_user(**kwargs): defaults = { "username": "factory_user", "email": "factory@example.com", "password": make_password("factorypass123"), } defaults.update(kwargs) return UserModel.objects.create(**defaults) return create_user @pytest.fixture def role_factory(): from infrasynth.security.models import Role def create_role(**kwargs): defaults = { "name": "Test Role", "slug": "test-role", "permissions": [], } defaults.update(kwargs) return Role.objects.create(**defaults) return create_role @pytest.fixture def media_root(tmp_path, settings): settings.MEDIA_ROOT = str(tmp_path) return tmp_path @pytest.fixture(autouse=True) def clear_feature_cache(): from django.core.cache import cache cache.clear() yield cache.clear() @pytest.fixture def clean_feature_registry(): """Clears the global FeatureRegistry for the test, then restores it.""" from infrasynth.features.registry import FeatureRegistry snapshot = dict(FeatureRegistry._features) FeatureRegistry._features.clear() yield FeatureRegistry._features = snapshot @pytest.fixture def clean_config_registry(): """Clears the global ConfigRegistry for the test, then restores it.""" from infrasynth.configs.registry import ConfigRegistry snapshot = dict(ConfigRegistry._definitions) ConfigRegistry.clear() yield ConfigRegistry._definitions = snapshot