"""Shared pytest fixtures and collection checks for the backend.""" import itertools import fakeredis import pytest import requests def pytest_collection_modifyitems(items): for item in items: parts = item.path.parts expected = "unit" if "unit" in parts else "integration" if "integration" in parts else None marked = [kind for kind in ("unit", "integration") if list(item.iter_markers(kind))] if expected is None or marked != [expected]: raise pytest.UsageError( f"{item.nodeid}: place tests under unit/ or integration/ " "and mark each test with exactly its directory's marker" ) if expected == "unit" and list(item.iter_markers("django_db")): raise pytest.UsageError(f"{item.nodeid}: unit tests cannot use the database") @pytest.fixture(autouse=True) def no_outbound_http(monkeypatch): def refuse_request(*args, **kwargs): raise AssertionError("Tests must fake outbound HTTP requests") monkeypatch.setattr(requests.sessions.Session, "request", refuse_request) @pytest.fixture(autouse=True) def isolate_redis(monkeypatch): from apps.notifications import services from apps.users.services import auth fake = fakeredis.FakeRedis(decode_responses=True) otp_fake = fakeredis.FakeRedis(decode_responses=False) monkeypatch.setattr(services, "redis_client", fake) monkeypatch.setattr(auth, "get_redis_connection", lambda alias: otp_fake) @pytest.fixture def fake_redis(): return fakeredis.FakeRedis(decode_responses=False) @pytest.fixture def fake_notification_redis(): return fakeredis.FakeRedis(decode_responses=True) @pytest.fixture def user_factory(db): from apps.users.models import User sequence = itertools.count(1) def create(**overrides): index = next(sequence) values = { "username": f"test_user_{index}", "mobile": f"0919000{index:04d}", "password": "TestPass123!", } values.update(overrides) return User.objects.create_user(**values) return create @pytest.fixture def auth_headers(): from core.authentication import create_jwt_token def headers(user): return {"HTTP_AUTHORIZATION": f"Bearer {create_jwt_token(user)}"} return headers @pytest.fixture def event_factory(db): from datetime import timedelta from django.utils import timezone from apps.events.models import Event sequence = itertools.count(1) def create(**overrides): now = timezone.now() index = next(sequence) values = { "title": f"Test event {index}", "slug": f"test-event-{index}", "description": "Test event description", "start_time": now + timedelta(days=2), "end_time": now + timedelta(days=2, hours=2), "registration_start_date": now - timedelta(days=1), "registration_end_date": now + timedelta(days=1), "capacity": 10, "is_published": True, } values.update(overrides) return Event.objects.create(**values) return create