Skip to content

Commit

Permalink
Tweak the featured and highlight choosers to relevant pages only
Browse files Browse the repository at this point in the history
  • Loading branch information
zerolab committed Feb 7, 2025
1 parent e28dbe7 commit 5e129ab
Show file tree
Hide file tree
Showing 5 changed files with 426 additions and 4 deletions.
23 changes: 23 additions & 0 deletions cms/topics/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from typing import Any

from django import forms
from wagtail.admin.forms import WagtailAdminPageForm


class TopicPageAdminForm(WagtailAdminPageForm):
topic_page_id = forms.CharField(required=False, widget=forms.HiddenInput())

def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)

if self.instance.pk:
self.fields["topic_page_id"].initial = self.instance.pk

def clean(self) -> dict[str, Any] | None:
cleaned_data: dict[str, Any] = super().clean()

# remove topic_page_id before save
if "topic_page_id" in cleaned_data:
del cleaned_data["topic_page_id"]

return cleaned_data
27 changes: 23 additions & 4 deletions cms/topics/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from modelcluster.fields import ParentalKey
from wagtail.admin.panels import FieldPanel, InlinePanel, PageChooserPanel
from wagtail.admin.panels import FieldPanel, InlinePanel
from wagtail.fields import RichTextField
from wagtail.models import Orderable, Page
from wagtail.search import index
Expand All @@ -18,6 +18,12 @@
from cms.core.utils import get_formatted_pages_list
from cms.methodology.models import MethodologyPage
from cms.topics.blocks import ExploreMoreStoryBlock
from cms.topics.forms import TopicPageAdminForm
from cms.topics.viewsets import (
FeaturedSeriesPageChooserWidget,
HighlightedArticlePageChooserWidget,
HighlightedMethodologyPageChooserWidget,
)

if TYPE_CHECKING:
from django.http import HttpRequest
Expand All @@ -36,7 +42,11 @@ class TopicPageRelatedArticle(Orderable):
related_name="+",
)

panels: ClassVar[list[FieldPanel]] = [PageChooserPanel("page", page_type=["articles.StatisticalArticlePage"])]
panels: ClassVar[list[FieldPanel]] = [
FieldPanel(
"page", widget=HighlightedArticlePageChooserWidget(linked_fields={"topic_page_id": "#id_topic_page_id"})
)
]


class TopicPageRelatedMethodology(Orderable):
Expand All @@ -47,12 +57,17 @@ class TopicPageRelatedMethodology(Orderable):
related_name="+",
)

panels: ClassVar[list[FieldPanel]] = [PageChooserPanel("page", page_type=["methodology.MethodologyPage"])]
panels: ClassVar[list[FieldPanel]] = [
FieldPanel(
"page", widget=HighlightedMethodologyPageChooserWidget(linked_fields={"topic_page_id": "#id_topic_page_id"})
)
]


class TopicPage(BasePage): # type: ignore[django-manager-missing]
"""The Topic page model."""

