Repository: sissbruecker/linkding
Pull request #945 (2025-01-12 21:03:25)

Provide accessible name to radio groups


Patch:
diff --git a/bookmarks/templates/bookmarks/search.html b/bookmarks/templates/bookmarks/search.html
index 930762a..009bdc6 100644
--- a/bookmarks/templates/bookmarks/search.html
+++ b/bookmarks/templates/bookmarks/search.html
@@ -42,8 +42,11 @@
           </div>
         {% endif %}
         {% if 'shared' in preferences_form.editable_fields %}
-          <div class="form-group radio-group">
-            <div class="form-label{% if 'shared' in search.modified_params %} text-bold{% endif %}">Shared filter</div>
+          <div class="form-group radio-group" role="radiogroup" aria-labelledby="search-shared-label">
+            <label id="search-shared-label"
+                   class="form-label{% if 'shared' in search.modified_params %} text-bold{% endif %}">
+              Shared filter
+            </label>
             {% for radio in preferences_form.shared %}
               <label for="{{ radio.id_for_label }}" class="form-radio form-inline">
                 {{ radio.tag }}
@@ -54,8 +57,11 @@
           </div>
         {% endif %}
         {% if 'unread' in preferences_form.editable_fields %}
-          <div class="form-group radio-group">
-            <div class="form-label{% if 'unread' in search.modified_params %} text-bold{% endif %}">Unread filter</div>
+          <div class="form-group radio-group" role="radiogroup" aria-labelledby="search-unread-label">
+            <label id="search-unread-label"
+                   class="form-label{% if 'unread' in search.modified_params %} text-bold{% endif %}">
+              Unread filter
+            </label>
             {% for radio in preferences_form.unread %}
               <label for="{{ radio.id_for_label }}" class="form-radio form-inline">
                 {{ radio.tag }}


Test patch:
diff --git a/bookmarks/tests/test_bookmark_search_tag.py b/bookmarks/tests/test_bookmark_search_tag.py
index 90be582..eb77675 100644
--- a/bookmarks/tests/test_bookmark_search_tag.py
+++ b/bookmarks/tests/test_bookmark_search_tag.py
@@ -71,19 +71,15 @@ class BookmarkSearchTagTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
         radios = form.select(f'input[name="{name}"][type="radio"]')
         self.assertTrue(len(radios) == 0)
 
-    def assertUnmodifiedLabel(self, html: str, text: str, id: str = ""):
-        id_attr = f'for="{id}"' if id else ""
-        tag = "label" if id else "div"
-        needle = f'<{tag} class="form-label" {id_attr}>{text}</{tag}>'
+    def assertUnmodifiedLabel(self, html: str, text: str):
+        soup = self.make_soup(html)
+        label = soup.find("label", string=lambda s: s and s.strip() == text)
+        self.assertEqual(label["class"], ["form-label"])
 
-        self.assertInHTML(needle, html)
-
-    def assertModifiedLabel(self, html: str, text: str, id: str = ""):
-        id_attr = f'for="{id}"' if id else ""
-        tag = "label" if id else "div"
-        needle = f'<{tag} class="form-label text-bold" {id_attr}>{text}</{tag}>'
-
-        self.assertInHTML(needle, html)
+    def assertModifiedLabel(self, html: str, text: str):
+        soup = self.make_soup(html)
+        label = soup.find("label", string=lambda s: s and s.strip() == text)
+        self.assertEqual(label["class"], ["form-label", "text-bold"])
 
     def test_search_form_inputs(self):
         # Without params
@@ -216,27 +212,27 @@ class BookmarkSearchTagTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
         url = "/test"
         rendered_template = self.render_template(url)
 
-        self.assertUnmodifiedLabel(rendered_template, "Sort by", "id_sort")
+        self.assertUnmodifiedLabel(rendered_template, "Sort by")
         self.assertUnmodifiedLabel(rendered_template, "Shared filter")
         self.assertUnmodifiedLabel(rendered_template, "Unread filter")
 
         # Modified sort
         url = "/test?sort=title_asc"
         rendered_template = self.render_template(url)
-        self.assertModifiedLabel(rendered_template, "Sort by", "id_sort")
+        self.assertModifiedLabel(rendered_template, "Sort by")
         self.assertUnmodifiedLabel(rendered_template, "Shared filter")
         self.assertUnmodifiedLabel(rendered_template, "Unread filter")
 
         # Modified shared
         url = "/test?shared=yes"
         rendered_template = self.render_template(url)
-        self.assertUnmodifiedLabel(rendered_template, "Sort by", "id_sort")
+        self.assertUnmodifiedLabel(rendered_template, "Sort by")
         self.assertModifiedLabel(rendered_template, "Shared filter")
         self.assertUnmodifiedLabel(rendered_template, "Unread filter")
 
         # Modified unread
         url = "/test?unread=yes"
         rendered_template = self.render_template(url)
-        self.assertUnmodifiedLabel(rendered_template, "Sort by", "id_sort")
+        self.assertUnmodifiedLabel(rendered_template, "Sort by")
         self.assertUnmodifiedLabel(rendered_template, "Shared filter")
         self.assertModifiedLabel(rendered_template, "Unread filter")