Skip to content

Commit

Permalink
Merge branch 'main' into fix/a11y-fixes
Browse files Browse the repository at this point in the history
# Conflicts:
#	templates/includes/pagination.html
  • Loading branch information
liamjohnston committed Sep 10, 2024
2 parents c5c8b55 + cfc3afc commit 569bfc3
Show file tree
Hide file tree
Showing 52 changed files with 247 additions and 1,149 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ cdhweb.dbml

# Media ignores
static/dist
static/
myapp/static
media
static/CACHE
Expand Down
8 changes: 5 additions & 3 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
CHANGELOG
=========

4.0.0-dev1
4.0.0
-----
- Redesigned and rebuilt
- TODO
- Major overhaul, redesigned and rebuilt by Springload
- Dropped custom views and shift logic to using wagtail pages throughout
- numerous new wagtail blocks added
- frontend build now uses webpack, dropped django compressor

3.5.3
-----
Expand Down
8 changes: 1 addition & 7 deletions cdhweb/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
__version_info__ = (4, 0, 0, "dev1")


# Dot-connect all but the last. Last is dash-connected if not None.
__version__ = ".".join([str(i) for i in __version_info__[:-1]])
if __version_info__[-1] is not None:
__version__ += "-%s" % (__version_info__[-1],)
__version__ = "4.0.0"


# context processor to add version to the template environment; can be
Expand Down
27 changes: 1 addition & 26 deletions cdhweb/blog/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import bleach

from django.core.paginator import Paginator
from django.db import models
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
Expand Down Expand Up @@ -226,30 +225,6 @@ def get_sitemap_urls(self, request):
urls[0]["priority"] = 0.6 # default is 0.5; slight increase
return urls

@cached_property
def feeds_description(self):
"""
Plaintext description for RSS and Atom feeds
Short description, then description, then looks for
the first paragraph of the text
"""
if self.short_description.strip():
return self.short_description.strip()

description = bleach.clean(self.description, tags=[], strip=True)
# Fall back to the first block of the page if
# there's no description, once the HTML is removed
if not description:
# Iterate over blocks and use content from first paragraph content
for block in self.body:
if block.block_type == "paragraph":
# Return the very first block
description = block
return bleach.clean(description, tags=[], strip=True)

return "" # We're really out of ideas, prevent a "None"


