From 4433d4f3c086714f3817d5413c2c436dd3d95558 Mon Sep 17 00:00:00 2001 From: c16192 Date: Tue, 8 Dec 2015 13:22:08 +0000 Subject: [PATCH] pep8 fixes Conflicts: wagtail/wagtailforms/models.py wagtail/wagtailimages/models.py wagtail/wagtailredirects/models.py wagtail/wagtailsnippets/edit_handlers.py wagtail/wagtailsnippets/tests.py wagtail/wagtailsnippets/views/snippets.py wagtail/wagtailsnippets/wagtail_hooks.py wagtail/wagtailusers/migrations/0001_initial.py wagtail/wagtailusers/migrations/0002_add_verbose_name_on_userprofile.py wagtail/wagtailusers/tests.py wagtail/wagtailusers/views/users.py wagtail/wagtailusers/wagtail_hooks.py --- CONTRIBUTORS.rst | 1 + wagtail/wagtailforms/models.py | 5 +- wagtail/wagtailforms/tests.py | 18 +- wagtail/wagtailforms/wagtail_hooks.py | 5 +- .../wagtailimages/migrations/0001_initial.py | 13 +- .../0004_make_focal_point_key_not_nullable.py | 22 +- .../migrations/0006_add_verbose_names.py | 5 +- wagtail/wagtailimages/models.py | 17 +- .../templatetags/wagtailimages_tags.py | 5 +- .../wagtailimages/tests/test_admin_views.py | 27 ++- wagtail/wagtailimages/tests/test_models.py | 8 +- wagtail/wagtailimages/tests/test_rich_text.py | 5 +- wagtail/wagtailimages/tests/tests.py | 30 ++- wagtail/wagtailimages/views/images.py | 4 +- wagtail/wagtailimages/wagtail_hooks.py | 5 +- wagtail/wagtailredirects/forms.py | 4 +- .../migrations/0001_initial.py | 17 +- .../migrations/0002_add_verbose_names.py | 5 +- .../0003_make_site_field_editable.py | 4 +- wagtail/wagtailredirects/models.py | 9 +- wagtail/wagtailredirects/tests.py | 80 ++++++-- wagtail/wagtailredirects/views.py | 10 +- wagtail/wagtailredirects/wagtail_hooks.py | 4 +- wagtail/wagtailsearch/backends/base.py | 17 +- .../wagtailsearch/backends/elasticsearch.py | 18 +- wagtail/wagtailsearch/models.py | 4 +- wagtail/wagtailsearch/tests/test_backends.py | 11 +- .../tests/test_elasticsearch_backend.py | 191 ++++++++++++++---- wagtail/wagtailsearch/views/queries.py | 10 +- wagtail/wagtailsites/wagtail_hooks.py | 3 +- wagtail/wagtailusers/tests.py | 3 +- 31 files changed, 426 insertions(+), 134 deletions(-) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 5a61205bc..946addab0 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -85,6 +85,7 @@ Contributors * LKozlowski * Matthew Downey * Maris Serzans +* Shu Ishida Translators diff --git a/wagtail/wagtailforms/models.py b/wagtail/wagtailforms/models.py index f13950559..9c24eb2d9 100644 --- a/wagtail/wagtailforms/models.py +++ b/wagtail/wagtailforms/models.py @@ -212,7 +212,10 @@ class AbstractEmailForm(AbstractForm): A Form Page that sends email. Pages implementing a form to be send to an email should inherit from it """ - to_address = models.CharField(verbose_name=_('to address'), max_length=255, blank=True, help_text=_("Optional - form submissions will be emailed to this address")) + to_address = models.CharField( + verbose_name=_('to address'), max_length=255, blank=True, + help_text=_("Optional - form submissions will be emailed to this address") + ) from_address = models.CharField(verbose_name=_('from address'), max_length=255, blank=True) subject = models.CharField(verbose_name=_('subject'), max_length=255, blank=True) diff --git a/wagtail/wagtailforms/tests.py b/wagtail/wagtailforms/tests.py index b79a9d57e..9842ce3a0 100644 --- a/wagtail/wagtailforms/tests.py +++ b/wagtail/wagtailforms/tests.py @@ -315,7 +315,9 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils): self.assertEqual(len(response.context['data_rows']), 2) def test_list_submissions_filtering(self): - response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/01/2014'}) + response = self.client.get( + reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/01/2014'} + ) # Check response self.assertEqual(response.status_code, 200) @@ -337,7 +339,9 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils): def test_list_submissions_pagination_invalid(self): self.make_list_submissions() - response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'p': 'Hello World!'}) + response = self.client.get( + reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'p': 'Hello World!'} + ) # Check response self.assertEqual(response.status_code, 200) @@ -359,7 +363,10 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils): self.assertEqual(response.context['submissions'].number, response.context['submissions'].paginator.num_pages) def test_list_submissions_csv_export(self): - response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/01/2014', 'action': 'CSV'}) + response = self.client.get( + reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), + {'date_from': '01/01/2014', 'action': 'CSV'} + ) # Check response self.assertEqual(response.status_code, 200) @@ -377,7 +384,10 @@ class TestFormsSubmissions(TestCase, WagtailTestUtils): unicode_form_submission.submit_time = '2014-01-02T12:00:00.000Z' unicode_form_submission.save() - response = self.client.get(reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), {'date_from': '01/02/2014', 'action': 'CSV'}) + response = self.client.get( + reverse('wagtailforms:list_submissions', args=(self.form_page.id, )), + {'date_from': '01/02/2014', 'action': 'CSV'} + ) # Check response self.assertEqual(response.status_code, 200) diff --git a/wagtail/wagtailforms/wagtail_hooks.py b/wagtail/wagtailforms/wagtail_hooks.py index 4f4f79a1a..14474eebd 100644 --- a/wagtail/wagtailforms/wagtail_hooks.py +++ b/wagtail/wagtailforms/wagtail_hooks.py @@ -24,4 +24,7 @@ class FormsMenuItem(MenuItem): @hooks.register('register_admin_menu_item') def register_forms_menu_item(): - return FormsMenuItem(_('Forms'), urlresolvers.reverse('wagtailforms:index'), name='forms', classnames='icon icon-form', order=700) + return FormsMenuItem( + _('Forms'), urlresolvers.reverse('wagtailforms:index'), + name='forms', classnames='icon icon-form', order=700 + ) diff --git a/wagtail/wagtailimages/migrations/0001_initial.py b/wagtail/wagtailimages/migrations/0001_initial.py index 745c03476..acb416577 100644 --- a/wagtail/wagtailimages/migrations/0001_initial.py +++ b/wagtail/wagtailimages/migrations/0001_initial.py @@ -31,7 +31,10 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(primary_key=True, serialize=False, auto_created=True, verbose_name='ID')), ('title', models.CharField(verbose_name='Title', max_length=255)), - ('file', models.ImageField(width_field='width', upload_to=wagtail.wagtailimages.models.get_upload_to, verbose_name='File', height_field='height')), + ('file', models.ImageField( + width_field='width', upload_to=wagtail.wagtailimages.models.get_upload_to, + verbose_name='File', height_field='height' + )), ('width', models.IntegerField(editable=False)), ('height', models.IntegerField(editable=False)), ('created_at', models.DateTimeField(auto_now_add=True)), @@ -39,8 +42,12 @@ class Migration(migrations.Migration): ('focal_point_y', models.PositiveIntegerField(editable=False, null=True)), ('focal_point_width', models.PositiveIntegerField(editable=False, null=True)), ('focal_point_height', models.PositiveIntegerField(editable=False, null=True)), - ('tags', taggit.managers.TaggableManager(verbose_name='Tags', blank=True, help_text=None, to='taggit.Tag', through='taggit.TaggedItem')), - ('uploaded_by_user', models.ForeignKey(editable=False, blank=True, null=True, to=settings.AUTH_USER_MODEL)), + ('tags', taggit.managers.TaggableManager( + verbose_name='Tags', blank=True, help_text=None, to='taggit.Tag', through='taggit.TaggedItem' + )), + ('uploaded_by_user', models.ForeignKey( + editable=False, blank=True, null=True, to=settings.AUTH_USER_MODEL + )), ], options={ 'abstract': False, diff --git a/wagtail/wagtailimages/migrations/0004_make_focal_point_key_not_nullable.py b/wagtail/wagtailimages/migrations/0004_make_focal_point_key_not_nullable.py index 2e6066903..0d3b2edbc 100644 --- a/wagtail/wagtailimages/migrations/0004_make_focal_point_key_not_nullable.py +++ b/wagtail/wagtailimages/migrations/0004_make_focal_point_key_not_nullable.py @@ -8,26 +8,36 @@ def remove_duplicate_renditions(apps, schema_editor): if schema_editor.connection.vendor == 'mysql': schema_editor.execute(""" DELETE FROM `wagtailimages_rendition` WHERE CONCAT(image_id, '-', filter_id) IN ( - SELECT CONCAT(image_id, '-', filter_id) FROM (SELECT * FROM `wagtailimages_rendition`) as x WHERE `focal_point_key` IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 + SELECT CONCAT(image_id, '-', filter_id) + FROM (SELECT * FROM `wagtailimages_rendition`) AS x + WHERE `focal_point_key` IS NULL + GROUP BY image_id, filter_id + HAVING COUNT(*) > 1 ) AND `focal_point_key` IS NULL """) elif schema_editor.connection.vendor == 'microsoft': schema_editor.execute(""" - DELETE FROM [wagtailimages_rendition] WHERE CAST(image_id AS VARCHAR(MAX)) + '-' + CAST(filter_id AS VARCHAR(MAX)) IN ( - SELECT CAST(image_id AS VARCHAR(MAX)) + '-' + CAST(filter_id AS VARCHAR(MAX)) FROM [wagtailimages_rendition] WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 + DELETE FROM [wagtailimages_rendition] WHERE CAST(image_id AS VARCHAR(MAX)) + '-' + + CAST(filter_id AS VARCHAR(MAX)) IN ( + SELECT CAST(image_id AS VARCHAR(MAX)) + '-' + CAST(filter_id AS VARCHAR(MAX)) + FROM [wagtailimages_rendition] WHERE focal_point_key IS NULL GROUP BY image_id, + filter_id HAVING COUNT(*) > 1 ) AND focal_point_key IS NULL """) schema_editor.execute(""" DECLARE @constraint_name VARCHAR(MAX) - SELECT @constraint_name = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME='wagtailimages_rendition' AND CONSTRAINT_TYPE='UNIQUE' + SELECT @constraint_name = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS + WHERE TABLE_NAME='wagtailimages_rendition' AND CONSTRAINT_TYPE='UNIQUE' EXEC('ALTER TABLE [wagtailimages_rendition] DROP CONSTRAINT ' + @constraint_name) ALTER TABLE [wagtailimages_rendition] ALTER COLUMN [focal_point_key] NVARCHAR(255) NOT NULL - EXEC('ALTER TABLE [wagtailimages_rendition] ADD CONSTRAINT ' + @constraint_name + ' UNIQUE NONCLUSTERED (image_id, filter_id, focal_point_key)') + EXEC('ALTER TABLE [wagtailimages_rendition] ADD CONSTRAINT ' + @constraint_name + + ' UNIQUE NONCLUSTERED (image_id, filter_id, focal_point_key)') """) else: schema_editor.execute(""" DELETE FROM wagtailimages_rendition WHERE image_id || '-' || filter_id IN ( - SELECT image_id || '-' || filter_id FROM wagtailimages_rendition WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 + SELECT image_id || '-' || filter_id FROM wagtailimages_rendition + WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 ) AND focal_point_key IS NULL """) diff --git a/wagtail/wagtailimages/migrations/0006_add_verbose_names.py b/wagtail/wagtailimages/migrations/0006_add_verbose_names.py index 4fc9f0e50..7945c69a9 100644 --- a/wagtail/wagtailimages/migrations/0006_add_verbose_names.py +++ b/wagtail/wagtailimages/migrations/0006_add_verbose_names.py @@ -25,7 +25,10 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='image', name='uploaded_by_user', - field=models.ForeignKey(blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True, verbose_name='Uploaded by user'), + field=models.ForeignKey( + blank=True, editable=False, to=settings.AUTH_USER_MODEL, null=True, + verbose_name='Uploaded by user' + ), ), migrations.AlterField( model_name='image', diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index 4bf701283..8212ecdc5 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -52,15 +52,18 @@ def get_upload_to(instance, filename): return instance.get_upload_to(filename) - @python_2_unicode_compatible class AbstractImage(models.Model, TagSearchable): title = models.CharField(max_length=255, verbose_name=_('title')) - file = models.ImageField(verbose_name=_('file'), upload_to=get_upload_to, width_field='width', height_field='height') + file = models.ImageField( + verbose_name=_('file'), upload_to=get_upload_to, width_field='width', height_field='height' + ) width = models.IntegerField(verbose_name=_('width'), editable=False) height = models.IntegerField(verbose_name=_('height'), editable=False) created_at = models.DateTimeField(verbose_name=_('created at'), auto_now_add=True, db_index=True) - uploaded_by_user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('uploaded by user'), null=True, blank=True, editable=False) + uploaded_by_user = models.ForeignKey( + settings.AUTH_USER_MODEL, verbose_name=_('uploaded by user'), null=True, blank=True, editable=False + ) tags = TaggableManager(help_text=None, blank=True, verbose_name=_('tags')) @@ -262,7 +265,8 @@ class AbstractImage(models.Model, TagSearchable): if cache_key: output_extension = cache_key + '.' + output_extension - output_filename_without_extension = input_filename_without_extension[:(59 - len(output_extension))] # Truncate filename to prevent it going over 60 chars + # Truncate filename to prevent it going over 60 chars + output_filename_without_extension = input_filename_without_extension[:(59 - len(output_extension))] output_filename = output_filename_without_extension + '.' + output_extension rendition, created = self.renditions.get_or_create( @@ -346,7 +350,10 @@ def get_image_model(): image_model = apps.get_model(app_label, model_name) if image_model is None: - raise ImproperlyConfigured("WAGTAILIMAGES_IMAGE_MODEL refers to model '%s' that has not been installed" % settings.WAGTAILIMAGES_IMAGE_MODEL) + raise ImproperlyConfigured( + "WAGTAILIMAGES_IMAGE_MODEL refers to model '%s' that has not been installed" % + settings.WAGTAILIMAGES_IMAGE_MODEL + ) return image_model diff --git a/wagtail/wagtailimages/templatetags/wagtailimages_tags.py b/wagtail/wagtailimages/templatetags/wagtailimages_tags.py index 9f2a4343c..a932b5058 100644 --- a/wagtail/wagtailimages/templatetags/wagtailimages_tags.py +++ b/wagtail/wagtailimages/templatetags/wagtailimages_tags.py @@ -24,7 +24,10 @@ def image(parser, token): try: name, value = bit.split('=') except ValueError: - raise template.TemplateSyntaxError("'image' tag should be of the form {% image self.photo max-320x200 [ custom-attr=\"value\" ... ] %} or {% image self.photo max-320x200 as img %}") + raise template.TemplateSyntaxError( + """'image' tag should be of the form {% image self.photo max-320x200 + [ custom-attr=\"value\" ... ] %} or {% image self.photo max-320x200 as img %}""" + ) attrs[name] = parser.compile_filter(value) # setup to resolve context variables as value return ImageNode(image_expr, filter_spec, attrs=attrs) diff --git a/wagtail/wagtailimages/tests/test_admin_views.py b/wagtail/wagtailimages/tests/test_admin_views.py index bc59f52b8..3726b8b02 100644 --- a/wagtail/wagtailimages/tests/test_admin_views.py +++ b/wagtail/wagtailimages/tests/test_admin_views.py @@ -130,10 +130,13 @@ class TestImageAddView(TestCase, WagtailTestUtils): self.assertTemplateUsed(response, 'wagtailimages/images/add.html') # The form should have an error - self.assertFormError(response, 'form', 'file', "This file is too big ({file_size}). Maximum filesize {max_file_size}.".format( - file_size=filesizeformat(len(file_content)), - max_file_size=filesizeformat(1), - )) + self.assertFormError( + response, 'form', 'file', + "This file is too big ({file_size}). Maximum filesize {max_file_size}.".format( + file_size=filesizeformat(len(file_content)), + max_file_size=filesizeformat(1), + ) + ) class TestImageEditView(TestCase, WagtailTestUtils): @@ -404,7 +407,9 @@ class TestMultipleImageUploader(TestCase, WagtailTestUtils): response = self.client.get(reverse('wagtailimages:add_multiple')) self.assertEqual(response.context['max_filesize'], 1000) - self.assertEqual(response.context['error_max_file_size'], "This file is too big. Maximum filesize 1000\xa0bytes.") + self.assertEqual( + response.context['error_max_file_size'], "This file is too big. Maximum filesize 1000\xa0bytes." + ) def test_add_post(self): """ @@ -473,7 +478,9 @@ class TestMultipleImageUploader(TestCase, WagtailTestUtils): self.assertIn('success', response_json) self.assertIn('error_message', response_json) self.assertFalse(response_json['success']) - self.assertEqual(response_json['error_message'], "Not a supported image format. Supported formats: GIF, JPEG, PNG.") + self.assertEqual( + response_json['error_message'], "Not a supported image format. Supported formats: GIF, JPEG, PNG." + ) def test_edit_get(self): """ @@ -562,7 +569,9 @@ class TestMultipleImageUploader(TestCase, WagtailTestUtils): This tests that a POST request to the delete view deletes the image """ # Send request - response = self.client.post(reverse('wagtailimages:delete_multiple', args=(self.image.id, )), HTTP_X_REQUESTED_WITH='XMLHttpRequest') + response = self.client.post(reverse( + 'wagtailimages:delete_multiple', args=(self.image.id, ) + ), HTTP_X_REQUESTED_WITH='XMLHttpRequest') # Check response self.assertEqual(response.status_code, 200) @@ -768,7 +777,9 @@ class TestEditOnlyPermissions(TestCase, WagtailTestUtils): ) # Create a user with change_image permission but not add_image - user = get_user_model().objects.create_user(username='changeonly', email='changeonly@example.com', password='password') + user = get_user_model().objects.create_user( + username='changeonly', email='changeonly@example.com', password='password' + ) change_permission = Permission.objects.get(content_type__app_label='wagtailimages', codename='change_image') admin_permission = Permission.objects.get(content_type__app_label='wagtailadmin', codename='access_admin') user.user_permissions.add(change_permission, admin_permission) diff --git a/wagtail/wagtailimages/tests/test_models.py b/wagtail/wagtailimages/tests/test_models.py index f678b27ed..723a66360 100644 --- a/wagtail/wagtailimages/tests/test_models.py +++ b/wagtail/wagtailimages/tests/test_models.py @@ -140,7 +140,9 @@ class TestImagePermissions(TestCase): self.owner = User.objects.create_user(username='owner', email='owner@email.com', password='password') self.editor = User.objects.create_user(username='editor', email='editor@email.com', password='password') self.editor.groups.add(Group.objects.get(name='Editors')) - self.administrator = User.objects.create_superuser(username='administrator', email='administrator@email.com', password='password') + self.administrator = User.objects.create_superuser( + username='administrator', email='administrator@email.com', password='password' + ) # Owner user must have the add_image permission self.owner.user_permissions.add(Permission.objects.get(codename='add_image')) @@ -328,7 +330,9 @@ class TestIssue573(TestCase): # Create an image with a big filename and focal point image = Image.objects.create( title="Test image", - file=get_test_image_file('thisisaverylongfilename-abcdefghijklmnopqrstuvwxyz-supercalifragilisticexpialidocious.png'), + file=get_test_image_file( + 'thisisaverylongfilename-abcdefghijklmnopqrstuvwxyz-supercalifragilisticexpialidocious.png' + ), focal_point_x=1000, focal_point_y=1000, focal_point_width=1000, diff --git a/wagtail/wagtailimages/tests/test_rich_text.py b/wagtail/wagtailimages/tests/test_rich_text.py index cae534825..057538e98 100644 --- a/wagtail/wagtailimages/tests/test_rich_text.py +++ b/wagtail/wagtailimages/tests/test_rich_text.py @@ -46,4 +46,7 @@ class TestImageEmbedHandler(TestCase): 'format': 'left'}, True ) - self.assertIn('') + temp = template.Template( + '{% load wagtailimages_tags %}{% image image_obj ' + filter_spec + + ' as test_img %}' + ) context = template.Context({'image_obj': image}) return temp.render(context) @@ -58,7 +61,10 @@ class TestImageTag(TestCase): self.assertTrue('alt="Test image"' in result) def render_image_tag_with_extra_attributes(self, image, title): - temp = template.Template('{% load wagtailimages_tags %}{% image image_obj width-400 class="photo" title=title|lower alt="Alternate" %}') + temp = template.Template( + '{% load wagtailimages_tags %}{% image image_obj width-400 \ + class="photo" title=title|lower alt="Alternate" %}' + ) context = template.Context({'image_obj': image, 'title': title}) return temp.render(context) @@ -73,7 +79,9 @@ class TestImageTag(TestCase): self.assertTrue('title="my wonderful title"' in result) def render_image_tag_with_filters(self, image): - temp = template.Template('{% load wagtailimages_tags %}{% image image_primary|default:image_alternate width-400 %}') + temp = template.Template( + '{% load wagtailimages_tags %}{% image image_primary|default:image_alternate width-400 %}' + ) context = template.Context({'image_primary': None, 'image_alternate': image}) return temp.render(context) @@ -94,12 +102,21 @@ class TestMissingImage(TestCase): def test_image_tag_with_missing_image(self): # the page /events/christmas/ has a missing image as the feed image response = self.client.get('/events/christmas/') - self.assertContains(response, 'A missing image', html=True) + self.assertContains( + response, + 'A missing image', + html=True + ) def test_rich_text_with_missing_image(self): # the page /events/final-event/ has a missing image in the rich text body response = self.client.get('/events/final-event/') - self.assertContains(response, 'where did my image go?', html=True) + self.assertContains( + response, + 'where did my image go?', + html=True + ) class TestFormat(TestCase): @@ -130,7 +147,8 @@ class TestFormat(TestCase): ) six.assertRegex( self, result, - 'test alt text', + 'test alt text', ) def test_image_to_html_no_classnames(self): diff --git a/wagtail/wagtailimages/views/images.py b/wagtail/wagtailimages/views/images.py index f4f93160d..14d366b5f 100644 --- a/wagtail/wagtailimages/views/images.py +++ b/wagtail/wagtailimages/views/images.py @@ -112,7 +112,9 @@ def edit(request, image_id): if image.is_stored_locally(): # Give error if image file doesn't exist if not os.path.isfile(image.file.path): - messages.error(request, _("The source image file could not be found. Please change the source or delete the image.").format(image.title), buttons=[ + messages.error(request, _( + "The source image file could not be found. Please change the source or delete the image." + ).format(image.title), buttons=[ messages.button(reverse('wagtailimages:delete', args=(image.id,)), _('Delete')) ]) diff --git a/wagtail/wagtailimages/wagtail_hooks.py b/wagtail/wagtailimages/wagtail_hooks.py index 60520bb54..d43c2ca93 100644 --- a/wagtail/wagtailimages/wagtail_hooks.py +++ b/wagtail/wagtailimages/wagtail_hooks.py @@ -28,7 +28,10 @@ class ImagesMenuItem(MenuItem): @hooks.register('register_admin_menu_item') def register_images_menu_item(): - return ImagesMenuItem(_('Images'), urlresolvers.reverse('wagtailimages:index'), name='images', classnames='icon icon-image', order=300) + return ImagesMenuItem( + _('Images'), urlresolvers.reverse('wagtailimages:index'), + name='images', classnames='icon icon-image', order=300 + ) @hooks.register('insert_editor_js') diff --git a/wagtail/wagtailredirects/forms.py b/wagtail/wagtailredirects/forms.py index 7ad630caf..c3fa68df1 100644 --- a/wagtail/wagtailredirects/forms.py +++ b/wagtail/wagtailredirects/forms.py @@ -8,7 +8,9 @@ from wagtail.wagtailredirects.models import Redirect class RedirectForm(forms.ModelForm): - site = forms.ModelChoiceField(label=_("From site"), queryset=Site.objects.all(), required=False, empty_label=_("All sites")) + site = forms.ModelChoiceField( + label=_("From site"), queryset=Site.objects.all(), required=False, empty_label=_("All sites") + ) def __init__(self, *args, **kwargs): super(RedirectForm, self).__init__(*args, **kwargs) diff --git a/wagtail/wagtailredirects/migrations/0001_initial.py b/wagtail/wagtailredirects/migrations/0001_initial.py index 98289544d..d3ab5d3d2 100644 --- a/wagtail/wagtailredirects/migrations/0001_initial.py +++ b/wagtail/wagtailredirects/migrations/0001_initial.py @@ -15,11 +15,20 @@ class Migration(migrations.Migration): name='Redirect', fields=[ ('id', models.AutoField(verbose_name='ID', auto_created=True, serialize=False, primary_key=True)), - ('old_path', models.CharField(verbose_name='Redirect from', max_length=255, unique=True, db_index=True)), - ('is_permanent', models.BooleanField(verbose_name='Permanent', default=True, help_text="Recommended. Permanent redirects ensure search engines forget the old page (the 'Redirect from') and index the new page instead.")), + ('old_path', models.CharField( + verbose_name='Redirect from', max_length=255, unique=True, db_index=True + )), + ('is_permanent', models.BooleanField( + verbose_name='Permanent', default=True, help_text="""Recommended. Permanent redirects \ + ensure search engines forget the old page (the 'Redirect from') and index the new page instead.""" + )), ('redirect_link', models.URLField(blank=True, verbose_name='Redirect to any URL')), - ('redirect_page', models.ForeignKey(blank=True, null=True, verbose_name='Redirect to a page', to='wagtailcore.Page')), - ('site', models.ForeignKey(blank=True, to='wagtailcore.Site', editable=False, null=True, related_name='redirects')), + ('redirect_page', models.ForeignKey( + blank=True, null=True, verbose_name='Redirect to a page', to='wagtailcore.Page' + )), + ('site', models.ForeignKey( + blank=True, to='wagtailcore.Site', editable=False, null=True, related_name='redirects' + )), ], options={ }, diff --git a/wagtail/wagtailredirects/migrations/0002_add_verbose_names.py b/wagtail/wagtailredirects/migrations/0002_add_verbose_names.py index 99ea82c09..391b9f1f6 100644 --- a/wagtail/wagtailredirects/migrations/0002_add_verbose_names.py +++ b/wagtail/wagtailredirects/migrations/0002_add_verbose_names.py @@ -18,6 +18,9 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='redirect', name='site', - field=models.ForeignKey(related_name='redirects', blank=True, editable=False, to='wagtailcore.Site', null=True, verbose_name='Site'), + field=models.ForeignKey( + related_name='redirects', blank=True, editable=False, + to='wagtailcore.Site', null=True, verbose_name='Site' + ), ), ] diff --git a/wagtail/wagtailredirects/migrations/0003_make_site_field_editable.py b/wagtail/wagtailredirects/migrations/0003_make_site_field_editable.py index e988b577a..b0ae5119b 100644 --- a/wagtail/wagtailredirects/migrations/0003_make_site_field_editable.py +++ b/wagtail/wagtailredirects/migrations/0003_make_site_field_editable.py @@ -14,6 +14,8 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='redirect', name='site', - field=models.ForeignKey(null=True, to='wagtailcore.Site', verbose_name='Site', blank=True, related_name='redirects'), + field=models.ForeignKey( + null=True, to='wagtailcore.Site', verbose_name='Site', blank=True, related_name='redirects' + ), ), ] diff --git a/wagtail/wagtailredirects/models.py b/wagtail/wagtailredirects/models.py index 2ef1974ac..a747a0315 100644 --- a/wagtail/wagtailredirects/models.py +++ b/wagtail/wagtailredirects/models.py @@ -7,8 +7,13 @@ from django.utils.translation import ugettext_lazy as _ class Redirect(models.Model): old_path = models.CharField(verbose_name=_("redirect from"), max_length=255, db_index=True) - site = models.ForeignKey('wagtailcore.Site', verbose_name=_('site'), null=True, blank=True, related_name='redirects', db_index=True) - is_permanent = models.BooleanField(verbose_name=_("permanent"), default=True, help_text=_("Recommended. Permanent redirects ensure search engines forget the old page (the 'Redirect from') and index the new page instead.")) + site = models.ForeignKey( + 'wagtailcore.Site', verbose_name=_('site'), null=True, blank=True, related_name='redirects', db_index=True + ) + is_permanent = models.BooleanField(verbose_name=_("permanent"), default=True, help_text=_( + "Recommended. Permanent redirects ensure search engines " + "forget the old page (the 'Redirect from') and index the new page instead." + )) redirect_page = models.ForeignKey('wagtailcore.Page', verbose_name=_("redirect to a page"), null=True, blank=True) redirect_link = models.URLField(verbose_name=_("redirect to any URL"), blank=True) diff --git a/wagtail/wagtailredirects/tests.py b/wagtail/wagtailredirects/tests.py index 764576e5b..d76288329 100644 --- a/wagtail/wagtailredirects/tests.py +++ b/wagtail/wagtailredirects/tests.py @@ -16,26 +16,62 @@ class TestRedirects(TestCase): path = normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2') # Test against equivalant paths - self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # The exact same URL - self.assertEqual(path, normalise_path('http://mywebsite.com:8000/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Scheme, hostname and port ignored - self.assertEqual(path, normalise_path('Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Leading slash can be omitted - self.assertEqual(path, normalise_path('Hello/world.html/;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Trailing slashes are ignored - self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2#cool')) # Fragments are ignored - self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?Baz=quux2&foo=Bar')) # Order of query string parameters is ignored - self.assertEqual(path, normalise_path('/Hello/world.html;buzz=five;fizz=three?foo=Bar&Baz=quux2')) # Order of parameters is ignored - self.assertEqual(path, normalise_path(' /Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Leading whitespace - self.assertEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2 ')) # Trailing whitespace + self.assertEqual(path, normalise_path( # The exact same URL + '/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertEqual(path, normalise_path( # Scheme, hostname and port ignored + 'http://mywebsite.com:8000/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertEqual(path, normalise_path( # Leading slash can be omitted + 'Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertEqual(path, normalise_path( # Trailing slashes are ignored + 'Hello/world.html/;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertEqual(path, normalise_path( # Fragments are ignored + '/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2#cool' + )) + self.assertEqual(path, normalise_path( # Order of query string parameters is ignored + '/Hello/world.html;fizz=three;buzz=five?Baz=quux2&foo=Bar' + )) + self.assertEqual(path, normalise_path( # Order of parameters is ignored + '/Hello/world.html;buzz=five;fizz=three?foo=Bar&Baz=quux2' + )) + self.assertEqual(path, normalise_path( # Leading whitespace + ' /Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertEqual(path, normalise_path( # Trailing whitespace + '/Hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2 ' + )) # Test against different paths - self.assertNotEqual(path, normalise_path('/hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # 'hello' is lowercase - self.assertNotEqual(path, normalise_path('/Hello/world;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # No '.html' - self.assertNotEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=bar&Baz=Quux2')) # Query string parameter value has wrong case - self.assertNotEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=five?foo=Bar&baz=quux2')) # Query string parameter name has wrong case - self.assertNotEqual(path, normalise_path('/Hello/world.html;fizz=three;buzz=Five?foo=Bar&Baz=quux2')) # Parameter value has wrong case - self.assertNotEqual(path, normalise_path('/Hello/world.html;Fizz=three;buzz=five?foo=Bar&Baz=quux2')) # Parameter name has wrong case - self.assertNotEqual(path, normalise_path('/Hello/world.html?foo=Bar&Baz=quux2')) # Missing params - self.assertNotEqual(path, normalise_path('/Hello/WORLD.html;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # 'WORLD' is uppercase - self.assertNotEqual(path, normalise_path('/Hello/world.htm;fizz=three;buzz=five?foo=Bar&Baz=quux2')) # '.htm' is not the same as '.html' + self.assertNotEqual(path, normalise_path( # 'hello' is lowercase + '/hello/world.html;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertNotEqual(path, normalise_path( # No '.html' + '/Hello/world;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertNotEqual(path, normalise_path( # Query string parameter value has wrong case + '/Hello/world.html;fizz=three;buzz=five?foo=bar&Baz=Quux2' + )) + self.assertNotEqual(path, normalise_path( # Query string parameter name has wrong case + '/Hello/world.html;fizz=three;buzz=five?foo=Bar&baz=quux2' + )) + self.assertNotEqual(path, normalise_path( # Parameter value has wrong case + '/Hello/world.html;fizz=three;buzz=Five?foo=Bar&Baz=quux2' + )) + self.assertNotEqual(path, normalise_path( # Parameter name has wrong case + '/Hello/world.html;Fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertNotEqual(path, normalise_path( # Missing params + '/Hello/world.html?foo=Bar&Baz=quux2' + )) + self.assertNotEqual(path, normalise_path( # 'WORLD' is uppercase + '/Hello/WORLD.html;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) + self.assertNotEqual(path, normalise_path( # '.htm' is not the same as '.html' + '/Hello/world.htm;fizz=three;buzz=five?foo=Bar&Baz=quux2' + )) # Normalise some rubbish to make sure it doesn't crash normalise_path('This is not a URL') @@ -67,7 +103,9 @@ class TestRedirects(TestCase): def test_redirect_stripping_query_string(self): # Create a redirect which includes a query string - redirect_with_query_string = models.Redirect(old_path='/redirectme?foo=Bar', redirect_link='/with-query-string-only') + redirect_with_query_string = models.Redirect( + old_path='/redirectme?foo=Bar', redirect_link='/with-query-string-only' + ) redirect_with_query_string.save() # ... and another redirect without the query string @@ -348,7 +386,9 @@ class TestRedirectsDeleteView(TestCase, WagtailTestUtils): return self.client.get(reverse('wagtailredirects:delete', args=(redirect_id or self.redirect.id, )), params) def post(self, post_data={}, redirect_id=None): - return self.client.post(reverse('wagtailredirects:delete', args=(redirect_id or self.redirect.id, )), post_data) + return self.client.post(reverse( + 'wagtailredirects:delete', args=(redirect_id or self.redirect.id, ) + ), post_data) def test_simple(self): response = self.get() diff --git a/wagtail/wagtailredirects/views.py b/wagtail/wagtailredirects/views.py index bde75f9d2..c88de7028 100644 --- a/wagtail/wagtailredirects/views.py +++ b/wagtail/wagtailredirects/views.py @@ -12,7 +12,11 @@ from wagtail.wagtailredirects import models from wagtail.wagtailredirects.forms import RedirectForm -@any_permission_required('wagtailredirects.add_redirect', 'wagtailredirects.change_redirect', 'wagtailredirects.delete_redirect') +@any_permission_required( + 'wagtailredirects.add_redirect', + 'wagtailredirects.change_redirect', + 'wagtailredirects.delete_redirect' +) @vary_on_headers('X-Requested-With') def index(request): query_string = request.GET.get('q', "") @@ -46,7 +50,9 @@ def index(request): 'ordering': ordering, 'redirects': redirects, 'query_string': query_string, - 'search_form': SearchForm(data=dict(q=query_string) if query_string else None, placeholder=_("Search redirects")), + 'search_form': SearchForm( + data=dict(q=query_string) if query_string else None, placeholder=_("Search redirects") + ), }) diff --git a/wagtail/wagtailredirects/wagtail_hooks.py b/wagtail/wagtailredirects/wagtail_hooks.py index ebacf956b..f8d21cebf 100644 --- a/wagtail/wagtailredirects/wagtail_hooks.py +++ b/wagtail/wagtailredirects/wagtail_hooks.py @@ -27,7 +27,9 @@ class RedirectsMenuItem(MenuItem): @hooks.register('register_settings_menu_item') def register_redirects_menu_item(): - return RedirectsMenuItem(_('Redirects'), urlresolvers.reverse('wagtailredirects:index'), classnames='icon icon-redirect', order=800) + return RedirectsMenuItem( + _('Redirects'), urlresolvers.reverse('wagtailredirects:index'), classnames='icon icon-redirect', order=800 + ) @hooks.register('register_permissions') diff --git a/wagtail/wagtailsearch/backends/base.py b/wagtail/wagtailsearch/backends/base.py index 600f355a2..3fd0c5bc9 100644 --- a/wagtail/wagtailsearch/backends/base.py +++ b/wagtail/wagtailsearch/backends/base.py @@ -54,13 +54,19 @@ class BaseSearchQuery(object): field = self._get_filterable_field(field_attname) if field is None: - raise FieldError('Cannot filter search results with field "' + field_attname + '". Please add index.FilterField(\'' + field_attname + '\') to ' + self.queryset.model.__name__ + '.search_fields.') + raise FieldError( + 'Cannot filter search results with field "' + field_attname + '". Please add index.FilterField(\'' + + field_attname + '\') to ' + self.queryset.model.__name__ + '.search_fields.' + ) # Process the lookup result = self._process_lookup(field, lookup, value) if result is None: - raise FilterError('Could not apply filter on search results: "' + field_attname + '__' + lookup + ' = ' + text_type(value) + '". Lookup "' + lookup + '"" not recognosed.') + raise FilterError( + 'Could not apply filter on search results: "' + field_attname + '__' + + lookup + ' = ' + text_type(value) + '". Lookup "' + lookup + '"" not recognosed.' + ) return result @@ -208,7 +214,8 @@ class BaseSearch(object): def delete(self, obj): raise NotImplementedError - def search(self, query_string, model_or_queryset, fields=None, filters=None, prefetch_related=None, operator=None, order_by_relevance=True): + def search(self, query_string, model_or_queryset, fields=None, filters=None, + prefetch_related=None, operator=None, order_by_relevance=True): # Find model/queryset if isinstance(model_or_queryset, QuerySet): model = model_or_queryset.model @@ -241,5 +248,7 @@ class BaseSearch(object): raise ValueError("operator must be either 'or' or 'and'") # Search - search_query = self.search_query_class(queryset, query_string, fields=fields, operator=operator, order_by_relevance=order_by_relevance) + search_query = self.search_query_class( + queryset, query_string, fields=fields, operator=operator, order_by_relevance=order_by_relevance + ) return self.search_results_class(self, search_query) diff --git a/wagtail/wagtailsearch/backends/elasticsearch.py b/wagtail/wagtailsearch/backends/elasticsearch.py index 27a5efa5e..3ee0c4831 100644 --- a/wagtail/wagtailsearch/backends/elasticsearch.py +++ b/wagtail/wagtailsearch/backends/elasticsearch.py @@ -371,7 +371,11 @@ class ElasticSearchQuery(BaseSearchQuery): class ElasticSearchResults(BaseSearchResults): def _get_es_body(self, for_count=False): # If to_es has been overridden, call it and raise a deprecation warning - if isinstance(self.query, ElasticSearchQuery) and six.get_method_function(self.query.to_es) != ElasticSearchQuery.to_es: + if ( + isinstance(self.query, ElasticSearchQuery) + and six.get_method_function(self.query.to_es) + != ElasticSearchQuery.to_es + ): warnings.warn( "The .to_es() method on Elasticsearch query classes is deprecated. " "Please rename {class_name}.to_es() to {class_name}.get_query()".format( @@ -465,7 +469,9 @@ class ElasticSearchIndexRebuilder(object): mapping = ElasticSearchMapping(model) # Put mapping - self.es.indices.put_mapping(index=self.index_name, doc_type=mapping.get_document_type(), body=mapping.get_mapping()) + self.es.indices.put_mapping( + index=self.index_name, doc_type=mapping.get_document_type(), body=mapping.get_mapping() + ) def add_items(self, model, obj_list): if not class_is_indexed(model): @@ -612,7 +618,9 @@ class ElasticSearch(BaseSearch): mapping = ElasticSearchMapping(model) # Put mapping - self.es.indices.put_mapping(index=self.es_index, doc_type=mapping.get_document_type(), body=mapping.get_mapping()) + self.es.indices.put_mapping( + index=self.es_index, doc_type=mapping.get_document_type(), body=mapping.get_mapping() + ) def refresh_index(self): self.es.indices.refresh(self.es_index) @@ -626,7 +634,9 @@ class ElasticSearch(BaseSearch): mapping = ElasticSearchMapping(obj.__class__) # Add document to index - self.es.index(self.es_index, mapping.get_document_type(), mapping.get_document(obj), id=mapping.get_document_id(obj)) + self.es.index( + self.es_index, mapping.get_document_type(), mapping.get_document(obj), id=mapping.get_document_id(obj) + ) def add_bulk(self, model, obj_list): if not class_is_indexed(model): diff --git a/wagtail/wagtailsearch/models.py b/wagtail/wagtailsearch/models.py index bab3d216c..788b54b45 100644 --- a/wagtail/wagtailsearch/models.py +++ b/wagtail/wagtailsearch/models.py @@ -49,7 +49,9 @@ class Query(models.Model): @classmethod def get_most_popular(cls, date_since=None): # TODO: Implement date_since - return cls.objects.filter(daily_hits__isnull=False).annotate(_hits=models.Sum('daily_hits__hits')).distinct().order_by('-_hits') + return (cls.objects.filter(daily_hits__isnull=False) + .annotate(_hits=models.Sum('daily_hits__hits')) + .distinct().order_by('-_hits')) class QueryDailyHits(models.Model): diff --git a/wagtail/wagtailsearch/tests/test_backends.py b/wagtail/wagtailsearch/tests/test_backends.py index 4b6efd602..25e31069b 100644 --- a/wagtail/wagtailsearch/tests/test_backends.py +++ b/wagtail/wagtailsearch/tests/test_backends.py @@ -141,8 +141,11 @@ class BackendTests(WagtailTestUtils): self.assertEqual(set(results), set()) # Run update_index command - with self.ignore_deprecation_warnings(): # ignore any DeprecationWarnings thrown by models with old-style indexed_fields definitions - management.call_command('update_index', backend_name=self.backend_name, interactive=False, stdout=StringIO()) + with self.ignore_deprecation_warnings(): + # ignore any DeprecationWarnings thrown by models with old-style indexed_fields definitions + management.call_command( + 'update_index', backend_name=self.backend_name, interactive=False, stdout=StringIO() + ) results = self.backend.search(None, models.SearchTest) self.assertEqual(set(results), {self.testa, self.testb, self.testc.searchtest_ptr, self.testd.searchtest_ptr}) @@ -167,7 +170,9 @@ class TestBackendLoader(TestCase): self.assertIsInstance(db, DBSearch) def test_nonexistent_backend_import(self): - self.assertRaises(InvalidSearchBackendError, get_search_backend, backend='wagtail.wagtailsearch.backends.doesntexist') + self.assertRaises( + InvalidSearchBackendError, get_search_backend, backend='wagtail.wagtailsearch.backends.doesntexist' + ) def test_invalid_backend_import(self): self.assertRaises(InvalidSearchBackendError, get_search_backend, backend="I'm not a backend!") diff --git a/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py b/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py index 13b0ac197..8545ef563 100644 --- a/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py +++ b/wagtail/wagtailsearch/tests/test_elasticsearch_backend.py @@ -205,7 +205,9 @@ class TestElasticSearchBackend(BackendTests, TestCase): self.assertEqual(list(results), [a, b]) # Do a search ordered by published date - results = self.backend.search("Hello", models.SearchTest.objects.order_by('-published_date'), order_by_relevance=False) + results = self.backend.search( + "Hello", models.SearchTest.objects.order_by('-published_date'), order_by_relevance=False + ) self.assertEqual(list(results), [b, a]) def test_and_operator_with_single_field(self): @@ -233,14 +235,19 @@ class TestElasticSearchBackend(BackendTests, TestCase): class TestElasticSearchQuery(TestCase): def assertDictEqual(self, a, b): default = JSONSerializer().default - self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)) + self.assertEqual( + json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default) + ) def test_simple(self): # Create a query query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello") # Check it - expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': { + 'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, + 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}} + }} self.assertDictEqual(query.get_query(), expected_result) def test_none_query_string(self): @@ -248,7 +255,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.all(), None) # Check it - expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match_all': {}}}} + expected_result = {'filtered': { + 'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, + 'query': {'match_all': {}} + }} self.assertDictEqual(query.get_query(), expected_result) def test_and_operator(self): @@ -256,7 +266,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", operator='and') # Check it - expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials'], 'operator': 'and'}}}} + expected_result = {'filtered': { + 'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, + 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials'], 'operator': 'and'}} + }} self.assertDictEqual(query.get_query(), expected_result) def test_filter(self): @@ -264,7 +277,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.filter(title="Test"), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'term': {'title_filter': 'Test'}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_and_filter(self): @@ -272,7 +288,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.filter(title="Test", live=True), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'and': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} # Make sure field filters are sorted (as they can be in any order which may cause false positives) query = query.get_query() @@ -291,7 +310,10 @@ class TestElasticSearchQuery(TestCase): field_filters[:] = sorted(field_filters, key=lambda f: list(f['term'].keys())[0]) # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'or': [{'term': {'live_filter': True}}, {'term': {'title_filter': 'Test'}}]} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query, expected_result) def test_negated_filter(self): @@ -299,7 +321,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.exclude(live=True), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'term': {'live_filter': True}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'not': {'term': {'live_filter': True}}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_fields(self): @@ -307,7 +332,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title']) # Check it - expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match': {'title': 'Hello'}}}} + expected_result = {'filtered': { + 'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, + 'query': {'match': {'title': 'Hello'}} + }} self.assertDictEqual(query.get_query(), expected_result) def test_fields_with_and_operator(self): @@ -315,7 +343,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title'], operator='and') # Check it - expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'match': {'title': {'query': 'Hello', 'operator': 'and'}}}}} + expected_result = {'filtered': { + 'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, + 'query': {'match': {'title': {'query': 'Hello', 'operator': 'and'}}} + }} self.assertDictEqual(query.get_query(), expected_result) def test_multiple_fields(self): @@ -323,15 +354,23 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title', 'content']) # Check it - expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello'}}}} + expected_result = {'filtered': { + 'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, + 'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello'}} + }} self.assertDictEqual(query.get_query(), expected_result) def test_multiple_fields_with_and_operator(self): # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.all(), "Hello", fields=['title', 'content'], operator='and') + query = ElasticSearchQuery( + models.SearchTest.objects.all(), "Hello", fields=['title', 'content'], operator='and' + ) # Check it - expected_result = {'filtered': {'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, 'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello', 'operator': 'and'}}}} + expected_result = {'filtered': { + 'filter': {'prefix': {'content_type': 'searchtests_searchtest'}}, + 'query': {'multi_match': {'fields': ['title', 'content'], 'query': 'Hello', 'operator': 'and'}} + }} self.assertDictEqual(query.get_query(), expected_result) def test_exact_lookup(self): @@ -339,7 +378,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.filter(title__exact="Test"), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'term': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'term': {'title_filter': 'Test'}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_none_lookup(self): @@ -347,7 +389,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.filter(title=None), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'missing': {'field': 'title_filter'}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_isnull_true_lookup(self): @@ -355,7 +400,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=True), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'missing': {'field': 'title_filter'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'missing': {'field': 'title_filter'}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_isnull_false_lookup(self): @@ -363,7 +411,10 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.filter(title__isnull=False), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'not': {'missing': {'field': 'title_filter'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'not': {'missing': {'field': 'title_filter'}}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_startswith_lookup(self): @@ -371,41 +422,64 @@ class TestElasticSearchQuery(TestCase): query = ElasticSearchQuery(models.SearchTest.objects.filter(title__startswith="Test"), "Hello") # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'prefix': {'title_filter': 'Test'}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'prefix': {'title_filter': 'Test'}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_gt_lookup(self): # This also tests conversion of python dates to strings # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gt=datetime.datetime(2014, 4, 29)), "Hello") + query = ElasticSearchQuery( + models.SearchTest.objects.filter(published_date__gt=datetime.datetime(2014, 4, 29)), "Hello" + ) # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'range': {'published_date_filter': {'gt': '2014-04-29'}}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_lt_lookup(self): # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lt=datetime.datetime(2014, 4, 29)), "Hello") + query = ElasticSearchQuery( + models.SearchTest.objects.filter(published_date__lt=datetime.datetime(2014, 4, 29)), "Hello" + ) # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lt': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'range': {'published_date_filter': {'lt': '2014-04-29'}}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_gte_lookup(self): # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__gte=datetime.datetime(2014, 4, 29)), "Hello") + query = ElasticSearchQuery( + models.SearchTest.objects.filter(published_date__gte=datetime.datetime(2014, 4, 29)), "Hello" + ) # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'range': {'published_date_filter': {'gte': '2014-04-29'}}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_lte_lookup(self): # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__lte=datetime.datetime(2014, 4, 29)), "Hello") + query = ElasticSearchQuery( + models.SearchTest.objects.filter(published_date__lte=datetime.datetime(2014, 4, 29)), "Hello" + ) # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'lte': '2014-04-29'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'range': {'published_date_filter': {'lte': '2014-04-29'}}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_range_lookup(self): @@ -413,15 +487,22 @@ class TestElasticSearchQuery(TestCase): end_date = datetime.datetime(2014, 8, 19) # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.filter(published_date__range=(start_date, end_date)), "Hello") + query = ElasticSearchQuery( + models.SearchTest.objects.filter(published_date__range=(start_date, end_date)), "Hello" + ) # Check it - expected_result = {'filtered': {'filter': {'and': [{'prefix': {'content_type': 'searchtests_searchtest'}}, {'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}}]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} + expected_result = {'filtered': {'filter': {'and': [ + {'prefix': {'content_type': 'searchtests_searchtest'}}, + {'range': {'published_date_filter': {'gte': '2014-04-29', 'lte': '2014-08-19'}}} + ]}, 'query': {'multi_match': {'query': 'Hello', 'fields': ['_all', '_partials']}}}} self.assertDictEqual(query.get_query(), expected_result) def test_custom_ordering(self): # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.order_by('published_date'), "Hello", order_by_relevance=False) + query = ElasticSearchQuery( + models.SearchTest.objects.order_by('published_date'), "Hello", order_by_relevance=False + ) # Check it expected_result = [{'published_date_filter': 'asc'}] @@ -429,7 +510,9 @@ class TestElasticSearchQuery(TestCase): def test_custom_ordering_reversed(self): # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.order_by('-published_date'), "Hello", order_by_relevance=False) + query = ElasticSearchQuery( + models.SearchTest.objects.order_by('-published_date'), "Hello", order_by_relevance=False + ) # Check it expected_result = [{'published_date_filter': 'desc'}] @@ -437,7 +520,9 @@ class TestElasticSearchQuery(TestCase): def test_custom_ordering_multiple(self): # Create a query - query = ElasticSearchQuery(models.SearchTest.objects.order_by('published_date', 'live'), "Hello", order_by_relevance=False) + query = ElasticSearchQuery( + models.SearchTest.objects.order_by('published_date', 'live'), "Hello", order_by_relevance=False + ) # Check it expected_result = [{'published_date_filter': 'asc'}, {'live_filter': 'asc'}] @@ -447,7 +532,9 @@ class TestElasticSearchQuery(TestCase): class TestElasticSearchResults(TestCase): def assertDictEqual(self, a, b): default = JSONSerializer().default - self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)) + self.assertEqual( + json.dumps(a, sort_keys=True, default=default), json.dumps + ) def setUp(self): self.objects = [] @@ -599,7 +686,9 @@ class TestElasticSearchResults(TestCase): @mock.patch('elasticsearch.Elasticsearch.search') def test_result_order(self, search): - search.return_value = self.construct_search_response([self.objects[0].id, self.objects[1].id, self.objects[2].id]) + search.return_value = self.construct_search_response( + [self.objects[0].id, self.objects[1].id, self.objects[2].id] + ) results = list(self.get_results()) # Must cast to list so we only create one query self.assertEqual(results[0], self.objects[0]) @@ -608,7 +697,9 @@ class TestElasticSearchResults(TestCase): @mock.patch('elasticsearch.Elasticsearch.search') def test_result_order_2(self, search): - search.return_value = self.construct_search_response([self.objects[2].id, self.objects[1].id, self.objects[0].id]) + search.return_value = self.construct_search_response( + [self.objects[2].id, self.objects[1].id, self.objects[0].id] + ) results = list(self.get_results()) # Must cast to list so we only create one query self.assertEqual(results[0], self.objects[2]) @@ -619,7 +710,9 @@ class TestElasticSearchResults(TestCase): class TestElasticSearchMapping(TestCase): def assertDictEqual(self, a, b): default = JSONSerializer().default - self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)) + self.assertEqual( + json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default) + ) def setUp(self): # Create ES mapping @@ -681,7 +774,9 @@ class TestElasticSearchMapping(TestCase): class TestElasticSearchMappingInheritance(TestCase): def assertDictEqual(self, a, b): default = JSONSerializer().default - self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)) + self.assertEqual( + json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default) + ) def setUp(self): # Create ES mapping @@ -820,7 +915,9 @@ class TestBackendConfiguration(TestCase): class TestRebuilder(TestCase): def assertDictEqual(self, a, b): default = JSONSerializer().default - self.assertEqual(json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default)) + self.assertEqual( + json.dumps(a, sort_keys=True, default=default), json.dumps(b, sort_keys=True, default=default) + ) def setUp(self): self.backend = get_search_backend('elasticsearch') @@ -847,13 +944,17 @@ class TestRebuilder(TestCase): def test_start_deletes_existing_index(self): # Put an alias into the index so we can check it was deleted self.es.indices.put_alias(name='this_index_should_be_deleted', index=self.backend.es_index) - self.assertTrue(self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index)) + self.assertTrue( + self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index) + ) # Run start self.rebuilder.start() # The alias should be gone (proving the index was deleted and recreated) - self.assertFalse(self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index)) + self.assertFalse( + self.es.indices.exists_alias(name='this_index_should_be_deleted', index=self.backend.es_index) + ) def test_add_model(self): self.rebuilder.start() @@ -866,13 +967,15 @@ class TestRebuilder(TestCase): response = self.es.indices.get_mapping(self.backend.es_index, mapping.get_document_type()) # Make some minor tweaks to the mapping so it matches what is in ES - # These are generally minor issues with the way Wagtail is generating the mapping that are being cleaned up by Elasticsearch + # These are generally minor issues with the way Wagtail is + # generating the mapping that are being cleaned up by Elasticsearch # TODO: Would be nice to fix these expected_mapping = mapping.get_mapping() expected_mapping['searchtests_searchtest']['properties']['pk']['store'] = True expected_mapping['searchtests_searchtest']['properties']['live_filter'].pop('index') expected_mapping['searchtests_searchtest']['properties']['live_filter'].pop('include_in_all') - expected_mapping['searchtests_searchtest']['properties']['published_date_filter']['format'] = 'dateOptionalTime' + expected_mapping['searchtests_searchtest']['properties']['published_date_filter']['format'] = \ + 'dateOptionalTime' expected_mapping['searchtests_searchtest']['properties']['published_date_filter'].pop('index') self.assertDictEqual(expected_mapping, response[self.backend.es_index]['mappings']) @@ -916,7 +1019,9 @@ class TestAtomicRebuilder(TestCase): self.rebuilder.start() # Check that the alias doesn't point to new index - self.assertFalse(self.es.indices.exists_alias(name=self.rebuilder.alias_name, index=self.rebuilder.index_name)) + self.assertFalse( + self.es.indices.exists_alias(name=self.rebuilder.alias_name, index=self.rebuilder.index_name) + ) # Run finish self.rebuilder.finish() diff --git a/wagtail/wagtailsearch/views/queries.py b/wagtail/wagtailsearch/views/queries.py index f672ac5a7..d14abda8d 100644 --- a/wagtail/wagtailsearch/views/queries.py +++ b/wagtail/wagtailsearch/views/queries.py @@ -30,10 +30,12 @@ def chooser(request, get_results=False): 'queries': queries, }) else: - return render_modal_workflow(request, 'wagtailsearch/queries/chooser/chooser.html', 'wagtailsearch/queries/chooser/chooser.js', { - 'queries': queries, - 'searchform': searchform, - }) + return render_modal_workflow( + request, 'wagtailsearch/queries/chooser/chooser.html', 'wagtailsearch/queries/chooser/chooser.js', { + 'queries': queries, + 'searchform': searchform, + } + ) def chooserresults(request): diff --git a/wagtail/wagtailsites/wagtail_hooks.py b/wagtail/wagtailsites/wagtail_hooks.py index 54e47f365..d1c0efded 100644 --- a/wagtail/wagtailsites/wagtail_hooks.py +++ b/wagtail/wagtailsites/wagtail_hooks.py @@ -27,7 +27,8 @@ class SitesMenuItem(MenuItem): @hooks.register('register_settings_menu_item') def register_sites_menu_item(): - return SitesMenuItem(_('Sites'), urlresolvers.reverse('wagtailsites:index'), classnames='icon icon-site', order=602) + return SitesMenuItem(_('Sites'), urlresolvers.reverse('wagtailsites:index'), + classnames='icon icon-site', order=602) @hooks.register('register_permissions') diff --git a/wagtail/wagtailusers/tests.py b/wagtail/wagtailusers/tests.py index ef1eb7428..2601a548a 100644 --- a/wagtail/wagtailusers/tests.py +++ b/wagtail/wagtailusers/tests.py @@ -314,7 +314,8 @@ class TestGroupEditView(TestCase, WagtailTestUtils): } for k, v in six.iteritems(post_defaults): post_data[k] = post_data.get(k, v) - return self.client.post(reverse('wagtailusers_groups:edit', args=(group_id or self.test_group.id, )), post_data) + return self.client.post(reverse( + 'wagtailusers_groups:edit', args=(group_id or self.test_group.id, )), post_data) def add_non_registered_perm(self): # Some groups may have django permissions assigned that are not