diff options
Diffstat (limited to '')
| -rw-r--r-- | pydis_site/apps/home/templatetags/wiki_extra.py | 53 | ||||
| -rw-r--r-- | pydis_site/apps/home/tests/test_wiki_templatetags.py | 187 | 
2 files changed, 195 insertions, 45 deletions
| diff --git a/pydis_site/apps/home/templatetags/wiki_extra.py b/pydis_site/apps/home/templatetags/wiki_extra.py index 16539ded..a6861fd9 100644 --- a/pydis_site/apps/home/templatetags/wiki_extra.py +++ b/pydis_site/apps/home/templatetags/wiki_extra.py @@ -1,12 +1,8 @@ -from typing import Union +from typing import Union, Dict, Type, Any  from django import template -from django.forms import ( -    BooleanField, BoundField, CharField, ChoiceField, ComboField, DateField, DateTimeField, DecimalField, DurationField, -    EmailField, Field, FileField, FilePathField, FloatField, GenericIPAddressField, ImageField, IntegerField, -    ModelChoiceField, ModelMultipleChoiceField, MultiValueField, MultipleChoiceField, NullBooleanField, RegexField, -    SlugField, SplitDateTimeField, TimeField, TypedChoiceField, TypedMultipleChoiceField, URLField, UUIDField) -from django.template import Template, Context +from django.forms import BooleanField, BoundField, CharField, Field, ImageField, ModelChoiceField +from django.template import Context  from django.template.loader import get_template  from django.utils.safestring import mark_safe  from wiki.editors.markitup import MarkItUpWidget @@ -16,38 +12,12 @@ from wiki.plugins.notifications.forms import SettingsModelChoiceField  TEMPLATE_PATH = "wiki/forms/fields/{0}.html" -TEMPLATES = { +TEMPLATES: Dict[Type, str] = {      BooleanField: TEMPLATE_PATH.format("boolean"),      CharField: TEMPLATE_PATH.format("char"), -    ChoiceField: TEMPLATE_PATH.format("in_place_render"), -    TypedChoiceField: TEMPLATE_PATH.format("in_place_render"), -    DateField: TEMPLATE_PATH.format("in_place_render"), -    DateTimeField: TEMPLATE_PATH.format("in_place_render"), -    DecimalField: TEMPLATE_PATH.format("in_place_render"), -    DurationField: TEMPLATE_PATH.format("in_place_render"), -    EmailField: TEMPLATE_PATH.format("in_place_render"), -    FileField: TEMPLATE_PATH.format("in_place_render"), -    FilePathField: TEMPLATE_PATH.format("in_place_render"), -    FloatField: TEMPLATE_PATH.format("in_place_render"),      ImageField: TEMPLATE_PATH.format("image"), -    IntegerField: TEMPLATE_PATH.format("in_place_render"), -    GenericIPAddressField: TEMPLATE_PATH.format("in_place_render"), -    MultipleChoiceField: TEMPLATE_PATH.format("in_place_render"), -    TypedMultipleChoiceField: TEMPLATE_PATH.format("in_place_render"), -    NullBooleanField: TEMPLATE_PATH.format("in_place_render"), -    RegexField: TEMPLATE_PATH.format("in_place_render"), -    SlugField: TEMPLATE_PATH.format("in_place_render"), -    TimeField: TEMPLATE_PATH.format("in_place_render"), -    URLField: TEMPLATE_PATH.format("in_place_render"), -    UUIDField: TEMPLATE_PATH.format("in_place_render"), - -    ComboField: TEMPLATE_PATH.format("in_place_render"), -    MultiValueField: TEMPLATE_PATH.format("in_place_render"), -    SplitDateTimeField: TEMPLATE_PATH.format("in_place_render"),      ModelChoiceField: TEMPLATE_PATH.format("model_choice"), -    ModelMultipleChoiceField: TEMPLATE_PATH.format("in_place_render"), -      SettingsModelChoiceField: TEMPLATE_PATH.format("model_choice"),      WikiSlugField: TEMPLATE_PATH.format("wiki_slug_render"),  } @@ -56,13 +26,17 @@ TEMPLATES = {  register = template.Library() -def get_unbound_field(field: BoundField): +def get_unbound_field(field: BoundField) -> Field:      while isinstance(field, BoundField):          field = field.field      return field +def render(template_path: str, context: Dict[str, Any]): +    return mark_safe(get_template(template_path).render(context)) + +  @register.simple_tag  def render_field(field: Field, render_labels: bool = True):      if isinstance(field, BoundField): @@ -73,16 +47,11 @@ def render_field(field: Field, render_labels: bool = True):      if not isinstance(render_labels, bool):          render_labels = True -    template_path = TEMPLATES.get(unbound_field.__class__) +    template_path = TEMPLATES.get(unbound_field.__class__, TEMPLATE_PATH.format("in_place_render"))      is_markitup = isinstance(unbound_field.widget, MarkItUpWidget) - -    if not template_path: -        raise NotImplementedError(f"Unknown field type: {unbound_field.__class__}") - -    template_obj: Template = get_template(template_path)      context = {"field": field, "is_markitup": is_markitup, "render_labels": render_labels} -    return mark_safe(template_obj.render(context)) +    return render(template_path, context)  @register.simple_tag(takes_context=True) diff --git a/pydis_site/apps/home/tests/test_wiki_templatetags.py b/pydis_site/apps/home/tests/test_wiki_templatetags.py index 5cd673bf..6399c0b6 100644 --- a/pydis_site/apps/home/tests/test_wiki_templatetags.py +++ b/pydis_site/apps/home/tests/test_wiki_templatetags.py @@ -1,9 +1,14 @@ -from unittest.mock import Mock +from unittest.mock import Mock, create_autospec +from django.forms import BooleanField, BoundField, CharField, ChoiceField, Field, Form, ImageField, ModelChoiceField +from django.template import Context, Template  from django.test import TestCase -from django.template import Template, Context -from wiki.models import URLPath as _URLPath +from wiki.editors.markitup import MarkItUpWidget +from wiki.forms import WikiSlugField +from wiki.models import Article, URLPath as _URLPath +from wiki.plugins.notifications.forms import SettingsModelChoiceField +from pydis_site.apps.home.templatetags import wiki_extra  URLPath = Mock(_URLPath) @@ -45,3 +50,179 @@ class TestURLPathFilter(TestCase):          rendered = self.TEMPLATE.render(Context(context))          self.assertEqual(rendered.strip(), "/") + + +class TestRenderField(TestCase): +    TEMPLATE = Template( +        """ +        {% load wiki_extra %} +        {% render_field field %} +        """ +    ) + +    TEMPLATE_NO_LABELS = Template( +        """ +        {% load wiki_extra %} +        {% render_field field render_labels=False %} +        """ +    ) + +    TEMPLATE_LABELS_NOT_BOOLEAN = Template( +        """ +        {% load wiki_extra %} +        {% render_field field render_labels="" %} +        """ +    ) + +    def test_bound_field(self): +        unbound_field = Field() +        field = BoundField(Form(), unbound_field, "field") + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +    def test_bound_field_no_labels(self): +        unbound_field = Field() +        field = BoundField(Form(), unbound_field, "field") + +        context = Context({"field": field}) +        self.TEMPLATE_NO_LABELS.render(context) + +    def test_bound_field_labels_not_boolean(self): +        unbound_field = Field() +        field = BoundField(Form(), unbound_field, "field") + +        context = Context({"field": field}) +        self.TEMPLATE_LABELS_NOT_BOOLEAN.render(context) + +    def test_unbound_field(self): +        field = Field() + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +    def test_unbound_field_no_labels(self): +        field = Field() + +        context = Context({"field": field}) +        self.TEMPLATE_NO_LABELS.render(context) + +    def test_unbound_field_labels_not_boolean(self): +        field = Field() + +        context = Context({"field": field}) +        self.TEMPLATE_LABELS_NOT_BOOLEAN.render(context) + + +class TestRenderFieldTypes(TestCase): +    TEMPLATE = Template( +        """ +        {% load wiki_extra %} +        {% render_field field %} +        """ +    ) + +    @classmethod +    def setUpClass(cls): +        cls._wiki_extra_render = wiki_extra.render +        wiki_extra.render = create_autospec(wiki_extra.render, return_value="") + +    @classmethod +    def tearDownClass(cls): +        wiki_extra.render = cls._wiki_extra_render +        del cls._wiki_extra_render + +    def test_field_boolean(self): +        field = BooleanField() + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +        template_path = "wiki/forms/fields/boolean.html" +        context = {"field": field, "is_markitup": False, "render_labels": True} + +        wiki_extra.render.assert_called_with(template_path, context) + +    def test_field_char(self): +        field = CharField() +        field.widget = None + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +        template_path = "wiki/forms/fields/char.html" +        context = {"field": field, "is_markitup": False, "render_labels": True} + +        wiki_extra.render.assert_called_with(template_path, context) + +    def test_field_char_markitup(self): +        field = CharField() +        field.widget = MarkItUpWidget() + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +        template_path = "wiki/forms/fields/char.html" +        context = {"field": field, "is_markitup": True, "render_labels": True} + +        wiki_extra.render.assert_called_with(template_path, context) + +    def test_field_image(self): +        field = ImageField() + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +        template_path = "wiki/forms/fields/image.html" +        context = {"field": field, "is_markitup": False, "render_labels": True} + +        wiki_extra.render.assert_called_with(template_path, context) + +    def test_field_model_choice(self): +        field = ModelChoiceField(Article.objects.all()) + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +        template_path = "wiki/forms/fields/model_choice.html" +        context = {"field": field, "is_markitup": False, "render_labels": True} + +        wiki_extra.render.assert_called_with(template_path, context) + +    def test_field_settings_model_choice(self): +        field = SettingsModelChoiceField(Article.objects.all()) + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +        template_path = "wiki/forms/fields/model_choice.html" +        context = {"field": field, "is_markitup": False, "render_labels": True} + +        wiki_extra.render.assert_called_with(template_path, context) + +    def test_field_wiki_slug(self): +        field = WikiSlugField() + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) + +        template_path = "wiki/forms/fields/wiki_slug_render.html" +        context = {"field": field, "is_markitup": False, "render_labels": True} + +        wiki_extra.render.assert_called_with(template_path, context) + + +class TestGetFieldOptions(TestCase): +    TEMPLATE = Template( +        """ +        {% load wiki_extra %} +        {% get_field_options field %} +        """ +    ) + +    def test_get_field_options(self): +        unbound_field = ChoiceField() +        field = BoundField(Form(), unbound_field, "field") + +        context = Context({"field": field}) +        self.TEMPLATE.render(context) | 
