refactor: update tests

This commit is contained in:
Juro Oravec 2024-06-02 16:22:49 +02:00
parent fee26ec1d8
commit 5f07f3d4da
3 changed files with 350 additions and 30 deletions

View file

@ -3,8 +3,9 @@ Tests focusing on the Component class.
For tests focusing on the `component` tag, see `test_templatetags_component.py`
"""
from django.http import HttpResponse
from django.core.exceptions import ImproperlyConfigured
from django.template import Context
from django.template import Context, Template, TemplateSyntaxError
# isort: off
from .django_test_setup import * # NOQA
@ -66,7 +67,7 @@ class ComponentTest(BaseTestCase):
EmptyComponent("empty_component").get_template(Context({}))
@parametrize_context_behavior(["django", "isolated"])
def test_simple_component(self):
def test_template_string_static_inlined(self):
class SimpleComponent(component.Component):
template: types.django_html = """
Variable: <strong>{{ variable }}</strong>
@ -81,26 +82,64 @@ class ComponentTest(BaseTestCase):
css = "style.css"
js = "script.js"
comp = SimpleComponent("simple_component")
context = Context(comp.get_context_data(variable="test"))
rendered = SimpleComponent.render(kwargs={"variable": "test"})
self.assertHTMLEqual(
comp.render_dependencies(),
"""
<link href="style.css" media="all" rel="stylesheet">
<script src="script.js"></script>
""",
)
self.assertHTMLEqual(
comp.render(context),
rendered,
"""
Variable: <strong>test</strong>
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_component_with_dynamic_template(self):
def test_template_string_dynamic(self):
class SimpleComponent(component.Component):
def get_template_string(self, context):
content: types.django_html = """
Variable: <strong>{{ variable }}</strong>
"""
return content
def get_context_data(self, variable=None):
return {
"variable": variable,
}
class Media:
css = "style.css"
js = "script.js"
rendered = SimpleComponent.render(kwargs={"variable": "test"})
self.assertHTMLEqual(
rendered,
"""
Variable: <strong>test</strong>
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_template_name_static(self):
class SimpleComponent(component.Component):
template_name = "simple_template.html"
def get_context_data(self, variable=None):
return {
"variable": variable,
}
class Media:
css = "style.css"
js = "script.js"
rendered = SimpleComponent.render(kwargs={"variable": "test"})
self.assertHTMLEqual(
rendered,
"""
Variable: <strong>test</strong>
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_template_name_dynamic(self):
class SvgComponent(component.Component):
def get_context_data(self, name, css_class="", title="", **attrs):
return {
@ -113,16 +152,297 @@ class ComponentTest(BaseTestCase):
def get_template_name(self, context):
return f"dynamic_{context['name']}.svg"
comp = SvgComponent("svg_component")
self.assertHTMLEqual(
comp.render(Context(comp.get_context_data(name="svg1"))),
SvgComponent.render(kwargs={"name": "svg1"}),
"""
<svg>Dynamic1</svg>
""",
)
self.assertHTMLEqual(
comp.render(Context(comp.get_context_data(name="svg2"))),
SvgComponent.render(kwargs={"name": "svg2"}),
"""
<svg>Dynamic2</svg>
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_allows_to_override_get_template(self):
class TestComponent(component.Component):
def get_context_data(self, variable, **attrs):
return {
"variable": variable,
}
def get_template(self, context):
template_str = "Variable: <strong>{{ variable }}</strong>"
return Template(template_str)
rendered = TestComponent.render(kwargs={"variable": "test"})
self.assertHTMLEqual(
rendered,
"""
Variable: <strong>test</strong>
""",
)
class ComponentRenderTest(BaseTestCase):
@parametrize_context_behavior(["django", "isolated"])
def test_render_minimal(self):
class SimpleComponent(component.Component):
template: types.django_html = """
{% load component_tags %}
the_arg2: {{ the_arg2 }}
args: {{ args|safe }}
the_kwarg: {{ the_kwarg }}
kwargs: {{ kwargs|safe }}
---
from_context: {{ from_context }}
---
slot_second: {% slot "second" default %}
SLOT_SECOND_DEFAULT
{% endslot %}
"""
def get_context_data(self, the_arg2=None, *args, the_kwarg=None, **kwargs):
return {
"the_arg2": the_arg2,
"the_kwarg": the_kwarg,
"args": args,
"kwargs": kwargs,
}
rendered = SimpleComponent.render()
self.assertHTMLEqual(
rendered,
"""
the_arg2: None
args: ()
the_kwarg: None
kwargs: {}
---
from_context:
---
slot_second: SLOT_SECOND_DEFAULT
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_render_full(self):
class SimpleComponent(component.Component):
template: types.django_html = """
{% load component_tags %}
the_arg: {{ the_arg }}
the_arg2: {{ the_arg2 }}
args: {{ args|safe }}
the_kwarg: {{ the_kwarg }}
kwargs: {{ kwargs|safe }}
---
from_context: {{ from_context }}
---
slot_first: {% slot "first" required %}
{% endslot %}
---
slot_second: {% slot "second" default %}
SLOT_SECOND_DEFAULT
{% endslot %}
"""
def get_context_data(self, the_arg, the_arg2=None, *args, the_kwarg, **kwargs):
return {
"the_arg": the_arg,
"the_arg2": the_arg2,
"the_kwarg": the_kwarg,
"args": args,
"kwargs": kwargs,
}
rendered = SimpleComponent.render(
context={"from_context": 98},
args=["one", "two", "three"],
kwargs={"the_kwarg": "test", "kw2": "ooo"},
slots={"first": "FIRST_SLOT"},
)
self.assertHTMLEqual(
rendered,
"""
the_arg: one
the_arg2: two
args: ('three',)
the_kwarg: test
kwargs: {'kw2': 'ooo'}
---
from_context: 98
---
slot_first: FIRST_SLOT
---
slot_second: SLOT_SECOND_DEFAULT
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_render_to_response_full(self):
class SimpleComponent(component.Component):
template: types.django_html = """
{% load component_tags %}
the_arg: {{ the_arg }}
the_arg2: {{ the_arg2 }}
args: {{ args|safe }}
the_kwarg: {{ the_kwarg }}
kwargs: {{ kwargs|safe }}
---
from_context: {{ from_context }}
---
slot_first: {% slot "first" required %}
{% endslot %}
---
slot_second: {% slot "second" default %}
SLOT_SECOND_DEFAULT
{% endslot %}
"""
def get_context_data(self, the_arg, the_arg2=None, *args, the_kwarg, **kwargs):
return {
"the_arg": the_arg,
"the_arg2": the_arg2,
"the_kwarg": the_kwarg,
"args": args,
"kwargs": kwargs,
}
rendered = SimpleComponent.render_to_response(
context={"from_context": 98},
args=["one", "two", "three"],
kwargs={"the_kwarg": "test", "kw2": "ooo"},
slots={"first": "FIRST_SLOT"},
)
self.assertIsInstance(rendered, HttpResponse)
self.assertHTMLEqual(
rendered.content.decode(),
"""
the_arg: one
the_arg2: two
args: ('three',)
the_kwarg: test
kwargs: {'kw2': 'ooo'}
---
from_context: 98
---
slot_first: FIRST_SLOT
---
slot_second: SLOT_SECOND_DEFAULT
""",
)
@parametrize_context_behavior([("django", False), ("isolated", True)])
def test_render_slot_as_func(self, context_behavior_data):
is_isolated = context_behavior_data
class SimpleComponent(component.Component):
template: types.django_html = """
{% load component_tags %}
{% slot "first" required %}
{% endslot %}
"""
def get_context_data(self, the_arg, the_kwarg=None, **kwargs):
return {
"the_arg": the_arg,
"the_kwarg": the_kwarg,
"kwargs": kwargs,
}
def first_slot(ctx: Context):
self.assertIsInstance(ctx, Context)
# NOTE: Since the slot has access to the Context object, it should behave
# the same way as it does in templates - when in "isolated" mode, then the
# slot fill has access only to the "root" context, but not to the data of
# get_context_data() of SimpleComponent.
if is_isolated:
self.assertEqual(ctx.get("the_arg"), None)
self.assertEqual(ctx.get("the_kwarg"), None)
self.assertEqual(ctx.get("kwargs"), None)
self.assertEqual(ctx.get("abc"), None)
else:
self.assertEqual(ctx["the_arg"], "1")
self.assertEqual(ctx["the_kwarg"], 3)
self.assertEqual(ctx["kwargs"], {})
self.assertEqual(ctx["abc"], "def")
return "FROM_INSIDE_FIRST_SLOT"
rendered = SimpleComponent.render(
context={"abc": "def"},
args=["1"],
kwargs={"the_kwarg": 3},
slots={"first": first_slot},
)
self.assertHTMLEqual(
rendered,
"FROM_INSIDE_FIRST_SLOT",
)
@parametrize_context_behavior(["django", "isolated"])
def test_render_raises_on_missing_slot(self):
class SimpleComponent(component.Component):
template: types.django_html = """
{% load component_tags %}
{% slot "first" required %}
{% endslot %}
"""
with self.assertRaises(TemplateSyntaxError):
SimpleComponent.render()
SimpleComponent.render(
slots={"first": "FIRST_SLOT"},
)
@parametrize_context_behavior(["django", "isolated"])
def test_render_with_include(self):
class SimpleComponent(component.Component):
template: types.django_html = """
{% load component_tags %}
{% include 'slotted_template.html' %}
"""
rendered = SimpleComponent.render()
self.assertHTMLEqual(
rendered,
"""
<custom-template>
<header>Default header</header>
<main>Default main</main>
<footer>Default footer</footer>
</custom-template>
""",
)
@parametrize_context_behavior(["django", "isolated"])
def test_render_with_extends(self):
class SimpleComponent(component.Component):
template: types.django_html = """
{% extends 'block.html' %}
{% block body %}
OVERRIDEN
{% endblock %}
"""
rendered = SimpleComponent.render()
self.assertHTMLEqual(
rendered,
"""
<!DOCTYPE html>
<html lang="en">
<body>
<main role="main">
<div class='container main-container'>
OVERRIDEN
</div>
</main>
</body>
</html>
""",
)