diff --git a/djangoproject/scss/_style.scss b/djangoproject/scss/_style.scss index 27bf24b36..4fcccf526 100644 --- a/djangoproject/scss/_style.scss +++ b/djangoproject/scss/_style.scss @@ -1459,7 +1459,7 @@ a.cta { margin-bottom: 5px; } - li { + > li { border-top: 1px solid var(--hairline-color); margin-top: 35px; padding-top: 10px; diff --git a/djangoproject/templates/base_foundation.html b/djangoproject/templates/base_foundation.html index cec983f3d..f63f04838 100644 --- a/djangoproject/templates/base_foundation.html +++ b/djangoproject/templates/base_foundation.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{% load fundraising_extras %} +{% load fundraising_extras meetings i18n %} {% block og_title %}Django Software Foundation{% endblock %} @@ -25,5 +25,8 @@

About the foundation

  • Contributor license agreements
  • Organizing a Django conference
  • +

    {% translate "Latest DSF meeting minutes" %}

    + {% render_latest_meeting_minute_entries 2 %} + {% translate "More meeting minutes" %} {% endblock %} diff --git a/djangoproject/templates/foundation/meeting_snippet.html b/djangoproject/templates/foundation/meeting_snippet.html new file mode 100644 index 000000000..0e72198eb --- /dev/null +++ b/djangoproject/templates/foundation/meeting_snippet.html @@ -0,0 +1,25 @@ +{% load i18n %} + diff --git a/foundation/templatetags/__init__.py b/foundation/templatetags/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/foundation/templatetags/meetings.py b/foundation/templatetags/meetings.py new file mode 100644 index 000000000..80aeec8e8 --- /dev/null +++ b/foundation/templatetags/meetings.py @@ -0,0 +1,11 @@ +from django import template + +from ..models import Meeting + +register = template.Library() + + +@register.inclusion_tag("foundation/meeting_snippet.html") +def render_latest_meeting_minute_entries(num): + meetings = Meeting.objects.order_by("-date").prefetch_related("business")[:num] + return {"meetings": meetings} diff --git a/foundation/tests.py b/foundation/tests.py index 11cbd2786..38569f375 100644 --- a/foundation/tests.py +++ b/foundation/tests.py @@ -5,13 +5,23 @@ from django.urls import reverse from djmoney.money import Money -from .models import ApprovedGrant, BoardMember, Meeting, Office, Term +from .models import ApprovedGrant, BoardMember, Business, Meeting, Office, Term class MeetingTestCase(TestCase): + @classmethod + def setUpTestData(cls): + cls.user = User.objects.create_superuser( + "admin", "admin@example.com", "password" + ) + cls.member = BoardMember.objects.create( + account=cls.user, + office=Office.objects.create(name="treasurer"), + term=Term.objects.create(year=2023), + ) + def test_meeting_initial(self): - user = User.objects.create_superuser("admin", "admin@example.com", "password") - self.client.force_login(user) + self.client.force_login(self.user) response = self.client.get(reverse("admin:foundation_meeting_add")) self.assertContains(response, "DSF Board monthly meeting") self.assertContains(response, "dsf-board-monthly-meeting") @@ -20,17 +30,11 @@ def test_meeting_minutes_feed(self): """ Make sure that the meeting minutes RSS feed works """ - user = User.objects.create_superuser("admin", "admin@example.com", "password") - member = BoardMember.objects.create( - account=user, - office=Office.objects.create(name="treasurer"), - term=Term.objects.create(year=2023), - ) Meeting.objects.create( date=date.today(), title="DSF Board monthly meeting", slug="dsf-board-monthly-meeting", - leader=member, + leader=self.member, treasurer_report="Hello World", ) @@ -39,18 +43,11 @@ def test_meeting_minutes_feed(self): self.assertIn(b"DSF Board monthly meeting", response.content) def test_meeting_details(self): - user = User.objects.create_superuser("admin", "admin@example.com", "password") - self.client.force_login(user) - member = BoardMember.objects.create( - account=user, - office=Office.objects.create(name="treasurer"), - term=Term.objects.create(year=2023), - ) meeting = Meeting.objects.create( date=date(2023, 1, 12), title="DSF Board monthly meeting", slug="dsf-board-monthly-meeting", - leader=member, + leader=self.member, treasurer_report="Hello World", ) ApprovedGrant.objects.create( @@ -77,3 +74,42 @@ def test_meeting_details(self): self.assertContains(response, "DSF Board monthly meeting") self.assertContains(response, "USD $10,000.00") self.assertContains(response, "EUR €5,000.00") + + def test_latest_meeting_minutes(self): + common_meeting_data = { + "slug": "dsf-board-monthly-meeting", + "leader": self.member, + "treasurer_report": "Hello World", + "title": "DSF Board monthly meeting", + } + latest_meeting = Meeting.objects.create( + date=date(2023, 5, 12), **common_meeting_data + ) + previous_meeting = Meeting.objects.create( + date=date(2023, 4, 12), **common_meeting_data + ) + Meeting.objects.create(date=date(2023, 3, 12), **common_meeting_data) + common_business_data = { + "body": "Example", + "body_html": "Example", + "business_type": "New", + "meeting": latest_meeting, + } + Business.objects.create(title="Business item 1", **common_business_data) + Business.objects.create(title="Business item 2", **common_business_data) + Business.objects.create(title="Business item 3", **common_business_data) + + response = self.client.get(reverse("foundation_meeting_archive_index")) + + self.assertContains(response, "Latest DSF meeting minutes") + + self.assertContains(response, "DSF Board monthly meeting, May 12, 2023") + self.assertContains(response, latest_meeting.get_absolute_url()) + self.assertContains(response, "DSF Board monthly meeting, April 12, 2023") + self.assertContains(response, previous_meeting.get_absolute_url()) + self.assertNotContains(response, "DSF Board monthly meeting, March 12, 2023") + + self.assertContains(response, "New and Ongoing business", count=1) + self.assertContains(response, "Business item 1") + self.assertContains(response, "Business item 2") + self.assertContains(response, "Business item 3")