summaryrefslogtreecommitdiff
path: root/tests/admin_widgets
diff options
context:
space:
mode:
authordjango-bot <ops@djangoproject.com>2022-02-03 20:24:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-02-07 20:37:05 +0100
commit9c19aff7c7561e3a82978a272ecdaad40dda5c00 (patch)
treef0506b668a013d0063e5fba3dbf4863b466713ba /tests/admin_widgets
parentf68fa8b45dfac545cfc4111d4e52804c86db68d3 (diff)
downloaddjango-9c19aff7c7561e3a82978a272ecdaad40dda5c00.tar.gz
Refs #33476 -- Reformatted code with Black.
Diffstat (limited to 'tests/admin_widgets')
-rw-r--r--tests/admin_widgets/models.py45
-rw-r--r--tests/admin_widgets/test_autocomplete_widget.py144
-rw-r--r--tests/admin_widgets/tests.py1154
-rw-r--r--tests/admin_widgets/urls.py2
-rw-r--r--tests/admin_widgets/widgetadmin.py39
5 files changed, 833 insertions, 551 deletions
diff --git a/tests/admin_widgets/models.py b/tests/admin_widgets/models.py
index 85ba6c4f36..15d7a3022e 100644
--- a/tests/admin_widgets/models.py
+++ b/tests/admin_widgets/models.py
@@ -11,7 +11,9 @@ class MyFileField(models.FileField):
class Member(models.Model):
name = models.CharField(max_length=100)
birthdate = models.DateTimeField(blank=True, null=True)
- gender = models.CharField(max_length=1, blank=True, choices=[('M', 'Male'), ('F', 'Female')])
+ gender = models.CharField(
+ max_length=1, blank=True, choices=[("M", "Male"), ("F", "Female")]
+ )
email = models.EmailField(blank=True)
def __str__(self):
@@ -36,16 +38,16 @@ class UnsafeLimitChoicesTo(models.Model):
band = models.ForeignKey(
Band,
models.CASCADE,
- limit_choices_to={'name': '"&><escapeme'},
+ limit_choices_to={"name": '"&><escapeme'},
)
class Album(models.Model):
- band = models.ForeignKey(Band, models.CASCADE, to_field='uuid')
- featuring = models.ManyToManyField(Band, related_name='featured')
+ band = models.ForeignKey(Band, models.CASCADE, to_field="uuid")
+ featuring = models.ManyToManyField(Band, related_name="featured")
name = models.CharField(max_length=100)
- cover_art = models.FileField(upload_to='albums')
- backside_art = MyFileField(upload_to='albums_back', null=True)
+ cover_art = models.FileField(upload_to="albums")
+ backside_art = MyFileField(upload_to="albums_back", null=True)
def __str__(self):
return self.name
@@ -56,11 +58,12 @@ class ReleaseEvent(models.Model):
Used to check that autocomplete widget correctly resolves attname for FK as
PK example.
"""
+
album = models.ForeignKey(Album, models.CASCADE, primary_key=True)
name = models.CharField(max_length=100)
class Meta:
- ordering = ['name']
+ ordering = ["name"]
def __str__(self):
return self.name
@@ -77,7 +80,9 @@ class HiddenInventoryManager(models.Manager):
class Inventory(models.Model):
barcode = models.PositiveIntegerField(unique=True)
- parent = models.ForeignKey('self', models.SET_NULL, to_field='barcode', blank=True, null=True)
+ parent = models.ForeignKey(
+ "self", models.SET_NULL, to_field="barcode", blank=True, null=True
+ )
name = models.CharField(blank=False, max_length=20)
hidden = models.BooleanField(default=False)
@@ -94,13 +99,13 @@ class Event(models.Model):
Band,
models.CASCADE,
limit_choices_to=models.Q(pk__gt=0),
- related_name='events_main_band_at',
+ related_name="events_main_band_at",
)
supporting_bands = models.ManyToManyField(
Band,
blank=True,
- related_name='events_supporting_band_at',
- help_text='Supporting Bands.',
+ related_name="events_supporting_band_at",
+ help_text="Supporting Bands.",
)
start_date = models.DateField(blank=True, null=True)
start_time = models.TimeField(blank=True, null=True)
@@ -122,6 +127,7 @@ class CarTire(models.Model):
"""
A single car tire. This to test that a user can only select their own cars.
"""
+
car = models.ForeignKey(Car, models.CASCADE)
@@ -136,6 +142,7 @@ class Bee(models.Model):
(Honeycomb) so the corresponding raw ID widget won't have a magnifying
glass link to select related honeycomb instances.
"""
+
honeycomb = models.ForeignKey(Honeycomb, models.CASCADE)
@@ -145,9 +152,12 @@ class Individual(models.Model):
corresponding raw ID widget won't have a magnifying glass link to select
related instances (rendering will be called programmatically in this case).
"""
+
name = models.CharField(max_length=20)
- parent = models.ForeignKey('self', models.SET_NULL, null=True)
- soulmate = models.ForeignKey('self', models.CASCADE, null=True, related_name='soulmates')
+ parent = models.ForeignKey("self", models.SET_NULL, null=True)
+ soulmate = models.ForeignKey(
+ "self", models.CASCADE, null=True, related_name="soulmates"
+ )
class Company(models.Model):
@@ -160,6 +170,7 @@ class Advisor(models.Model):
(Company) so the corresponding raw ID widget won't have a magnifying
glass link to select related company instances.
"""
+
name = models.CharField(max_length=20)
companies = models.ManyToManyField(Company)
@@ -168,7 +179,7 @@ class Student(models.Model):
name = models.CharField(max_length=255)
class Meta:
- ordering = ('name',)
+ ordering = ("name",)
def __str__(self):
return self.name
@@ -176,15 +187,15 @@ class Student(models.Model):
class School(models.Model):
name = models.CharField(max_length=255)
- students = models.ManyToManyField(Student, related_name='current_schools')
- alumni = models.ManyToManyField(Student, related_name='previous_schools')
+ students = models.ManyToManyField(Student, related_name="current_schools")
+ alumni = models.ManyToManyField(Student, related_name="previous_schools")
def __str__(self):
return self.name
class Profile(models.Model):
- user = models.ForeignKey('auth.User', models.CASCADE, to_field='username')
+ user = models.ForeignKey("auth.User", models.CASCADE, to_field="username")
def __str__(self):
return self.user.username
diff --git a/tests/admin_widgets/test_autocomplete_widget.py b/tests/admin_widgets/test_autocomplete_widget.py
index a1c6e0ad7b..c7bcbd1d13 100644
--- a/tests/admin_widgets/test_autocomplete_widget.py
+++ b/tests/admin_widgets/test_autocomplete_widget.py
@@ -11,24 +11,26 @@ from .models import Album, Band, ReleaseEvent, VideoStream
class AlbumForm(forms.ModelForm):
class Meta:
model = Album
- fields = ['band', 'featuring']
+ fields = ["band", "featuring"]
widgets = {
- 'band': AutocompleteSelect(
- Album._meta.get_field('band'),
+ "band": AutocompleteSelect(
+ Album._meta.get_field("band"),
admin.site,
- attrs={'class': 'my-class'},
+ attrs={"class": "my-class"},
),
- 'featuring': AutocompleteSelect(
- Album._meta.get_field('featuring'),
+ "featuring": AutocompleteSelect(
+ Album._meta.get_field("featuring"),
admin.site,
- )
+ ),
}
class NotRequiredBandForm(forms.Form):
band = ModelChoiceField(
queryset=Album.objects.all(),
- widget=AutocompleteSelect(Album._meta.get_field('band').remote_field, admin.site),
+ widget=AutocompleteSelect(
+ Album._meta.get_field("band").remote_field, admin.site
+ ),
required=False,
)
@@ -36,7 +38,9 @@ class NotRequiredBandForm(forms.Form):
class RequiredBandForm(forms.Form):
band = ModelChoiceField(
queryset=Album.objects.all(),
- widget=AutocompleteSelect(Album._meta.get_field('band').remote_field, admin.site),
+ widget=AutocompleteSelect(
+ Album._meta.get_field("band").remote_field, admin.site
+ ),
required=True,
)
@@ -44,73 +48,84 @@ class RequiredBandForm(forms.Form):
class VideoStreamForm(forms.ModelForm):
class Meta:
model = VideoStream
- fields = ['release_event']
+ fields = ["release_event"]
widgets = {
- 'release_event': AutocompleteSelect(
- VideoStream._meta.get_field('release_event'),
+ "release_event": AutocompleteSelect(
+ VideoStream._meta.get_field("release_event"),
admin.site,
),
}
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class AutocompleteMixinTests(TestCase):
empty_option = '<option value=""></option>'
maxDiff = 1000
def test_build_attrs(self):
form = AlbumForm()
- attrs = form['band'].field.widget.get_context(name='my_field', value=None, attrs={})['widget']['attrs']
- self.assertEqual(attrs, {
- 'class': 'my-class admin-autocomplete',
- 'data-ajax--cache': 'true',
- 'data-ajax--delay': 250,
- 'data-ajax--type': 'GET',
- 'data-ajax--url': '/autocomplete/',
- 'data-theme': 'admin-autocomplete',
- 'data-allow-clear': 'false',
- 'data-app-label': 'admin_widgets',
- 'data-field-name': 'band',
- 'data-model-name': 'album',
- 'data-placeholder': '',
- 'lang': 'en',
- })
+ attrs = form["band"].field.widget.get_context(
+ name="my_field", value=None, attrs={}
+ )["widget"]["attrs"]
+ self.assertEqual(
+ attrs,
+ {
+ "class": "my-class admin-autocomplete",
+ "data-ajax--cache": "true",
+ "data-ajax--delay": 250,
+ "data-ajax--type": "GET",
+ "data-ajax--url": "/autocomplete/",
+ "data-theme": "admin-autocomplete",
+ "data-allow-clear": "false",
+ "data-app-label": "admin_widgets",
+ "data-field-name": "band",
+ "data-model-name": "album",
+ "data-placeholder": "",
+ "lang": "en",
+ },
+ )
def test_build_attrs_no_custom_class(self):
form = AlbumForm()
- attrs = form['featuring'].field.widget.get_context(name='name', value=None, attrs={})['widget']['attrs']
- self.assertEqual(attrs['class'], 'admin-autocomplete')
+ attrs = form["featuring"].field.widget.get_context(
+ name="name", value=None, attrs={}
+ )["widget"]["attrs"]
+ self.assertEqual(attrs["class"], "admin-autocomplete")
def test_build_attrs_not_required_field(self):
form = NotRequiredBandForm()
- attrs = form['band'].field.widget.build_attrs({})
- self.assertJSONEqual(attrs['data-allow-clear'], True)
+ attrs = form["band"].field.widget.build_attrs({})
+ self.assertJSONEqual(attrs["data-allow-clear"], True)
def test_build_attrs_required_field(self):
form = RequiredBandForm()
- attrs = form['band'].field.widget.build_attrs({})
- self.assertJSONEqual(attrs['data-allow-clear'], False)
+ attrs = form["band"].field.widget.build_attrs({})
+ self.assertJSONEqual(attrs["data-allow-clear"], False)
def test_get_url(self):
- rel = Album._meta.get_field('band')
+ rel = Album._meta.get_field("band")
w = AutocompleteSelect(rel, admin.site)
url = w.get_url()
- self.assertEqual(url, '/autocomplete/')
+ self.assertEqual(url, "/autocomplete/")
def test_render_options(self):
- beatles = Band.objects.create(name='The Beatles', style='rock')
- who = Band.objects.create(name='The Who', style='rock')
+ beatles = Band.objects.create(name="The Beatles", style="rock")
+ who = Band.objects.create(name="The Who", style="rock")
# With 'band', a ForeignKey.
- form = AlbumForm(initial={'band': beatles.uuid})
+ form = AlbumForm(initial={"band": beatles.uuid})
output = form.as_table()
- selected_option = '<option value="%s" selected>The Beatles</option>' % beatles.uuid
+ selected_option = (
+ '<option value="%s" selected>The Beatles</option>' % beatles.uuid
+ )
option = '<option value="%s">The Who</option>' % who.uuid
self.assertIn(selected_option, output)
self.assertNotIn(option, output)
# With 'featuring', a ManyToManyField.
- form = AlbumForm(initial={'featuring': [beatles.pk, who.pk]})
+ form = AlbumForm(initial={"featuring": [beatles.pk, who.pk]})
output = form.as_table()
- selected_option = '<option value="%s" selected>The Beatles</option>' % beatles.pk
+ selected_option = (
+ '<option value="%s" selected>The Beatles</option>' % beatles.pk
+ )
option = '<option value="%s" selected>The Who</option>' % who.pk
self.assertIn(selected_option, output)
self.assertIn(option, output)
@@ -128,41 +143,48 @@ class AutocompleteMixinTests(TestCase):
self.assertNotIn(self.empty_option, output)
def test_render_options_fk_as_pk(self):
- beatles = Band.objects.create(name='The Beatles', style='rock')
- rubber_soul = Album.objects.create(name='Rubber Soul', band=beatles)
- release_event = ReleaseEvent.objects.create(name='Test Target', album=rubber_soul)
- form = VideoStreamForm(initial={'release_event': release_event.pk})
+ beatles = Band.objects.create(name="The Beatles", style="rock")
+ rubber_soul = Album.objects.create(name="Rubber Soul", band=beatles)
+ release_event = ReleaseEvent.objects.create(
+ name="Test Target", album=rubber_soul
+ )
+ form = VideoStreamForm(initial={"release_event": release_event.pk})
output = form.as_table()
- selected_option = '<option value="%s" selected>Test Target</option>' % release_event.pk
+ selected_option = (
+ '<option value="%s" selected>Test Target</option>' % release_event.pk
+ )
self.assertIn(selected_option, output)
def test_media(self):
- rel = Album._meta.get_field('band').remote_field
+ rel = Album._meta.get_field("band").remote_field
base_files = (
- 'admin/js/vendor/jquery/jquery.min.js',
- 'admin/js/vendor/select2/select2.full.min.js',
+ "admin/js/vendor/jquery/jquery.min.js",
+ "admin/js/vendor/select2/select2.full.min.js",
# Language file is inserted here.
- 'admin/js/jquery.init.js',
- 'admin/js/autocomplete.js',
+ "admin/js/jquery.init.js",
+ "admin/js/autocomplete.js",
)
languages = (
- ('de', 'de'),
+ ("de", "de"),
# Language with code 00 does not exist.
- ('00', None),
+ ("00", None),
# Language files are case sensitive.
- ('sr-cyrl', 'sr-Cyrl'),
- ('zh-hans', 'zh-CN'),
- ('zh-hant', 'zh-TW'),
+ ("sr-cyrl", "sr-Cyrl"),
+ ("zh-hans", "zh-CN"),
+ ("zh-hant", "zh-TW"),
)
for lang, select_lang in languages:
with self.subTest(lang=lang):
if select_lang:
expected_files = (
- base_files[:2] +
- (('admin/js/vendor/select2/i18n/%s.js' % select_lang),) +
- base_files[2:]
+ base_files[:2]
+ + (("admin/js/vendor/select2/i18n/%s.js" % select_lang),)
+ + base_files[2:]
)
else:
expected_files = base_files
with translation.override(lang):
- self.assertEqual(AutocompleteSelect(rel, admin.site).media._js, list(expected_files))
+ self.assertEqual(
+ AutocompleteSelect(rel, admin.site).media._js,
+ list(expected_files),
+ )
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 677ee18cff..35563653b0 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -18,28 +18,48 @@ from django.contrib.auth.models import User
from django.core.files.storage import default_storage
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models import (
- CharField, DateField, DateTimeField, ManyToManyField, UUIDField,
+ CharField,
+ DateField,
+ DateTimeField,
+ ManyToManyField,
+ UUIDField,
)
from django.test import SimpleTestCase, TestCase, override_settings
from django.urls import reverse
from django.utils import translation
from .models import (
- Advisor, Album, Band, Bee, Car, Company, Event, Honeycomb, Individual,
- Inventory, Member, MyFileField, Profile, ReleaseEvent, School, Student,
- UnsafeLimitChoicesTo, VideoStream,
+ Advisor,
+ Album,
+ Band,
+ Bee,
+ Car,
+ Company,
+ Event,
+ Honeycomb,
+ Individual,
+ Inventory,
+ Member,
+ MyFileField,
+ Profile,
+ ReleaseEvent,
+ School,
+ Student,
+ UnsafeLimitChoicesTo,
+ VideoStream,
)
from .widgetadmin import site as widget_admin_site
class TestDataMixin:
-
@classmethod
def setUpTestData(cls):
- cls.superuser = User.objects.create_superuser(username='super', password='secret', email=None)
- cls.u2 = User.objects.create_user(username='testser', password='secret')
- Car.objects.create(owner=cls.superuser, make='Volkswagen', model='Passat')
- Car.objects.create(owner=cls.u2, make='BMW', model='M3')
+ cls.superuser = User.objects.create_superuser(
+ username="super", password="secret", email=None
+ )
+ cls.u2 = User.objects.create_user(username="testser", password="secret")
+ Car.objects.create(owner=cls.superuser, make="Volkswagen", model="Passat")
+ Car.objects.create(owner=cls.u2, make="BMW", model="M3")
class AdminFormfieldForDBFieldTests(SimpleTestCase):
@@ -55,6 +75,7 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
# Override any settings on the model admin
class MyModelAdmin(admin.ModelAdmin):
pass
+
for k in admin_overrides:
setattr(MyModelAdmin, k, admin_overrides[k])
@@ -74,75 +95,91 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
return ff
def test_DateField(self):
- self.assertFormfield(Event, 'start_date', widgets.AdminDateWidget)
+ self.assertFormfield(Event, "start_date", widgets.AdminDateWidget)
def test_DateTimeField(self):
- self.assertFormfield(Member, 'birthdate', widgets.AdminSplitDateTime)
+ self.assertFormfield(Member, "birthdate", widgets.AdminSplitDateTime)
def test_TimeField(self):
- self.assertFormfield(Event, 'start_time', widgets.AdminTimeWidget)
+ self.assertFormfield(Event, "start_time", widgets.AdminTimeWidget)
def test_TextField(self):
- self.assertFormfield(Event, 'description', widgets.AdminTextareaWidget)
+ self.assertFormfield(Event, "description", widgets.AdminTextareaWidget)
def test_URLField(self):
- self.assertFormfield(Event, 'link', widgets.AdminURLFieldWidget)
+ self.assertFormfield(Event, "link", widgets.AdminURLFieldWidget)
def test_IntegerField(self):
- self.assertFormfield(Event, 'min_age', widgets.AdminIntegerFieldWidget)
+ self.assertFormfield(Event, "min_age", widgets.AdminIntegerFieldWidget)
def test_CharField(self):
- self.assertFormfield(Member, 'name', widgets.AdminTextInputWidget)
+ self.assertFormfield(Member, "name", widgets.AdminTextInputWidget)
def test_EmailField(self):
- self.assertFormfield(Member, 'email', widgets.AdminEmailInputWidget)
+ self.assertFormfield(Member, "email", widgets.AdminEmailInputWidget)
def test_FileField(self):
- self.assertFormfield(Album, 'cover_art', widgets.AdminFileWidget)
+ self.assertFormfield(Album, "cover_art", widgets.AdminFileWidget)
def test_ForeignKey(self):
- self.assertFormfield(Event, 'main_band', forms.Select)
+ self.assertFormfield(Event, "main_band", forms.Select)
def test_raw_id_ForeignKey(self):
- self.assertFormfield(Event, 'main_band', widgets.ForeignKeyRawIdWidget,
- raw_id_fields=['main_band'])
+ self.assertFormfield(
+ Event,
+ "main_band",
+ widgets.ForeignKeyRawIdWidget,
+ raw_id_fields=["main_band"],
+ )
def test_radio_fields_ForeignKey(self):
- ff = self.assertFormfield(Event, 'main_band', widgets.AdminRadioSelect,
- radio_fields={'main_band': admin.VERTICAL})
+ ff = self.assertFormfield(
+ Event,
+ "main_band",
+ widgets.AdminRadioSelect,
+ radio_fields={"main_band": admin.VERTICAL},
+ )
self.assertIsNone(ff.empty_label)
def test_many_to_many(self):
- self.assertFormfield(Band, 'members', forms.SelectMultiple)
+ self.assertFormfield(Band, "members", forms.SelectMultiple)
def test_raw_id_many_to_many(self):
- self.assertFormfield(Band, 'members', widgets.ManyToManyRawIdWidget,
- raw_id_fields=['members'])
+ self.assertFormfield(
+ Band, "members", widgets.ManyToManyRawIdWidget, raw_id_fields=["members"]
+ )
def test_filtered_many_to_many(self):
- self.assertFormfield(Band, 'members', widgets.FilteredSelectMultiple,
- filter_vertical=['members'])
+ self.assertFormfield(
+ Band, "members", widgets.FilteredSelectMultiple, filter_vertical=["members"]
+ )
def test_formfield_overrides(self):
- self.assertFormfield(Event, 'start_date', forms.TextInput,
- formfield_overrides={DateField: {'widget': forms.TextInput}})
+ self.assertFormfield(
+ Event,
+ "start_date",
+ forms.TextInput,
+ formfield_overrides={DateField: {"widget": forms.TextInput}},
+ )
def test_formfield_overrides_widget_instances(self):
"""
Widget instances in formfield_overrides are not shared between
different fields. (#19423)
"""
+
class BandAdmin(admin.ModelAdmin):
formfield_overrides = {
- CharField: {'widget': forms.TextInput(attrs={'size': '10'})}
+ CharField: {"widget": forms.TextInput(attrs={"size": "10"})}
}
+
ma = BandAdmin(Band, admin.site)
- f1 = ma.formfield_for_dbfield(Band._meta.get_field('name'), request=None)
- f2 = ma.formfield_for_dbfield(Band._meta.get_field('style'), request=None)
+ f1 = ma.formfield_for_dbfield(Band._meta.get_field("name"), request=None)
+ f2 = ma.formfield_for_dbfield(Band._meta.get_field("style"), request=None)
self.assertNotEqual(f1.widget, f2.widget)
- self.assertEqual(f1.widget.attrs['maxlength'], '100')
- self.assertEqual(f2.widget.attrs['maxlength'], '20')
- self.assertEqual(f2.widget.attrs['size'], '10')
+ self.assertEqual(f1.widget.attrs["maxlength"], "100")
+ self.assertEqual(f2.widget.attrs["maxlength"], "20")
+ self.assertEqual(f2.widget.attrs["size"], "10")
def test_formfield_overrides_m2m_filter_widget(self):
"""
@@ -150,13 +187,15 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
filter_horizontal widgets for ManyToManyFields may be overridden by
specifying a widget in formfield_overrides.
"""
+
class BandAdmin(admin.ModelAdmin):
- filter_vertical = ['members']
+ filter_vertical = ["members"]
formfield_overrides = {
- ManyToManyField: {'widget': forms.CheckboxSelectMultiple},
+ ManyToManyField: {"widget": forms.CheckboxSelectMultiple},
}
+
ma = BandAdmin(Band, admin.site)
- field = ma.formfield_for_dbfield(Band._meta.get_field('members'), request=None)
+ field = ma.formfield_for_dbfield(Band._meta.get_field("members"), request=None)
self.assertIsInstance(field.widget.widget, forms.CheckboxSelectMultiple)
def test_formfield_overrides_for_datetime_field(self):
@@ -164,10 +203,14 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
Overriding the widget for DateTimeField doesn't overrides the default
form_class for that field (#26449).
"""
+
class MemberAdmin(admin.ModelAdmin):
- formfield_overrides = {DateTimeField: {'widget': widgets.AdminSplitDateTime}}
+ formfield_overrides = {
+ DateTimeField: {"widget": widgets.AdminSplitDateTime}
+ }
+
ma = MemberAdmin(Member, admin.site)
- f1 = ma.formfield_for_dbfield(Member._meta.get_field('birthdate'), request=None)
+ f1 = ma.formfield_for_dbfield(Member._meta.get_field("birthdate"), request=None)
self.assertIsInstance(f1.widget, widgets.AdminSplitDateTime)
self.assertIsInstance(f1, forms.SplitDateTimeField)
@@ -175,69 +218,79 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
"""
formfield_overrides works for a custom field class.
"""
+
class AlbumAdmin(admin.ModelAdmin):
- formfield_overrides = {MyFileField: {'widget': forms.TextInput()}}
+ formfield_overrides = {MyFileField: {"widget": forms.TextInput()}}
+
ma = AlbumAdmin(Member, admin.site)
- f1 = ma.formfield_for_dbfield(Album._meta.get_field('backside_art'), request=None)
+ f1 = ma.formfield_for_dbfield(
+ Album._meta.get_field("backside_art"), request=None
+ )
self.assertIsInstance(f1.widget, forms.TextInput)
def test_field_with_choices(self):
- self.assertFormfield(Member, 'gender', forms.Select)
+ self.assertFormfield(Member, "gender", forms.Select)
def test_choices_with_radio_fields(self):
- self.assertFormfield(Member, 'gender', widgets.AdminRadioSelect,
- radio_fields={'gender': admin.VERTICAL})
+ self.assertFormfield(
+ Member,
+ "gender",
+ widgets.AdminRadioSelect,
+ radio_fields={"gender": admin.VERTICAL},
+ )
def test_inheritance(self):
- self.assertFormfield(Album, 'backside_art', widgets.AdminFileWidget)
+ self.assertFormfield(Album, "backside_art", widgets.AdminFileWidget)
def test_m2m_widgets(self):
"""m2m fields help text as it applies to admin app (#9321)."""
+
class AdvisorAdmin(admin.ModelAdmin):
- filter_vertical = ['companies']
+ filter_vertical = ["companies"]
- self.assertFormfield(Advisor, 'companies', widgets.FilteredSelectMultiple,
- filter_vertical=['companies'])
+ self.assertFormfield(
+ Advisor,
+ "companies",
+ widgets.FilteredSelectMultiple,
+ filter_vertical=["companies"],
+ )
ma = AdvisorAdmin(Advisor, admin.site)
- f = ma.formfield_for_dbfield(Advisor._meta.get_field('companies'), request=None)
+ f = ma.formfield_for_dbfield(Advisor._meta.get_field("companies"), request=None)
self.assertEqual(
f.help_text,
- 'Hold down “Control”, or “Command” on a Mac, to select more than one.'
+ "Hold down “Control”, or “Command” on a Mac, to select more than one.",
)
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class AdminFormfieldForDBFieldWithRequestTests(TestDataMixin, TestCase):
-
def test_filter_choices_by_request_user(self):
"""
Ensure the user can only see their own cars in the foreign key dropdown.
"""
self.client.force_login(self.superuser)
- response = self.client.get(reverse('admin:admin_widgets_cartire_add'))
+ response = self.client.get(reverse("admin:admin_widgets_cartire_add"))
self.assertNotContains(response, "BMW M3")
self.assertContains(response, "Volkswagen Passat")
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class AdminForeignKeyWidgetChangeList(TestDataMixin, TestCase):
-
def setUp(self):
self.client.force_login(self.superuser)
def test_changelist_ForeignKey(self):
- response = self.client.get(reverse('admin:admin_widgets_car_changelist'))
- self.assertContains(response, '/auth/user/add/')
+ response = self.client.get(reverse("admin:admin_widgets_car_changelist"))
+ self.assertContains(response, "/auth/user/add/")
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class AdminForeignKeyRawIdWidget(TestDataMixin, TestCase):
-
def setUp(self):
self.client.force_login(self.superuser)
def test_nonexistent_target_id(self):
- band = Band.objects.create(name='Bogey Blues')
+ band = Band.objects.create(name="Bogey Blues")
pk = band.pk
band.delete()
post_data = {
@@ -245,54 +298,63 @@ class AdminForeignKeyRawIdWidget(TestDataMixin, TestCase):
}
# Try posting with a nonexistent pk in a raw id field: this
# should result in an error message, not a server exception.
- response = self.client.post(reverse('admin:admin_widgets_event_add'), post_data)
- self.assertContains(response, 'Select a valid choice. That choice is not one of the available choices.')
+ response = self.client.post(reverse("admin:admin_widgets_event_add"), post_data)
+ self.assertContains(
+ response,
+ "Select a valid choice. That choice is not one of the available choices.",
+ )
def test_invalid_target_id(self):
- for test_str in ('Iñtërnâtiônàlizætiøn', "1234'", -1234):
+ for test_str in ("Iñtërnâtiônàlizætiøn", "1234'", -1234):
# This should result in an error message, not a server exception.
- response = self.client.post(reverse('admin:admin_widgets_event_add'), {"main_band": test_str})
+ response = self.client.post(
+ reverse("admin:admin_widgets_event_add"), {"main_band": test_str}
+ )
- self.assertContains(response, 'Select a valid choice. That choice is not one of the available choices.')
+ self.assertContains(
+ response,
+ "Select a valid choice. That choice is not one of the available choices.",
+ )
def test_url_params_from_lookup_dict_any_iterable(self):
- lookup1 = widgets.url_params_from_lookup_dict({'color__in': ('red', 'blue')})
- lookup2 = widgets.url_params_from_lookup_dict({'color__in': ['red', 'blue']})
- self.assertEqual(lookup1, {'color__in': 'red,blue'})
+ lookup1 = widgets.url_params_from_lookup_dict({"color__in": ("red", "blue")})
+ lookup2 = widgets.url_params_from_lookup_dict({"color__in": ["red", "blue"]})
+ self.assertEqual(lookup1, {"color__in": "red,blue"})
self.assertEqual(lookup1, lookup2)
def test_url_params_from_lookup_dict_callable(self):
def my_callable():
- return 'works'
- lookup1 = widgets.url_params_from_lookup_dict({'myfield': my_callable})
- lookup2 = widgets.url_params_from_lookup_dict({'myfield': my_callable()})
+ return "works"
+
+ lookup1 = widgets.url_params_from_lookup_dict({"myfield": my_callable})
+ lookup2 = widgets.url_params_from_lookup_dict({"myfield": my_callable()})
self.assertEqual(lookup1, lookup2)
def test_label_and_url_for_value_invalid_uuid(self):
- field = Bee._meta.get_field('honeycomb')
+ field = Bee._meta.get_field("honeycomb")
self.assertIsInstance(field.target_field, UUIDField)
widget = widgets.ForeignKeyRawIdWidget(field.remote_field, admin.site)
- self.assertEqual(widget.label_and_url_for_value('invalid-uuid'), ('', ''))
+ self.assertEqual(widget.label_and_url_for_value("invalid-uuid"), ("", ""))
class FilteredSelectMultipleWidgetTest(SimpleTestCase):
def test_render(self):
# Backslash in verbose_name to ensure it is JavaScript escaped.
- w = widgets.FilteredSelectMultiple('test\\', False)
+ w = widgets.FilteredSelectMultiple("test\\", False)
self.assertHTMLEqual(
- w.render('test', 'test'),
+ w.render("test", "test"),
'<select multiple name="test" class="selectfilter" '
- 'data-field-name="test\\" data-is-stacked="0">\n</select>'
+ 'data-field-name="test\\" data-is-stacked="0">\n</select>',
)
def test_stacked_render(self):
# Backslash in verbose_name to ensure it is JavaScript escaped.
- w = widgets.FilteredSelectMultiple('test\\', True)
+ w = widgets.FilteredSelectMultiple("test\\", True)
self.assertHTMLEqual(
- w.render('test', 'test'),
+ w.render("test", "test"),
'<select multiple name="test" class="selectfilterstacked" '
- 'data-field-name="test\\" data-is-stacked="1">\n</select>'
+ 'data-field-name="test\\" data-is-stacked="1">\n</select>',
)
@@ -300,13 +362,13 @@ class AdminDateWidgetTest(SimpleTestCase):
def test_attrs(self):
w = widgets.AdminDateWidget()
self.assertHTMLEqual(
- w.render('test', datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30)),
'<input value="2007-12-01" type="text" class="vDateField" name="test" size="10">',
)
# pass attrs to widget
- w = widgets.AdminDateWidget(attrs={'size': 20, 'class': 'myDateField'})
+ w = widgets.AdminDateWidget(attrs={"size": 20, "class": "myDateField"})
self.assertHTMLEqual(
- w.render('test', datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30)),
'<input value="2007-12-01" type="text" class="myDateField" name="test" size="20">',
)
@@ -315,13 +377,13 @@ class AdminTimeWidgetTest(SimpleTestCase):
def test_attrs(self):
w = widgets.AdminTimeWidget()
self.assertHTMLEqual(
- w.render('test', datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30)),
'<input value="09:30:00" type="text" class="vTimeField" name="test" size="8">',
)
# pass attrs to widget
- w = widgets.AdminTimeWidget(attrs={'size': 20, 'class': 'myTimeField'})
+ w = widgets.AdminTimeWidget(attrs={"size": 20, "class": "myTimeField"})
self.assertHTMLEqual(
- w.render('test', datetime(2007, 12, 1, 9, 30)),
+ w.render("test", datetime(2007, 12, 1, 9, 30)),
'<input value="09:30:00" type="text" class="myTimeField" name="test" size="20">',
)
@@ -330,59 +392,58 @@ 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)),
'<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>'
+ 'name="test_1" size="8"></p>',
)
def test_localization(self):
w = widgets.AdminSplitDateTime()
- with translation.override('de-at'):
+ 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)),
'<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>'
+ 'name="test_1" size="8"></p>',
)
class AdminURLWidgetTest(SimpleTestCase):
def test_get_context_validates_url(self):
w = widgets.AdminURLFieldWidget()
- for invalid in ['', '/not/a/full/url/', 'javascript:alert("Danger XSS!")']:
+ for invalid in ["", "/not/a/full/url/", 'javascript:alert("Danger XSS!")']:
with self.subTest(url=invalid):
- self.assertFalse(w.get_context('name', invalid, {})['url_valid'])
- self.assertTrue(w.get_context('name', 'http://example.com', {})['url_valid'])
+ self.assertFalse(w.get_context("name", invalid, {})["url_valid"])
+ self.assertTrue(w.get_context("name", "http://example.com", {})["url_valid"])
def test_render(self):
w = widgets.AdminURLFieldWidget()
self.assertHTMLEqual(
- w.render('test', ''),
- '<input class="vURLField" name="test" type="url">'
+ w.render("test", ""), '<input class="vURLField" name="test" type="url">'
)
self.assertHTMLEqual(
- w.render('test', 'http://example.com'),
+ w.render("test", "http://example.com"),
'<p class="url">Currently:<a href="http://example.com">'
- 'http://example.com</a><br>'
+ "http://example.com</a><br>"
'Change:<input class="vURLField" name="test" type="url" '
- 'value="http://example.com"></p>'
+ 'value="http://example.com"></p>',
)
def test_render_idn(self):
w = widgets.AdminURLFieldWidget()
self.assertHTMLEqual(
- w.render('test', 'http://example-äüö.com'),
+ w.render("test", "http://example-äüö.com"),
'<p class="url">Currently: <a href="http://xn--example--7za4pnc.com">'
- 'http://example-äüö.com</a><br>'
+ "http://example-äüö.com</a><br>"
'Change:<input class="vURLField" name="test" type="url" '
- 'value="http://example-äüö.com"></p>'
+ 'value="http://example-äüö.com"></p>',
)
def test_render_quoting(self):
@@ -392,47 +453,49 @@ class AdminURLWidgetTest(SimpleTestCase):
"""
HREF_RE = re.compile('href="([^"]+)"')
VALUE_RE = re.compile('value="([^"]+)"')
- TEXT_RE = re.compile('<a[^>]+>([^>]+)</a>')
+ TEXT_RE = re.compile("<a[^>]+>([^>]+)</a>")
w = widgets.AdminURLFieldWidget()
- output = w.render('test', 'http://example.com/<sometag>some-text</sometag>')
+ output = w.render("test", "http://example.com/<sometag>some-text</sometag>")
self.assertEqual(
HREF_RE.search(output)[1],
- 'http://example.com/%3Csometag%3Esome-text%3C/sometag%3E',
+ "http://example.com/%3Csometag%3Esome-text%3C/sometag%3E",
)
self.assertEqual(
TEXT_RE.search(output)[1],
- 'http://example.com/&lt;sometag&gt;some-text&lt;/sometag&gt;',
+ "http://example.com/&lt;sometag&gt;some-text&lt;/sometag&gt;",
)
self.assertEqual(
VALUE_RE.search(output)[1],
- 'http://example.com/&lt;sometag&gt;some-text&lt;/sometag&gt;',
+ "http://example.com/&lt;sometag&gt;some-text&lt;/sometag&gt;",
)
- output = w.render('test', 'http://example-äüö.com/<sometag>some-text</sometag>')
+ output = w.render("test", "http://example-äüö.com/<sometag>some-text</sometag>")
self.assertEqual(
HREF_RE.search(output)[1],
- 'http://xn--example--7za4pnc.com/%3Csometag%3Esome-text%3C/sometag%3E',
+ "http://xn--example--7za4pnc.com/%3Csometag%3Esome-text%3C/sometag%3E",
)
self.assertEqual(
TEXT_RE.search(output)[1],
- 'http://example-äüö.com/&lt;sometag&gt;some-text&lt;/sometag&gt;',
+ "http://example-äüö.com/&lt;sometag&gt;some-text&lt;/sometag&gt;",
)
self.assertEqual(
VALUE_RE.search(output)[1],
- 'http://example-äüö.com/&lt;sometag&gt;some-text&lt;/sometag&gt;',
+ "http://example-äüö.com/&lt;sometag&gt;some-text&lt;/sometag&gt;",
+ )
+ output = w.render(
+ "test", 'http://www.example.com/%C3%A4"><script>alert("XSS!")</script>"'
)
- output = w.render('test', 'http://www.example.com/%C3%A4"><script>alert("XSS!")</script>"')
self.assertEqual(
HREF_RE.search(output)[1],
- 'http://www.example.com/%C3%A4%22%3E%3Cscript%3Ealert(%22XSS!%22)%3C/script%3E%22',
+ "http://www.example.com/%C3%A4%22%3E%3Cscript%3Ealert(%22XSS!%22)%3C/script%3E%22",
)
self.assertEqual(
TEXT_RE.search(output)[1],
- 'http://www.example.com/%C3%A4&quot;&gt;&lt;script&gt;'
- 'alert(&quot;XSS!&quot;)&lt;/script&gt;&quot;'
+ "http://www.example.com/%C3%A4&quot;&gt;&lt;script&gt;"
+ "alert(&quot;XSS!&quot;)&lt;/script&gt;&quot;",
)
self.assertEqual(
VALUE_RE.search(output)[1],
- 'http://www.example.com/%C3%A4&quot;&gt;&lt;script&gt;alert(&quot;XSS!&quot;)&lt;/script&gt;&quot;',
+ "http://www.example.com/%C3%A4&quot;&gt;&lt;script&gt;alert(&quot;XSS!&quot;)&lt;/script&gt;&quot;",
)
@@ -440,42 +503,42 @@ class AdminUUIDWidgetTests(SimpleTestCase):
def test_attrs(self):
w = widgets.AdminUUIDInputWidget()
self.assertHTMLEqual(
- w.render('test', '550e8400-e29b-41d4-a716-446655440000'),
+ w.render("test", "550e8400-e29b-41d4-a716-446655440000"),
'<input value="550e8400-e29b-41d4-a716-446655440000" type="text" class="vUUIDField" name="test">',
)
- w = widgets.AdminUUIDInputWidget(attrs={'class': 'myUUIDInput'})
+ w = widgets.AdminUUIDInputWidget(attrs={"class": "myUUIDInput"})
self.assertHTMLEqual(
- w.render('test', '550e8400-e29b-41d4-a716-446655440000'),
+ w.render("test", "550e8400-e29b-41d4-a716-446655440000"),
'<input value="550e8400-e29b-41d4-a716-446655440000" type="text" class="myUUIDInput" name="test">',
)
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class AdminFileWidgetTests(TestDataMixin, TestCase):
-
@classmethod
def setUpTestData(cls):
super().setUpTestData()
- band = Band.objects.create(name='Linkin Park')
+ band = Band.objects.create(name="Linkin Park")
cls.album = band.album_set.create(
- name='Hybrid Theory', cover_art=r'albums\hybrid_theory.jpg'
+ name="Hybrid Theory", cover_art=r"albums\hybrid_theory.jpg"
)
def test_render(self):
w = widgets.AdminFileWidget()
self.assertHTMLEqual(
- w.render('test', self.album.cover_art),
+ w.render("test", self.album.cover_art),
'<p class="file-upload">Currently: <a href="%(STORAGE_URL)salbums/'
r'hybrid_theory.jpg">albums\hybrid_theory.jpg</a> '
'<span class="clearable-file-input">'
'<input type="checkbox" name="test-clear" id="test-clear_id"> '
'<label for="test-clear_id">Clear</label></span><br>'
- 'Change: <input type="file" name="test"></p>' % {
- 'STORAGE_URL': default_storage.url(''),
+ 'Change: <input type="file" name="test"></p>'
+ % {
+ "STORAGE_URL": default_storage.url(""),
},
)
self.assertHTMLEqual(
- w.render('test', SimpleUploadedFile('test', b'content')),
+ w.render("test", SimpleUploadedFile("test", b"content")),
'<input type="file" name="test">',
)
@@ -483,25 +546,27 @@ class AdminFileWidgetTests(TestDataMixin, TestCase):
widget = widgets.AdminFileWidget()
widget.is_required = True
self.assertHTMLEqual(
- widget.render('test', self.album.cover_art),
+ widget.render("test", self.album.cover_art),
'<p class="file-upload">Currently: <a href="%(STORAGE_URL)salbums/'
r'hybrid_theory.jpg">albums\hybrid_theory.jpg</a><br>'
- 'Change: <input type="file" name="test"></p>' % {
- 'STORAGE_URL': default_storage.url(''),
+ 'Change: <input type="file" name="test"></p>'
+ % {
+ "STORAGE_URL": default_storage.url(""),
},
)
def test_render_disabled(self):
- widget = widgets.AdminFileWidget(attrs={'disabled': True})
+ widget = widgets.AdminFileWidget(attrs={"disabled": True})
self.assertHTMLEqual(
- widget.render('test', self.album.cover_art),
+ widget.render("test", self.album.cover_art),
'<p class="file-upload">Currently: <a href="%(STORAGE_URL)salbums/'
r'hybrid_theory.jpg">albums\hybrid_theory.jpg</a> '
'<span class="clearable-file-input">'
'<input type="checkbox" name="test-clear" id="test-clear_id" disabled>'
'<label for="test-clear_id">Clear</label></span><br>'
- 'Change: <input type="file" name="test" disabled></p>' % {
- 'STORAGE_URL': default_storage.url(''),
+ 'Change: <input type="file" name="test" disabled></p>'
+ % {
+ "STORAGE_URL": default_storage.url(""),
},
)
@@ -510,11 +575,14 @@ class AdminFileWidgetTests(TestDataMixin, TestCase):
File widgets should render as a link when they're marked "read only."
"""
self.client.force_login(self.superuser)
- response = self.client.get(reverse('admin:admin_widgets_album_change', args=(self.album.id,)))
+ response = self.client.get(
+ reverse("admin:admin_widgets_album_change", args=(self.album.id,))
+ )
self.assertContains(
response,
'<div class="readonly"><a href="%(STORAGE_URL)salbums/hybrid_theory.jpg">'
- r'albums\hybrid_theory.jpg</a></div>' % {'STORAGE_URL': default_storage.url('')},
+ r"albums\hybrid_theory.jpg</a></div>"
+ % {"STORAGE_URL": default_storage.url("")},
html=True,
)
self.assertNotContains(
@@ -522,7 +590,7 @@ class AdminFileWidgetTests(TestDataMixin, TestCase):
'<input type="file" name="cover_art" id="id_cover_art">',
html=True,
)
- response = self.client.get(reverse('admin:admin_widgets_album_add'))
+ response = self.client.get(reverse("admin:admin_widgets_album_add"))
self.assertContains(
response,
'<div class="readonly"></div>',
@@ -530,30 +598,29 @@ class AdminFileWidgetTests(TestDataMixin, TestCase):
)
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class ForeignKeyRawIdWidgetTest(TestCase):
-
def test_render(self):
- band = Band.objects.create(name='Linkin Park')
+ band = Band.objects.create(name="Linkin Park")
band.album_set.create(
- name='Hybrid Theory', cover_art=r'albums\hybrid_theory.jpg'
+ name="Hybrid Theory", cover_art=r"albums\hybrid_theory.jpg"
)
- rel_uuid = Album._meta.get_field('band').remote_field
+ rel_uuid = Album._meta.get_field("band").remote_field
w = widgets.ForeignKeyRawIdWidget(rel_uuid, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', band.uuid, attrs={}),
+ w.render("test", band.uuid, attrs={}),
'<input type="text" name="test" value="%(banduuid)s" '
'class="vForeignKeyRawIdAdminField vUUIDField">'
'<a href="/admin_widgets/band/?_to_field=uuid" class="related-lookup" '
'id="lookup_id_test" title="Lookup"></a>&nbsp;<strong>'
'<a href="/admin_widgets/band/%(bandpk)s/change/">Linkin Park</a>'
- '</strong>' % {'banduuid': band.uuid, 'bandpk': band.pk}
+ "</strong>" % {"banduuid": band.uuid, "bandpk": band.pk},
)
- rel_id = ReleaseEvent._meta.get_field('album').remote_field
+ rel_id = ReleaseEvent._meta.get_field("album").remote_field
w = widgets.ForeignKeyRawIdWidget(rel_id, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', None, attrs={}),
+ w.render("test", None, attrs={}),
'<input type="text" name="test" class="vForeignKeyRawIdAdminField">'
'<a href="/admin_widgets/album/?_to_field=id" class="related-lookup" '
'id="lookup_id_test" title="Lookup"></a>',
@@ -562,156 +629,159 @@ class ForeignKeyRawIdWidgetTest(TestCase):
def test_relations_to_non_primary_key(self):
# ForeignKeyRawIdWidget works with fields which aren't related to
# the model's primary key.
- apple = Inventory.objects.create(barcode=86, name='Apple')
- Inventory.objects.create(barcode=22, name='Pear')
- core = Inventory.objects.create(
- barcode=87, name='Core', parent=apple
- )
- rel = Inventory._meta.get_field('parent').remote_field
+ apple = Inventory.objects.create(barcode=86, name="Apple")
+ Inventory.objects.create(barcode=22, name="Pear")
+ core = Inventory.objects.create(barcode=87, name="Core", parent=apple)
+ rel = Inventory._meta.get_field("parent").remote_field
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', core.parent_id, attrs={}),
+ w.render("test", core.parent_id, attrs={}),
'<input type="text" name="test" value="86" '
'class="vForeignKeyRawIdAdminField">'
'<a href="/admin_widgets/inventory/?_to_field=barcode" '
'class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
'&nbsp;<strong><a href="/admin_widgets/inventory/%(pk)s/change/">'
- 'Apple</a></strong>' % {'pk': apple.pk}
+ "Apple</a></strong>" % {"pk": apple.pk},
)
def test_fk_related_model_not_in_admin(self):
# FK to a model not registered with admin site. Raw ID widget should
# have no magnifying glass link. See #16542
- big_honeycomb = Honeycomb.objects.create(location='Old tree')
+ big_honeycomb = Honeycomb.objects.create(location="Old tree")
big_honeycomb.bee_set.create()
- rel = Bee._meta.get_field('honeycomb').remote_field
+ rel = Bee._meta.get_field("honeycomb").remote_field
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('honeycomb_widget', big_honeycomb.pk, attrs={}),
+ w.render("honeycomb_widget", big_honeycomb.pk, attrs={}),
'<input type="text" name="honeycomb_widget" value="%(hcombpk)s">'
- '&nbsp;<strong>%(hcomb)s</strong>'
- % {'hcombpk': big_honeycomb.pk, 'hcomb': big_honeycomb}
+ "&nbsp;<strong>%(hcomb)s</strong>"
+ % {"hcombpk": big_honeycomb.pk, "hcomb": big_honeycomb},
)
def test_fk_to_self_model_not_in_admin(self):
# FK to self, not registered with admin site. Raw ID widget should have
# no magnifying glass link. See #16542
- subject1 = Individual.objects.create(name='Subject #1')
- Individual.objects.create(name='Child', parent=subject1)
- rel = Individual._meta.get_field('parent').remote_field
+ subject1 = Individual.objects.create(name="Subject #1")
+ Individual.objects.create(name="Child", parent=subject1)
+ rel = Individual._meta.get_field("parent").remote_field
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('individual_widget', subject1.pk, attrs={}),
+ w.render("individual_widget", subject1.pk, attrs={}),
'<input type="text" name="individual_widget" value="%(subj1pk)s">'
- '&nbsp;<strong>%(subj1)s</strong>'
- % {'subj1pk': subject1.pk, 'subj1': subject1}
+ "&nbsp;<strong>%(subj1)s</strong>"
+ % {"subj1pk": subject1.pk, "subj1": subject1},
)
def test_proper_manager_for_label_lookup(self):
# see #9258
- rel = Inventory._meta.get_field('parent').remote_field
+ rel = Inventory._meta.get_field("parent").remote_field
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
- hidden = Inventory.objects.create(
- barcode=93, name='Hidden', hidden=True
- )
+ hidden = Inventory.objects.create(barcode=93, name="Hidden", hidden=True)
child_of_hidden = Inventory.objects.create(
- barcode=94, name='Child of hidden', parent=hidden
+ barcode=94, name="Child of hidden", parent=hidden
)
self.assertHTMLEqual(
- w.render('test', child_of_hidden.parent_id, attrs={}),
+ w.render("test", child_of_hidden.parent_id, attrs={}),
'<input type="text" name="test" value="93" class="vForeignKeyRawIdAdminField">'
'<a href="/admin_widgets/inventory/?_to_field=barcode" '
'class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
'&nbsp;<strong><a href="/admin_widgets/inventory/%(pk)s/change/">'
- 'Hidden</a></strong>' % {'pk': hidden.pk}
+ "Hidden</a></strong>" % {"pk": hidden.pk},
)
def test_render_unsafe_limit_choices_to(self):
- rel = UnsafeLimitChoicesTo._meta.get_field('band').remote_field
+ rel = UnsafeLimitChoicesTo._meta.get_field("band").remote_field
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', None),
+ w.render("test", None),
'<input type="text" name="test" class="vForeignKeyRawIdAdminField">\n'
'<a href="/admin_widgets/band/?name=%22%26%3E%3Cescapeme&amp;_to_field=artist_ptr" '
- 'class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
+ 'class="related-lookup" id="lookup_id_test" title="Lookup"></a>',
)
def test_render_fk_as_pk_model(self):
- rel = VideoStream._meta.get_field('release_event').remote_field
+ rel = VideoStream._meta.get_field("release_event").remote_field
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', None),
+ w.render("test", None),
'<input type="text" name="test" class="vForeignKeyRawIdAdminField">\n'
'<a href="/admin_widgets/releaseevent/?_to_field=album" '
- 'class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
+ 'class="related-lookup" id="lookup_id_test" title="Lookup"></a>',
)
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class ManyToManyRawIdWidgetTest(TestCase):
-
def test_render(self):
- band = Band.objects.create(name='Linkin Park')
+ band = Band.objects.create(name="Linkin Park")
- m1 = Member.objects.create(name='Chester')
- m2 = Member.objects.create(name='Mike')
+ m1 = Member.objects.create(name="Chester")
+ m2 = Member.objects.create(name="Mike")
band.members.add(m1, m2)
- rel = Band._meta.get_field('members').remote_field
+ rel = Band._meta.get_field("members").remote_field
w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('test', [m1.pk, m2.pk], attrs={}), (
+ w.render("test", [m1.pk, m2.pk], attrs={}),
+ (
'<input type="text" name="test" value="%(m1pk)s,%(m2pk)s" class="vManyToManyRawIdAdminField">'
'<a href="/admin_widgets/member/" class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
- ) % {'m1pk': m1.pk, 'm2pk': m2.pk}
+ )
+ % {"m1pk": m1.pk, "m2pk": m2.pk},
)
self.assertHTMLEqual(
- w.render('test', [m1.pk]), (
+ w.render("test", [m1.pk]),
+ (
'<input type="text" name="test" value="%(m1pk)s" class="vManyToManyRawIdAdminField">'
'<a href="/admin_widgets/member/" class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
- ) % {'m1pk': m1.pk}
+ )
+ % {"m1pk": m1.pk},
)
def test_m2m_related_model_not_in_admin(self):
# M2M relationship with model not registered with admin site. Raw ID
# widget should have no magnifying glass link. See #16542
- consultor1 = Advisor.objects.create(name='Rockstar Techie')
+ consultor1 = Advisor.objects.create(name="Rockstar Techie")
- c1 = Company.objects.create(name='Doodle')
- c2 = Company.objects.create(name='Pear')
+ c1 = Company.objects.create(name="Doodle")
+ c2 = Company.objects.create(name="Pear")
consultor1.companies.add(c1, c2)
- rel = Advisor._meta.get_field('companies').remote_field
+ rel = Advisor._meta.get_field("companies").remote_field
w = widgets.ManyToManyRawIdWidget(rel, widget_admin_site)
self.assertHTMLEqual(
- w.render('company_widget1', [c1.pk, c2.pk], attrs={}),
- '<input type="text" name="company_widget1" value="%(c1pk)s,%(c2pk)s">' % {'c1pk': c1.pk, 'c2pk': c2.pk}
+ w.render("company_widget1", [c1.pk, c2.pk], attrs={}),
+ '<input type="text" name="company_widget1" value="%(c1pk)s,%(c2pk)s">'
+ % {"c1pk": c1.pk, "c2pk": c2.pk},
)
self.assertHTMLEqual(
- w.render('company_widget2', [c1.pk]),
- '<input type="text" name="company_widget2" value="%(c1pk)s">' % {'c1pk': c1.pk}
+ w.render("company_widget2", [c1.pk]),
+ '<input type="text" name="company_widget2" value="%(c1pk)s">'
+ % {"c1pk": c1.pk},
)
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class RelatedFieldWidgetWrapperTests(SimpleTestCase):
def test_no_can_add_related(self):
- rel = Individual._meta.get_field('parent').remote_field
+ rel = Individual._meta.get_field("parent").remote_field
w = widgets.AdminRadioSelect()
# Used to fail with a name error.
w = widgets.RelatedFieldWidgetWrapper(w, rel, widget_admin_site)
self.assertFalse(w.can_add_related)
def test_select_multiple_widget_cant_change_delete_related(self):
- rel = Individual._meta.get_field('parent').remote_field
+ rel = Individual._meta.get_field("parent").remote_field
widget = forms.SelectMultiple()
wrapper = widgets.RelatedFieldWidgetWrapper(
- widget, rel, widget_admin_site,
+ widget,
+ rel,
+ widget_admin_site,
can_add_related=True,
can_change_related=True,
can_delete_related=True,
@@ -721,10 +791,12 @@ class RelatedFieldWidgetWrapperTests(SimpleTestCase):
self.assertFalse(wrapper.can_delete_related)
def test_on_delete_cascade_rel_cant_delete_related(self):
- rel = Individual._meta.get_field('soulmate').remote_field
+ rel = Individual._meta.get_field("soulmate").remote_field
widget = forms.Select()
wrapper = widgets.RelatedFieldWidgetWrapper(
- widget, rel, widget_admin_site,
+ widget,
+ rel,
+ widget_admin_site,
can_add_related=True,
can_change_related=True,
can_delete_related=True,
@@ -736,62 +808,67 @@ class RelatedFieldWidgetWrapperTests(SimpleTestCase):
def test_custom_widget_render(self):
class CustomWidget(forms.Select):
def render(self, *args, **kwargs):
- return 'custom render output'
- rel = Album._meta.get_field('band').remote_field
+ return "custom render output"
+
+ rel = Album._meta.get_field("band").remote_field
widget = CustomWidget()
wrapper = widgets.RelatedFieldWidgetWrapper(
- widget, rel, widget_admin_site,
+ widget,
+ rel,
+ widget_admin_site,
can_add_related=True,
can_change_related=True,
can_delete_related=True,
)
- output = wrapper.render('name', 'value')
- self.assertIn('custom render output', output)
+ output = wrapper.render("name", "value")
+ self.assertIn("custom render output", output)
def test_widget_delegates_value_omitted_from_data(self):
class CustomWidget(forms.Select):
def value_omitted_from_data(self, data, files, name):
return False
- rel = Album._meta.get_field('band').remote_field
+
+ rel = Album._meta.get_field("band").remote_field
widget = CustomWidget()
wrapper = widgets.RelatedFieldWidgetWrapper(widget, rel, widget_admin_site)
- self.assertIs(wrapper.value_omitted_from_data({}, {}, 'band'), False)
+ self.assertIs(wrapper.value_omitted_from_data({}, {}, "band"), False)
def test_widget_is_hidden(self):
- rel = Album._meta.get_field('band').remote_field
+ rel = Album._meta.get_field("band").remote_field
widget = forms.HiddenInput()
widget.choices = ()
wrapper = widgets.RelatedFieldWidgetWrapper(widget, rel, widget_admin_site)
self.assertIs(wrapper.is_hidden, True)
- context = wrapper.get_context('band', None, {})
- self.assertIs(context['is_hidden'], True)
- output = wrapper.render('name', 'value')
+ context = wrapper.get_context("band", None, {})
+ self.assertIs(context["is_hidden"], True)
+ output = wrapper.render("name", "value")
# Related item links are hidden.
- self.assertNotIn('<a ', output)
+ self.assertNotIn("<a ", output)
def test_widget_is_not_hidden(self):
- rel = Album._meta.get_field('band').remote_field
+ rel = Album._meta.get_field("band").remote_field
widget = forms.Select()
wrapper = widgets.RelatedFieldWidgetWrapper(widget, rel, widget_admin_site)
self.assertIs(wrapper.is_hidden, False)
- context = wrapper.get_context('band', None, {})
- self.assertIs(context['is_hidden'], False)
- output = wrapper.render('name', 'value')
+ context = wrapper.get_context("band", None, {})
+ self.assertIs(context["is_hidden"], False)
+ output = wrapper.render("name", "value")
# Related item links are present.
- self.assertIn('<a ', output)
+ self.assertIn("<a ", output)
-@override_settings(ROOT_URLCONF='admin_widgets.urls')
+@override_settings(ROOT_URLCONF="admin_widgets.urls")
class AdminWidgetSeleniumTestCase(AdminSeleniumTestCase):
- available_apps = ['admin_widgets'] + AdminSeleniumTestCase.available_apps
+ available_apps = ["admin_widgets"] + AdminSeleniumTestCase.available_apps
def setUp(self):
- self.u1 = User.objects.create_superuser(username='super', password='secret', email='super@example.com')
+ self.u1 = User.objects.create_superuser(
+ username="super", password="secret", email="super@example.com"
+ )
class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
-
def test_show_hide_date_time_picker_widgets(self):
"""
Pressing the ESC key or clicking on a widget value closes the date and
@@ -800,57 +877,69 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
- self.admin_login(username='super', password='secret', login_url='/')
+ self.admin_login(username="super", password="secret", login_url="/")
# Open a page that has a date and time picker widgets
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_member_add'))
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_member_add")
+ )
# First, with the date picker widget ---------------------------------
- cal_icon = self.selenium.find_element(By.ID, 'calendarlink0')
+ cal_icon = self.selenium.find_element(By.ID, "calendarlink0")
# The date picker is hidden
- self.assertFalse(self.selenium.find_element(By.ID, 'calendarbox0').is_displayed())
+ self.assertFalse(
+ self.selenium.find_element(By.ID, "calendarbox0").is_displayed()
+ )
# Click the calendar icon
cal_icon.click()
# The date picker is visible
- self.assertTrue(self.selenium.find_element(By.ID, 'calendarbox0').is_displayed())
+ self.assertTrue(
+ self.selenium.find_element(By.ID, "calendarbox0").is_displayed()
+ )
# Press the ESC key
- self.selenium.find_element(By.TAG_NAME, 'body').send_keys([Keys.ESCAPE])
+ self.selenium.find_element(By.TAG_NAME, "body").send_keys([Keys.ESCAPE])
# The date picker is hidden again
- self.assertFalse(self.selenium.find_element(By.ID, 'calendarbox0').is_displayed())
+ self.assertFalse(
+ self.selenium.find_element(By.ID, "calendarbox0").is_displayed()
+ )
# Click the calendar icon, then on the 15th of current month
cal_icon.click()
self.selenium.find_element(By.XPATH, "//a[contains(text(), '15')]").click()
- self.assertFalse(self.selenium.find_element(By.ID, 'calendarbox0').is_displayed())
+ self.assertFalse(
+ self.selenium.find_element(By.ID, "calendarbox0").is_displayed()
+ )
self.assertEqual(
- self.selenium.find_element(By.ID, 'id_birthdate_0').get_attribute('value'),
- datetime.today().strftime('%Y-%m-') + '15',
+ self.selenium.find_element(By.ID, "id_birthdate_0").get_attribute("value"),
+ datetime.today().strftime("%Y-%m-") + "15",
)
# Then, with the time picker widget ----------------------------------
- time_icon = self.selenium.find_element(By.ID, 'clocklink0')
+ time_icon = self.selenium.find_element(By.ID, "clocklink0")
# The time picker is hidden
- self.assertFalse(self.selenium.find_element(By.ID, 'clockbox0').is_displayed())
+ self.assertFalse(self.selenium.find_element(By.ID, "clockbox0").is_displayed())
# Click the time icon
time_icon.click()
# The time picker is visible
- self.assertTrue(self.selenium.find_element(By.ID, 'clockbox0').is_displayed())
+ self.assertTrue(self.selenium.find_element(By.ID, "clockbox0").is_displayed())
self.assertEqual(
[
- x.text for x in
- self.selenium.find_elements(By.XPATH, "//ul[@class='timelist']/li/a")
+ x.text
+ for x in self.selenium.find_elements(
+ By.XPATH, "//ul[@class='timelist']/li/a"
+ )
],
- ['Now', 'Midnight', '6 a.m.', 'Noon', '6 p.m.']
+ ["Now", "Midnight", "6 a.m.", "Noon", "6 p.m."],
)
# Press the ESC key
- self.selenium.find_element(By.TAG_NAME, 'body').send_keys([Keys.ESCAPE])
+ self.selenium.find_element(By.TAG_NAME, "body").send_keys([Keys.ESCAPE])
# The time picker is hidden again
- self.assertFalse(self.selenium.find_element(By.ID, 'clockbox0').is_displayed())
+ self.assertFalse(self.selenium.find_element(By.ID, "clockbox0").is_displayed())
# Click the time icon, then select the 'Noon' value
time_icon.click()
self.selenium.find_element(By.XPATH, "//a[contains(text(), 'Noon')]").click()
- self.assertFalse(self.selenium.find_element(By.ID, 'clockbox0').is_displayed())
+ self.assertFalse(self.selenium.find_element(By.ID, "clockbox0").is_displayed())
self.assertEqual(
- self.selenium.find_element(By.ID, 'id_birthdate_1').get_attribute('value'),
- '12:00:00',
+ self.selenium.find_element(By.ID, "id_birthdate_1").get_attribute("value"),
+ "12:00:00",
)
def test_calendar_nonday_class(self):
@@ -859,23 +948,26 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
Refs #4574.
"""
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret', login_url='/')
+
+ self.admin_login(username="super", password="secret", login_url="/")
# Open a page that has a date and time picker widgets
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_member_add'))
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_member_add")
+ )
# fill in the birth date.
- self.selenium.find_element(By.ID, 'id_birthdate_0').send_keys('2013-06-01')
+ self.selenium.find_element(By.ID, "id_birthdate_0").send_keys("2013-06-01")
# Click the calendar icon
- self.selenium.find_element(By.ID, 'calendarlink0').click()
+ self.selenium.find_element(By.ID, "calendarlink0").click()
# get all the tds within the calendar
- calendar0 = self.selenium.find_element(By.ID, 'calendarin0')
- tds = calendar0.find_elements(By.TAG_NAME, 'td')
+ calendar0 = self.selenium.find_element(By.ID, "calendarin0")
+ tds = calendar0.find_elements(By.TAG_NAME, "td")
# make sure the first and last 6 cells have class nonday
for td in tds[:6] + tds[-6:]:
- self.assertEqual(td.get_attribute('class'), 'nonday')
+ self.assertEqual(td.get_attribute("class"), "nonday")
def test_calendar_selected_class(self):
"""
@@ -883,25 +975,28 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
Refs #4574.
"""
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret', login_url='/')
+
+ self.admin_login(username="super", password="secret", login_url="/")
# Open a page that has a date and time picker widgets
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_member_add'))
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_member_add")
+ )
# fill in the birth date.
- self.selenium.find_element(By.ID, 'id_birthdate_0').send_keys('2013-06-01')
+ self.selenium.find_element(By.ID, "id_birthdate_0").send_keys("2013-06-01")
# Click the calendar icon
- self.selenium.find_element(By.ID, 'calendarlink0').click()
+ self.selenium.find_element(By.ID, "calendarlink0").click()
# get all the tds within the calendar
- calendar0 = self.selenium.find_element(By.ID, 'calendarin0')
- tds = calendar0.find_elements(By.TAG_NAME, 'td')
+ calendar0 = self.selenium.find_element(By.ID, "calendarin0")
+ tds = calendar0.find_elements(By.TAG_NAME, "td")
# verify the selected cell
selected = tds[6]
- self.assertEqual(selected.get_attribute('class'), 'selected')
+ self.assertEqual(selected.get_attribute("class"), "selected")
- self.assertEqual(selected.text, '1')
+ self.assertEqual(selected.text, "1")
def test_calendar_no_selected_class(self):
"""
@@ -909,19 +1004,22 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
Refs #4574.
"""
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret', login_url='/')
+
+ self.admin_login(username="super", password="secret", login_url="/")
# Open a page that has a date and time picker widgets
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_member_add'))
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_member_add")
+ )
# Click the calendar icon
- self.selenium.find_element(By.ID, 'calendarlink0').click()
+ self.selenium.find_element(By.ID, "calendarlink0").click()
# get all the tds within the calendar
- calendar0 = self.selenium.find_element(By.ID, 'calendarin0')
- tds = calendar0.find_elements(By.TAG_NAME, 'td')
+ calendar0 = self.selenium.find_element(By.ID, "calendarin0")
+ tds = calendar0.find_elements(By.TAG_NAME, "td")
# verify there are no cells with the selected class
- selected = [td for td in tds if td.get_attribute('class') == 'selected']
+ selected = [td for td in tds if td.get_attribute("class") == "selected"]
self.assertEqual(len(selected), 0)
@@ -931,18 +1029,23 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
supported by Django.
"""
from selenium.webdriver.common.by import By
+
self.selenium.set_window_size(1024, 768)
- self.admin_login(username='super', password='secret', login_url='/')
+ self.admin_login(username="super", password="secret", login_url="/")
# Enter test data
- member = Member.objects.create(name='Bob', birthdate=datetime(1984, 5, 15), gender='M')
+ member = Member.objects.create(
+ name="Bob", birthdate=datetime(1984, 5, 15), gender="M"
+ )
# Get month name translations for every locale
- month_string = 'May'
- path = os.path.join(os.path.dirname(import_module('django.contrib.admin').__file__), 'locale')
+ month_string = "May"
+ path = os.path.join(
+ os.path.dirname(import_module("django.contrib.admin").__file__), "locale"
+ )
for language_code, language_name in settings.LANGUAGES:
try:
- catalog = gettext.translation('djangojs', path, [language_code])
+ catalog = gettext.translation("djangojs", path, [language_code])
except OSError:
continue
if month_string in catalog._catalog:
@@ -952,23 +1055,22 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
# Get the expected caption
may_translation = month_name
- expected_caption = '{:s} {:d}'.format(may_translation.upper(), 1984)
+ expected_caption = "{:s} {:d}".format(may_translation.upper(), 1984)
# Test with every locale
with override_settings(LANGUAGE_CODE=language_code):
# Open a page that has a date picker widget
- url = reverse('admin:admin_widgets_member_change', args=(member.pk,))
+ url = reverse("admin:admin_widgets_member_change", args=(member.pk,))
self.selenium.get(self.live_server_url + url)
# Click on the calendar icon
- self.selenium.find_element(By.ID, 'calendarlink0').click()
+ self.selenium.find_element(By.ID, "calendarlink0").click()
# Make sure that the right month and year are displayed
- self.wait_for_text('#calendarin0 caption', expected_caption)
+ self.wait_for_text("#calendarin0 caption", expected_caption)
-@override_settings(TIME_ZONE='Asia/Singapore')
+@override_settings(TIME_ZONE="Asia/Singapore")
class DateTimePickerShortcutsSeleniumTests(AdminWidgetSeleniumTestCase):
-
def test_date_time_picker_shortcuts(self):
"""
date/time/datetime picker shortcuts work in the current time zone.
@@ -979,142 +1081,175 @@ class DateTimePickerShortcutsSeleniumTests(AdminWidgetSeleniumTestCase):
the time zone to "Asia/Singapore".
"""
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret', login_url='/')
+
+ self.admin_login(username="super", password="secret", login_url="/")
error_margin = timedelta(seconds=10)
# If we are neighbouring a DST, we add an hour of error margin.
- tz = zoneinfo.ZoneInfo('America/Chicago')
- utc_now = datetime.now(zoneinfo.ZoneInfo('UTC'))
+ tz = zoneinfo.ZoneInfo("America/Chicago")
+ utc_now = datetime.now(zoneinfo.ZoneInfo("UTC"))
tz_yesterday = (utc_now - timedelta(days=1)).astimezone(tz).tzname()
tz_tomorrow = (utc_now + timedelta(days=1)).astimezone(tz).tzname()
if tz_yesterday != tz_tomorrow:
error_margin += timedelta(hours=1)
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_member_add'))
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_member_add")
+ )
- self.selenium.find_element(By.ID, 'id_name').send_keys('test')
+ self.selenium.find_element(By.ID, "id_name").send_keys("test")
# Click on the "today" and "now" shortcuts.
- shortcuts = self.selenium.find_elements(By.CSS_SELECTOR, '.field-birthdate .datetimeshortcuts')
+ shortcuts = self.selenium.find_elements(
+ By.CSS_SELECTOR, ".field-birthdate .datetimeshortcuts"
+ )
now = datetime.now()
for shortcut in shortcuts:
- shortcut.find_element(By.TAG_NAME, 'a').click()
+ shortcut.find_element(By.TAG_NAME, "a").click()
# There is a time zone mismatch warning.
# Warning: This would effectively fail if the TIME_ZONE defined in the
# settings has the same UTC offset as "Asia/Singapore" because the
# mismatch warning would be rightfully missing from the page.
- self.assertCountSeleniumElements('.field-birthdate .timezonewarning', 1)
+ self.assertCountSeleniumElements(".field-birthdate .timezonewarning", 1)
# Submit the form.
with self.wait_page_loaded():
- self.selenium.find_element(By.NAME, '_save').click()
+ self.selenium.find_element(By.NAME, "_save").click()
# Make sure that "now" in JavaScript is within 10 seconds
# from "now" on the server side.
- member = Member.objects.get(name='test')
+ member = Member.objects.get(name="test")
self.assertGreater(member.birthdate, now - error_margin)
self.assertLess(member.birthdate, now + error_margin)
# The above tests run with Asia/Singapore which are on the positive side of
# UTC. Here we test with a timezone on the negative side.
-@override_settings(TIME_ZONE='US/Eastern')
+@override_settings(TIME_ZONE="US/Eastern")
class DateTimePickerAltTimezoneSeleniumTests(DateTimePickerShortcutsSeleniumTests):
pass
class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
-
def setUp(self):
super().setUp()
- self.lisa = Student.objects.create(name='Lisa')
- self.john = Student.objects.create(name='John')
- self.bob = Student.objects.create(name='Bob')
- self.peter = Student.objects.create(name='Peter')
- self.jenny = Student.objects.create(name='Jenny')
- self.jason = Student.objects.create(name='Jason')
- self.cliff = Student.objects.create(name='Cliff')
- self.arthur = Student.objects.create(name='Arthur')
- self.school = School.objects.create(name='School of Awesome')
-
- def assertActiveButtons(self, mode, field_name, choose, remove, choose_all=None, remove_all=None):
- choose_link = '#id_%s_add_link' % field_name
- choose_all_link = '#id_%s_add_all_link' % field_name
- remove_link = '#id_%s_remove_link' % field_name
- remove_all_link = '#id_%s_remove_all_link' % field_name
- self.assertEqual(self.has_css_class(choose_link, 'active'), choose)
- self.assertEqual(self.has_css_class(remove_link, 'active'), remove)
- if mode == 'horizontal':
- self.assertEqual(self.has_css_class(choose_all_link, 'active'), choose_all)
- self.assertEqual(self.has_css_class(remove_all_link, 'active'), remove_all)
+ self.lisa = Student.objects.create(name="Lisa")
+ self.john = Student.objects.create(name="John")
+ self.bob = Student.objects.create(name="Bob")
+ self.peter = Student.objects.create(name="Peter")
+ self.jenny = Student.objects.create(name="Jenny")
+ self.jason = Student.objects.create(name="Jason")
+ self.cliff = Student.objects.create(name="Cliff")
+ self.arthur = Student.objects.create(name="Arthur")
+ self.school = School.objects.create(name="School of Awesome")
+
+ def assertActiveButtons(
+ self, mode, field_name, choose, remove, choose_all=None, remove_all=None
+ ):
+ choose_link = "#id_%s_add_link" % field_name
+ choose_all_link = "#id_%s_add_all_link" % field_name
+ remove_link = "#id_%s_remove_link" % field_name
+ remove_all_link = "#id_%s_remove_all_link" % field_name
+ self.assertEqual(self.has_css_class(choose_link, "active"), choose)
+ self.assertEqual(self.has_css_class(remove_link, "active"), remove)
+ if mode == "horizontal":
+ self.assertEqual(self.has_css_class(choose_all_link, "active"), choose_all)
+ self.assertEqual(self.has_css_class(remove_all_link, "active"), remove_all)
def execute_basic_operations(self, mode, field_name):
from selenium.webdriver.common.by import By
+
original_url = self.selenium.current_url
- from_box = '#id_%s_from' % field_name
- to_box = '#id_%s_to' % field_name
- choose_link = 'id_%s_add_link' % field_name
- choose_all_link = 'id_%s_add_all_link' % field_name
- remove_link = 'id_%s_remove_link' % field_name
- remove_all_link = 'id_%s_remove_all_link' % field_name
+ from_box = "#id_%s_from" % field_name
+ to_box = "#id_%s_to" % field_name
+ choose_link = "id_%s_add_link" % field_name
+ choose_all_link = "id_%s_add_all_link" % field_name
+ remove_link = "id_%s_remove_link" % field_name
+ remove_all_link = "id_%s_remove_all_link" % field_name
# Initial positions ---------------------------------------------------
- self.assertSelectOptions(from_box, [
- str(self.arthur.id), str(self.bob.id),
- str(self.cliff.id), str(self.jason.id),
- str(self.jenny.id), str(self.john.id),
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.arthur.id),
+ str(self.bob.id),
+ str(self.cliff.id),
+ str(self.jason.id),
+ str(self.jenny.id),
+ str(self.john.id),
+ ],
+ )
self.assertSelectOptions(to_box, [str(self.lisa.id), str(self.peter.id)])
self.assertActiveButtons(mode, field_name, False, False, True, True)
# Click 'Choose all' --------------------------------------------------
- if mode == 'horizontal':
+ if mode == "horizontal":
self.selenium.find_element(By.ID, choose_all_link).click()
- elif mode == 'vertical':
+ elif mode == "vertical":
# There 's no 'Choose all' button in vertical mode, so individually
# select all options and click 'Choose'.
- for option in self.selenium.find_elements(By.CSS_SELECTOR, from_box + ' > option'):
+ for option in self.selenium.find_elements(
+ By.CSS_SELECTOR, from_box + " > option"
+ ):
option.click()
self.selenium.find_element(By.ID, choose_link).click()
self.assertSelectOptions(from_box, [])
- self.assertSelectOptions(to_box, [
- str(self.lisa.id), str(self.peter.id),
- str(self.arthur.id), str(self.bob.id),
- str(self.cliff.id), str(self.jason.id),
- str(self.jenny.id), str(self.john.id),
- ])
+ self.assertSelectOptions(
+ to_box,
+ [
+ str(self.lisa.id),
+ str(self.peter.id),
+ str(self.arthur.id),
+ str(self.bob.id),
+ str(self.cliff.id),
+ str(self.jason.id),
+ str(self.jenny.id),
+ str(self.john.id),
+ ],
+ )
self.assertActiveButtons(mode, field_name, False, False, False, True)
# Click 'Remove all' --------------------------------------------------
- if mode == 'horizontal':
+ if mode == "horizontal":
self.selenium.find_element(By.ID, remove_all_link).click()
- elif mode == 'vertical':
+ elif mode == "vertical":
# There 's no 'Remove all' button in vertical mode, so individually
# select all options and click 'Remove'.
- for option in self.selenium.find_elements(By.CSS_SELECTOR, to_box + ' > option'):
+ for option in self.selenium.find_elements(
+ By.CSS_SELECTOR, to_box + " > option"
+ ):
option.click()
self.selenium.find_element(By.ID, remove_link).click()
- self.assertSelectOptions(from_box, [
- str(self.lisa.id), str(self.peter.id),
- str(self.arthur.id), str(self.bob.id),
- str(self.cliff.id), str(self.jason.id),
- str(self.jenny.id), str(self.john.id),
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.lisa.id),
+ str(self.peter.id),
+ str(self.arthur.id),
+ str(self.bob.id),
+ str(self.cliff.id),
+ str(self.jason.id),
+ str(self.jenny.id),
+ str(self.john.id),
+ ],
+ )
self.assertSelectOptions(to_box, [])
self.assertActiveButtons(mode, field_name, False, False, True, False)
# Choose some options ------------------------------------------------
from_lisa_select_option = self.selenium.find_element(
- By.CSS_SELECTOR,
- '{} > option[value="{}"]'.format(from_box, self.lisa.id)
+ By.CSS_SELECTOR, '{} > option[value="{}"]'.format(from_box, self.lisa.id)
)
# Check the title attribute is there for tool tips: ticket #20821
- self.assertEqual(from_lisa_select_option.get_attribute('title'), from_lisa_select_option.get_attribute('text'))
+ self.assertEqual(
+ from_lisa_select_option.get_attribute("title"),
+ from_lisa_select_option.get_attribute("text"),
+ )
self.select_option(from_box, str(self.lisa.id))
self.select_option(from_box, str(self.jason.id))
@@ -1124,21 +1259,33 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
self.selenium.find_element(By.ID, choose_link).click()
self.assertActiveButtons(mode, field_name, False, False, True, True)
- self.assertSelectOptions(from_box, [
- str(self.peter.id), str(self.arthur.id),
- str(self.cliff.id), str(self.jenny.id),
- ])
- self.assertSelectOptions(to_box, [
- str(self.lisa.id), str(self.bob.id),
- str(self.jason.id), str(self.john.id),
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.peter.id),
+ str(self.arthur.id),
+ str(self.cliff.id),
+ str(self.jenny.id),
+ ],
+ )
+ self.assertSelectOptions(
+ to_box,
+ [
+ str(self.lisa.id),
+ str(self.bob.id),
+ str(self.jason.id),
+ str(self.john.id),
+ ],
+ )
# Check the tooltip is still there after moving: ticket #20821
to_lisa_select_option = self.selenium.find_element(
- By.CSS_SELECTOR,
- '{} > option[value="{}"]'.format(to_box, self.lisa.id)
+ By.CSS_SELECTOR, '{} > option[value="{}"]'.format(to_box, self.lisa.id)
+ )
+ self.assertEqual(
+ to_lisa_select_option.get_attribute("title"),
+ to_lisa_select_option.get_attribute("text"),
)
- self.assertEqual(to_lisa_select_option.get_attribute('title'), to_lisa_select_option.get_attribute('text'))
# Remove some options -------------------------------------------------
self.select_option(to_box, str(self.lisa.id))
@@ -1147,11 +1294,17 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
self.selenium.find_element(By.ID, remove_link).click()
self.assertActiveButtons(mode, field_name, False, False, True, True)
- self.assertSelectOptions(from_box, [
- str(self.peter.id), str(self.arthur.id),
- str(self.cliff.id), str(self.jenny.id),
- str(self.lisa.id), str(self.bob.id)
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.peter.id),
+ str(self.arthur.id),
+ str(self.cliff.id),
+ str(self.jenny.id),
+ str(self.lisa.id),
+ str(self.bob.id),
+ ],
+ )
self.assertSelectOptions(to_box, [str(self.jason.id), str(self.john.id)])
# Choose some more options --------------------------------------------
@@ -1159,14 +1312,24 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
self.select_option(from_box, str(self.cliff.id))
self.selenium.find_element(By.ID, choose_link).click()
- self.assertSelectOptions(from_box, [
- str(self.peter.id), str(self.jenny.id),
- str(self.lisa.id), str(self.bob.id),
- ])
- self.assertSelectOptions(to_box, [
- str(self.jason.id), str(self.john.id),
- str(self.arthur.id), str(self.cliff.id),
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.peter.id),
+ str(self.jenny.id),
+ str(self.lisa.id),
+ str(self.bob.id),
+ ],
+ )
+ self.assertSelectOptions(
+ to_box,
+ [
+ str(self.jason.id),
+ str(self.john.id),
+ str(self.arthur.id),
+ str(self.cliff.id),
+ ],
+ )
# Choose some more options --------------------------------------------
self.select_option(from_box, str(self.peter.id))
@@ -1199,23 +1362,33 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
def test_basic(self):
from selenium.webdriver.common.by import By
+
self.selenium.set_window_size(1024, 768)
self.school.students.set([self.lisa, self.peter])
self.school.alumni.set([self.lisa, self.peter])
- self.admin_login(username='super', password='secret', login_url='/')
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_school_change', args=(self.school.id,)))
+ self.admin_login(username="super", password="secret", login_url="/")
+ self.selenium.get(
+ self.live_server_url
+ + reverse("admin:admin_widgets_school_change", args=(self.school.id,))
+ )
self.wait_page_ready()
- self.execute_basic_operations('vertical', 'students')
- self.execute_basic_operations('horizontal', 'alumni')
+ self.execute_basic_operations("vertical", "students")
+ self.execute_basic_operations("horizontal", "alumni")
# Save and check that everything is properly stored in the database ---
self.selenium.find_element(By.XPATH, '//input[@value="Save"]').click()
self.wait_page_ready()
self.school = School.objects.get(id=self.school.id) # Reload from database
- self.assertEqual(list(self.school.students.all()), [self.arthur, self.cliff, self.jason, self.john])
- self.assertEqual(list(self.school.alumni.all()), [self.arthur, self.cliff, self.jason, self.john])
+ self.assertEqual(
+ list(self.school.students.all()),
+ [self.arthur, self.cliff, self.jason, self.john],
+ )
+ self.assertEqual(
+ list(self.school.alumni.all()),
+ [self.arthur, self.cliff, self.jason, self.john],
+ )
def test_filter(self):
"""
@@ -1229,49 +1402,75 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
self.school.students.set([self.lisa, self.peter])
self.school.alumni.set([self.lisa, self.peter])
- self.admin_login(username='super', password='secret', login_url='/')
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_school_change', args=(self.school.id,)))
+ self.admin_login(username="super", password="secret", login_url="/")
+ self.selenium.get(
+ self.live_server_url
+ + reverse("admin:admin_widgets_school_change", args=(self.school.id,))
+ )
- for field_name in ['students', 'alumni']:
- from_box = '#id_%s_from' % field_name
- to_box = '#id_%s_to' % field_name
- choose_link = 'id_%s_add_link' % field_name
- remove_link = 'id_%s_remove_link' % field_name
- input = self.selenium.find_element(By.ID, 'id_%s_input' % field_name)
+ for field_name in ["students", "alumni"]:
+ from_box = "#id_%s_from" % field_name
+ to_box = "#id_%s_to" % field_name
+ choose_link = "id_%s_add_link" % field_name
+ remove_link = "id_%s_remove_link" % field_name
+ input = self.selenium.find_element(By.ID, "id_%s_input" % field_name)
# Initial values
- self.assertSelectOptions(from_box, [
- str(self.arthur.id), str(self.bob.id),
- str(self.cliff.id), str(self.jason.id),
- str(self.jenny.id), str(self.john.id),
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.arthur.id),
+ str(self.bob.id),
+ str(self.cliff.id),
+ str(self.jason.id),
+ str(self.jenny.id),
+ str(self.john.id),
+ ],
+ )
# Typing in some characters filters out non-matching options
- input.send_keys('a')
- self.assertSelectOptions(from_box, [str(self.arthur.id), str(self.jason.id)])
- input.send_keys('R')
+ input.send_keys("a")
+ self.assertSelectOptions(
+ from_box, [str(self.arthur.id), str(self.jason.id)]
+ )
+ input.send_keys("R")
self.assertSelectOptions(from_box, [str(self.arthur.id)])
# Clearing the text box makes the other options reappear
input.send_keys([Keys.BACK_SPACE])
- self.assertSelectOptions(from_box, [str(self.arthur.id), str(self.jason.id)])
+ self.assertSelectOptions(
+ from_box, [str(self.arthur.id), str(self.jason.id)]
+ )
input.send_keys([Keys.BACK_SPACE])
- self.assertSelectOptions(from_box, [
- str(self.arthur.id), str(self.bob.id),
- str(self.cliff.id), str(self.jason.id),
- str(self.jenny.id), str(self.john.id),
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.arthur.id),
+ str(self.bob.id),
+ str(self.cliff.id),
+ str(self.jason.id),
+ str(self.jenny.id),
+ str(self.john.id),
+ ],
+ )
# -----------------------------------------------------------------
# Choosing a filtered option sends it properly to the 'to' box.
- input.send_keys('a')
- self.assertSelectOptions(from_box, [str(self.arthur.id), str(self.jason.id)])
+ input.send_keys("a")
+ self.assertSelectOptions(
+ from_box, [str(self.arthur.id), str(self.jason.id)]
+ )
self.select_option(from_box, str(self.jason.id))
self.selenium.find_element(By.ID, choose_link).click()
self.assertSelectOptions(from_box, [str(self.arthur.id)])
- self.assertSelectOptions(to_box, [
- str(self.lisa.id), str(self.peter.id), str(self.jason.id),
- ])
+ self.assertSelectOptions(
+ to_box,
+ [
+ str(self.lisa.id),
+ str(self.peter.id),
+ str(self.jason.id),
+ ],
+ )
self.select_option(to_box, str(self.lisa.id))
self.selenium.find_element(By.ID, remove_link).click()
@@ -1279,11 +1478,17 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
self.assertSelectOptions(to_box, [str(self.peter.id), str(self.jason.id)])
input.send_keys([Keys.BACK_SPACE]) # Clear text box
- self.assertSelectOptions(from_box, [
- str(self.arthur.id), str(self.bob.id),
- str(self.cliff.id), str(self.jenny.id),
- str(self.john.id), str(self.lisa.id),
- ])
+ self.assertSelectOptions(
+ from_box,
+ [
+ str(self.arthur.id),
+ str(self.bob.id),
+ str(self.cliff.id),
+ str(self.jenny.id),
+ str(self.john.id),
+ str(self.lisa.id),
+ ],
+ )
self.assertSelectOptions(to_box, [str(self.peter.id), str(self.jason.id)])
# -----------------------------------------------------------------
@@ -1291,7 +1496,7 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
# the 'to' box.
self.select_option(to_box, str(self.jason.id))
self.selenium.find_element(By.ID, remove_link).click()
- input.send_keys('ja')
+ input.send_keys("ja")
self.assertSelectOptions(from_box, [str(self.jason.id)])
input.send_keys([Keys.ENTER])
self.assertSelectOptions(to_box, [str(self.peter.id), str(self.jason.id)])
@@ -1311,24 +1516,31 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
filter_horizontal/filter_vertical widgets (#13614).
"""
from selenium.webdriver.common.by import By
+
self.school.students.set([self.lisa, self.peter])
self.school.alumni.set([self.lisa, self.peter])
- self.admin_login(username='super', password='secret', login_url='/')
- change_url = reverse('admin:admin_widgets_school_change', args=(self.school.id,))
+ self.admin_login(username="super", password="secret", login_url="/")
+ change_url = reverse(
+ "admin:admin_widgets_school_change", args=(self.school.id,)
+ )
self.selenium.get(self.live_server_url + change_url)
# Navigate away and go back to the change form page.
- self.selenium.find_element(By.LINK_TEXT, 'Home').click()
+ self.selenium.find_element(By.LINK_TEXT, "Home").click()
self.selenium.back()
expected_unselected_values = [
- str(self.arthur.id), str(self.bob.id), str(self.cliff.id),
- str(self.jason.id), str(self.jenny.id), str(self.john.id),
+ str(self.arthur.id),
+ str(self.bob.id),
+ str(self.cliff.id),
+ str(self.jason.id),
+ str(self.jenny.id),
+ str(self.john.id),
]
expected_selected_values = [str(self.lisa.id), str(self.peter.id)]
# Everything is still in place
- self.assertSelectOptions('#id_students_from', expected_unselected_values)
- self.assertSelectOptions('#id_students_to', expected_selected_values)
- self.assertSelectOptions('#id_alumni_from', expected_unselected_values)
- self.assertSelectOptions('#id_alumni_to', expected_selected_values)
+ self.assertSelectOptions("#id_students_from", expected_unselected_values)
+ self.assertSelectOptions("#id_students_to", expected_selected_values)
+ self.assertSelectOptions("#id_alumni_from", expected_unselected_values)
+ self.assertSelectOptions("#id_alumni_to", expected_selected_values)
def test_refresh_page(self):
"""
@@ -1338,11 +1550,13 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
self.school.students.add(self.arthur, self.jason)
self.school.alumni.add(self.arthur, self.jason)
- self.admin_login(username='super', password='secret', login_url='/')
- change_url = reverse('admin:admin_widgets_school_change', args=(self.school.id,))
+ self.admin_login(username="super", password="secret", login_url="/")
+ change_url = reverse(
+ "admin:admin_widgets_school_change", args=(self.school.id,)
+ )
self.selenium.get(self.live_server_url + change_url)
- self.assertCountSeleniumElements('#id_students_to > option', 2)
+ self.assertCountSeleniumElements("#id_students_to > option", 2)
# self.selenium.refresh() or send_keys(Keys.F5) does hard reload and
# doesn't replicate what happens when a user clicks the browser's
@@ -1350,126 +1564,146 @@ class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
with self.wait_page_loaded():
self.selenium.execute_script("location.reload()")
- self.assertCountSeleniumElements('#id_students_to > option', 2)
+ self.assertCountSeleniumElements("#id_students_to > option", 2)
class AdminRawIdWidgetSeleniumTests(AdminWidgetSeleniumTestCase):
-
def setUp(self):
super().setUp()
- Band.objects.create(id=42, name='Bogey Blues')
- Band.objects.create(id=98, name='Green Potatoes')
+ Band.objects.create(id=42, name="Bogey Blues")
+ Band.objects.create(id=98, name="Green Potatoes")
def test_ForeignKey(self):
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret', login_url='/')
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_event_add'))
+
+ self.admin_login(username="super", password="secret", login_url="/")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_event_add")
+ )
main_window = self.selenium.current_window_handle
# No value has been selected yet
- self.assertEqual(self.selenium.find_element(By.ID, 'id_main_band').get_attribute('value'), '')
+ self.assertEqual(
+ self.selenium.find_element(By.ID, "id_main_band").get_attribute("value"), ""
+ )
# Open the popup window and click on a band
- self.selenium.find_element(By.ID, 'lookup_id_main_band').click()
+ self.selenium.find_element(By.ID, "lookup_id_main_band").click()
self.wait_for_and_switch_to_popup()
- link = self.selenium.find_element(By.LINK_TEXT, 'Bogey Blues')
- self.assertIn('/band/42/', link.get_attribute('href'))
+ link = self.selenium.find_element(By.LINK_TEXT, "Bogey Blues")
+ self.assertIn("/band/42/", link.get_attribute("href"))
link.click()
# The field now contains the selected band's id
self.selenium.switch_to.window(main_window)
- self.wait_for_value('#id_main_band', '42')
+ self.wait_for_value("#id_main_band", "42")
# Reopen the popup window and click on another band
- self.selenium.find_element(By.ID, 'lookup_id_main_band').click()
+ self.selenium.find_element(By.ID, "lookup_id_main_band").click()
self.wait_for_and_switch_to_popup()
- link = self.selenium.find_element(By.LINK_TEXT, 'Green Potatoes')
- self.assertIn('/band/98/', link.get_attribute('href'))
+ link = self.selenium.find_element(By.LINK_TEXT, "Green Potatoes")
+ self.assertIn("/band/98/", link.get_attribute("href"))
link.click()
# The field now contains the other selected band's id
self.selenium.switch_to.window(main_window)
- self.wait_for_value('#id_main_band', '98')
+ self.wait_for_value("#id_main_band", "98")
def test_many_to_many(self):
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret', login_url='/')
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_event_add'))
+
+ self.admin_login(username="super", password="secret", login_url="/")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_event_add")
+ )
main_window = self.selenium.current_window_handle
# No value has been selected yet
- self.assertEqual(self.selenium.find_element(By.ID, 'id_supporting_bands').get_attribute('value'), '')
+ self.assertEqual(
+ self.selenium.find_element(By.ID, "id_supporting_bands").get_attribute(
+ "value"
+ ),
+ "",
+ )
# Help text for the field is displayed
self.assertEqual(
- self.selenium.find_element(By.CSS_SELECTOR, '.field-supporting_bands div.help').text,
- 'Supporting Bands.'
+ self.selenium.find_element(
+ By.CSS_SELECTOR, ".field-supporting_bands div.help"
+ ).text,
+ "Supporting Bands.",
)
# Open the popup window and click on a band
- self.selenium.find_element(By.ID, 'lookup_id_supporting_bands').click()
+ self.selenium.find_element(By.ID, "lookup_id_supporting_bands").click()
self.wait_for_and_switch_to_popup()
- link = self.selenium.find_element(By.LINK_TEXT, 'Bogey Blues')
- self.assertIn('/band/42/', link.get_attribute('href'))
+ link = self.selenium.find_element(By.LINK_TEXT, "Bogey Blues")
+ self.assertIn("/band/42/", link.get_attribute("href"))
link.click()
# The field now contains the selected band's id
self.selenium.switch_to.window(main_window)
- self.wait_for_value('#id_supporting_bands', '42')
+ self.wait_for_value("#id_supporting_bands", "42")
# Reopen the popup window and click on another band
- self.selenium.find_element(By.ID, 'lookup_id_supporting_bands').click()
+ self.selenium.find_element(By.ID, "lookup_id_supporting_bands").click()
self.wait_for_and_switch_to_popup()
- link = self.selenium.find_element(By.LINK_TEXT, 'Green Potatoes')
- self.assertIn('/band/98/', link.get_attribute('href'))
+ link = self.selenium.find_element(By.LINK_TEXT, "Green Potatoes")
+ self.assertIn("/band/98/", link.get_attribute("href"))
link.click()
# The field now contains the two selected bands' ids
self.selenium.switch_to.window(main_window)
- self.wait_for_value('#id_supporting_bands', '42,98')
+ self.wait_for_value("#id_supporting_bands", "42,98")
class RelatedFieldWidgetSeleniumTests(AdminWidgetSeleniumTestCase):
-
def test_ForeignKey_using_to_field(self):
from selenium.webdriver.common.by import By
- self.admin_login(username='super', password='secret', login_url='/')
- self.selenium.get(self.live_server_url + reverse('admin:admin_widgets_profile_add'))
+
+ self.admin_login(username="super", password="secret", login_url="/")
+ self.selenium.get(
+ self.live_server_url + reverse("admin:admin_widgets_profile_add")
+ )
main_window = self.selenium.current_window_handle
# Click the Add User button to add new
- self.selenium.find_element(By.ID, 'add_id_user').click()
+ self.selenium.find_element(By.ID, "add_id_user").click()
self.wait_for_and_switch_to_popup()
- password_field = self.selenium.find_element(By.ID, 'id_password')
- password_field.send_keys('password')
+ password_field = self.selenium.find_element(By.ID, "id_password")
+ password_field.send_keys("password")
- username_field = self.selenium.find_element(By.ID, 'id_username')
- username_value = 'newuser'
+ username_field = self.selenium.find_element(By.ID, "id_username")
+ username_value = "newuser"
username_field.send_keys(username_value)
- save_button_css_selector = '.submit-row > input[type=submit]'
+ save_button_css_selector = ".submit-row > input[type=submit]"
self.selenium.find_element(By.CSS_SELECTOR, save_button_css_selector).click()
self.selenium.switch_to.window(main_window)
# The field now contains the new user
- self.selenium.find_element(By.CSS_SELECTOR, '#id_user option[value=newuser]')
+ self.selenium.find_element(By.CSS_SELECTOR, "#id_user option[value=newuser]")
# Click the Change User button to change it
- self.selenium.find_element(By.ID, 'change_id_user').click()
+ self.selenium.find_element(By.ID, "change_id_user").click()
self.wait_for_and_switch_to_popup()
- username_field = self.selenium.find_element(By.ID, 'id_username')
- username_value = 'changednewuser'
+ username_field = self.selenium.find_element(By.ID, "id_username")
+ username_value = "changednewuser"
username_field.clear()
username_field.send_keys(username_value)
- save_button_css_selector = '.submit-row > input[type=submit]'
+ save_button_css_selector = ".submit-row > input[type=submit]"
self.selenium.find_element(By.CSS_SELECTOR, save_button_css_selector).click()
self.selenium.switch_to.window(main_window)
- self.selenium.find_element(By.CSS_SELECTOR, '#id_user option[value=changednewuser]')
+ self.selenium.find_element(
+ By.CSS_SELECTOR, "#id_user option[value=changednewuser]"
+ )
# Go ahead and submit the form to make sure it works
self.selenium.find_element(By.CSS_SELECTOR, save_button_css_selector).click()
- self.wait_for_text('li.success', 'The profile “changednewuser” was added successfully.')
+ self.wait_for_text(
+ "li.success", "The profile “changednewuser” was added successfully."
+ )
profiles = Profile.objects.all()
self.assertEqual(len(profiles), 1)
self.assertEqual(profiles[0].user.username, username_value)
diff --git a/tests/admin_widgets/urls.py b/tests/admin_widgets/urls.py
index d9372ac756..76012ddd85 100644
--- a/tests/admin_widgets/urls.py
+++ b/tests/admin_widgets/urls.py
@@ -3,5 +3,5 @@ from django.urls import path
from . import widgetadmin
urlpatterns = [
- path('', widgetadmin.site.urls),
+ path("", widgetadmin.site.urls),
]
diff --git a/tests/admin_widgets/widgetadmin.py b/tests/admin_widgets/widgetadmin.py
index a025bc82a7..d7bb62be99 100644
--- a/tests/admin_widgets/widgetadmin.py
+++ b/tests/admin_widgets/widgetadmin.py
@@ -1,8 +1,20 @@
from django.contrib import admin
from .models import (
- Advisor, Album, Band, Bee, Car, CarTire, Event, Inventory, Member, Profile,
- ReleaseEvent, School, User, VideoStream,
+ Advisor,
+ Album,
+ Band,
+ Bee,
+ Car,
+ CarTire,
+ Event,
+ Inventory,
+ Member,
+ Profile,
+ ReleaseEvent,
+ School,
+ User,
+ VideoStream,
)
@@ -11,8 +23,8 @@ class WidgetAdmin(admin.AdminSite):
class CarAdmin(admin.ModelAdmin):
- list_display = ['make', 'model', 'owner']
- list_editable = ['owner']
+ list_display = ["make", "model", "owner"]
+ list_editable = ["owner"]
class CarTireAdmin(admin.ModelAdmin):
@@ -24,20 +36,23 @@ class CarTireAdmin(admin.ModelAdmin):
class EventAdmin(admin.ModelAdmin):
- raw_id_fields = ['main_band', 'supporting_bands']
+ raw_id_fields = ["main_band", "supporting_bands"]
class AlbumAdmin(admin.ModelAdmin):
- fields = ('name', 'cover_art',)
- readonly_fields = ('cover_art',)
+ fields = (
+ "name",
+ "cover_art",
+ )
+ readonly_fields = ("cover_art",)
class SchoolAdmin(admin.ModelAdmin):
- filter_vertical = ('students',)
- filter_horizontal = ('alumni',)
+ filter_vertical = ("students",)
+ filter_horizontal = ("alumni",)
-site = WidgetAdmin(name='widget-admin')
+site = WidgetAdmin(name="widget-admin")
site.register(User)
site.register(Car, CarAdmin)
@@ -47,8 +62,8 @@ site.register(Member)
site.register(Band)
site.register(Event, EventAdmin)
site.register(Album, AlbumAdmin)
-site.register(ReleaseEvent, search_fields=['name'])
-site.register(VideoStream, autocomplete_fields=['release_event'])
+site.register(ReleaseEvent, search_fields=["name"])
+site.register(VideoStream, autocomplete_fields=["release_event"])
site.register(Inventory)