from __future__ import annotations import pytest from django.contrib import messages from django.contrib.auth.models import AnonymousUser from django.contrib.messages import get_messages from django.contrib.messages.storage.fallback import FallbackStorage from django.contrib.sessions.middleware import SessionMiddleware from django.http import HttpResponse from django.shortcuts import render from django.test import RequestFactory, override_settings from django.urls import include, path from apps.core.middleware import AdminMessageGuardMiddleware def admin_message_test_view(request): messages.success(request, "Page 'Test page' has been updated.") messages.success(request, "Page 'Test page' has been updated.") messages.success(request, "Page 'Test page' has been published.") return render(request, "wagtailadmin/base.html", {}) urlpatterns = [ path("cms/__tests__/admin-messages/", admin_message_test_view), path("", include("config.urls")), ] def _build_request(rf: RequestFactory, path: str): request = rf.get(path) SessionMiddleware(lambda req: None).process_request(request) request.session.save() request.user = AnonymousUser() setattr(request, "_messages", FallbackStorage(request)) return request @pytest.mark.django_db def test_admin_message_guard_clears_stale_messages_on_frontend(rf): request = _build_request(rf, "/articles/test/") messages.success(request, "Page 'Test page' has been updated.") response = AdminMessageGuardMiddleware(lambda req: HttpResponse("ok"))(request) assert response.status_code == 200 assert list(get_messages(request)) == [] @pytest.mark.django_db def test_admin_message_guard_preserves_admin_messages(rf): request = _build_request(rf, "/cms/pages/1/edit/") messages.success(request, "Page 'Test page' has been updated.") response = AdminMessageGuardMiddleware(lambda req: HttpResponse("ok"))(request) remaining = list(get_messages(request)) assert response.status_code == 200 assert len(remaining) == 1 assert remaining[0].message == "Page 'Test page' has been updated." @pytest.mark.django_db @override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling") def test_wagtail_admin_template_deduplicates_consecutive_messages(client, django_user_model): admin = django_user_model.objects.create_superuser( username="admin-messages", email="admin-messages@example.com", password="admin-pass", ) client.force_login(admin) response = client.get("/cms/__tests__/admin-messages/") content = response.content.decode() assert response.status_code == 200 assert content.count("has been updated.") == 1 assert content.count("has been published.") == 1 @pytest.mark.django_db @override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling") def test_admin_messages_have_auto_clear(client, django_user_model): """The messages container must set auto-clear so messages dismiss themselves.""" admin = django_user_model.objects.create_superuser( username="admin-autoclear", email="admin-autoclear@example.com", password="admin-pass", ) client.force_login(admin) response = client.get("/cms/__tests__/admin-messages/") content = response.content.decode() assert response.status_code == 200 assert "data-w-messages-auto-clear-value" in content