summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorantoliny0919 <antoliny0919@gmail.com>2025-07-28 07:59:26 +0900
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-08-19 16:35:56 +0200
commit4187da258fe212d494cb578a0bc2b52c4979ab95 (patch)
tree67f6205a16b1f6785f1ed4e06348d332c36a50f3 /tests
parentad4a9e0f3b1de261409bc083aa49dba705531824 (diff)
Fixed #35892 -- Supported Widget.use_fieldset in admin forms.
Diffstat (limited to 'tests')
-rw-r--r--tests/admin_views/admin.py6
-rw-r--r--tests/admin_views/models.py16
-rw-r--r--tests/admin_views/tests.py25
-rw-r--r--tests/admin_widgets/tests.py40
-rw-r--r--tests/auth_tests/test_views.py6
-rw-r--r--tests/forms_tests/widget_tests/test_clearablefileinput.py15
6 files changed, 87 insertions, 21 deletions
diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py
index b6d009b388..69570a8062 100644
--- a/tests/admin_views/admin.py
+++ b/tests/admin_views/admin.py
@@ -47,6 +47,7 @@ from .models import (
Color2,
ComplexSortedPerson,
Country,
+ Course,
CoverLetter,
CustomArticle,
CyclicOne,
@@ -1190,6 +1191,10 @@ class CamelCaseAdmin(admin.ModelAdmin):
filter_horizontal = ["m2m"]
+class CourseAdmin(admin.ModelAdmin):
+ radio_fields = {"difficulty": admin.VERTICAL}
+
+
site = admin.AdminSite(name="admin")
site.site_url = "/my-site-url/"
site.register(Article, ArticleAdmin)
@@ -1280,6 +1285,7 @@ site.register(ChapterXtra1, ChapterXtra1Admin)
site.register(Pizza, PizzaAdmin)
site.register(ReadOnlyPizza, ReadOnlyPizzaAdmin)
site.register(ReadablePizza)
+site.register(Course, CourseAdmin)
site.register(Topping, ToppingAdmin)
site.register(Album, AlbumAdmin)
site.register(Song)
diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py
index 8f102dece3..4e2d13efa8 100644
--- a/tests/admin_views/models.py
+++ b/tests/admin_views/models.py
@@ -623,6 +623,22 @@ class CyclicTwo(models.Model):
return self.name
+class Course(models.Model):
+ DIFFICULTY_CHOICES = [
+ ("beginner", "Beginner Class"),
+ ("intermediate", "Intermediate Class"),
+ ("advanced", "Advanced Class"),
+ ]
+
+ title = models.CharField(max_length=100)
+ materials = models.FileField(upload_to="test_upload")
+ difficulty = models.CharField(
+ max_length=20, choices=DIFFICULTY_CHOICES, null=True, blank=True
+ )
+ categories = models.ManyToManyField(Category, blank=True)
+ start_datetime = models.DateTimeField(null=True, blank=True)
+
+
class Topping(models.Model):
name = models.CharField(max_length=20)
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 26fdacfa00..db638c1ea8 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -70,6 +70,7 @@ from .models import (
Color,
ComplexSortedPerson,
Country,
+ Course,
CoverLetter,
CustomArticle,
CyclicOne,
@@ -6908,6 +6909,30 @@ class SeleniumTests(AdminSeleniumTestCase):
name_input_value = name_input.get_attribute("value")
self.assertEqual(name_input_value, "Test section 1")
+ def test_use_fieldset_fields_render(self):
+ from selenium.webdriver.common.by import By
+
+ self.admin_login(
+ username="super", password="secret", login_url=reverse("admin:index")
+ )
+ course = Course.objects.create(
+ title="Django Class", materials="django_documents"
+ )
+ expected_legend_tags_text = [
+ "Materials:",
+ "Difficulty:",
+ "Categories:",
+ "Start datetime:",
+ ]
+ url = reverse("admin:admin_views_course_change", args=(course.pk,))
+ self.selenium.get(self.live_server_url + url)
+ fieldsets = self.selenium.find_elements(
+ By.CSS_SELECTOR, "fieldset.aligned fieldset"
+ )
+ for index, fieldset in enumerate(fieldsets):
+ legend = fieldset.find_element(By.TAG_NAME, "legend")
+ self.assertEqual(legend.text, expected_legend_tags_text[index])
+
@screenshot_cases(["desktop_size", "mobile_size", "rtl", "dark", "high_contrast"])
@override_settings(MESSAGE_LEVEL=10)
def test_messages(self):
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index c47e0e3ec1..9a5c846bdd 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -399,7 +399,8 @@ class AdminDateWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
'<p class="date">'
- '<input value="2007-12-01" type="text" class="vDateField" name="test" '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="2007-12-01" type="text" class="vDateField" name="test" '
'size="10"></p>',
)
# pass attrs to widget
@@ -407,7 +408,8 @@ class AdminDateWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
'<p class="date">'
- '<input value="2007-12-01" type="text" class="myDateField" name="test" '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="2007-12-01" type="text" class="myDateField" name="test" '
'size="20"></p>',
)
@@ -418,7 +420,8 @@ class AdminTimeWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
'<p class="time">'
- '<input value="09:30:00" type="text" class="vTimeField" name="test" '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="09:30:00" type="text" class="vTimeField" name="test" '
'size="8"></p>',
)
# pass attrs to widget
@@ -426,7 +429,8 @@ class AdminTimeWidgetTest(SimpleTestCase):
self.assertHTMLEqual(
w.render("test", datetime(2007, 12, 1, 9, 30)),
'<p class="time">'
- '<input value="09:30:00" type="text" class="myTimeField" name="test" '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="09:30:00" type="text" class="myTimeField" name="test" '
'size="20"></p>',
)
@@ -435,12 +439,16 @@ class AdminSplitDateTimeWidgetTest(SimpleTestCase):
def test_render(self):
w = widgets.AdminSplitDateTime()
self.assertHTMLEqual(
- w.render("test", datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30), attrs={"id": "id_test"}),
'<p class="datetime">'
- 'Date: <input value="2007-12-01" type="text" class="vDateField" '
- 'name="test_0" size="10"><br>'
- 'Time: <input value="09:30:00" type="text" class="vTimeField" '
- 'name="test_1" size="8"></p>',
+ '<label for="id_test_0">Date:</label> '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="2007-12-01" type="text" class="vDateField" '
+ 'name="test_0" size="10" id="id_test_0"><br>'
+ '<label for="id_test_1">Time:</label> '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="09:30:00" type="text" class="vTimeField" '
+ 'name="test_1" size="8" id="id_test_1"></p>',
)
def test_localization(self):
@@ -449,12 +457,16 @@ class AdminSplitDateTimeWidgetTest(SimpleTestCase):
with translation.override("de-at"):
w.is_localized = True
self.assertHTMLEqual(
- w.render("test", datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30), attrs={"id": "id_test"}),
'<p class="datetime">'
- 'Datum: <input value="01.12.2007" type="text" '
- 'class="vDateField" name="test_0"size="10"><br>'
- 'Zeit: <input value="09:30:00" type="text" class="vTimeField" '
- 'name="test_1" size="8"></p>',
+ '<label for="id_test_0">Datum:</label> '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="01.12.2007" type="text" '
+ 'class="vDateField" name="test_0" size="10" id="id_test_0"><br>'
+ '<label for="id_test_1">Zeit:</label> '
+ '<input aria-describedby="id_test_timezone_warning_helptext" '
+ 'value="09:30:00" type="text" class="vTimeField" '
+ 'name="test_1" size="8" id="id_test_1"></p>',
)
diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py
index 0a4f7d28c8..23dc858ddd 100644
--- a/tests/auth_tests/test_views.py
+++ b/tests/auth_tests/test_views.py
@@ -1550,6 +1550,12 @@ class ChangelistTests(MessagesTestMixin, AuthViewsTestCase):
self.assertContains(
response, f"{self.admin.username}</a>\n&rsaquo; Change password"
)
+ # Usable password field.
+ self.assertContains(
+ response,
+ '<fieldset class="flex-container">'
+ "<legend>Password-based authentication:</legend>",
+ )
# Submit buttons
self.assertContains(response, '<input type="submit" name="set-password"')
self.assertContains(response, '<input type="submit" name="unset-password"')
diff --git a/tests/forms_tests/widget_tests/test_clearablefileinput.py b/tests/forms_tests/widget_tests/test_clearablefileinput.py
index ae54cc4b5d..8d3bff4b45 100644
--- a/tests/forms_tests/widget_tests/test_clearablefileinput.py
+++ b/tests/forms_tests/widget_tests/test_clearablefileinput.py
@@ -246,18 +246,19 @@ class ClearableFileInputTest(WidgetTest):
)
form = TestForm()
- self.assertIs(self.widget.use_fieldset, False)
+ self.assertIs(self.widget.use_fieldset, True)
self.assertHTMLEqual(
- '<div><label for="id_field">Field:</label>'
- '<input id="id_field" name="field" type="file" required></div>'
- '<div><label for="id_with_file">With file:</label>Currently: '
+ '<div><fieldset><legend for="id_field">Field:</legend>'
+ '<input id="id_field" name="field" type="file" required></fieldset></div>'
+ '<div><fieldset><legend for="id_with_file">With file:</legend>Currently: '
'<a href="something">something</a><br>Change:<input type="file" '
- 'name="with_file" id="id_with_file"></div>'
- '<div><label for="id_clearable_file">Clearable file:</label>'
+ 'name="with_file" id="id_with_file"></fieldset></div>'
+ '<div><fieldset><legend for="id_clearable_file">Clearable file:</legend>'
'Currently: <a href="something">something</a><input '
'type="checkbox" name="clearable_file-clear" id="clearable_file-clear_id">'
'<label for="clearable_file-clear_id">Clear</label><br>Change:'
- '<input type="file" name="clearable_file" id="id_clearable_file"></div>',
+ '<input type="file" name="clearable_file" id="id_clearable_file">'
+ "</fieldset></div>",
form.render(),
)