feat: allow to set main JS and CSS from files + lazy-load component m… (#870)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Juro Oravec 2024-12-30 18:00:46 +01:00 committed by GitHub
parent 8fcb84c002
commit 715bf7d447
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 1014 additions and 248 deletions

View file

@ -17,8 +17,10 @@ from .testutils import BaseTestCase, autodiscover_with_cleanup
setup_test_config({"autodiscover": False})
class InlineComponentTest(BaseTestCase):
def test_html(self):
# "Main media" refer to the HTML, JS, and CSS set on the Component class itself
# (as opposed via the `Media` class). These have special handling in the Component.
class MainMediaTest(BaseTestCase):
def test_html_inlined(self):
class InlineHTMLComponent(Component):
template = "<div class='inline'>Hello Inline</div>"
@ -27,7 +29,20 @@ class InlineComponentTest(BaseTestCase):
'<div class="inline" data-djc-id-a1bc3e>Hello Inline</div>',
)
def test_inlined_js_and_css(self):
def test_html_filepath(self):
class Test(Component):
template_name = "simple_template.html"
rendered = Test.render(context={"variable": "test"})
self.assertHTMLEqual(
rendered,
"""
Variable: <strong data-djc-id-a1bc3e>test</strong>
""",
)
def test_js_css_inlined(self):
class TestComponent(Component):
template = """
{% load component_tags %}
@ -38,6 +53,15 @@ class InlineComponentTest(BaseTestCase):
css = ".html-css-only { color: blue; }"
js = "console.log('HTML and JS only');"
self.assertEqual(
TestComponent.css,
".html-css-only { color: blue; }",
)
self.assertEqual(
TestComponent.js,
"console.log('HTML and JS only');",
)
rendered = TestComponent.render()
self.assertInHTML(
@ -53,6 +77,127 @@ class InlineComponentTest(BaseTestCase):
rendered,
)
@override_settings(
STATICFILES_DIRS=[
os.path.join(Path(__file__).resolve().parent, "static_root"),
],
)
def test_js_css_filepath_rel_to_component(self):
from tests.test_app.components.app_lvl_comp.app_lvl_comp import AppLvlCompComponent
class TestComponent(AppLvlCompComponent):
template_name = None
template = """
{% load component_tags %}
{% component_js_dependencies %}
{% component_css_dependencies %}
<div class='html-css-only'>Content</div>
"""
self.assertIn(
".html-css-only {\n color: blue;\n}",
TestComponent.css,
)
self.assertIn(
'console.log("JS file");',
TestComponent.js,
)
rendered = TestComponent.render(kwargs={"variable": "test"})
self.assertInHTML(
'<div class="html-css-only" data-djc-id-a1bc3e>Content</div>',
rendered,
)
self.assertInHTML(
"<style>.html-css-only { color: blue; }</style>",
rendered,
)
self.assertInHTML(
'<script>console.log("JS file");</script>',
rendered,
)
@override_settings(
STATICFILES_DIRS=[
os.path.join(Path(__file__).resolve().parent, "static_root"),
],
)
def test_js_css_filepath_from_static(self):
class TestComponent(Component):
template = """
{% load component_tags %}
{% component_js_dependencies %}
{% component_css_dependencies %}
<div class='html-css-only'>Content</div>
"""
css_file = "style.css"
js_file = "script.js"
self.assertIn(
".html-css-only {\n color: blue;\n}",
TestComponent.css,
)
self.assertIn(
'console.log("HTML and JS only");',
TestComponent.js,
)
rendered = TestComponent.render()
self.assertInHTML(
'<div class="html-css-only" data-djc-id-a1bc3e>Content</div>',
rendered,
)
self.assertInHTML(
"<style>/* Used in `MainMediaTest` tests in `test_component_media.py` */\n.html-css-only {\n color: blue;\n}</style>",
rendered,
)
self.assertInHTML(
'<script>/* Used in `MainMediaTest` tests in `test_component_media.py` */\nconsole.log("HTML and JS only");</script>',
rendered,
)
@override_settings(
STATICFILES_DIRS=[
os.path.join(Path(__file__).resolve().parent, "static_root"),
],
)
def test_js_css_filepath_lazy_loaded(self):
from tests.test_app.components.app_lvl_comp.app_lvl_comp import AppLvlCompComponent
class TestComponent(AppLvlCompComponent):
template_name = None
template = """
{% load component_tags %}
{% component_js_dependencies %}
{% component_css_dependencies %}
<div class='html-css-only'>Content</div>
"""
# NOTE: Since this is a subclass, actual CSS is defined on the parent class, and thus
# the corresponding ComponentMedia instance is also on the parent class.
self.assertEqual(
AppLvlCompComponent._component_media.css, # type: ignore[attr-defined]
None,
)
self.assertEqual(
AppLvlCompComponent._component_media.css_file, # type: ignore[attr-defined]
"app_lvl_comp.css",
)
# Access the property to load the CSS
_ = TestComponent.css
self.assertHTMLEqual(
AppLvlCompComponent._component_media.css, # type: ignore[attr-defined]
".html-css-only { color: blue; }",
)
self.assertEqual(
AppLvlCompComponent._component_media.css_file, # type: ignore[attr-defined]
"app_lvl_comp/app_lvl_comp.css",
)
def test_html_variable(self):
class VariableHTMLComponent(Component):
def get_template(self, context):