Skip to content

Commit

Permalink
7048: Include page URLs in exported aging pages reports (#1015)
Browse files Browse the repository at this point in the history
* Disable built-in report

* Add custom report

* Register the custom report with Wagtail

* Add tests

(cherry picked from commit ea8c97c)
  • Loading branch information
ababic committed Jul 5, 2024
1 parent 194b047 commit a49d859
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 0 deletions.
Empty file added rca/reports/__init__.py
Empty file.
Empty file added rca/reports/tests/__init__.py
Empty file.
102 changes: 102 additions & 0 deletions rca/reports/tests/test_reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from datetime import timedelta

from django.contrib.auth.models import Group, Permission
from django.test import TestCase
from django.urls import reverse
from wagtail.models import GroupPagePermission, Page
from wagtail.test.utils import WagtailTestUtils

from rca.editorial.factories import EditorialPageFactory


class TestAgingPagesView(WagtailTestUtils, TestCase):
def setUp(self):
self.user = self.login()
self.root = Page.objects.first()
self.home = Page.objects.get(slug="home").specific
self.home.strapline = "This is a strapline"

def get(self, params={}):
return self.client.get(reverse("rca_aging_pages_report"), params)

def publish_home_page(self):
self.home.save_revision().publish(user=self.user)

def test_simple(self):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/reports/aging_pages.html")

def test_displays_only_published_pages(self):
response = self.get()
self.assertContains(response, "No pages found.")

self.publish_home_page()
response = self.get()

# Home Page should be listed
self.assertContains(response, self.home.title)
# Last published by user is set
self.assertContains(response, self.user.get_username())

self.assertNotContains(response, self.root.title)
self.assertNotContains(response, "No pages found.")

def test_permissions(self):
# Publish home page
self.publish_home_page()

# Remove privileges from user
self.user.is_superuser = False
self.user.user_permissions.add(
Permission.objects.get(
content_type__app_label="wagtailadmin", codename="access_admin"
)
)
self.user.save()

response = self.get()
self.assertEqual(response.status_code, 302)

# Add minimal permissions to the same user
group = Group.objects.create(name="test group")
GroupPagePermission.objects.create(
group=group,
page=Page.objects.first(),
permission_type="add",
)
self.user.groups.add(group)

response = self.get()
self.assertEqual(response.status_code, 200)

def test_csv_export(self):
self.publish_home_page()

# Set `last_published_at` to predictable value
self.home.last_published_at = "2013-01-01T12:00:00.000Z"
self.home.save()

# Publish more pages, so we can check for n+1 query issues
# and support for null 'last_published_by_user' values
for i in range(1, 10):
EditorialPageFactory(
parent=self.home,
title=f"Subpage {i}",
last_published_at=self.home.last_published_at + timedelta(days=i),
)

# Request report as CSV
with self.assertNumQueries(9):
response = self.get(params={"export": "csv"})
self.assertEqual(response.status_code, 200)

# Test CSV contents
data_lines = response.getvalue().decode().split("\n")
self.assertEqual(
data_lines[0], "Title,URL,Status,Last published at,Last published by,Type\r"
)
self.assertEqual(
data_lines[1],
f"Home,http://localhost/,live + draft,2013-01-01 12:00:00+00:00,[email protected],Home page\r", # noqa E501
)
43 changes: 43 additions & 0 deletions rca/reports/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from collections import OrderedDict

from django.utils.translation import gettext_lazy as _
from wagtail.admin.views.reports.aging_pages import (
AgingPagesView as OriginalAgingPagesView,
)
from wagtail.coreutils import multigetattr


class AgingPagesReportView(OriginalAgingPagesView):
"""
A customised version of Wagtail's built-in report, which includes
page's full URL as a column when the data is exported.
"""

list_export = [
"title",
"get_full_url",
"status_string",
"last_published_at",
"last_published_by_user",
"content_type",
]

export_headings = {
"get_full_url": _("URL"),
**OriginalAgingPagesView.export_headings,
}

def to_row_dict(self, item):
"""
Overrides `wagtail.admin.views.mixins.SpreadsheetExportMixin.to_row_dict()`
to call the 'get_full_url()' method when it comes across it - passing along
the current `HttpRequest` to allow sharing of 'site root path' data,
vastly reducing the number of database queries.
"""
row_dict = {}
for fieldname in self.list_export:
if fieldname == "get_full_url":
row_dict[fieldname] = item.specific_deferred.get_full_url(self.request)
else:
row_dict[fieldname] = multigetattr(item, fieldname)
return OrderedDict(row_dict)
35 changes: 35 additions & 0 deletions rca/reports/wagtail_hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from django.urls import path, reverse
from wagtail import hooks
from wagtail.admin.menu import MenuItem
from wagtail.permissions import page_permission_policy

from .views import AgingPagesReportView


@hooks.register("register_admin_urls")
def register_custom_aging_pages_report():
return [
path(
"reports/rca-aging-pages/",
AgingPagesReportView.as_view(),
name="rca_aging_pages_report",
),
]


class AgingPagesReportMenuItem(MenuItem):
def is_shown(self, request):
return page_permission_policy.user_has_any_permission(
request.user, ["add", "change", "publish"]
)


@hooks.register("register_reports_menu_item")
def register_aging_pages_report_menu_item():
return AgingPagesReportMenuItem(
"Aging pages",
reverse("rca_aging_pages_report"),
name="aging-pages",
icon_name="time",
order=1100,
)
4 changes: 4 additions & 0 deletions rca/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"rca.account_management",
"rca.donate",
"rca.scholarships",
"rca.reports",
"birdbath",
"django_countries",
"wagtail.contrib.settings",
Expand Down Expand Up @@ -652,6 +653,9 @@
{"class": "rca.utils.embed_finders.WixEmbedFinder"},
]

# This project uses it's own customised version
WAGTAIL_AGING_PAGES_ENABLED = False


# This is used by Wagtail's email notifications for constructing absolute
# URLs. Please set to the domain that users will access the admin site.
Expand Down

0 comments on commit a49d859

Please sign in to comment.