Source code for src.testing.testcases

"""Pytest fixtures for tenant-aware test lifecycle.

Replaces Django's TestCase with pytest fixtures that handle tenant schema
creation, activation, and teardown automatically.

Usage::

    # In your conftest.py
    from src.testing import tenant_fixture, tenant_context_fixture

    # In your test
    def test_invoice_creation(tenant_context_fixture):
        invoice = Invoice.objects.create(number="INV-001")
        assert invoice.tenant_id == tenant_context_fixture.id
"""

from __future__ import annotations

from collections.abc import Generator
from typing import Any

import pytest


[docs] @pytest.fixture(scope="session") def tenant_fixture(django_db_setup: Any, django_db_blocker: Any) -> Generator[Any, None, None]: """Session-scoped fixture: creates a test tenant with provisioned storage. The tenant is created once per session and reused across all tests. Destroys the tenant and its storage after the session ends. """ from src.testing.helpers import create_test_tenant, drop_test_tenant with django_db_blocker.unblock(): tenant = create_test_tenant("test-tenant") yield tenant drop_test_tenant(tenant)
[docs] @pytest.fixture() def tenant_context_fixture( tenant_fixture: Any, db: Any, ) -> Generator[Any, None, None]: """Function-scoped fixture: activates the tenant context for a single test. Sets contextvars and activates the isolation backend so all DB operations target the test tenant's storage. Restores the previous 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_fixture, connection) token = current_tenant_var.set(tenant_fixture) yield tenant_fixture backend.deactivate_tenant(connection) current_tenant_var.reset(token)
[docs] @pytest.fixture() def tenant_tx_context_fixture( tenant_fixture: Any, transactional_db: Any, ) -> Generator[Any, None, None]: """Function-scoped fixture for tests requiring real transaction commits. Same as ``tenant_context_fixture`` but uses ``transactional_db`` instead of ``db``, allowing tests to commit and observe side effects. """ 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_fixture, connection) token = current_tenant_var.set(tenant_fixture) yield tenant_fixture backend.deactivate_tenant(connection) current_tenant_var.reset(token)