Files
guilan-ace-backend/conftest.py
Amirhossein Khalili ff99130938 test: migrate backend suites to pytest with module coverage gate
Split backend tests into unit and integration suites, add isolated fixtures and coverage enforcement, and update CI and test documentation. Cover current authentication, content, notification, payment, media, and admin flows; fix behaviors revealed by the new tests. Validate both suites and the per-module gate against local PostgreSQL.
2026-09-26 16:50:29 +03:30

110 lines
3.1 KiB
Python

"""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,
"status": Event.StatusChoices.PUBLISHED,
}
values.update(overrides)
return Event.objects.create(**values)
return create