Fix A() component

Replaced single `url` parameter with explicit `url_name` (URL pattern name resolved via `reverse()`) and `href` (literal path). Fixes:
- Silent fallback (typos like `"ad_puchase"` silently became broken links) → now raises `NoReverseMatch` at render time
- `type(url) is str` gate → removed (implicit dual-mode eliminated entirely)
- Callable parameter (`url: Callable`) dead code → removed
- Implicit dual-mode (`url="name"` vs `url=reverse("name")`) → `url_name` vs `href` are now mutually exclusive params
- Inconsistent type annotation mixing `Callable` with string default → cleaned up
- Added `ValueError` when both `url_name` and `href` are provided
- Updated all 10 call sites across 6 view files and internal callers (`LinkedPurchase()`, `NameWithIcon()`)
This commit is contained in:
2026-05-12 09:01:05 +02:00
parent 8c3e819a5f
commit 656a96f55c
9 changed files with 50 additions and 40 deletions
+16 -1
View File
@@ -376,9 +376,24 @@ class ComponentReturnTypeTest(unittest.TestCase):
self.assertIsInstance(result, SafeText)
def test_a_literal_href(self):
result = components.A([], "x", url="/literal/path")
result = components.A([], "x", href="/literal/path")
self.assertIn('href="/literal/path"', result)
def test_a_url_name_reversed(self):
from unittest.mock import patch
with patch("common.components.reverse", return_value="/resolved/url"):
result = 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")
self.assertIn('<a>link</a>', 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")
def test_button_returns_safe_text(self):
result = components.Button([], "click")
self.assertIsInstance(result, SafeText)