diff --git a/tests/test_components.py b/tests/test_components.py
index 0d75965..38f2398 100644
--- a/tests/test_components.py
+++ b/tests/test_components.py
@@ -2,47 +2,29 @@ import unittest
from unittest.mock import MagicMock, patch
import django
-
+from django.test import SimpleTestCase
from django.utils.safestring import SafeText, mark_safe
-from common import components as _components
-from common.components.core import Node
+from common import components
from games.models import Platform, Game, Purchase, Session
-
-class _RenderingComponents:
- """Test accessor that renders lazy component nodes to safe HTML strings.
-
- Component builders now return ``Node`` objects (the lazy tree). These tests
- assert on rendered HTML, so we render any node a capitalized builder returns
- to a ``SafeText`` string. Internals (``_render_element``) and the legacy
- string-returning ``Component()`` are untouched (non-node results pass
- through), so cache/escaping tests keep working unchanged.
- """
-
- def __getattr__(self, name):
- attr = getattr(_components, name)
- if not (callable(attr) and name[:1].isupper()):
- return attr
-
- def rendered(*args, **kwargs):
- result = attr(*args, **kwargs)
- return str(result) if isinstance(result, Node) else result
-
- return rendered
-
-
-components = _RenderingComponents()
+# Component builders return lazy ``Node`` objects; these tests assert on rendered
+# HTML, so node-returning calls are wrapped in ``str(...)`` at the call site
+# (``Node.__str__`` returns a ``SafeText``). Non-node helpers (``randomid``,
+# ``_resolve_name_with_icon``, the legacy string ``Component()``) are called
+# directly.
class ComponentIntegrationTest(unittest.TestCase):
"""Test Component() works correctly with caching transparent."""
def test_tag_name_component(self):
- result = components.Component(
- tag_name="div",
- attributes=[("class", "test")],
- children="hello",
+ result = str(
+ components.Component(
+ tag_name="div",
+ attributes=[("class", "test")],
+ children="hello",
+ )
)
self.assertEqual(result, '
hello
')
@@ -54,9 +36,17 @@ class ComponentCacheTest(unittest.TestCase):
components._render_element.cache_clear()
def test_identical_components_hit_cache(self):
- components.Component(tag_name="div", attributes=[("class", "x")], children="hi")
+ str(
+ components.Component(
+ tag_name="div", attributes=[("class", "x")], children="hi"
+ )
+ )
misses = components._render_element.cache_info().misses
- components.Component(tag_name="div", attributes=[("class", "x")], children="hi")
+ str(
+ components.Component(
+ tag_name="div", attributes=[("class", "x")], children="hi"
+ )
+ )
info = components._render_element.cache_info()
self.assertEqual(info.misses, misses) # no new miss
self.assertGreaterEqual(info.hits, 1) # served from cache
@@ -67,8 +57,10 @@ class ComponentCacheTest(unittest.TestCase):
def test_safe_and_unsafe_children_do_not_collide(self):
"""A SafeText "" and a plain "" are equal as strings but must
render differently — the cache key must keep them distinct."""
- safe = components.Component(tag_name="span", children=[mark_safe("x")])
- unsafe = components.Component(tag_name="span", children=["x"])
+ safe = str(
+ components.Component(tag_name="span", children=[mark_safe("x")])
+ )
+ unsafe = str(components.Component(tag_name="span", children=["x"]))
self.assertIn("x", safe)
self.assertIn("<b>x</b>", unsafe)
self.assertNotEqual(safe, unsafe)
@@ -140,33 +132,37 @@ class PopoverDeterministicTest(unittest.TestCase):
"""Test that Popover() produces deterministic HTML output."""
def test_same_popover_same_id(self):
- r1 = components.Popover("hello", wrapped_content="hello")
- r2 = components.Popover("hello", wrapped_content="hello")
+ r1 = str(components.Popover("hello", wrapped_content="hello"))
+ r2 = str(components.Popover("hello", wrapped_content="hello"))
self.assertEqual(r1, r2)
def test_different_content_different_id(self):
- r1 = components.Popover("content_a", wrapped_content="content_a")
- r2 = components.Popover("content_b", wrapped_content="content_b")
+ r1 = str(components.Popover("content_a", wrapped_content="content_a"))
+ r2 = str(components.Popover("content_b", wrapped_content="content_b"))
self.assertNotEqual(r1, r2)
def test_wrapped_classes_affect_id(self):
- r1 = components.Popover("c", wrapped_content="c", wrapped_classes="class_x")
- r2 = components.Popover("c", wrapped_content="c", wrapped_classes="class_y")
+ r1 = str(
+ components.Popover("c", wrapped_content="c", wrapped_classes="class_x")
+ )
+ r2 = str(
+ components.Popover("c", wrapped_content="c", wrapped_classes="class_y")
+ )
self.assertNotEqual(r1, r2)
def test_wrapped_content_affects_id(self):
- r1 = components.Popover("popover", wrapped_content="wrapped_a")
- r2 = components.Popover("popover", wrapped_content="wrapped_b")
+ r1 = str(components.Popover("popover", wrapped_content="wrapped_a"))
+ r2 = str(components.Popover("popover", wrapped_content="wrapped_b"))
self.assertNotEqual(r1, r2)
def test_popover_content_affects_id(self):
- r1 = components.Popover("popover_a", wrapped_content="wrapped")
- r2 = components.Popover("popover_b", wrapped_content="wrapped")
+ r1 = str(components.Popover("popover_a", wrapped_content="wrapped"))
+ r2 = str(components.Popover("popover_b", wrapped_content="wrapped"))
self.assertNotEqual(r1, r2)
def test_full_html_deterministic(self):
- r1 = components.Popover("hello world", wrapped_content="hello world")
- r2 = components.Popover("hello world", wrapped_content="hello world")
+ r1 = str(components.Popover("hello world", wrapped_content="hello world"))
+ r2 = str(components.Popover("hello world", wrapped_content="hello world"))
self.assertEqual(r1.encode(), r2.encode())
@@ -206,26 +202,26 @@ class ComponentReturnTypeTest(unittest.TestCase):
"""Test that component functions return SafeText and render correctly."""
def test_div_returns_safe_text(self):
- result = components.Div([("class", "x")], "hello")
+ result = str(components.Div([("class", "x")], "hello"))
self.assertIsInstance(result, SafeText)
def test_div_deterministic(self):
- r1 = components.Div([("class", "x")], "hello")
- r2 = components.Div([("class", "x")], "hello")
+ r1 = str(components.Div([("class", "x")], "hello"))
+ r2 = str(components.Div([("class", "x")], "hello"))
self.assertEqual(r1, r2)
self.assertIn('hello
', r1)
def test_div_no_args(self):
- result = components.Div(children="test")
+ result = str(components.Div(children="test"))
self.assertIsInstance(result, SafeText)
self.assertIn("test
", result)
def test_a_returns_safe_text(self):
- result = components.A([], "link")
+ result = str(components.A([], "link"))
self.assertIsInstance(result, SafeText)
def test_a_literal_href(self):
- result = components.A([], "x", href="/literal/path")
+ result = str(components.A([], "x", href="/literal/path"))
self.assertIn('href="/literal/path"', result)
def test_a_url_name_reversed(self):
@@ -234,35 +230,35 @@ class ComponentReturnTypeTest(unittest.TestCase):
with patch(
"common.components.primitives.reverse", return_value="/resolved/url"
):
- result = components.A([], "link", url_name="some_name")
+ result = str(components.A([], "link", url_name="some_name"))
self.assertIn('href="/resolved/url"', result)
def test_a_no_url_or_href(self):
- result = components.A([], "link")
+ result = str(components.A([], "link"))
self.assertIn("link", result)
self.assertNotIn("href=", result)
def test_a_both_url_name_and_href_raises(self):
with self.assertRaises(ValueError):
- components.A(href="/path", url_name="some_name")
+ str(components.A(href="/path", url_name="some_name"))
def test_button_returns_safe_text(self):
- result = components.Button([], "click")
+ result = str(components.Button([], "click"))
self.assertIsInstance(result, SafeText)
self.assertIn("