feat: add community contribution ranks
This commit is contained in:
116
apps/gamification/tests/integration/test_events.py
Normal file
116
apps/gamification/tests/integration/test_events.py
Normal file
@@ -0,0 +1,116 @@
|
||||
from io import StringIO
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
from django.contrib import admin
|
||||
from django.core.management import call_command
|
||||
|
||||
from apps.events.admin import RegistrationAdmin
|
||||
from apps.events.models import Registration
|
||||
from apps.events.services import verify_registration_attendance
|
||||
from apps.gamification.models import ContributionLedger
|
||||
from apps.gamification.services import summary_for_user
|
||||
|
||||
|
||||
pytestmark = [pytest.mark.integration, pytest.mark.django_db]
|
||||
|
||||
|
||||
def test_attendee_cannot_mark_their_own_registration_as_attended(
|
||||
client, event_factory, user_factory, auth_headers,
|
||||
):
|
||||
attendee = user_factory()
|
||||
event = event_factory()
|
||||
registration = Registration.objects.create(
|
||||
event=event,
|
||||
user=attendee,
|
||||
status=Registration.StatusChoices.CONFIRMED,
|
||||
)
|
||||
|
||||
response = client.put(
|
||||
f"/api/events/registrations/{registration.id}",
|
||||
data={"status": "attended"},
|
||||
content_type="application/json",
|
||||
**auth_headers(attendee),
|
||||
)
|
||||
|
||||
registration.refresh_from_db()
|
||||
assert response.status_code == 403
|
||||
assert registration.status == Registration.StatusChoices.CONFIRMED
|
||||
assert summary_for_user(attendee)["points_total"] == 0
|
||||
|
||||
|
||||
def test_staff_attendance_action_records_verifier_and_awards_once(
|
||||
event_factory, user_factory, mocker,
|
||||
):
|
||||
staff = user_factory(is_staff=True)
|
||||
attendee = user_factory()
|
||||
registration = Registration.objects.create(
|
||||
event=event_factory(),
|
||||
user=attendee,
|
||||
status=Registration.StatusChoices.CONFIRMED,
|
||||
)
|
||||
mocker.patch.object(RegistrationAdmin, "message_user")
|
||||
registration_admin = RegistrationAdmin(Registration, admin.site)
|
||||
request = SimpleNamespace(user=staff)
|
||||
|
||||
registration_admin.mark_attended(request, Registration.objects.filter(pk=registration.pk))
|
||||
registration.refresh_from_db()
|
||||
registration_admin.mark_attended(request, Registration.objects.filter(pk=registration.pk))
|
||||
|
||||
assert registration.status == Registration.StatusChoices.ATTENDED
|
||||
assert registration.attendance_verified_by_id == staff.id
|
||||
assert registration.attendance_verification_source == Registration.AttendanceVerificationSource.STAFF_ADMIN
|
||||
assert summary_for_user(attendee)["points_total"] == 30
|
||||
assert ContributionLedger.objects.filter(user=attendee).count() == 1
|
||||
|
||||
|
||||
def test_attendance_backfill_is_read_only_by_default_and_safe_to_repeat(
|
||||
event_factory, user_factory,
|
||||
):
|
||||
attendee = user_factory()
|
||||
event = event_factory()
|
||||
registration = Registration.objects.create(
|
||||
event=event,
|
||||
user=attendee,
|
||||
status=Registration.StatusChoices.ATTENDED,
|
||||
)
|
||||
Registration.objects.create(
|
||||
event=event_factory(),
|
||||
user=user_factory(),
|
||||
status=Registration.StatusChoices.CONFIRMED,
|
||||
)
|
||||
output = StringIO()
|
||||
|
||||
call_command("backfill_event_attendance", stdout=output)
|
||||
assert summary_for_user(attendee)["points_total"] == 0
|
||||
registration.refresh_from_db()
|
||||
assert registration.attendance_verification_source == ""
|
||||
assert "Dry run only" in output.getvalue()
|
||||
|
||||
call_command("backfill_event_attendance", apply=True, stdout=StringIO())
|
||||
call_command("backfill_event_attendance", apply=True, stdout=StringIO())
|
||||
|
||||
registration.refresh_from_db()
|
||||
assert registration.attendance_verification_source == Registration.AttendanceVerificationSource.HISTORICAL
|
||||
assert registration.attendance_verified_at is not None
|
||||
assert summary_for_user(attendee)["points_total"] == 30
|
||||
assert ContributionLedger.objects.filter(user=attendee).count() == 1
|
||||
|
||||
|
||||
def test_removing_verified_attendance_reverses_points_and_badges(event_factory, user_factory):
|
||||
attendee = user_factory()
|
||||
registration = Registration.objects.create(
|
||||
event=event_factory(),
|
||||
user=attendee,
|
||||
status=Registration.StatusChoices.CONFIRMED,
|
||||
)
|
||||
verify_registration_attendance(registration)
|
||||
assert summary_for_user(attendee)["points_total"] == 30
|
||||
registration.status = Registration.StatusChoices.CANCELLED
|
||||
registration.save(update_fields=["status", "updated_at"])
|
||||
|
||||
summary = summary_for_user(attendee)
|
||||
assert summary["points_total"] == 0
|
||||
assert summary["activity_counts"]["attendance"] == 0
|
||||
assert not any(badge["category"] == "attendance" for badge in summary["badges"])
|
||||
assert ContributionLedger.objects.filter(user=attendee).count() == 2
|
||||
Reference in New Issue
Block a user