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.
62 lines
3.0 KiB
Python
62 lines
3.0 KiB
Python
import json
|
|
|
|
import pytest
|
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
|
|
from apps.events.models import Event, Registration
|
|
from apps.gallery.models import Gallery
|
|
|
|
|
|
pytestmark = [pytest.mark.integration, pytest.mark.django_db]
|
|
|
|
|
|
def _put(client, path, payload, headers):
|
|
return client.put(path, data=json.dumps(payload), content_type="application/json", **headers)
|
|
|
|
|
|
def test_event_reschedule_and_cancellation_notify_registered_users(client, user_factory, auth_headers,
|
|
event_factory, mocker):
|
|
staff = user_factory(is_staff=True)
|
|
attendee = user_factory(is_mobile_verified=True)
|
|
event = event_factory()
|
|
Registration.objects.create(event=event, user=attendee, status=Registration.StatusChoices.CONFIRMED)
|
|
notify = mocker.patch("apps.events.api.views.notify_user")
|
|
sms = mocker.patch("apps.events.api.views.send_critical_sms.delay")
|
|
path = f"/api/events/{event.pk}"
|
|
assert _put(client, path, {"location": "New hall"}, auth_headers(attendee)).status_code == 403
|
|
changed = _put(client, path, {"location": "New hall"}, auth_headers(staff))
|
|
assert changed.status_code == 200, changed.content
|
|
event.refresh_from_db()
|
|
assert event.location == "New hall"
|
|
assert notify.call_args.args[1]["type"] == "event_rescheduled"
|
|
sms.assert_called_with(attendee.mobile, "event_reschedule", event.title)
|
|
cancelled = _put(client, path, {"status": Event.StatusChoices.CANCELLED}, auth_headers(staff))
|
|
assert cancelled.status_code == 200, cancelled.content
|
|
event.refresh_from_db()
|
|
assert event.status == Event.StatusChoices.CANCELLED
|
|
assert notify.call_args.args[1]["type"] == "event_cancelled"
|
|
assert sms.call_count == 2
|
|
|
|
|
|
def test_event_gallery_upload_validation_and_removal(client, user_factory, auth_headers,
|
|
event_factory, mocker, tmp_path, settings):
|
|
settings.MEDIA_ROOT = tmp_path
|
|
staff = user_factory(is_staff=True)
|
|
member = user_factory()
|
|
event = event_factory()
|
|
headers = auth_headers(staff)
|
|
path = f"/api/events/{event.pk}/gallery"
|
|
queued = mocker.patch("apps.events.api.views.process_uploaded_image.delay")
|
|
assert client.get(path, **auth_headers(member)).status_code == 403
|
|
invalid = client.post(path, {"file": SimpleUploadedFile("bad.txt", b"bad", content_type="text/plain")}, **headers)
|
|
assert invalid.status_code == 400
|
|
uploaded = client.post(path, {"file": SimpleUploadedFile("photo.png", b"image", content_type="image/png")}, **headers)
|
|
assert uploaded.status_code == 201, uploaded.content
|
|
image = Gallery.objects.get(pk=uploaded.json()["id"])
|
|
assert event.gallery_images.filter(pk=image.pk).exists()
|
|
queued.assert_called_once_with(image.pk)
|
|
assert client.get(path, **headers).json()[0]["id"] == image.pk
|
|
assert client.delete(f"{path}/{image.pk}", **headers).status_code == 200
|
|
assert not event.gallery_images.filter(pk=image.pk).exists()
|
|
assert Gallery.deleted_objects.filter(pk=image.pk).exists()
|