Source code for src.testing.fixtures

"""Pytest fixtures for tenant-aware testing.

Import these fixtures in your ``conftest.py`` to get automatic tenant
schema lifecycle management::

    # conftest.py
    from src.testing.fixtures import *  # noqa: F401,F403

    # test_invoices.py
    def test_create_invoice(tenant_context):
        invoice = Invoice.objects.create(number="INV-001")
        assert invoice.tenant_id is not None
"""

from __future__ import annotations

from collections.abc import Generator
from typing import Any

import pytest


[docs] @pytest.fixture(scope="session") def tenant_schema(django_db_setup: Any, django_db_blocker: Any) -> Generator[Any, None, None]: """Session-scoped fixture: creates a test tenant schema once. The tenant is created with storage provisioned (schema, RLS policies, etc.) and reused for the entire test session. Destroyed at session end. """ from src.testing.helpers import create_test_tenant, drop_test_tenant with django_db_blocker.unblock(): tenant = create_test_tenant("test-session") yield tenant drop_test_tenant(tenant)
[docs] @pytest.fixture() def tenant_context(tenant_schema: Any, db: Any) -> Generator[Any, None, None]: """Function-scoped fixture: activates tenant context for a single test. Activates the isolation backend and sets contextvars so all DB operations target the test tenant. Restores state on teardown. """ from django.db import connection from src.share_kernel.infrastructure.context import current_tenant_var from src.share_kernel.infrastructure.isolation import get_isolation_backend backend = get_isolation_backend() backend.activate_tenant(tenant_schema, connection) token = current_tenant_var.set(tenant_schema) yield tenant_schema backend.deactivate_tenant(connection) current_tenant_var.reset(token)