diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e6a92c4..49bf8af0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1 +1,53 @@ -repos: [] +# To enable this pre-commit hook run: +# `pip install pre-commit` or `brew install pre-commit` +# Then run `pre-commit install` + +# Learn more about this config here: https://pre-commit.com + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-toml + - id: check-yaml + - id: detect-private-key + - id: end-of-file-fixer + - id: mixed-line-ending + - id: requirements-txt-fixer + #- id: name-tests-test + # args: + # - --django + #- id: trailing-whitespace + # args: + # - --markdown-linebreak-ext=md + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.6 + hooks: + - id: ruff + args: + - --ignore=DJ007,DJ008,PLW2901,UP031,UP032 + - --line-length=119 + - --select=ASYNC,C4,C90,DJ,E,F,PL,UP,W + + - repo: https://github.com/psf/black + rev: 23.11.0 + hooks: + - id: black + args: + - --skip-string-normalization + - --target-version=py38 + + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + additional_dependencies: + - tomli + args: + [--skip, "*.po"] + + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.15 + hooks: + - id: validate-pyproject diff --git a/Makefile b/Makefile index dd931ccc..e29945d5 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ docs: $(MAKE) -C docs clean html test: - @flake8 + @ruff . @isort --check-only --diff formtools tests @ python -W error::DeprecationWarning -W error::PendingDeprecationWarning -m coverage run `which django-admin` test tests @coverage report diff --git a/docs/conf.py b/docs/conf.py index 9e6723b6..94e4daec 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,13 +12,13 @@ import os import sys -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tests.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.settings") # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('extensions')) -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath("extensions")) +sys.path.insert(0, os.path.abspath("..")) # -- General configuration ----------------------------------------------------- @@ -27,25 +27,31 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig', - 'sphinx.ext.viewcode', 'settings'] +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.ifconfig", + "sphinx.ext.viewcode", + "settings", +] # Add any paths that contain templates here, relative to this directory. # templates_path = ['_templates'] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = 'django-formtools' -copyright = '2014, Django Software Foundation and individual contributors' +project = "django-formtools" +copyright = "2014, Django Software Foundation and individual contributors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -54,12 +60,13 @@ # The short X.Y version. try: from formtools import __version__ + # The short X.Y version. - version = '.'.join(__version__.split('.')[:2]) + version = ".".join(__version__.split(".")[:2]) # The full version, including alpha/beta/rc tags. release = __version__ except ImportError: - version = release = 'dev' + version = release = "dev" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -73,7 +80,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] +exclude_patterns = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. # default_role = None @@ -90,7 +97,7 @@ # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -103,7 +110,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = "default" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -176,7 +183,7 @@ # html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'django-formtoolsdoc' +htmlhelp_basename = "django-formtoolsdoc" # -- Options for LaTeX output -------------------------------------------------- @@ -184,10 +191,8 @@ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # 'preamble': '', } @@ -195,8 +200,13 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'django-formtools.tex', 'django-formtools Documentation', - 'Django Software Foundation and individual contributors', 'manual'), + ( + "index", + "django-formtools.tex", + "django-formtools Documentation", + "Django Software Foundation and individual contributors", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of @@ -225,8 +235,13 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'django-formtools', 'django-formtools Documentation', - ['Django Software Foundation and individual contributors'], 1) + ( + "index", + "django-formtools", + "django-formtools Documentation", + ["Django Software Foundation and individual contributors"], + 1, + ) ] # If true, show URL addresses after external links. @@ -239,9 +254,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'django-formtools', 'django-formtools Documentation', - 'Django Software Foundation and individual contributors', 'django-formtools', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "django-formtools", + "django-formtools Documentation", + "Django Software Foundation and individual contributors", + "django-formtools", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. @@ -260,10 +281,10 @@ # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. -epub_title = 'django-formtools' -epub_author = 'Django Software Foundation and individual contributors' -epub_publisher = 'Django Software Foundation and individual contributors' -epub_copyright = '2014, Django Software Foundation and individual contributors' +epub_title = "django-formtools" +epub_author = "Django Software Foundation and individual contributors" +epub_publisher = "Django Software Foundation and individual contributors" +epub_copyright = "2014, Django Software Foundation and individual contributors" # The language of the text. It defaults to the language option # or en if the language is not set. @@ -317,7 +338,9 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = { - 'http://docs.python.org/': None, - 'django': ('http://docs.djangoproject.com/en/dev/', - 'http://docs.djangoproject.com/en/dev/_objects/'), + "http://docs.python.org/": None, + "django": ( + "http://docs.djangoproject.com/en/dev/", + "http://docs.djangoproject.com/en/dev/_objects/", + ), } diff --git a/formtools/preview.py b/formtools/preview.py index 9482dde8..54c0d4ed 100644 --- a/formtools/preview.py +++ b/formtools/preview.py @@ -50,8 +50,7 @@ def unused_name(self, name): def preview_get(self, request): "Displays the form" - f = self.form(auto_id=self.get_auto_id(), - initial=self.get_initial(request)) + f = self.form(auto_id=self.get_auto_id(), initial=self.get_initial(request)) return render(request, self.form_template, self.get_context(request, f)) def preview_post(self, request): @@ -61,7 +60,9 @@ def preview_post(self, request): """ # Even if files are not supported in preview, we still initialize files # to give a chance to process_preview to access files content. - f = self.form(data=request.POST, files=request.FILES, auto_id=self.get_auto_id()) + f = self.form( + data=request.POST, files=request.FILES, auto_id=self.get_auto_id() + ) context = self.get_context(request, f) if f.is_valid(): self.process_preview(request, f, context) @@ -82,8 +83,8 @@ def post_post(self, request): form = self.form(request.POST, auto_id=self.get_auto_id()) if form.is_valid(): if not self._check_security_hash( - request.POST.get(self.unused_name('hash'), ''), - request, form): + request.POST.get(self.unused_name('hash'), ''), request, form + ): return self.failed_hash(request) # Security hash failed. return self.done(request, form.cleaned_data) else: @@ -166,5 +167,7 @@ def done(self, request, cleaned_data): return an :class:`~django.http.HttpResponseRedirect`, e.g. to a success page. """ - raise NotImplementedError('You must define a done() method on your ' - '%s subclass.' % self.__class__.__name__) + raise NotImplementedError( + 'You must define a done() method on your ' + '%s subclass.' % self.__class__.__name__ + ) diff --git a/formtools/wizard/forms.py b/formtools/wizard/forms.py index 11cf4222..59037f2a 100644 --- a/formtools/wizard/forms.py +++ b/formtools/wizard/forms.py @@ -5,5 +5,6 @@ class ManagementForm(forms.Form): """ ``ManagementForm`` is used to keep track of the current wizard step. """ + template_name = "django/forms/p.html" # Remove when Django 5.0 is minimal version. current_step = forms.CharField(widget=forms.HiddenInput) diff --git a/formtools/wizard/storage/__init__.py b/formtools/wizard/storage/__init__.py index 66aa9ea1..6a8e81ca 100644 --- a/formtools/wizard/storage/__init__.py +++ b/formtools/wizard/storage/__init__.py @@ -4,7 +4,10 @@ from .exceptions import MissingStorage, NoFileStorageConfigured __all__ = [ - "BaseStorage", "MissingStorage", "NoFileStorageConfigured", "get_storage", + "BaseStorage", + "MissingStorage", + "NoFileStorageConfigured", + "get_storage", ] diff --git a/formtools/wizard/storage/base.py b/formtools/wizard/storage/base.py index ac2cf73e..dff5053c 100644 --- a/formtools/wizard/storage/base.py +++ b/formtools/wizard/storage/base.py @@ -90,7 +90,8 @@ def get_step_files(self, step): if wizard_files and not self.file_storage: raise NoFileStorageConfigured( "You need to define 'file_storage' in your " - "wizard view in order to handle file uploads.") + "wizard view in order to handle file uploads." + ) files = {} for field, field_dict in wizard_files.items(): @@ -98,7 +99,8 @@ def get_step_files(self, step): tmp_name = field_dict.pop('tmp_name') if (step, field) not in self._files: self._files[(step, field)] = UploadedFile( - file=self.file_storage.open(tmp_name), **field_dict) + file=self.file_storage.open(tmp_name), **field_dict + ) files[field] = self._files[(step, field)] return files or None @@ -106,7 +108,8 @@ def set_step_files(self, step, files): if files and not self.file_storage: raise NoFileStorageConfigured( "You need to define 'file_storage' in your " - "wizard view in order to handle file uploads.") + "wizard view in order to handle file uploads." + ) if step not in self.data[self.step_files_key]: self.data[self.step_files_key][step] = {} @@ -118,7 +121,7 @@ def set_step_files(self, step, files): 'name': field_file.name, 'content_type': field_file.content_type, 'size': field_file.size, - 'charset': field_file.charset + 'charset': field_file.charset, } self.data[self.step_files_key][step][field] = file_dict diff --git a/formtools/wizard/storage/cookie.py b/formtools/wizard/storage/cookie.py index 2becc48a..c9f613d3 100644 --- a/formtools/wizard/storage/cookie.py +++ b/formtools/wizard/storage/cookie.py @@ -21,7 +21,6 @@ def load_data(self): def update_response(self, response): super().update_response(response) if self.data: - response.set_signed_cookie(self.prefix, - self.encoder.encode(self.data)) + response.set_signed_cookie(self.prefix, self.encoder.encode(self.data)) else: response.delete_cookie(self.prefix) diff --git a/formtools/wizard/storage/session.py b/formtools/wizard/storage/session.py index c6ba7b85..6715af25 100644 --- a/formtools/wizard/storage/session.py +++ b/formtools/wizard/storage/session.py @@ -2,7 +2,6 @@ class SessionStorage(BaseStorage): - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.prefix not in self.request.session: diff --git a/formtools/wizard/views.py b/formtools/wizard/views.py index 07e0a6b7..f00fafae 100644 --- a/formtools/wizard/views.py +++ b/formtools/wizard/views.py @@ -30,7 +30,6 @@ def normalize_name(name): class StepsHelper: - def __init__(self, wizard): self._wizard = wizard @@ -101,6 +100,7 @@ class WizardView(TemplateView): storage and validation stuff. The wizard is based on Django's generic class based views. """ + storage_name = None form_list = None initial_dict = None @@ -122,8 +122,15 @@ def as_view(cls, *args, **kwargs): return super().as_view(**initkwargs) @classmethod - def get_initkwargs(cls, form_list=None, initial_dict=None, instance_dict=None, - condition_dict=None, *args, **kwargs): + def get_initkwargs( + cls, + form_list=None, + initial_dict=None, + instance_dict=None, + condition_dict=None, + *args, + **kwargs, + ): """ Creates a dict with all needed parameters for the form wizard instances @@ -146,22 +153,31 @@ def get_initkwargs(cls, form_list=None, initial_dict=None, instance_dict=None, will be called with the wizardview instance as the only argument. If the return value is true, the step's form will be used. """ - kwargs.update({ - 'initial_dict': ( - initial_dict or - kwargs.pop('initial_dict', getattr(cls, 'initial_dict', None)) or {} - ), - 'instance_dict': ( - instance_dict or - kwargs.pop('instance_dict', getattr(cls, 'instance_dict', None)) or {} - ), - 'condition_dict': ( - condition_dict or - kwargs.pop('condition_dict', getattr(cls, 'condition_dict', None)) or {} - ) - }) + kwargs.update( + { + 'initial_dict': ( + initial_dict + or kwargs.pop('initial_dict', getattr(cls, 'initial_dict', None)) + or {} + ), + 'instance_dict': ( + instance_dict + or kwargs.pop('instance_dict', getattr(cls, 'instance_dict', None)) + or {} + ), + 'condition_dict': ( + condition_dict + or kwargs.pop( + 'condition_dict', getattr(cls, 'condition_dict', None) + ) + or {} + ), + } + ) - form_list = form_list or kwargs.pop('form_list', getattr(cls, 'form_list', None)) or [] + form_list = ( + form_list or kwargs.pop('form_list', getattr(cls, 'form_list', None)) or [] + ) computed_form_list = OrderedDict() @@ -186,8 +202,9 @@ def get_initkwargs(cls, form_list=None, initial_dict=None, instance_dict=None, # check if any form contains a FileField, if yes, we need a # file_storage added to the wizardview (by subclassing). for field in form.base_fields.values(): - if (isinstance(field, forms.FileField) and - not hasattr(cls, 'file_storage')): + if isinstance(field, forms.FileField) and not hasattr( + cls, 'file_storage' + ): raise NoFileStorageConfigured( "You need to define 'file_storage' in your " "wizard view in order to handle file uploads." @@ -243,7 +260,9 @@ def dispatch(self, request, *args, **kwargs): # add the storage engine to the current wizardview instance self.prefix = self.get_prefix(request, *args, **kwargs) self.storage = get_storage( - self.storage_name, self.prefix, request, + self.storage_name, + self.prefix, + request, getattr(self, 'file_storage', None), ) self.steps = StepsHelper(self) @@ -285,11 +304,15 @@ def post(self, *args, **kwargs): # Check if form was refreshed management_form = ManagementForm(self.request.POST, prefix=self.prefix) if not management_form.is_valid(): - raise SuspiciousOperation(_('ManagementForm data is missing or has been tampered.')) + raise SuspiciousOperation( + _('ManagementForm data is missing or has been tampered.') + ) form_current_step = management_form.cleaned_data['current_step'] - if (form_current_step != self.steps.current and - self.storage.current_step is not None): + if ( + form_current_step != self.steps.current + and self.storage.current_step is not None + ): # form refreshed, change current step self.storage.current_step = form_current_step @@ -300,7 +323,9 @@ def post(self, *args, **kwargs): if form.is_valid(): # if the form is valid, store the cleaned data and files. self.storage.set_step_data(self.steps.current, self.process_step(form)) - self.storage.set_step_files(self.steps.current, self.process_step_files(form)) + self.storage.set_step_files( + self.steps.current, self.process_step_files(form) + ) # check if the current step is the last step if self.steps.current == self.steps.last: @@ -336,7 +361,8 @@ def render_goto_step(self, goto_step, **kwargs): self.storage.current_step = goto_step form = self.get_form( data=self.storage.get_step_data(self.steps.current), - files=self.storage.get_step_files(self.steps.current)) + files=self.storage.get_step_files(self.steps.current), + ) return self.render(form, **kwargs) def render_done(self, form, **kwargs): @@ -352,7 +378,7 @@ def render_done(self, form, **kwargs): form_obj = self.get_form( step=form_key, data=self.storage.get_step_data(form_key), - files=self.storage.get_step_files(form_key) + files=self.storage.get_step_files(form_key), ) if not form_obj.is_valid(): return self.render_revalidation_failure(form_key, form_obj, **kwargs) @@ -361,7 +387,9 @@ def render_done(self, form, **kwargs): # render the done view and reset the wizard before returning the # response. This is needed to prevent from rendering done with the # same data twice. - done_response = self.done(list(final_forms.values()), form_dict=final_forms, **kwargs) + done_response = self.done( + list(final_forms.values()), form_dict=final_forms, **kwargs + ) self.storage.reset() return done_response @@ -415,12 +443,14 @@ def get_form(self, step=None, data=None, files=None): form_class = self.get_form_list()[step] # prepare the kwargs for the form instance. kwargs = self.get_form_kwargs(step) - kwargs.update({ - 'data': data, - 'files': files, - 'prefix': self.get_form_prefix(step, form_class), - 'initial': self.get_form_initial(step), - }) + kwargs.update( + { + 'data': data, + 'files': files, + 'prefix': self.get_form_prefix(step, form_class), + 'initial': self.get_form_initial(step), + } + ) if issubclass(form_class, (forms.ModelForm, forms.models.BaseInlineFormSet)): # If the form is based on ModelForm or InlineFormSet, # add instance if available and not previously set. @@ -479,13 +509,13 @@ def get_all_cleaned_data(self): form_obj = self.get_form( step=form_key, data=self.storage.get_step_data(form_key), - files=self.storage.get_step_files(form_key) + files=self.storage.get_step_files(form_key), ) if form_obj.is_valid(): if isinstance(form_obj.cleaned_data, (tuple, list)): - cleaned_data.update({ - 'formset-%s' % form_key: form_obj.cleaned_data - }) + cleaned_data.update( + {'formset-%s' % form_key: form_obj.cleaned_data} + ) else: cleaned_data.update(form_obj.cleaned_data) return cleaned_data @@ -582,9 +612,12 @@ def get_context_data(self, form, **kwargs): context['wizard'] = { 'form': form, 'steps': self.steps, - 'management_form': ManagementForm(prefix=self.prefix, initial={ - 'current_step': self.steps.current, - }), + 'management_form': ManagementForm( + prefix=self.prefix, + initial={ + 'current_step': self.steps.current, + }, + ), } return context @@ -611,6 +644,7 @@ class SessionWizardView(WizardView): """ A WizardView with pre-configured SessionStorage backend. """ + storage_name = 'formtools.wizard.storage.session.SessionStorage' @@ -618,6 +652,7 @@ class CookieWizardView(WizardView): """ A WizardView with pre-configured CookieStorage backend. """ + storage_name = 'formtools.wizard.storage.cookie.CookieStorage' @@ -625,6 +660,7 @@ class NamedUrlWizardView(WizardView): """ A WizardView with URL named steps support. """ + url_name = None done_step_name = None @@ -642,8 +678,9 @@ def get_initkwargs(cls, *args, **kwargs): initkwargs = super().get_initkwargs(*args, **kwargs) initkwargs.update(extra_kwargs) - assert initkwargs['done_step_name'] not in initkwargs['form_list'], \ + assert initkwargs['done_step_name'] not in initkwargs['form_list'], ( 'step name "%s" is reserved for "done" view' % initkwargs['done_step_name'] + ) return initkwargs def get_step_url(self, step): @@ -691,7 +728,7 @@ def get(self, *args, **kwargs): data=self.storage.current_step_data, files=self.storage.current_step_files, ), - **kwargs + **kwargs, ) # invalid step name, reset to first and redirect. @@ -757,6 +794,7 @@ class NamedUrlSessionWizardView(NamedUrlWizardView): """ A NamedUrlWizardView with pre-configured SessionStorage backend. """ + storage_name = 'formtools.wizard.storage.session.SessionStorage' @@ -764,4 +802,5 @@ class NamedUrlCookieWizardView(NamedUrlWizardView): """ A NamedUrlFormWizard with pre-configured CookieStorageBackend. """ + storage_name = 'formtools.wizard.storage.cookie.CookieStorage' diff --git a/setup.cfg b/setup.cfg index 5f2896ee..5a4a9a51 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,3 @@ -[flake8] -max-line-length = 119 - [isort] combine_as_imports = true default_section = THIRDPARTY diff --git a/setup.py b/setup.py index 42cd4a9b..b8d24ea5 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ def read(*parts): setup_requires=["setuptools_scm"], url="https://django-formtools.readthedocs.io/en/latest/", project_urls={ - "Source": 'https://github.com/jazzband/django-formtools', + "Source": "https://github.com/jazzband/django-formtools", }, license="BSD", description="A set of high-level abstractions for Django forms", diff --git a/tests/requirements.txt b/tests/requirements.txt index e0c7a889..d17a8c31 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,3 +1,3 @@ coverage==7.3.2 -flake8 isort>=5.11.1, <6.0 +ruff diff --git a/tests/settings.py b/tests/settings.py index f3df07ea..38885e7c 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -19,7 +19,7 @@ CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', - 'LOCATION': 'spam-and-eggs' + 'LOCATION': 'spam-and-eggs', } } @@ -31,10 +31,12 @@ SITE_ID = 1 -TEMPLATES = [{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'APP_DIRS': True, -}] +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + } +] MEDIA_ROOT = 'media' STATIC_ROOT = 'static' diff --git a/tests/tests.py b/tests/tests.py index f9a2a35b..af59390a 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -6,14 +6,18 @@ from django import http from django.core.files.uploadedfile import ( - InMemoryUploadedFile, TemporaryUploadedFile, + InMemoryUploadedFile, + TemporaryUploadedFile, ) from django.test import TestCase, override_settings from formtools import preview, utils from .forms import ( - HashTestBlankForm, HashTestForm, HashTestFormWithFile, TestForm, + HashTestBlankForm, + HashTestForm, + HashTestFormWithFile, + TestForm, ) success_string = "Done was called!" @@ -37,15 +41,16 @@ def done(self, request, cleaned_data): @override_settings( - TEMPLATES=[{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')], - 'APP_DIRS': True, - }], + TEMPLATES=[ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(os.path.dirname(__file__), 'templates')], + 'APP_DIRS': True, + } + ], ROOT_URLCONF='tests.urls', ) class PreviewTests(TestCase): - def setUp(self): super().setUp() # Create a FormPreview instance to share between tests @@ -174,7 +179,6 @@ def test_form_submit_bad_hash(self): class FormHmacTests(unittest.TestCase): - def test_textfield_hash(self): """ Regression test for #10034: the hash generation function should ignore @@ -199,7 +203,9 @@ def test_empty_permitted(self): self.assertEqual(hash1, hash2) def test_hash_with_file(self): - with InMemoryUploadedFile(StringIO('1'), '', 'test', 'text/plain', 1, 'utf8') as some_file: + with InMemoryUploadedFile( + StringIO('1'), '', 'test', 'text/plain', 1, 'utf8' + ) as some_file: f1 = HashTestFormWithFile({'name': 'joe'}) f2 = HashTestFormWithFile({'name': 'joe'}, files={'attachment': some_file}) hash1 = utils.form_hmac(f1) diff --git a/tests/wizard/namedwizardtests/forms.py b/tests/wizard/namedwizardtests/forms.py index 54876206..2052b31a 100644 --- a/tests/wizard/namedwizardtests/forms.py +++ b/tests/wizard/namedwizardtests/forms.py @@ -37,11 +37,13 @@ class ContactWizard(NamedUrlWizardView): file_storage = temp_storage def done(self, form_list, **kwargs): - c = Context({ - 'form_list': [x.cleaned_data for x in form_list], - 'form_dict': kwargs.get('form_dict'), - 'all_cleaned_data': self.get_all_cleaned_data() - }) + c = Context( + { + 'form_list': [x.cleaned_data for x in form_list], + 'form_dict': kwargs.get('form_dict'), + 'all_cleaned_data': self.get_all_cleaned_data(), + } + ) for form in self.form_list.keys(): c[form] = self.get_cleaned_data_for_step(form) diff --git a/tests/wizard/namedwizardtests/tests.py b/tests/wizard/namedwizardtests/tests.py index c1dc1faa..14062d2c 100644 --- a/tests/wizard/namedwizardtests/tests.py +++ b/tests/wizard/namedwizardtests/tests.py @@ -6,7 +6,8 @@ from django.urls import reverse from formtools.wizard.views import ( - NamedUrlCookieWizardView, NamedUrlSessionWizardView, + NamedUrlCookieWizardView, + NamedUrlSessionWizardView, ) from ..test_forms import Step1, Step2, get_request @@ -16,7 +17,6 @@ class NamedWizardTests: - def setUp(self): self.testuser, created = User.objects.get_or_create(username='testuser1') # Get new step data, since we modify it during the tests. @@ -50,31 +50,35 @@ def test_initial_call(self): def test_initial_call_with_params(self): get_params = {'getvar1': 'getval1', 'getvar2': 'getval2'} - response = self.client.get(reverse('%s_start' % self.wizard_urlname), - get_params) + response = self.client.get( + reverse('%s_start' % self.wizard_urlname), get_params + ) self.assertEqual(response.status_code, 302) # Test for proper redirect GET parameters location = response.url self.assertNotEqual(location.find('?'), -1) - querydict = QueryDict(location[location.find('?') + 1:]) + querydict = QueryDict(location[location.find('?') + 1 :]) self.assertEqual(dict(querydict.items()), get_params) def test_form_post_error(self): response = self.client.post( reverse(self.wizard_urlname, kwargs={'step': 'form1'}), - self.wizard_step_1_data) + self.wizard_step_1_data, + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form1') - self.assertEqual(response.context['wizard']['form'].errors, - {'name': ['This field is required.'], - 'user': ['This field is required.']}) + self.assertEqual( + response.context['wizard']['form'].errors, + {'name': ['This field is required.'], 'user': ['This field is required.']}, + ) def test_form_post_success(self): response = self.client.post( reverse(self.wizard_urlname, kwargs={'step': 'form1'}), - self.wizard_step_data[0]) + self.wizard_step_data[0], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -86,23 +90,28 @@ def test_form_post_success(self): def test_form_stepback(self): response = self.client.get( - reverse(self.wizard_urlname, kwargs={'step': 'form1'})) + reverse(self.wizard_urlname, kwargs={'step': 'form1'}) + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form1') response = self.client.post( reverse(self.wizard_urlname, kwargs={'step': 'form1'}), - self.wizard_step_data[0]) + self.wizard_step_data[0], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form2') response = self.client.post( - reverse(self.wizard_urlname, kwargs={ - 'step': response.context['wizard']['steps'].current - }), {'wizard_goto_step': response.context['wizard']['steps'].prev}) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + {'wizard_goto_step': response.context['wizard']['steps'].prev}, + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -110,27 +119,33 @@ def test_form_stepback(self): def test_form_jump(self): response = self.client.get( - reverse(self.wizard_urlname, kwargs={'step': 'form1'})) + reverse(self.wizard_urlname, kwargs={'step': 'form1'}) + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form1') response = self.client.get( - reverse(self.wizard_urlname, kwargs={'step': 'form3'})) + reverse(self.wizard_urlname, kwargs={'step': 'form3'}) + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form3') def test_form_finish(self): response = self.client.get( - reverse(self.wizard_urlname, kwargs={'step': 'form1'})) + reverse(self.wizard_urlname, kwargs={'step': 'form1'}) + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form1') response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[0]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[0], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -140,9 +155,12 @@ def test_form_finish(self): with open(__file__, 'rb') as post_file: post_data['form2-file1'] = post_file response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - post_data) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + post_data, + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -153,18 +171,24 @@ def test_form_finish(self): self.assertEqual(f.read(), f2.read()) response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[2]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[2], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form4') response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[3]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[3], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -173,21 +197,29 @@ def test_form_finish(self): all_data = response.context['form_list'] del all_data[1]['file1'] - self.assertEqual(all_data, [ - {'name': 'Pony', 'thirsty': True, 'user': self.testuser}, - {'address1': '123 Main St', 'address2': 'Djangoland'}, - {'random_crap': 'blah blah'}, - [{'random_crap': 'blah blah'}, {'random_crap': 'blah blah'}]]) + self.assertEqual( + all_data, + [ + {'name': 'Pony', 'thirsty': True, 'user': self.testuser}, + {'address1': '123 Main St', 'address2': 'Djangoland'}, + {'random_crap': 'blah blah'}, + [{'random_crap': 'blah blah'}, {'random_crap': 'blah blah'}], + ], + ) def test_cleaned_data(self): response = self.client.get( - reverse(self.wizard_urlname, kwargs={'step': 'form1'})) + reverse(self.wizard_urlname, kwargs={'step': 'form1'}) + ) self.assertEqual(response.status_code, 200) response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[0]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[0], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -195,9 +227,12 @@ def test_cleaned_data(self): with open(__file__, 'rb') as post_file: post_data['form2-file1'] = post_file response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - post_data) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + post_data, + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) self.assertTrue(temp_storage.exists(UPLOADED_FILE_NAME)) @@ -210,16 +245,22 @@ def test_cleaned_data(self): self.assertEqual(f.read(), f2.read()) response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[2]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[2], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[3]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[3], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -230,27 +271,40 @@ def test_cleaned_data(self): del all_data['file1'] self.assertEqual( all_data, - {'name': 'Pony', 'thirsty': True, 'user': self.testuser, - 'address1': '123 Main St', 'address2': 'Djangoland', - 'random_crap': 'blah blah', 'formset-form4': [ - {'random_crap': 'blah blah'}, - {'random_crap': 'blah blah'} - ]}) + { + 'name': 'Pony', + 'thirsty': True, + 'user': self.testuser, + 'address1': '123 Main St', + 'address2': 'Djangoland', + 'random_crap': 'blah blah', + 'formset-form4': [ + {'random_crap': 'blah blah'}, + {'random_crap': 'blah blah'}, + ], + }, + ) form_dict = response.context['form_dict'] self.assertIn('form1', form_dict.keys()) self.assertIn('form2', form_dict.keys()) - self.assertEqual(form_dict['form1'].cleaned_data, response.context['form_list'][0]) + self.assertEqual( + form_dict['form1'].cleaned_data, response.context['form_list'][0] + ) def test_manipulated_data(self): response = self.client.get( - reverse(self.wizard_urlname, kwargs={'step': 'form1'})) + reverse(self.wizard_urlname, kwargs={'step': 'form1'}) + ) self.assertEqual(response.status_code, 200) response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[0]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[0], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) @@ -258,16 +312,22 @@ def test_manipulated_data(self): with open(__file__, 'rb') as post_file: post_data['form2-file1'] = post_file response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - post_data) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + post_data, + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[2]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[2], + ) loc = response.url response = self.client.get(loc) self.assertEqual(response.status_code, 200, loc) @@ -276,9 +336,12 @@ def test_manipulated_data(self): self.client.cookies.pop('wizard_cookie_contact_wizard', None) response = self.client.post( - reverse(self.wizard_urlname, - kwargs={'step': response.context['wizard']['steps'].current}), - self.wizard_step_data[3]) + reverse( + self.wizard_urlname, + kwargs={'step': response.context['wizard']['steps'].current}, + ), + self.wizard_step_data[3], + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form1') @@ -286,13 +349,15 @@ def test_manipulated_data(self): def test_form_reset(self): response = self.client.post( reverse(self.wizard_urlname, kwargs={'step': 'form1'}), - self.wizard_step_data[0]) + self.wizard_step_data[0], + ) response = self.client.get(response.url) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form2') response = self.client.get( - '%s?reset=1' % reverse('%s_start' % self.wizard_urlname)) + '%s?reset=1' % reverse('%s_start' % self.wizard_urlname) + ) self.assertEqual(response.status_code, 302) response = self.client.get(response.url) @@ -328,7 +393,7 @@ class NamedSessionWizardTests(NamedWizardTests, TestCase): 'form4-0-random_crap': 'blah blah', 'form4-1-random_crap': 'blah blah', 'session_contact_wizard-current_step': 'form4', - } + }, ) @@ -360,18 +425,17 @@ class NamedCookieWizardTests(NamedWizardTests, TestCase): 'form4-0-random_crap': 'blah blah', 'form4-1-random_crap': 'blah blah', 'cookie_contact_wizard-current_step': 'form4', - } + }, ) class NamedFormTests: - def test_revalidation(self): request = get_request() testform = self.formwizard_class.as_view( - [('start', Step1), ('step2', Step2)], - url_name=self.wizard_urlname) + [('start', Step1), ('step2', Step2)], url_name=self.wizard_urlname + ) response, instance = testform(request, step='done') instance.render_done(None) @@ -379,14 +443,12 @@ def test_revalidation(self): class TestNamedUrlSessionWizardView(NamedUrlSessionWizardView): - def dispatch(self, request, *args, **kwargs): response = super().dispatch(request, *args, **kwargs) return response, self class TestNamedUrlCookieWizardView(NamedUrlCookieWizardView): - def dispatch(self, request, *args, **kwargs): response = super().dispatch(request, *args, **kwargs) return response, self diff --git a/tests/wizard/namedwizardtests/urls.py b/tests/wizard/namedwizardtests/urls.py index 2eb7eef6..9a2c9228 100644 --- a/tests/wizard/namedwizardtests/urls.py +++ b/tests/wizard/namedwizardtests/urls.py @@ -1,7 +1,12 @@ from django.urls import path, re_path from .forms import ( - CookieContactWizard, Page1, Page2, Page3, Page4, SessionContactWizard, + CookieContactWizard, + Page1, + Page2, + Page3, + Page4, + SessionContactWizard, ) @@ -9,7 +14,7 @@ def get_named_session_wizard(): return SessionContactWizard.as_view( [('form1', Page1), ('form2', Page2), ('form3', Page3), ('form4', Page4)], url_name='nwiz_session', - done_step_name='nwiz_session_done' + done_step_name='nwiz_session_done', ) @@ -17,13 +22,17 @@ def get_named_cookie_wizard(): return CookieContactWizard.as_view( [('form1', Page1), ('form2', Page2), ('form3', Page3), ('form4', Page4)], url_name='nwiz_cookie', - done_step_name='nwiz_cookie_done' + done_step_name='nwiz_cookie_done', ) urlpatterns = [ - re_path(r'^nwiz_session/(?P.+)/$', get_named_session_wizard(), name='nwiz_session'), + re_path( + r'^nwiz_session/(?P.+)/$', get_named_session_wizard(), name='nwiz_session' + ), path('nwiz_session/', get_named_session_wizard(), name='nwiz_session_start'), - re_path(r'nwiz_cookie/(?P.+)/$', get_named_cookie_wizard(), name='nwiz_cookie'), + re_path( + r'nwiz_cookie/(?P.+)/$', get_named_cookie_wizard(), name='nwiz_cookie' + ), path('nwiz_cookie/', get_named_cookie_wizard(), name='nwiz_cookie_start'), ] diff --git a/tests/wizard/storage.py b/tests/wizard/storage.py index d1455c93..615240a3 100644 --- a/tests/wizard/storage.py +++ b/tests/wizard/storage.py @@ -45,10 +45,12 @@ def test_step_data(self): request = get_request() storage = self.get_storage()('wizard1', request, None) step1 = 'start' - step_data1 = {'field1': 'data1', - 'field2': 'data2', - 'field3': datetime.now(), - 'field4': self.testuser} + step_data1 = { + 'field1': 'data1', + 'field2': 'data2', + 'field3': datetime.now(), + 'field4': self.testuser, + } self.assertEqual(storage.get_step_data(step1), None) @@ -65,10 +67,12 @@ def test_step_data(self): def test_extra_context(self): request = get_request() storage = self.get_storage()('wizard1', request, None) - extra_context = {'key1': 'data1', - 'key2': 'data2', - 'key3': datetime.now(), - 'key4': self.testuser} + extra_context = { + 'key1': 'data1', + 'key2': 'data2', + 'key3': datetime.now(), + 'key4': self.testuser, + } self.assertEqual(storage.extra_data, {}) diff --git a/tests/wizard/test_basestorage.py b/tests/wizard/test_basestorage.py index bbf509bd..73c24954 100644 --- a/tests/wizard/test_basestorage.py +++ b/tests/wizard/test_basestorage.py @@ -4,7 +4,6 @@ class TestBaseStorage(TestCase): - def test_subclass_can_override_get_current_step(self): class MyStorage(BaseStorage): def _get_current_step(self): diff --git a/tests/wizard/test_cookiestorage.py b/tests/wizard/test_cookiestorage.py index aa6c7a81..fdd1436b 100644 --- a/tests/wizard/test_cookiestorage.py +++ b/tests/wizard/test_cookiestorage.py @@ -41,8 +41,10 @@ def test_reset_cookie(self): storage.init_data() storage.update_response(response) - unsigned_cookie_data = cookie_signer.unsign(response.cookies[storage.prefix].value) + unsigned_cookie_data = cookie_signer.unsign( + response.cookies[storage.prefix].value + ) self.assertJSONEqual( unsigned_cookie_data, - {"step_files": {}, "step": None, "extra_data": {}, "step_data": {}} + {"step_files": {}, "step": None, "extra_data": {}, "step_data": {}}, ) diff --git a/tests/wizard/test_forms.py b/tests/wizard/test_forms.py index 9bee6cfe..a9befca6 100644 --- a/tests/wizard/test_forms.py +++ b/tests/wizard/test_forms.py @@ -9,7 +9,9 @@ from django.test import TestCase from formtools.wizard.views import ( - CookieWizardView, SessionWizardView, WizardView, + CookieWizardView, + SessionWizardView, + WizardView, ) @@ -43,7 +45,6 @@ class Step3(forms.Form): class CustomKwargsStep1(Step1): - def __init__(self, test=None, *args, **kwargs): self.test = test super().__init__(*args, **kwargs) @@ -62,7 +63,9 @@ class Meta: fields = '__all__' -TestModelFormSet = forms.models.modelformset_factory(TestModel, form=TestModelForm, extra=2, fields='__all__') +TestModelFormSet = forms.models.modelformset_factory( + TestModel, form=TestModelForm, extra=2, fields='__all__' +) class TestWizard(WizardView): @@ -88,12 +91,13 @@ class TestWizardWithInitAttrs(TestWizard): class TestWizardWithTypeCheck(TestWizard): def done(self, form_list, **kwargs): - assert type(form_list) is list, "`form_list` was {}, should be a list".format(type(form_list)) + assert ( + type(form_list) is list # noqa: E721 + ), f"`form_list` was {type(form_list)}, should be a list" return http.HttpResponse("All good") class TestWizardWithCustomGetFormList(TestWizard): - form_list = [Step1] def get_form_list(self): @@ -109,7 +113,9 @@ def test_form_init(self): self.assertEqual(testform['form_list'], {'start': Step1, 'step2': Step2}) testform = TestWizard.get_initkwargs([Step1, Step2, ('finish', Step3)]) - self.assertEqual(testform['form_list'], {'0': Step1, '1': Step2, 'finish': Step3}) + self.assertEqual( + testform['form_list'], {'0': Step1, '1': Step2, 'finish': Step3} + ) testform = TestWizardWithInitAttrs.get_initkwargs() self.assertEqual(testform['form_list'], {'0': Step1, '1': Step2}) @@ -141,14 +147,14 @@ def test_form_condition(self): request = get_request() testform = TestWizard.as_view( [('start', Step1), ('step2', Step2), ('step3', Step3)], - condition_dict={'step2': True} + condition_dict={'step2': True}, ) response, instance = testform(request) self.assertEqual(instance.get_next_step(), 'step2') testform = TestWizard.as_view( [('start', Step1), ('step2', Step2), ('step3', Step3)], - condition_dict={'step2': False} + condition_dict={'step2': False}, ) response, instance = testform(request) self.assertEqual(instance.get_next_step(), 'step3') @@ -166,7 +172,7 @@ def subsequent_step_check(wizard): testform = TestWizard.as_view( [('start', Step1), ('step2', Step2), ('step3', Step3)], - condition_dict={'step3': subsequent_step_check} + condition_dict={'step3': subsequent_step_check}, ) request = get_request() old_limit = sys.getrecursionlimit() @@ -183,7 +189,7 @@ def test_form_condition_unstable(self): request = get_request() testform = TestWizard.as_view( [('start', Step1), ('step2', Step2), ('step3', Step3)], - condition_dict={'step2': True} + condition_dict={'step2': True}, ) response, instance = testform(request) self.assertEqual(instance.get_step_index('step2'), 1) @@ -194,10 +200,12 @@ def test_form_condition_unstable(self): def test_form_kwargs(self): request = get_request() - testform = TestWizard.as_view([ - ('start', Step1), - ('kwargs_test', CustomKwargsStep1), - ]) + testform = TestWizard.as_view( + [ + ('start', Step1), + ('kwargs_test', CustomKwargsStep1), + ] + ) response, instance = testform(request) self.assertEqual(instance.get_form_kwargs('start'), {}) self.assertEqual(instance.get_form_kwargs('kwargs_test'), {'test': True}) @@ -214,15 +222,13 @@ def test_form_initial(self): request = get_request() testform = TestWizard.as_view( [('start', Step1), ('step2', Step2)], - initial_dict={'start': {'name': 'value1'}} + initial_dict={'start': {'name': 'value1'}}, ) response, instance = testform(request) self.assertEqual(instance.get_form_initial('start'), {'name': 'value1'}) self.assertEqual(instance.get_form_initial('step2'), {}) - testform = TestWizardWithInitAttrs.as_view( - [('start', Step1), ('step2', Step2)] - ) + testform = TestWizardWithInitAttrs.as_view([('start', Step1), ('step2', Step2)]) response, instance = testform(request) self.assertEqual(instance.get_form_initial('start'), {'name': 'value1'}) @@ -233,17 +239,19 @@ def test_form_instance(self): the_instance = TestModel() testform = TestWizard.as_view( [('start', TestModelForm), ('step2', Step2)], - instance_dict={'start': the_instance} + instance_dict={'start': the_instance}, ) response, instance = testform(request) self.assertEqual(instance.get_form_instance('start'), the_instance) self.assertIsNone(instance.get_form_instance('non_exist_instance')) - testform = TestWizardWithInitAttrs.as_view([('start', TestModelForm), ('step2', Step2)]) + testform = TestWizardWithInitAttrs.as_view( + [('start', TestModelForm), ('step2', Step2)] + ) response, instance = testform(request) self.assertEqual( instance.get_form_instance('start'), - TestWizardWithInitAttrs.instance_dict['start'] + TestWizardWithInitAttrs.instance_dict['start'], ) def test_formset_instance(self): @@ -252,7 +260,7 @@ def test_formset_instance(self): the_instance2, created = TestModel.objects.get_or_create(name='test object 2') testform = TestWizard.as_view( [('start', TestModelFormSet), ('step2', Step2)], - instance_dict={'start': TestModel.objects.filter(name='test object 1')} + instance_dict={'start': TestModel.objects.filter(name='test object 1')}, ) response, instance = testform(request) self.assertEqual(list(instance.get_form_instance('start')), [the_instance1]) @@ -281,7 +289,9 @@ def test_revalidation(self): self.assertEqual(instance.storage.current_step, 'start') def test_form_list_type(self): - request = get_request({'test_wizard_with_type_check-current_step': 'start', 'start-name': 'data1'}) + request = get_request( + {'test_wizard_with_type_check-current_step': 'start', 'start-name': 'data1'} + ) testform = TestWizardWithTypeCheck.as_view([('start', Step1)]) response, instance = testform(request) self.assertEqual(response.status_code, 200) diff --git a/tests/wizard/test_loadstorage.py b/tests/wizard/test_loadstorage.py index f0d72b30..f3b6afb8 100644 --- a/tests/wizard/test_loadstorage.py +++ b/tests/wizard/test_loadstorage.py @@ -8,11 +8,13 @@ class TestLoadStorage(TestCase): def test_load_storage(self): self.assertIsInstance( get_storage('formtools.wizard.storage.base.BaseStorage', 'wizard1'), - BaseStorage + BaseStorage, ) def test_missing_storage(self): with self.assertRaises(MissingStorage): - get_storage('formtools.wizard.storage.idontexist.IDontExistStorage', 'wizard1') + get_storage( + 'formtools.wizard.storage.idontexist.IDontExistStorage', 'wizard1' + ) with self.assertRaises(MissingStorage): get_storage('formtools.wizard.storage.base.IDontExistStorage', 'wizard1') diff --git a/tests/wizard/wizardtests/forms.py b/tests/wizard/wizardtests/forms.py index 5454b88e..20d92c5a 100644 --- a/tests/wizard/wizardtests/forms.py +++ b/tests/wizard/wizardtests/forms.py @@ -38,10 +38,12 @@ class ContactWizard(WizardView): file_storage = temp_storage def done(self, form_list, **kwargs): - c = Context({ - 'form_list': [x.cleaned_data for x in form_list], - 'all_cleaned_data': self.get_all_cleaned_data(), - }) + c = Context( + { + 'form_list': [x.cleaned_data for x in form_list], + 'all_cleaned_data': self.get_all_cleaned_data(), + } + ) for form in self.form_list.keys(): c[form] = self.get_cleaned_data_for_step(form) diff --git a/tests/wizard/wizardtests/tests.py b/tests/wizard/wizardtests/tests.py index 96a6c06d..69ef5a53 100644 --- a/tests/wizard/wizardtests/tests.py +++ b/tests/wizard/wizardtests/tests.py @@ -24,7 +24,6 @@ class Meta: class WizardTests: - def setUp(self): self.testuser, created = User.objects.get_or_create(username='testuser1') # Get new step data, since we modify it during the tests. @@ -57,9 +56,10 @@ def test_form_post_error(self): response = self.client.post(self.wizard_url, self.wizard_step_1_data) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form1') - self.assertEqual(response.context['wizard']['form'].errors, - {'name': ['This field is required.'], - 'user': ['This field is required.']}) + self.assertEqual( + response.context['wizard']['form'].errors, + {'name': ['This field is required.'], 'user': ['This field is required.']}, + ) def test_form_post_mgmt_data_missing(self): wizard_step_data = self.wizard_step_data[0].copy() @@ -91,8 +91,10 @@ def test_form_stepback(self): self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form2') - response = self.client.post(self.wizard_url, { - 'wizard_goto_step': response.context['wizard']['steps'].prev}) + response = self.client.post( + self.wizard_url, + {'wizard_goto_step': response.context['wizard']['steps'].prev}, + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['wizard']['steps'].current, 'form1') @@ -143,12 +145,15 @@ def test_form_finish(self): all_data = response.context['form_list'] del all_data[1]['file1'] - self.assertEqual(all_data, [ - {'name': 'Pony', 'thirsty': True, 'user': self.testuser}, - {'address1': '123 Main St', 'address2': 'Djangoland'}, - {'random_crap': 'blah blah'}, - [{'random_crap': 'blah blah'}, - {'random_crap': 'blah blah'}]]) + self.assertEqual( + all_data, + [ + {'name': 'Pony', 'thirsty': True, 'user': self.testuser}, + {'address1': '123 Main St', 'address2': 'Djangoland'}, + {'random_crap': 'blah blah'}, + [{'random_crap': 'blah blah'}, {'random_crap': 'blah blah'}], + ], + ) def test_cleaned_data(self): response = self.client.get(self.wizard_url) @@ -175,12 +180,21 @@ def test_cleaned_data(self): self.assertTrue(all_data['file1'].closed) self.assertFalse(temp_storage.exists(UPLOADED_FILE_NAME)) del all_data['file1'] - self.assertEqual(all_data, { - 'name': 'Pony', 'thirsty': True, 'user': self.testuser, - 'address1': '123 Main St', 'address2': 'Djangoland', - 'random_crap': 'blah blah', 'formset-form4': [ - {'random_crap': 'blah blah'}, - {'random_crap': 'blah blah'}]}) + self.assertEqual( + all_data, + { + 'name': 'Pony', + 'thirsty': True, + 'user': self.testuser, + 'address1': '123 Main St', + 'address2': 'Djangoland', + 'random_crap': 'blah blah', + 'formset-form4': [ + {'random_crap': 'blah blah'}, + {'random_crap': 'blah blah'}, + ], + }, + ) def test_manipulated_data(self): response = self.client.get(self.wizard_url) @@ -264,7 +278,7 @@ class SessionWizardTests(WizardTests, TestCase): 'form4-0-random_crap': 'blah blah', 'form4-1-random_crap': 'blah blah', 'session_contact_wizard-current_step': 'form4', - } + }, ) @@ -296,7 +310,7 @@ class CookieWizardTests(WizardTests, TestCase): 'form4-0-random_crap': 'blah blah', 'form4-1-random_crap': 'blah blah', 'cookie_contact_wizard-current_step': 'form4', - } + }, ) @@ -328,7 +342,7 @@ class WizardTestKwargs(TestCase): 'form4-0-random_crap': 'blah blah', 'form4-1-random_crap': 'blah blah', 'cookie_contact_wizard-current_step': 'form4', - } + }, ) def setUp(self): @@ -349,6 +363,7 @@ class TestWizard(CookieWizardView): See ticket #17148. """ + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['test_key'] = 'test_value' @@ -374,6 +389,7 @@ class TestWizard(AnotherMixin, CookieWizardView): See ticket #17148. """ + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['test_key'] = 'test_value' @@ -424,8 +440,12 @@ def setUp(self): # Create two users so we can filter by is_staff when handing our # wizard a queryset keyword argument. - self.normal_user = User.objects.create(username='test1', email='normal@example.com') - self.staff_user = User.objects.create(username='test2', email='staff@example.com', is_staff=True) + self.normal_user = User.objects.create( + username='test1', email='normal@example.com' + ) + self.staff_user = User.objects.create( + username='test2', email='staff@example.com', is_staff=True + ) def test_instance_is_maintained(self): self.assertEqual(2, User.objects.count()) @@ -458,7 +478,10 @@ def get_form_kwargs(self, step): self.assertNotEqual(formset.queryset, None) self.assertEqual(formset.initial_form_count(), 1) - self.assertEqual(['staff@example.com'], list(formset.queryset.values_list('email', flat=True))) + self.assertEqual( + ['staff@example.com'], + list(formset.queryset.values_list('email', flat=True)), + ) class WizardInlineFormSetTests(TestCase): diff --git a/tests/wizard/wizardtests/urls.py b/tests/wizard/wizardtests/urls.py index 9ab82b8d..48b227c0 100644 --- a/tests/wizard/wizardtests/urls.py +++ b/tests/wizard/wizardtests/urls.py @@ -1,24 +1,32 @@ from django.urls import path from .forms import ( - CookieContactWizard, Page1, Page2, Page3, Page4, SessionContactWizard, + CookieContactWizard, + Page1, + Page2, + Page3, + Page4, + SessionContactWizard, ) urlpatterns = [ - path('wiz_session/', SessionContactWizard.as_view( - [('form1', Page1), - ('form2', Page2), - ('form3', Page3), - ('form4', Page4)])), - path('wiz_cookie/', CookieContactWizard.as_view( - [('form1', Page1), - ('form2', Page2), - ('form3', Page3), - ('form4', Page4)])), - path('wiz_other_template/', CookieContactWizard.as_view( - [('form1', Page1), - ('form2', Page2), - ('form3', Page3), - ('form4', Page4)], - template_name='other_wizard_form.html')), + path( + 'wiz_session/', + SessionContactWizard.as_view( + [('form1', Page1), ('form2', Page2), ('form3', Page3), ('form4', Page4)] + ), + ), + path( + 'wiz_cookie/', + CookieContactWizard.as_view( + [('form1', Page1), ('form2', Page2), ('form3', Page3), ('form4', Page4)] + ), + ), + path( + 'wiz_other_template/', + CookieContactWizard.as_view( + [('form1', Page1), ('form2', Page2), ('form3', Page3), ('form4', Page4)], + template_name='other_wizard_form.html', + ), + ), ]