class BlogLinkPageArchived(LinkPage):
"""Container page that defines where blog posts can be created."""
Expand Down
1 change: 1 addition & 0 deletions cdhweb/blog/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def make_article(blog_link_page, staffer, postdoc):
in_2019 = timezone.datetime(2019, 3, 4, 8, 25, tzinfo=EST).astimezone(tz.utc)
in_2020 = timezone.datetime(2020, 1, 15, 20, 12, tzinfo=EST).astimezone(tz.utc)
post = BlogPost(
short_title="We wrote an article together for the CDH website",
title="We wrote an article together, and it got published on the CDH website",
body=to_streamfield_safe(
"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>"
Expand Down
2 changes: 1 addition & 1 deletion cdhweb/blog/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def test_str(self, article):
author = article.authors.first()
assert (
str(author)
== 'Staffer on "We wrote an article together, and it got published on the CDH we…" (March 4, 2019)'
== "Staffer on We wrote an article together, and it got published on the CDH website"
)


Expand Down
26 changes: 8 additions & 18 deletions cdhweb/blog/tests/test_pages.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
import pytest
from wagtail.test.utils import WagtailPageTestCase

from cdhweb.blog.models import BlogLinkPageArchived, BlogPost
from cdhweb.blog.models import BlogLandingPage, BlogLinkPageArchived, BlogPost


class TestBlogPost:
def test_short_title(self, article):
"""blog post should truncate title to 65char with ellipsis"""
# article fixture has a long title
assert (
article.short_title
== "We wrote an article together, and it got published on the CDH we…"
)

def test_short_description(self, article):
"""blog post should truncate description to 250char with ellipsis"""
# article fixture has a long description
assert article.short_description == (
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
"enim ad minim veniam, quis nostrud exercitation ullamco laboris "
"nisi ut aliquip ex ea commodo con…"
)
assert article.short_title == "We wrote an article together for the CDH website"

def test_author_list(self, article, staffer, postdoc):
"""blog post should list author names in order"""
Expand All @@ -38,12 +25,13 @@ def test_author_list(self, article, staffer, postdoc):
assert article.authors.all()[1].person == staffer

def test_str(self, article):
"""blog post should display as title + formatted date"""
"""blog post should display as title"""
assert (
str(article)
== '"We wrote an article together, and it got published on the CDH we…" (March 4, 2019)'
== "We wrote an article together, and it got published on the CDH website"
)

@pytest.mark.skip("updated logic; test get_url_parts?")
def test_get_url(self, article):
"""blog post should be accessed via custom url with y/m/d info"""
# should pad with zeroes and include year, month, day, slug
Expand All @@ -70,7 +58,9 @@ def test_subpage_types(self):

def test_parent_page_types(self):
"""blog posts always go under the blog link page"""
self.assertAllowedParentPageTypes(BlogPost, [BlogLinkPageArchived])
self.assertAllowedParentPageTypes(
BlogPost, [BlogLinkPageArchived, BlogLandingPage]
)


class TestBlogLinkPageArchived(WagtailPageTestCase):
Expand Down
55 changes: 0 additions & 55 deletions cdhweb/blog/tests/test_sitemaps.py

This file was deleted.

2 changes: 2 additions & 0 deletions cdhweb/blog/tests/test_templates.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest
from pytest_django.asserts import assertContains


@pytest.mark.skip("broken tests, url routing error; templates no longer used?")
class TestBlogPostDetail:
def test_title(self, client, announcement):
"""blog post detail page should include post title"""
Expand Down
83 changes: 8 additions & 75 deletions cdhweb/blog/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,110 +1,43 @@
from datetime import date, timezone

import pytest
from django.urls import reverse
from pytest_django.asserts import assertContains

from cdhweb.blog.tests.conftest import announcement


class TestBlogYearArchiveView:
def test_month_list(self, client, blog_posts):
"""blog post year archive should add months for all posts to context"""
# year is irrelevant; we always want all months to render the dropdown
response = client.get(reverse("blog:by-year", kwargs={"year": "2019"}))
dates = [post.first_published_at for _title, post in blog_posts.items()]
# months will appear as datetime.date objects with day set to 1
months = set([date(pubdate.year, pubdate.month, 1) for pubdate in dates])
# should be ordered with most recent first
assert list(response.context["date_list"]) == sorted(months, reverse=True)

def test_title(self, client, blog_posts):
"""blog post year archive should add year to context as title"""
response = client.get(reverse("blog:by-year", kwargs={"year": "2019"}))
assert response.context["page_title"] == "2019 Updates"


class TestBlogMonthArchiveView:
def test_month_list(self, client, blog_posts):
"""blog post year archive should add months for all posts to context"""
# args are irrelevant; we always want all months to render the dropdown
response = client.get(
reverse("blog:by-month", kwargs={"year": "2019", "month": "03"})
)
dates = [post.first_published_at for _title, post in blog_posts.items()]
# months will appear as datetime.date objects with day set to 1
months = set([date(pubdate.year, pubdate.month, 1) for pubdate in dates])
# should be ordered with most recent first
assert list(response.context["date_list"]) == sorted(months, reverse=True)

def test_title(self, client, blog_posts):
"""blog post year archive should add year/month to context as title"""
response = client.get(
reverse("blog:by-month", kwargs={"year": "2019", "month": "03"})
)
assert response.context["page_title"] == "March 2019 Updates"


class TestBlogPostDetailView:
def test_context_obj(self, client, announcement):
"""blog post detail view should serve blog post in context"""
response = client.get(announcement.get_url())
assert response.context["page"] == announcement

def test_draft_404(self, client, announcement):
"""blog post detail view should serve 404 for draft posts"""
announcement.unpublish()
response = client.get(announcement.get_url())
assert response.status_code == 404

def test_next_prev(self, client, blog_posts):
"""blog post detail view should have next/prev posts in context"""
article = blog_posts["article"]
feature = blog_posts["project_feature"]
announcement = blog_posts["announcement"]
# feature is oldest post; should have no prev and only next
response = client.get(feature.get_url())
assert response.context["previous"] == None
assert response.context["next"] == article
# article is in the middle; should have prev and next
response = client.get(article.get_url())
assert response.context["previous"] == feature
assert response.context["next"] == announcement
# announcement is newest; should have prev but no next
response = client.get(announcement.get_url())
assert response.context["previous"] == article
assert response.context["next"] == None


class TestRssBlogPostFeed:
def test_titles(self, client, blog_posts):
"""rss feed should list post titles"""
response = client.get(reverse("blog:rss"))
response = client.get(reverse("rss"))
for _, post in blog_posts.items():
assertContains(response, "<title>%s</title>" % post.title)

@pytest.mark.skip("broken in update, now using description template")
def test_descriptions(self, client, blog_posts):
"""rss feed should list post descriptions"""
response = client.get(reverse("blog:rss"))
response = client.get(reverse("rss"))
for _, post in blog_posts.items():
assertContains(
response, "<description>%s</description>" % post.get_description()
)

def test_links(self, client, blog_posts):
"""rss feed should list post descriptions"""
response = client.get(reverse("blog:rss"))
response = client.get(reverse("rss"))
for _, post in blog_posts.items():
assertContains(response, "<link>%s</link>" % post.get_full_url())

def test_author_names(self, client, blog_posts):
"""rss feed should list author names and emails if present"""
response = client.get(reverse("blog:rss"))
response = client.get(reverse("rss"))
# author name is combined with email, if present and single author
assertContains(response, "<author>[email protected] (Tom)</author>")

def test_pubdates(self, client, blog_posts):
"""rss feed should list post publication dates"""
response = client.get(reverse("blog:rss"))
response = client.get(reverse("rss"))
# all dates will display as their UTC versions
for _, post in blog_posts.items():
assertContains(
Expand All @@ -117,7 +50,7 @@ def test_pubdates(self, client, blog_posts):

def test_last_modified(self, client, blog_posts):
"""rss feed should list most recent modification date for whole feed"""
response = client.get(reverse("blog:rss"))
response = client.get(reverse("rss"))
# most recently modified post was announcement; displays as UTC
announcement = blog_posts["announcement"]
assertContains(
Expand Down
Loading

0 comments on commit 569bfc3

Please sign in to comment.