chore(startpage/*): reformat using ruff (#18)

mk-personal-profile
Christian Merten 3 weeks ago committed by GitHub
parent 1c0744811b
commit 91575eb280
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,11 +1,15 @@
from django.contrib import admin
from django.conf import settings
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _ from django.conf import settings
from django.contrib import admin
from django.db.models import TextField from django.db.models import TextField
from django.forms import Textarea from django.forms import Textarea
from django.utils.translation import gettext_lazy as _
from .models import Post, Image, Section, MemberOnPost, Link from .models import Image
from .models import Link
from .models import MemberOnPost
from .models import Post
from .models import Section
class ImageInline(admin.TabularInline): class ImageInline(admin.TabularInline):
@ -19,37 +23,42 @@ class MemberOnPostInline(admin.TabularInline):
class PostForm(forms.ModelForm): class PostForm(forms.ModelForm):
urlname = forms.RegexField(regex=r'^{pattern}+$'.format(pattern=settings.STARTPAGE_URL_NAME_PATTERN), urlname = forms.RegexField(
label=_('URL'), regex=r"^{pattern}+$".format(pattern=settings.STARTPAGE_URL_NAME_PATTERN),
error_messages={'invalid': _('The url may only consist of letters, numerals, _, -, :, * and spaces.')}) label=_("URL"),
error_messages={
"invalid": _("The url may only consist of letters, numerals, _, -, :, * and spaces.")
},
)
@admin.register(Post) @admin.register(Post)
class PostAdmin(admin.ModelAdmin): class PostAdmin(admin.ModelAdmin):
inlines = [ImageInline, MemberOnPostInline] inlines = [ImageInline, MemberOnPostInline]
list_display = ['title', 'date', 'section', 'absolute_urlname'] list_display = ["title", "date", "section", "absolute_urlname"]
list_filter = ['section'] list_filter = ["section"]
search_fields = ['title'] search_fields = ["title"]
form = PostForm form = PostForm
class SectionForm(forms.ModelForm): class SectionForm(forms.ModelForm):
urlname = forms.RegexField(regex=r'^{pattern}+$'.format(pattern=settings.STARTPAGE_URL_NAME_PATTERN), urlname = forms.RegexField(
label=_('URL'), regex=r"^{pattern}+$".format(pattern=settings.STARTPAGE_URL_NAME_PATTERN),
error_messages={'invalid': _('The url may only consist of letters, numerals, _, -, :, * and spaces.')}) label=_("URL"),
error_messages={
"invalid": _("The url may only consist of letters, numerals, _, -, :, * and spaces.")
},
)
@admin.register(Section) @admin.register(Section)
class SectionAdmin(admin.ModelAdmin): class SectionAdmin(admin.ModelAdmin):
list_display = ['title', 'absolute_urlname'] list_display = ["title", "absolute_urlname"]
form = SectionForm form = SectionForm
@admin.register(Link) @admin.register(Link)
class LinkAdmin(admin.ModelAdmin): class LinkAdmin(admin.ModelAdmin):
list_display = ['title', 'url', 'visible'] list_display = ["title", "url", "visible"]
formfield_overrides = {
TextField: {'widget': Textarea(attrs={'rows': 2, 'cols': 40})}
}
formfield_overrides = {TextField: {"widget": Textarea(attrs={"rows": 2, "cols": 40})}}

@ -2,4 +2,4 @@ from django.apps import AppConfig
class StartpageConfig(AppConfig): class StartpageConfig(AppConfig):
name = 'startpage' name = "startpage"

@ -1,53 +1,61 @@
import os import os
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.urls import NoReverseMatch
from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.urls import reverse, NoReverseMatch from django.utils.translation import gettext_lazy as _
from utils import RestrictedFileField
from members.models import Group, Member
from markdownx.models import MarkdownxField from markdownx.models import MarkdownxField
from members.models import Group
from members.models import Member
from utils import RestrictedFileField
class Section(models.Model): class Section(models.Model):
""" """
A section of the website. A section of the website.
""" """
title = models.CharField(verbose_name=_('Title'), max_length=50)
urlname = models.CharField(verbose_name=_('URL'), max_length=25) title = models.CharField(verbose_name=_("Title"), max_length=50)
website_text = MarkdownxField(verbose_name=_('website text'), default='', blank=True) urlname = models.CharField(verbose_name=_("URL"), max_length=25)
show_in_navigation = models.BooleanField(verbose_name=_('Show in navigation'), default=True) website_text = MarkdownxField(verbose_name=_("website text"), default="", blank=True)
show_in_navigation = models.BooleanField(verbose_name=_("Show in navigation"), default=True)
class Meta: class Meta:
verbose_name = _('Section') verbose_name = _("Section")
verbose_name_plural = _('Sections') verbose_name_plural = _("Sections")
unique_together = ['urlname'] unique_together = ["urlname"]
def __str__(self): def __str__(self):
return self.title return self.title
def absolute_urlname(self): def absolute_urlname(self):
try: try:
return reverse('startpage:section', args=(self.urlname,)) return reverse("startpage:section", args=(self.urlname,))
except NoReverseMatch: except NoReverseMatch:
return _('deactivated') return _("deactivated")
absolute_urlname.short_description = 'URL'
absolute_urlname.short_description = "URL"
class Post(models.Model): class Post(models.Model):
""" """
A post with title, markdown and images. A post with title, markdown and images.
""" """
title = models.CharField(verbose_name=_('Title'), default='', max_length=50)
urlname = models.CharField(verbose_name=_('URL'), default='', max_length=50)
date = models.DateField(default=timezone.localdate, verbose_name=_('Date'), null=True, blank=True)
website_text = MarkdownxField(verbose_name=_('website text'), default='', blank=True)
groups = models.ManyToManyField(Group, verbose_name=_('Groups'), blank=True) title = models.CharField(verbose_name=_("Title"), default="", max_length=50)
detailed = models.BooleanField(verbose_name=_('detailed'), default=False) urlname = models.CharField(verbose_name=_("URL"), default="", max_length=50)
date = models.DateField(
default=timezone.localdate, verbose_name=_("Date"), null=True, blank=True
)
website_text = MarkdownxField(verbose_name=_("website text"), default="", blank=True)
groups = models.ManyToManyField(Group, verbose_name=_("Groups"), blank=True)
detailed = models.BooleanField(verbose_name=_("detailed"), default=False)
section = models.ForeignKey(Section, verbose_name=_('section'), on_delete=models.CASCADE, null=True, blank=False) section = models.ForeignKey(
Section, verbose_name=_("section"), on_delete=models.CASCADE, null=True, blank=False
)
def __str__(self): def __str__(self):
"""String represenation""" """String represenation"""
@ -56,53 +64,56 @@ class Post(models.Model):
class Meta: class Meta:
verbose_name = _("Post") verbose_name = _("Post")
verbose_name_plural = _("Posts") verbose_name_plural = _("Posts")
unique_together = ['section', 'urlname'] unique_together = ["section", "urlname"]
def absolute_section(self): def absolute_section(self):
if self.section is None: if self.section is None:
return 'Aktuelles' return "Aktuelles"
else: else:
return self.section.title return self.section.title
absolute_section.short_description = _('Section')
absolute_section.short_description = _("Section")
def absolute_urlname(self): def absolute_urlname(self):
try: try:
if self.section is None: if self.section is None:
return reverse('startpage:post', args=('aktuelles', self.urlname)) return reverse("startpage:post", args=("aktuelles", self.urlname))
else: else:
return reverse('startpage:post', args=(self.section.urlname, self.urlname)) return reverse("startpage:post", args=(self.section.urlname, self.urlname))
except NoReverseMatch: except NoReverseMatch:
return _('deactivated') return _("deactivated")
absolute_urlname.short_description = 'URL'
absolute_urlname.short_description = "URL"
class Image(models.Model): class Image(models.Model):
""" """
An image on a post. An image on a post.
""" """
post = models.ForeignKey(Post, on_delete=models.CASCADE) post = models.ForeignKey(Post, on_delete=models.CASCADE)
# file (not naming it file because of builtin) # file (not naming it file because of builtin)
f = RestrictedFileField(_('file'), f = RestrictedFileField(_("file"), upload_to="images", blank=True, max_upload_size=10)
upload_to='images',
blank=True,
max_upload_size=10)
def __str__(self): def __str__(self):
return os.path.basename(self.f.name) if self.f.name else str(_("Empty")) return os.path.basename(self.f.name) if self.f.name else str(_("Empty"))
class Meta: class Meta:
verbose_name = _('image') verbose_name = _("image")
verbose_name_plural = _('images') verbose_name_plural = _("images")
class MemberOnPost(models.Model): class MemberOnPost(models.Model):
""" """
One or multiple members on a post. One or multiple members on a post.
""" """
members = models.ManyToManyField(Member, verbose_name=_('Member'), blank=True)
post = models.ForeignKey(Post, verbose_name=_('Member'), on_delete=models.CASCADE, related_name='people') members = models.ManyToManyField(Member, verbose_name=_("Member"), blank=True)
description = models.TextField(_('Description'), default='', blank=True) post = models.ForeignKey(
tag = models.CharField(_('Tag'), max_length=20, default='', blank=True) Post, verbose_name=_("Member"), on_delete=models.CASCADE, related_name="people"
)
description = models.TextField(_("Description"), default="", blank=True)
tag = models.CharField(_("Tag"), max_length=20, default="", blank=True)
class Meta: class Meta:
verbose_name = _("Person") verbose_name = _("Person")
@ -114,23 +125,23 @@ class Link(models.Model):
Link to external resources that should be shown on the internal startpage. Link to external resources that should be shown on the internal startpage.
""" """
title = models.CharField(_('Title'), max_length=100, default='', blank=True) title = models.CharField(_("Title"), max_length=100, default="", blank=True)
description = models.TextField(_('Description'), default='', blank=True) description = models.TextField(_("Description"), default="", blank=True)
url = models.URLField(max_length=250) url = models.URLField(max_length=250)
icon = RestrictedFileField(verbose_name=_('Link Icon'), icon = RestrictedFileField(
upload_to='icons', verbose_name=_("Link Icon"),
blank=True, upload_to="icons",
max_upload_size=5, blank=True,
content_types=['image/jpeg', max_upload_size=5,
'image/png', content_types=["image/jpeg", "image/png", "image/gif"],
'image/gif']) )
visible = models.BooleanField(verbose_name=_('Visible'), default=True) visible = models.BooleanField(verbose_name=_("Visible"), default=True)
class Meta: class Meta:
verbose_name = _('Link') verbose_name = _("Link")
verbose_name_plural = _('Links') verbose_name_plural = _("Links")
def __str__(self): def __str__(self):
return self.title return self.title

@ -1,93 +1,137 @@
import os import os
from django.test import TestCase, Client, RequestFactory from importlib import reload
from django.urls import reverse, NoReverseMatch
from django.conf import settings
from django.templatetags.static import static
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.core.files.uploadedfile import SimpleUploadedFile
from django.template import Template, Context, TemplateSyntaxError, VariableDoesNotExist
from unittest import mock from unittest import mock
from unittest.mock import Mock from unittest.mock import Mock
from importlib import reload
from members.models import Member, Group, DIVERSE from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.template import Context
from django.template import TemplateSyntaxError
from django.test import Client
from django.test import RequestFactory
from django.test import TestCase
from django.urls import NoReverseMatch
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from members.models import DIVERSE
from members.models import Group
from members.models import Member
from startpage import urls from startpage import urls
from startpage.views import redirect, handler500 from startpage.templatetags.markdown_extras import render_as_template
from startpage.templatetags.markdown_extras import RenderAsTemplateNode, render_as_template from startpage.templatetags.markdown_extras import RenderAsTemplateNode
from startpage.views import handler500
from startpage.views import redirect
from .models import Post, Section, Image, Link, MemberOnPost from .models import Image
from .models import Link
from .models import Post
from .models import Section
class BasicTestCase(TestCase): class BasicTestCase(TestCase):
def setUp(self): def setUp(self):
orga = Section.objects.create(title='Organisation', urlname='orga', website_text='Section is a about everything.') orga = Section.objects.create(
recent = Section.objects.create(title='Recent', urlname=settings.RECENT_SECTION, website_text='Recently recent.') title="Organisation", urlname="orga", website_text="Section is a about everything."
reports = Section.objects.create(title='Reports', urlname=settings.REPORTS_SECTION, website_text='Reporty reports.') )
Post.objects.create(title='Climbing is fun', urlname='climbing-is-fun', website_text='Climbing is fun!', recent = Section.objects.create(
section=recent) title="Recent", urlname=settings.RECENT_SECTION, website_text="Recently recent."
Post.objects.create(title='Last trip', urlname='last-trip', website_text='A fun trip.', )
section=reports) reports = Section.objects.create(
title="Reports", urlname=settings.REPORTS_SECTION, website_text="Reporty reports."
)
Post.objects.create(
title="Climbing is fun",
urlname="climbing-is-fun",
website_text="Climbing is fun!",
section=recent,
)
Post.objects.create(
title="Last trip", urlname="last-trip", website_text="A fun trip.", section=reports
)
file = SimpleUploadedFile("post_image.jpg", b"file_content", content_type="image/jpeg") file = SimpleUploadedFile("post_image.jpg", b"file_content", content_type="image/jpeg")
staff_post = Post.objects.create(title='Staff', urlname='staff', website_text='This is our staff: Peter.', staff_post = Post.objects.create(
section=orga) title="Staff", urlname="staff", website_text="This is our staff: Peter.", section=orga
)
self.image_with_file = Image.objects.create(post=staff_post, f=file) self.image_with_file = Image.objects.create(post=staff_post, f=file)
file = SimpleUploadedFile("member_image.jpg", b"file_content", content_type="image/jpeg") file = SimpleUploadedFile("member_image.jpg", b"file_content", content_type="image/jpeg")
m = Member.objects.create(prename='crazy', lastname='cool', birth_date=timezone.now().date(), m = Member.objects.create(
email=settings.TEST_MAIL, gender=DIVERSE, prename="crazy",
image=file) lastname="cool",
crazy_group = Group.objects.create(name='CrazyClimbers', show_website=True) birth_date=timezone.now().date(),
email=settings.TEST_MAIL,
gender=DIVERSE,
image=file,
)
crazy_group = Group.objects.create(name="CrazyClimbers", show_website=True)
m.group.add(crazy_group) m.group.add(crazy_group)
m.save() m.save()
Group.objects.create(name='SuperClimbers', show_website=False) Group.objects.create(name="SuperClimbers", show_website=False)
crazy_post = Post.objects.create(title='The crazy climbers', urlname='crazy', website_text='foobar', crazy_post = Post.objects.create(
section=orga) title="The crazy climbers", urlname="crazy", website_text="foobar", section=orga
)
crazy_post.groups.add(crazy_group) crazy_post.groups.add(crazy_group)
crazy_post.save() crazy_post.save()
self.post_no_section = Post.objects.create(title='No Section', urlname='no-section', section=None) self.post_no_section = Post.objects.create(
title="No Section", urlname="no-section", section=None
)
self.image_no_file = Image.objects.create(post=staff_post) self.image_no_file = Image.objects.create(post=staff_post)
self.test_link = Link.objects.create(title='Test Link', url='https://example.com') self.test_link = Link.objects.create(title="Test Link", url="https://example.com")
class ModelsTestCase(BasicTestCase): class ModelsTestCase(BasicTestCase):
def test_str(self): def test_str(self):
orga = Section.objects.get(urlname='orga') orga = Section.objects.get(urlname="orga")
self.assertEqual(str(orga), orga.title, 'String representation does not match title.') self.assertEqual(str(orga), orga.title, "String representation does not match title.")
post = Post.objects.get(urlname='staff', section=orga) post = Post.objects.get(urlname="staff", section=orga)
self.assertEqual(post.absolute_section(), orga.title, 'Displayed section of post does not match section title.') self.assertEqual(
self.assertEqual(str(post), post.title, 'String representation does not match title.') post.absolute_section(),
orga.title,
"Displayed section of post does not match section title.",
)
self.assertEqual(str(post), post.title, "String representation does not match title.")
def test_absolute_urlnames(self): def test_absolute_urlnames(self):
orga = Section.objects.get(urlname='orga') orga = Section.objects.get(urlname="orga")
recent = Section.objects.get(urlname=settings.RECENT_SECTION) recent = Section.objects.get(urlname=settings.RECENT_SECTION)
reports = Section.objects.get(urlname=settings.REPORTS_SECTION) reports = Section.objects.get(urlname=settings.REPORTS_SECTION)
self.assertEqual(orga.absolute_urlname(), '/de/orga') self.assertEqual(orga.absolute_urlname(), "/de/orga")
post1 = Post.objects.get(urlname='staff', section=orga) post1 = Post.objects.get(urlname="staff", section=orga)
self.assertEqual(post1.absolute_urlname(), '/de/orga/staff') self.assertEqual(post1.absolute_urlname(), "/de/orga/staff")
self.assertEqual(post1.absolute_urlname(), reverse('startpage:post', args=(orga.urlname, 'staff'))) self.assertEqual(
post2 = Post.objects.get(urlname='climbing-is-fun', section=recent) post1.absolute_urlname(), reverse("startpage:post", args=(orga.urlname, "staff"))
self.assertEqual(post2.absolute_urlname(), )
'/de/{name}/climbing-is-fun'.format(name=settings.RECENT_SECTION)) post2 = Post.objects.get(urlname="climbing-is-fun", section=recent)
self.assertEqual(post2.absolute_urlname(), reverse('startpage:post', args=(recent.urlname, 'climbing-is-fun'))) self.assertEqual(
post3 = Post.objects.get(urlname='last-trip', section=reports) post2.absolute_urlname(),
self.assertEqual(post3.absolute_urlname(), "/de/{name}/climbing-is-fun".format(name=settings.RECENT_SECTION),
'/de/{name}/last-trip'.format(name=settings.REPORTS_SECTION)) )
self.assertEqual(post3.absolute_urlname(), reverse('startpage:post', args=(reports.urlname, 'last-trip'))) self.assertEqual(
post2.absolute_urlname(),
reverse("startpage:post", args=(recent.urlname, "climbing-is-fun")),
)
post3 = Post.objects.get(urlname="last-trip", section=reports)
self.assertEqual(
post3.absolute_urlname(), "/de/{name}/last-trip".format(name=settings.REPORTS_SECTION)
)
self.assertEqual(
post3.absolute_urlname(), reverse("startpage:post", args=(reports.urlname, "last-trip"))
)
def test_post_absolute_section_none(self): def test_post_absolute_section_none(self):
"""Test Post.absolute_section when section is None""" """Test Post.absolute_section when section is None"""
self.assertEqual(self.post_no_section.absolute_section(), 'Aktuelles') self.assertEqual(self.post_no_section.absolute_section(), "Aktuelles")
def test_post_absolute_urlname_no_section(self): def test_post_absolute_urlname_no_section(self):
"""Test Post.absolute_urlname when section is None""" """Test Post.absolute_urlname when section is None"""
expected_url = reverse('startpage:post', args=('aktuelles', 'no-section')) expected_url = reverse("startpage:post", args=("aktuelles", "no-section"))
self.assertEqual(self.post_no_section.absolute_urlname(), expected_url) self.assertEqual(self.post_no_section.absolute_urlname(), expected_url)
def test_image_str_without_file(self): def test_image_str_without_file(self):
"""Test Image.__str__ when no file is associated""" """Test Image.__str__ when no file is associated"""
self.assertEqual(str(self.image_no_file), str(_('Empty'))) self.assertEqual(str(self.image_no_file), str(_("Empty")))
def test_image_str_with_file(self): def test_image_str_with_file(self):
"""Test Image.__str__ when file is associated""" """Test Image.__str__ when file is associated"""
@ -97,133 +141,135 @@ class ModelsTestCase(BasicTestCase):
def test_link_str(self): def test_link_str(self):
"""Test Link.__str__ method""" """Test Link.__str__ method"""
self.assertEqual(str(self.test_link), 'Test Link') self.assertEqual(str(self.test_link), "Test Link")
def test_section_absolute_urlname_no_reverse_match(self): def test_section_absolute_urlname_no_reverse_match(self):
"""Test Section.absolute_urlname when NoReverseMatch occurs""" """Test Section.absolute_urlname when NoReverseMatch occurs"""
section = Section.objects.get(urlname='orga') section = Section.objects.get(urlname="orga")
with mock.patch('startpage.models.reverse', side_effect=NoReverseMatch): with mock.patch("startpage.models.reverse", side_effect=NoReverseMatch):
self.assertEqual(section.absolute_urlname(), str(_('deactivated'))) self.assertEqual(section.absolute_urlname(), str(_("deactivated")))
def test_post_absolute_urlname_no_reverse_match(self): def test_post_absolute_urlname_no_reverse_match(self):
"""Test Post.absolute_urlname when NoReverseMatch occurs""" """Test Post.absolute_urlname when NoReverseMatch occurs"""
post = Post.objects.get(urlname='staff') post = Post.objects.get(urlname="staff")
with mock.patch('startpage.models.reverse', side_effect=NoReverseMatch): with mock.patch("startpage.models.reverse", side_effect=NoReverseMatch):
self.assertEqual(post.absolute_urlname(), str(_('deactivated'))) self.assertEqual(post.absolute_urlname(), str(_("deactivated")))
class ViewTestCase(BasicTestCase): class ViewTestCase(BasicTestCase):
def test_index(self): def test_index(self):
c = Client() c = Client()
url = reverse('startpage:index') url = reverse("startpage:index")
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200, 'Response code is not 200 for index.') self.assertEqual(response.status_code, 200, "Response code is not 200 for index.")
def test_posts_no_category(self): def test_posts_no_category(self):
c = Client() c = Client()
url = reverse('startpage:post', args=(settings.RECENT_SECTION, 'climbing-is-fun')) url = reverse("startpage:post", args=(settings.RECENT_SECTION, "climbing-is-fun"))
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200, 'Response code is not 200 for climbing post.') self.assertEqual(response.status_code, 200, "Response code is not 200 for climbing post.")
def test_posts_orga(self): def test_posts_orga(self):
c = Client() c = Client()
url = reverse('startpage:post', args=('orga', 'staff')) url = reverse("startpage:post", args=("orga", "staff"))
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200, 'Response code is not 200 for staff post.') self.assertEqual(response.status_code, 200, "Response code is not 200 for staff post.")
def test_section(self): def test_section(self):
c = Client() c = Client()
url = reverse('startpage:section', args=('orga',)) url = reverse("startpage:section", args=("orga",))
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200, 'Response code is not 200 for section page.') self.assertEqual(response.status_code, 200, "Response code is not 200 for section page.")
def test_section_recent(self): def test_section_recent(self):
c = Client() c = Client()
url = reverse('startpage:' + settings.RECENT_SECTION) url = reverse("startpage:" + settings.RECENT_SECTION)
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200, 'Response code is not 200 for section page.') self.assertEqual(response.status_code, 200, "Response code is not 200 for section page.")
def test_section_reports(self): def test_section_reports(self):
c = Client() c = Client()
url = reverse('startpage:' + settings.REPORTS_SECTION) url = reverse("startpage:" + settings.REPORTS_SECTION)
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200, 'Response code is not 200 for section page.') self.assertEqual(response.status_code, 200, "Response code is not 200 for section page.")
def test_404(self): def test_404(self):
c = Client() c = Client()
response = c.get('/de/asdfasdfasdf') response = c.get("/de/asdfasdfasdf")
self.assertEqual(response.status_code, 404, 'Response code is not 404 when page not found.') self.assertEqual(response.status_code, 404, "Response code is not 404 when page not found.")
def test_impressum(self): def test_impressum(self):
c = Client() c = Client()
response = c.get('/de/impressum') response = c.get("/de/impressum")
self.assertEqual(response.status_code, 200, 'Response code is not 200 for impressum.') self.assertEqual(response.status_code, 200, "Response code is not 200 for impressum.")
def test_gruppen(self): def test_gruppen(self):
c = Client() c = Client()
url = reverse('startpage:gruppe_detail', args=('CrazyClimbers',)) url = reverse("startpage:gruppe_detail", args=("CrazyClimbers",))
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200, 'Response code is not 200 for group.') self.assertEqual(response.status_code, 200, "Response code is not 200 for group.")
def test_gruppen_404(self): def test_gruppen_404(self):
c = Client() c = Client()
url = reverse('startpage:gruppe_detail', args=('SuperClimbers',)) url = reverse("startpage:gruppe_detail", args=("SuperClimbers",))
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 404, 'Response code is not 404 for group.') self.assertEqual(response.status_code, 404, "Response code is not 404 for group.")
url = reverse('startpage:gruppe_detail', args=('SuperClimbersNotExisting',)) url = reverse("startpage:gruppe_detail", args=("SuperClimbersNotExisting",))
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 404, 'Response code is not 404 for group.') self.assertEqual(response.status_code, 404, "Response code is not 404 for group.")
def test_post_with_groups(self): def test_post_with_groups(self):
c = Client() c = Client()
url = reverse('startpage:post', args=('orga', 'crazy')) url = reverse("startpage:post", args=("orga", "crazy"))
response = c.get(url) response = c.get(url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_post_image(self): def test_post_image(self):
c = Client() c = Client()
url = self.image_with_file.f.url url = self.image_with_file.f.url
response = c.get('/de' + url) response = c.get("/de" + url)
self.assertEqual(response.status_code, 200, 'Images on posts should be visible without login.') self.assertEqual(
response.status_code, 200, "Images on posts should be visible without login."
)
def test_urlpatterns_with_redirect_url(self): def test_urlpatterns_with_redirect_url(self):
"""Test URL patterns when STARTPAGE_REDIRECT_URL is not empty""" """Test URL patterns when STARTPAGE_REDIRECT_URL is not empty"""
# Mock settings to have a non-empty STARTPAGE_REDIRECT_URL # Mock settings to have a non-empty STARTPAGE_REDIRECT_URL
with mock.patch.object(settings, 'STARTPAGE_REDIRECT_URL', 'https://example.com'): with mock.patch.object(settings, "STARTPAGE_REDIRECT_URL", "https://example.com"):
# Reload the urls module to trigger the conditional urlpatterns creation # Reload the urls module to trigger the conditional urlpatterns creation
reload(urls) reload(urls)
# Check that urlpatterns contains the redirect view # Check that urlpatterns contains the redirect view
url_names = [pattern.name for pattern in urls.urlpatterns if hasattr(pattern, 'name')] url_names = [pattern.name for pattern in urls.urlpatterns if hasattr(pattern, "name")]
self.assertIn('index', url_names) self.assertIn("index", url_names)
self.assertEqual(len(urls.urlpatterns), 2) # Should have index and impressum only self.assertEqual(len(urls.urlpatterns), 2) # Should have index and impressum only
def test_redirect_view(self): def test_redirect_view(self):
"""Test redirect view functionality""" """Test redirect view functionality"""
request = RequestFactory().get('/') request = RequestFactory().get("/")
with mock.patch.object(settings, 'STARTPAGE_REDIRECT_URL', 'https://example.com'): with mock.patch.object(settings, "STARTPAGE_REDIRECT_URL", "https://example.com"):
response = redirect(request) response = redirect(request)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, 'https://example.com') self.assertEqual(response.url, "https://example.com")
def test_handler500(self): def test_handler500(self):
"""Test custom 500 error handler""" """Test custom 500 error handler"""
request = RequestFactory().get('/') request = RequestFactory().get("/")
response = handler500(request) response = handler500(request)
self.assertEqual(response.status_code, 500) self.assertEqual(response.status_code, 500)
class MarkdownExtrasTestCase(TestCase): class MarkdownExtrasTestCase(TestCase):
def test_render_as_template_node_variable_does_not_exist(self): def test_render_as_template_node_variable_does_not_exist(self):
node = RenderAsTemplateNode('nonexistent_var', 'result') node = RenderAsTemplateNode("nonexistent_var", "result")
context = Context({}) context = Context({})
result = node.render(context) result = node.render(context)
self.assertEqual(result, '') self.assertEqual(result, "")
def test_render_as_template_no_arguments(self): def test_render_as_template_no_arguments(self):
token = Mock() token = Mock()
token.contents = 'render_as_template' token.contents = "render_as_template"
parser = Mock() parser = Mock()
with self.assertRaises(TemplateSyntaxError): with self.assertRaises(TemplateSyntaxError):
render_as_template(parser, token) render_as_template(parser, token)
@ -237,7 +283,7 @@ class MarkdownExtrasTestCase(TestCase):
def test_render_as_template_unquoted_argument(self): def test_render_as_template_unquoted_argument(self):
token = Mock() token = Mock()
token.contents = 'render_as_template content as result' token.contents = "render_as_template content as result"
parser = Mock() parser = Mock()
with self.assertRaises(TemplateSyntaxError): with self.assertRaises(TemplateSyntaxError):
render_as_template(parser, token) render_as_template(parser, token)

@ -5,23 +5,36 @@ from . import views
app_name = "startpage" app_name = "startpage"
if settings.STARTPAGE_REDIRECT_URL != '': if settings.STARTPAGE_REDIRECT_URL != "":
urlpatterns = [ urlpatterns = [
re_path(r'^$', views.redirect, name='index'), re_path(r"^$", views.redirect, name="index"),
re_path(r'^impressum/?$', views.static_view('startpage/impressum.html'), name='impressum'), re_path(r"^impressum/?$", views.static_view("startpage/impressum.html"), name="impressum"),
] ]
else: else:
urlpatterns = [ urlpatterns = [
re_path(r'^$', views.index, name='index'), re_path(r"^$", views.index, name="index"),
re_path(r'^impressum/?$', views.static_view('startpage/impressum.html'), name='impressum'), re_path(r"^impressum/?$", views.static_view("startpage/impressum.html"), name="impressum"),
re_path(r'^aktuelles/?$', views.aktuelles, name='aktuelles'), re_path(r"^aktuelles/?$", views.aktuelles, name="aktuelles"),
re_path(r'^berichte/?$', views.berichte, name='berichte'), re_path(r"^berichte/?$", views.berichte, name="berichte"),
re_path(r'^gruppen/?$', views.static_view('startpage/gruppen.html'), name='gruppen'), re_path(r"^gruppen/?$", views.static_view("startpage/gruppen.html"), name="gruppen"),
re_path(r'^gruppen/faq/?$', views.static_view('startpage/gruppen/faq.html'), name='faq'), re_path(r"^gruppen/faq/?$", views.static_view("startpage/gruppen/faq.html"), name="faq"),
re_path(r'^gruppen/(?P<group_name>{pattern}+)/?$'.format(pattern=settings.STARTPAGE_URL_NAME_PATTERN), re_path(
views.gruppe_detail, name='gruppe_detail'), r"^gruppen/(?P<group_name>{pattern}+)/?$".format(
re_path(r'^(?P<section_name>{pattern}+)/(?P<post_name>{pattern}+)/?$'.format(pattern=settings.STARTPAGE_URL_NAME_PATTERN), pattern=settings.STARTPAGE_URL_NAME_PATTERN
views.post, name='post'), ),
re_path(r'^(?P<section_name>{pattern}+)/?$'.format(pattern=settings.STARTPAGE_URL_NAME_PATTERN), views.gruppe_detail,
views.section, name='section'), name="gruppe_detail",
),
re_path(
r"^(?P<section_name>{pattern}+)/(?P<post_name>{pattern}+)/?$".format(
pattern=settings.STARTPAGE_URL_NAME_PATTERN
),
views.post,
name="post",
),
re_path(
r"^(?P<section_name>{pattern}+)/?$".format(pattern=settings.STARTPAGE_URL_NAME_PATTERN),
views.section,
name="section",
),
] ]

@ -1,20 +1,20 @@
from django.shortcuts import redirect as django_redirect, get_object_or_404
from django import shortcuts from django import shortcuts
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.http import Http404
from django.http import HttpResponseNotFound, Http404 from django.shortcuts import get_object_or_404
from itertools import chain from django.shortcuts import redirect as django_redirect
from members.models import Group from members.models import Group
from .models import Post, Section
from .models import Post
from .models import Section
# render shortcut adding additional context variables, needed for navbar # render shortcut adding additional context variables, needed for navbar
def render(request, template_path, context={}): def render(request, template_path, context={}):
context['groups'] = Group.objects.filter(show_website=True).order_by('name') context["groups"] = Group.objects.filter(show_website=True).order_by("name")
context['sections'] = Section.objects.all() context["sections"] = Section.objects.all()
try: try:
context['root_section'] = Section.objects.get(urlname=settings.ROOT_SECTION) context["root_section"] = Section.objects.get(urlname=settings.ROOT_SECTION)
except Section.DoesNotExist: except Section.DoesNotExist:
pass pass
return shortcuts.render(request, template_path, context) return shortcuts.render(request, template_path, context)
@ -22,10 +22,12 @@ def render(request, template_path, context={}):
def index(request): def index(request):
context = { context = {
'recent_posts': Post.objects.filter(section__urlname=settings.RECENT_SECTION).order_by('-date'), "recent_posts": Post.objects.filter(section__urlname=settings.RECENT_SECTION).order_by(
'reports': Post.objects.filter(section__urlname=settings.REPORTS_SECTION).order_by('-date'), "-date"
),
"reports": Post.objects.filter(section__urlname=settings.REPORTS_SECTION).order_by("-date"),
} }
return render(request, 'startpage/index.html', context) return render(request, "startpage/index.html", context)
def redirect(request): def redirect(request):
@ -36,6 +38,7 @@ def redirect(request):
def static_view(template_path): def static_view(template_path):
def view(request): def view(request):
return render(request, template_path) return render(request, template_path)
return view return view
@ -48,58 +51,58 @@ def gruppe_detail(request, group_name):
raise Http404 raise Http404
context = { context = {
'group': group, "group": group,
'people': group.leiters.all(), "people": group.leiters.all(),
} }
return render(request, 'startpage/gruppen/detail.html', context) return render(request, "startpage/gruppen/detail.html", context)
def aktuelles(request): def aktuelles(request):
section = get_object_or_404(Section, urlname=settings.RECENT_SECTION) section = get_object_or_404(Section, urlname=settings.RECENT_SECTION)
posts = Post.objects.filter(section=section) posts = Post.objects.filter(section=section)
context = { context = {
'posts': posts, "posts": posts,
} }
return render(request, 'startpage/aktuelles.html', context) return render(request, "startpage/aktuelles.html", context)
def berichte(request): def berichte(request):
section = get_object_or_404(Section, urlname=settings.REPORTS_SECTION) section = get_object_or_404(Section, urlname=settings.REPORTS_SECTION)
posts = Post.objects.filter(section=section) posts = Post.objects.filter(section=section)
context = { context = {
'posts': posts, "posts": posts,
} }
return render(request, 'startpage/berichte.html', context) return render(request, "startpage/berichte.html", context)
def post(request, section_name, post_name): def post(request, section_name, post_name):
section = get_object_or_404(Section, urlname=section_name) section = get_object_or_404(Section, urlname=section_name)
post = get_object_or_404(Post, section=section, urlname=post_name) post = get_object_or_404(Post, section=section, urlname=post_name)
context = { context = {
'post': post, "post": post,
'section': section, "section": section,
'people': [m for group in post.groups.all() for m in group.member_set.all()], "people": [m for group in post.groups.all() for m in group.member_set.all()],
} }
return render(request, 'startpage/post.html', context) return render(request, "startpage/post.html", context)
def section(request, section_name): def section(request, section_name):
assert section_name != 'aktuelles' assert section_name != "aktuelles"
assert section_name != 'berichte' assert section_name != "berichte"
section = get_object_or_404(Section, urlname=section_name) section = get_object_or_404(Section, urlname=section_name)
context = { context = {
'section': section, "section": section,
} }
return render(request, 'startpage/section.html', context) return render(request, "startpage/section.html", context)
def handler404(request, exception): def handler404(request, exception):
response = render(request, 'startpage/404.html') response = render(request, "startpage/404.html")
response.status_code = 404 response.status_code = 404
return response return response
def handler500(request): def handler500(request):
response = render(request, 'startpage/500.html') response = render(request, "startpage/500.html")
response.status_code = 500 response.status_code = 500
return response return response

Loading…
Cancel
Save