base_form_class = TopicPageAdminForm
template = "templates/pages/topic_page.html"
parent_page_types: ClassVar[list[str]] = ["themes.ThemePage"]
subpage_types: ClassVar[list[str]] = ["articles.ArticleSeriesPage", "methodology.MethodologyPage"]
Expand All @@ -71,7 +86,11 @@ class TopicPage(BasePage): # type: ignore[django-manager-missing]
content_panels: ClassVar[list["Panel"]] = [
*BasePage.content_panels,
FieldPanel("summary"),
FieldPanel("featured_series", heading=_("Featured")),
FieldPanel(
"featured_series",
heading=_("Featured"),
widget=FeaturedSeriesPageChooserWidget(linked_fields={"topic_page_id": "#id_topic_page_id"}),
),
InlinePanel(
"related_articles",
heading=_("Highlighted articles"),
Expand Down
217 changes: 217 additions & 0 deletions cms/topics/tests/test_viewsets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
from datetime import datetime

from django.test import TestCase
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from wagtail.test.utils import WagtailTestUtils

from cms.articles.tests.factories import ArticleSeriesPageFactory, StatisticalArticlePageFactory
from cms.methodology.tests.factories import MethodologyPageFactory
from cms.topics.tests.factories import TopicPageFactory
from cms.topics.viewsets import (
featured_series_page_chooser_viewset,
highlighted_article_page_chooser_viewset,
highlighted_methodology_page_chooser_viewset,
)


class FeaturedSeriesPageChooserViewSetTest(WagtailTestUtils, TestCase):
@classmethod
def setUpTestData(cls):
cls.superuser = cls.create_superuser(username="admin")

# Create test pages
cls.topic_page = TopicPageFactory(title="PSF")
cls.series1 = ArticleSeriesPageFactory(parent=cls.topic_page, title="Series A")
cls.series2 = ArticleSeriesPageFactory(parent=cls.topic_page, title="Series B")

cls.another_topic = TopicPageFactory(title="GDP")
cls.another_series = ArticleSeriesPageFactory(parent=cls.another_topic, title="Series Z")

cls.chooser_url = featured_series_page_chooser_viewset.widget_class().get_chooser_modal_url()
cls.chooser_results_url = reverse(featured_series_page_chooser_viewset.get_url_name("choose_results"))

cls.unused_topic = TopicPageFactory(title="CPI")

def setUp(self):
self.client.force_login(self.superuser)

def test_choose_view(self):
"""Test the choose view loads with the expected content."""
response = self.client.get(self.chooser_url)

self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/chooser/chooser.html")

for title in [self.series1.title, self.series2.title, self.another_series.title]:
self.assertContains(response, title)

self.assertContains(response, self.topic_page.title)
self.assertContains(response, self.another_topic.title)
self.assertNotContains(response, self.unused_topic.title)

# Check column headers
self.assertContains(response, "Topic")
self.assertContains(response, "Updated")
self.assertContains(response, "Status")

def test_chooser_search(self):
"""Test the AJAX results view."""
response = self.client.get(f"{self.chooser_results_url}?q=Series A")

self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/chooser/results.html")

self.assertContains(response, self.topic_page.title)
self.assertContains(response, self.series1.title)
self.assertNotContains(response, self.series2.title)
self.assertNotContains(response, self.another_series.title)
self.assertNotContains(response, self.another_topic.title)


class HighlightedPageChooserViewSetTest(WagtailTestUtils, TestCase):
@classmethod
def setUpTestData(cls):
cls.superuser = cls.create_superuser(username="admin")

# Create test pages
cls.topic_page = TopicPageFactory()
cls.article_series = ArticleSeriesPageFactory(parent=cls.topic_page)
cls.article = StatisticalArticlePageFactory(
parent=cls.article_series,
title="Article 1",
release_date=datetime(2024, 1, 1),
)
cls.second_article = StatisticalArticlePageFactory(
parent=cls.article_series,
title="Another Article",
release_date=datetime(2024, 2, 1),
)

cls.another_article = StatisticalArticlePageFactory(title="Article in another topic")
cls.methodology = MethodologyPageFactory(
parent=cls.topic_page,
title="Methodology 1",
publication_date=datetime(2024, 1, 1),
)
cls.second_methodology = MethodologyPageFactory(
parent=cls.topic_page,
title="Another Methodology",
publication_date=datetime(2023, 1, 1),
)

cls.unused_methodology = MethodologyPageFactory(
title="Unused Method",
publication_date=datetime(2024, 1, 1),
)

cls.article_chooser_url = highlighted_article_page_chooser_viewset.widget_class().get_chooser_modal_url()
cls.article_chooser_results_url = reverse(
highlighted_article_page_chooser_viewset.get_url_name("choose_results")
)
cls.methodology_chooser_url = (
highlighted_methodology_page_chooser_viewset.widget_class().get_chooser_modal_url()
)
cls.methodology_chooser_results_url = reverse(
highlighted_methodology_page_chooser_viewset.get_url_name("choose_results")
)

def setUp(self):
self.client.force_login(self.superuser)

def test_article_choose_view_with_topic_filter(self):
"""Test the article chooser view with topic_page_id filter."""
response = self.client.get(f"{self.article_chooser_url}?topic_page_id={self.topic_page.id}")

self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/chooser/chooser.html")

# Check articles are shown
self.assertListEqual(
response.context["items"].object_list,
[self.second_article, self.article],
)

# Check column headers
self.assertContains(response, "Release date")
self.assertContains(response, "Status")

def test_article_choose_view_without_topic_filter(self):
"""Test the article chooser view without topic_page_id returns no results."""
response = self.client.get(self.article_chooser_url)

self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/chooser/chooser.html")
self.assertNotContains(response, "Article 1")
self.assertNotContains(response, "Article 2")

def test_article_results_view_with_topic_filter(self):
"""Test the article AJAX results view with topic_page_id filter."""
response = self.client.get(f"{self.article_chooser_results_url}?topic_page_id={self.topic_page.id}&q=Another")

self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/chooser/results.html")

# Check articles are ordered by release_date descending
self.assertListEqual(
response.context["items"].object_list,
[self.second_article],
)

def test_methodology_choose_view_with_topic_filter(self):
"""Test the methodology chooser view with topic_page_id filter."""
response = self.client.get(f"{self.methodology_chooser_url}?topic_page_id={self.topic_page.id}")

self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/chooser/chooser.html")

# Check methodology is shown
self.assertListEqual(
response.context["items"].object_list,
[self.methodology, self.second_methodology],
)

def test_methodology_results_view_with_topic_filter(self):
"""Test the methodology AJAX results view with topic_page_id filter."""
response = self.client.get(
f"{self.methodology_chooser_results_url}?topic_page_id={self.topic_page.id}&q=Another"
)

self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/chooser/results.html")

self.assertListEqual(
response.context["items"].object_list,
[self.second_methodology],
)


class ViewSetConfigurationTest(TestCase):
"""Test the configuration of the viewsets."""

def test_featured_series_viewset_configuration(self):
self.assertFalse(featured_series_page_chooser_viewset.register_widget)
self.assertEqual(featured_series_page_chooser_viewset.model, ArticleSeriesPageFactory._meta.model)
self.assertEqual(featured_series_page_chooser_viewset.choose_one_text, _("Choose Article Series page"))
self.assertEqual(
featured_series_page_chooser_viewset.choose_another_text, _("Choose another Article Series page")
)
self.assertEqual(featured_series_page_chooser_viewset.edit_item_text, _("Edit Article Series page"))

def test_highlighted_article_viewset_configuration(self):
self.assertFalse(highlighted_article_page_chooser_viewset.register_widget)
self.assertEqual(highlighted_article_page_chooser_viewset.model, StatisticalArticlePageFactory._meta.model)
self.assertEqual(highlighted_article_page_chooser_viewset.choose_one_text, _("Choose Article page"))
self.assertEqual(highlighted_article_page_chooser_viewset.choose_another_text, _("Choose another Article page"))
self.assertEqual(highlighted_article_page_chooser_viewset.edit_item_text, _("Edit Article page"))
self.assertIn("topic_page_id", highlighted_article_page_chooser_viewset.preserve_url_parameters)

def test_highlighted_methodology_viewset_configuration(self):
self.assertFalse(highlighted_methodology_page_chooser_viewset.register_widget)
self.assertEqual(highlighted_methodology_page_chooser_viewset.model, MethodologyPageFactory._meta.model)
self.assertEqual(highlighted_methodology_page_chooser_viewset.choose_one_text, _("Choose Methodology page"))
self.assertEqual(
highlighted_methodology_page_chooser_viewset.choose_another_text, _("Choose another Methodology page")
)
self.assertEqual(highlighted_methodology_page_chooser_viewset.edit_item_text, _("Edit Methodology page"))
self.assertIn("topic_page_id", highlighted_methodology_page_chooser_viewset.preserve_url_parameters)
Loading

0 comments on commit 5e129ab

Please sign in to comment.