Skip to content

Commit

Permalink
Filter by locale and slug; add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit Vermeulen committed Nov 25, 2024
1 parent ad65929 commit 78717e9
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 33 deletions.
46 changes: 26 additions & 20 deletions home/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from wagtail.api.v2.views import BaseAPIViewSet, PagesAPIViewSet
from wagtail.documents.api.v2.views import DocumentsAPIViewSet
from wagtail.images.api.v2.views import ImagesAPIViewSet
from wagtail.models import Locale
from wagtailmedia.api.views import MediaAPIViewSet

from .models import Assessment, AssessmentTag, OrderedContentSet
Expand Down Expand Up @@ -134,9 +135,11 @@ class OrderedContentSetViewSet(BaseAPIViewSet):
"name",
"profile_fields",
"pages",
"locale",
"slug",
]
known_query_parameters = BaseAPIViewSet.known_query_parameters.union(
["page", "qa", "gender", "age", "relationship"]
["page", "qa", "gender", "age", "relationship", "slug"]
)
pagination_class = PageNumberPagination
search_fields = ["name", "profile_fields"]
Expand Down Expand Up @@ -202,38 +205,41 @@ def get_queryset(self):
gender = self.request.query_params.get("gender", "")
age = self.request.query_params.get("age", "")
relationship = self.request.query_params.get("relationship", "")
slug = self.request.query_params.get("slug", "")
locale = self.request.query_params.get("locale", "")

if qa:
# return the latest revision for each OrderedContentSet
queryset = OrderedContentSet.objects.all().order_by("latest_revision_id")

for ocs in queryset:
latest_revision = ocs.revisions.order_by("-created_at").first()
if latest_revision:
latest_revision = latest_revision.as_object()
ocs.name = latest_revision.name
ocs.pages = latest_revision.pages
ocs.profile_fields = latest_revision.profile_fields
ocs.locale = latest_revision.locale
ocs.slug = latest_revision.slug

else:
if gender or age or relationship:
# it looks like you can't use advanced queries to filter on StreamFields
# so we have to do it like this.``
queryset = OrderedContentSet.objects.filter(
live=True,
)
filter_ids = [
self._filter_queryset_by_profile_fields(
x, gender, age, relationship
)
for x in queryset
]
queryset = OrderedContentSet.objects.filter(id__in=filter_ids).order_by(
"last_published_at"
)
else:
queryset = OrderedContentSet.objects.filter(
live=True,
).order_by("last_published_at")
queryset = OrderedContentSet.objects.filter(
live=True,
).order_by("last_published_at")

if gender or age or relationship:
# it looks like you can't use advanced queries to filter on StreamFields
# so we have to do it like this.``
filter_ids = [
self._filter_queryset_by_profile_fields(x, gender, age, relationship)
for x in queryset
]
queryset = queryset.filter(id__in=filter_ids).order_by("last_published_at")
if slug:
queryset = queryset.filter(slug=slug)
if locale:
locale = Locale.objects.get(language_code=locale)
queryset = queryset.filter(locale=locale)
return queryset


Expand Down
7 changes: 4 additions & 3 deletions home/import_ordered_content_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def _add_pages(
self,
ordered_set: OrderedContentSet,
pages: list[OrderedContentSetPage],
index: int,
) -> None:
"""
Given the extracted values from a row of the file, create the corresponding ordered content set pages.
Expand All @@ -146,7 +147,7 @@ def _add_pages(
ordered_set.pages.append(("pages", os_page))
else:
raise ImportException(
f"Content page not found for slug '{page.page_slug}'"
f"Content page not found for slug '{page.page_slug}'", index
)

def _create_ordered_set_from_row(
Expand All @@ -161,14 +162,14 @@ def _create_ordered_set_from_row(
:raises ImportException: If time, units, before_or_afters, page_slugs and contact_fields are not all equal length.
"""
ordered_set = self._get_or_init_ordered_content_set(
row, row["Slug"], row["Locale"]
row, row["Slug"].lower(), row["Locale"]
)
ordered_set.name = row["Name"]
self._add_profile_fields(ordered_set, row)

pages = self._extract_ordered_content_set_pages(row, index)

self._add_pages(ordered_set, pages)
self._add_pages(ordered_set, pages, index)

