"""Replay paid-event outcomes in the isolated Bundle 0 Django test database. External gateway calls, notifications, and SMS are mocked. This script is baseline evidence, not a production payment test or a browser gateway substitute. """ import json import os from unittest.mock import Mock, patch from django.conf import settings from django.test import Client, override_settings from apps.events.models import Event, Registration from apps.payments.models import Payment from apps.users.models import User from core.authentication import create_jwt_token assert os.environ.get("DJANGO_SETTINGS_MODULE") == "config.settings.test" assert settings.DATABASES["default"]["ENGINE"] == "django.db.backends.sqlite3" student = User.objects.get(username="bundle0_student") event = Event.objects.get(slug="bundle0-paid") client = Client() headers = {"HTTP_AUTHORIZATION": f"Bearer {create_jwt_token(student)}"} body = json.dumps({"event_id": event.pk, "description": "Local mocked payment replay"}) def create_payment(): return client.post( "/api/payments/create", data=body, content_type="application/json", **headers, ) with ( override_settings(ALLOWED_HOSTS=["testserver", "localhost"]), patch("apps.payments.api.views.notify_user"), patch("apps.payments.api.views.send_critical_sms.delay"), patch("apps.payments.api.views.requests.post") as gateway, ): gateway.side_effect = RuntimeError("simulated gateway outage") failed_request = create_payment() assert failed_request.status_code == 502, failed_request.content assert not Payment.objects.filter(user=student, event=event).exists() gateway.side_effect = None gateway.return_value = Mock() gateway.return_value.json.return_value = { "data": {"code": 100, "authority": "BUNDLE0-CANCEL"} } pending = create_payment() assert pending.status_code == 200, pending.content assert pending.json()["start_pay_url"] canceled = client.get( "/api/payments/callback", {"Authority": "BUNDLE0-CANCEL", "Status": "NOK"}, ) assert canceled.status_code == 302 assert "status=failed" in canceled.url assert Payment.objects.get(authority="BUNDLE0-CANCEL").status == Payment.OrderStatusChoices.CANCELED gateway.return_value.json.return_value = { "data": {"code": 100, "authority": "BUNDLE0-SUCCESS"} } pending = create_payment() assert pending.status_code == 200, pending.content gateway.return_value.json.return_value = { "data": {"code": 100, "ref_id": "BUNDLE0-REF"} } paid = client.get( "/api/payments/callback", {"Authority": "BUNDLE0-SUCCESS", "Status": "OK"}, ) assert paid.status_code == 302 assert "status=success" in paid.url assert Payment.objects.get(authority="BUNDLE0-SUCCESS").status == Payment.OrderStatusChoices.PAID assert Registration.objects.get(user=student, event=event).status == Registration.StatusChoices.CONFIRMED duplicate = create_payment() assert duplicate.status_code == 400 print("Paid replay: gateway outage 502; cancellation redirect; mocked success and confirmed registration; duplicate blocked.")