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.
67 lines
3.3 KiB
Python
67 lines
3.3 KiB
Python
import json
|
|
|
|
import pytest
|
|
|
|
from apps.communications.models import Announcement, PushNotificationDevice
|
|
|
|
|
|
pytestmark = [pytest.mark.integration, pytest.mark.django_db]
|
|
|
|
|
|
def _send(client, method, path, headers, payload=None):
|
|
kwargs = dict(headers)
|
|
if payload is not None:
|
|
kwargs.update(data=json.dumps(payload), content_type="application/json")
|
|
return getattr(client, method)(path, **kwargs)
|
|
|
|
|
|
def test_announcement_staff_crud_and_public_listing(client, user_factory, auth_headers):
|
|
staff = user_factory(is_staff=True)
|
|
member = user_factory()
|
|
staff_headers = auth_headers(staff)
|
|
member_headers = auth_headers(member)
|
|
payload = {"title": "Meeting", "content": "Welcome", "is_published": True}
|
|
assert _send(client, "post", "/api/communications/announcements/", member_headers, payload).status_code == 403
|
|
created = _send(client, "post", "/api/communications/announcements/", staff_headers, payload)
|
|
assert created.status_code == 200, created.content
|
|
item = Announcement.objects.get(title="Meeting")
|
|
listing = client.get("/api/communications/announcements/").json()
|
|
assert listing["items"][0]["id"] == item.id
|
|
assert client.get(f"/api/communications/announcements/{item.id}/").json()["title"] == "Meeting"
|
|
stats = _send(client, "get", "/api/communications/announcements/stats/", staff_headers)
|
|
assert stats.status_code == 200, stats.content
|
|
assert stats.json()["published_announcements"] == 1
|
|
updated = _send(client, "put", f"/api/communications/announcements/{item.id}/", staff_headers,
|
|
{"title": "Revised", "content": "New", "is_published": False})
|
|
assert updated.status_code == 200, updated.content
|
|
item.refresh_from_db()
|
|
assert item.title == "Revised" and not item.is_published
|
|
assert client.get("/api/communications/announcements/").json()["items"] == []
|
|
deleted = _send(client, "delete", f"/api/communications/announcements/{item.id}/", staff_headers)
|
|
assert deleted.status_code == 200, deleted.content
|
|
assert Announcement.deleted_objects.filter(pk=item.pk).exists()
|
|
|
|
|
|
def test_push_device_registration_update_and_removal(client, user_factory, auth_headers):
|
|
user = user_factory()
|
|
other = user_factory()
|
|
headers = auth_headers(user)
|
|
path = "/api/communications/push-devices/"
|
|
payload = {"device_token": "device-1", "device_type": "web"}
|
|
assert client.get(path).status_code == 401
|
|
first = _send(client, "post", path, headers, payload)
|
|
assert first.status_code == 200, first.content
|
|
device = PushNotificationDevice.objects.get(user=user, device_token="device-1")
|
|
device.is_active = False
|
|
device.save()
|
|
assert _send(client, "post", path, headers, payload).status_code == 200
|
|
device.refresh_from_db()
|
|
assert device.is_active
|
|
assert [row["id"] for row in _send(client, "get", path, headers).json()] == [device.id]
|
|
assert _send(client, "put", f"{path}{device.id}/", auth_headers(other), {"is_active": False}).status_code == 404
|
|
assert _send(client, "put", f"{path}{device.id}/", headers, {"is_active": False}).status_code == 200
|
|
device.refresh_from_db()
|
|
assert not device.is_active
|
|
assert _send(client, "delete", path + "?device_token=device-1", headers).status_code == 200
|
|
assert not PushNotificationDevice.objects.filter(pk=device.pk).exists()
|