ordered_set.save()
return ordered_set
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.2.11 on 2024-11-19 13:19
# Generated by Django 4.2.11 on 2024-11-25 12:05

from django.db import migrations, models
from django.db.models import Count
Expand Down Expand Up @@ -31,14 +31,17 @@ def rename_duplicate_slugs(OrderedContentSet):


def set_locale_from_instance(OrderedContentSet, Site):
site = Site.objects.get(is_default_site=True)
for ocs in OrderedContentSet.objects.all():
if ocs.pages:
# Get the first page's data
first_page_data = ocs.pages[0]
contentpage = first_page_data.value.get("contentpage")
ocs.locale = contentpage.locale
if contentpage:
ocs.locale = contentpage.locale
else:
ocs.locale = site.root_page.locale
else:
site = Site.objects.get(is_default_site=True)
ocs.locale = site.root_page.locale
ocs.save(update_fields=["locale"])

Expand Down
4 changes: 4 additions & 0 deletions home/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1207,12 +1207,16 @@ def status(self) -> str:
return status

panels = [
FieldPanel("slug"),
FieldPanel("locale"),
FieldPanel("name"),
FieldPanel("profile_fields"),
FieldPanel("pages"),
]

api_fields = [
APIField("slug"),
APIField("locale"),
APIField("name"),
APIField("profile_fields"),
APIField("pages"),
Expand Down
13 changes: 13 additions & 0 deletions home/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,21 @@ def to_representation(self, instance):
return text


class OrderedLocaleField(serializers.Field):
"""
Serializes the "locale" field.
"""

def get_attribute(self, instance):
return instance

def to_representation(self, instance):
return instance.locale.language_code


class OrderedContentSetSerializer(BaseSerializer):
name = NameField(read_only=True)
locale = OrderedLocaleField(read_only=True)
pages = OrderedPagesField(read_only=True)
profile_fields = ProfileFieldsField(read_only=True)

Expand Down
2 changes: 1 addition & 1 deletion home/tests/import-export-data/ordered_content.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Name,Profile Fields,Page Slugs,Time,Unit,Before Or After,Contact Field,Slug,Locale
Test Set,"gender:male, relationship:in_a_relationship","first_time_user, first_time_user, first_time_user","2, 3, 4","days, months, years","before, before, after",edd,test_set,en
Test Set,"gender:male, relationship:in_a_relationship","first_time_user, first_time_user, first_time_user","2, 3, 4","days, months, years","before, before, after",edd,Test_Set,en
74 changes: 71 additions & 3 deletions home/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from wagtail import blocks
from wagtail.documents.models import Document # type: ignore
from wagtail.images.models import Image # type: ignore
from wagtail.models import Workflow, WorkflowContentType
from wagtail.models import Locale, Workflow, WorkflowContentType
from wagtail.models.sites import Site # type: ignore
from wagtailmedia.models import Media # type: ignore

Expand Down Expand Up @@ -1056,8 +1056,9 @@ def create_test_data(self):
import_content(f, "CSV", queue.Queue())
self.page1 = ContentPage.objects.first()
site = Site.objects.get(is_default_site=True)
self.default_locale = site.root_page.locale
self.ordered_content_set = OrderedContentSet(
name="Test set", slug="ordered-set-1", locale=site.root_page.locale
name="Test set", slug="ordered-set-1", locale=self.default_locale
)
self.ordered_content_set.pages.append(("pages", {"contentpage": self.page1}))
self.ordered_content_set.profile_fields.append(("gender", "female"))
Expand All @@ -1067,7 +1068,7 @@ def create_test_data(self):
self.ordered_content_set_timed = OrderedContentSet(
name="Test set timed",
slug="ordered-set-timed-1",
locale=site.root_page.locale,
locale=self.default_locale,
)
self.ordered_content_set_timed.pages.append(
(
Expand Down Expand Up @@ -1096,6 +1097,11 @@ def test_orderedcontent_endpoint(self, uclient):
content = json.loads(response.content)
assert content["count"] == 2
assert content["results"][0]["name"] == self.ordered_content_set.name
assert content["results"][0]["slug"] == self.ordered_content_set.slug
assert (
content["results"][0]["locale"]
== self.ordered_content_set.locale.language_code
)
assert content["results"][0]["profile_fields"][0] == {
"profile_field": "gender",
"value": "female",
Expand All @@ -1114,6 +1120,8 @@ def test_orderedcontent_detail_endpoint(self, uclient):
"profile_field": "gender",
"value": "female",
}
assert content["slug"] == self.ordered_content_set.slug
assert content["locale"] == self.ordered_content_set.locale.language_code
assert content["pages"][0] == {
"id": self.page1.id,
"title": self.page1.title,
Expand Down Expand Up @@ -1212,6 +1220,43 @@ def test_orderedcontent_endpoint_with_drafts(self, uclient):
"value": "female",
}

def test_orderedcontent_endpoint_filter_on_slug(self, uclient):
"""
The correct ordered content sets are returned if the filter is applied.
"""
url = "/api/v2/orderedcontent/?slug=ordered-set-1"
response = uclient.get(url)
content = json.loads(response.content)

assert response.status_code == 200
assert content["count"] == 1

assert content["results"][0]["name"] == self.ordered_content_set.name
assert content["results"][0]["profile_fields"][0] == {
"profile_field": "gender",
"value": "female",
}

def test_orderedcntent_endpoint_filter_on_locale(self, uclient):
"""
The correct ordered content sets are returned if the filter is applied.
"""
pt, _created = Locale.objects.get_or_create(language_code="pt")
ordered_content_set = OrderedContentSet(
name="Test set", slug="ordered-set-2", locale=pt
)
ordered_content_set.pages.append(("pages", {"contentpage": self.page1}))
ordered_content_set.profile_fields.append(("gender", "male"))
ordered_content_set.save()
ordered_content_set.save_revision().publish()

url = "/api/v2/orderedcontent/?locale=pt"
response = uclient.get(url)
content = json.loads(response.content)

assert response.status_code == 200
assert content["count"] == 1

def test_orderedcontent_endpoint_filter_male_on_gender_profile_field(self, uclient):
"""
The correct ordered content sets are returned if the filter is applied.
Expand Down Expand Up @@ -1245,6 +1290,29 @@ def test_orderedcontent_endpoint_filter_female_on_gender_profile_field(
assert response.status_code == 200
assert content["count"] == 2

def test_orderedcontent_endpoint_filter_female_on_gender_profile_field_qa_flag_set(
self, uclient
):
"""
The correct ordered content sets are returned if the filter is applied.
"""
site = Site.objects.get(is_default_site=True)
ordered_content_set = OrderedContentSet(
name="Test set", slug="ordered-set-2", locale=site.root_page.locale
)
ordered_content_set.pages.append(("pages", {"contentpage": self.page1}))
ordered_content_set.profile_fields.append(("gender", "male"))
ordered_content_set.save()
ordered_content_set.save_revision().publish()
self.ordered_content_set.unpublish()

url = "/api/v2/orderedcontent/?qa=true&gender=female"
response = uclient.get(url)
content = json.loads(response.content)

assert response.status_code == 200
assert content["count"] == 2

def test_orderedcontent_endpoint_filter_on_age_profile_field(self, uclient):
"""
The correct ordered content sets are returned if the filter is applied.
Expand Down
2 changes: 2 additions & 0 deletions home/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,8 @@ def test_add_form_content_loads(self, admin_client):

form = soup.find("form")
assert [heading.text.strip() for heading in form.find_all("h2")] == [
"Slug*",
"Locale*",
"Name*",
"Profile fields",
"Pages",
Expand Down
7 changes: 4 additions & 3 deletions home/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,6 @@ def __init__(self, purge, **kwargs):
def run(self):
try:
import_ordered_sets(self.file, self.file_type, self.progress_queue)
except Exception:
self.result_queue.put((messages.ERROR, "Ordered content set import failed"))
logger.exception("Ordered content set import failed")
except ImportException as e:
self.result_queue.put(
(
Expand All @@ -255,6 +252,10 @@ def run(self):
],
)
)
except Exception:
self.result_queue.put((messages.ERROR, "Ordered content set import failed"))
logger.exception("Ordered content set import failed")

else:
self.result_queue.put(
(messages.SUCCESS, "Ordered content set import successful")
Expand Down

0 comments on commit 78717e9

Please sign in to comment.