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)