From 7b129a82b3418edba3e26fe654f303df184a3efc Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Thu, 28 Apr 2011 14:19:25 +0000 Subject: [PATCH] Fixed #11726 - FormWizard does sanity check on step number performed before dynamic steps can be inserted Thanks to Eric Friesen for the report and michalm/esper256 for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16119 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/formtools/tests/__init__.py | 32 ++++++++++++++++++++++ django/contrib/formtools/wizard.py | 7 ++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/django/contrib/formtools/tests/__init__.py b/django/contrib/formtools/tests/__init__.py index b5037f428d..be0372ac2f 100644 --- a/django/contrib/formtools/tests/__init__.py +++ b/django/contrib/formtools/tests/__init__.py @@ -322,6 +322,38 @@ class WizardTests(TestCase): response = self.client.post('/wizard/', data) self.assertEqual(2, response.context['step0']) + def test_11726(self): + """ + Regression test for ticket #11726. + Wizard should not raise Http404 when steps are added dynamically. + """ + reached = [False] + that = self + + class WizardWithProcessStep(WizardClass): + def process_step(self, request, form, step): + if step == 0: + if self.num_steps() < 2: + self.form_list.append(WizardPageTwoForm) + if step == 1: + that.assertTrue(isinstance(form, WizardPageTwoForm)) + reached[0] = True + + wizard = WizardWithProcessStep([WizardPageOneForm]) + data = {"0-field": "test", + "1-field": "test2", + "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c", + "wizard_step": "1"} + wizard(DummyRequest(POST=data)) + self.assertTrue(reached[0]) + + data = {"0-field": "test", + "1-field": "test2", + "hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c", + "hash_1": "d5b434e3934cc92fee4bd2964c4ebc06f81d362d", + "wizard_step": "2"} + self.assertRaises(http.Http404, wizard, DummyRequest(POST=data)) + def test_14498(self): """ Regression test for ticket #14498. All previous steps' forms should be diff --git a/django/contrib/formtools/wizard.py b/django/contrib/formtools/wizard.py index af6f97bf45..c19578c390 100644 --- a/django/contrib/formtools/wizard.py +++ b/django/contrib/formtools/wizard.py @@ -47,6 +47,9 @@ class FormWizard(object): def get_form(self, step, data=None): "Helper method that returns the Form instance for the given step." + # Sanity check. + if step >= self.num_steps(): + raise Http404('Step %s does not exist' % step) return self.form_list[step](data, prefix=self.prefix_for_step(step), initial=self.initial.get(step, None)) def num_steps(self): @@ -71,10 +74,6 @@ class FormWizard(object): current_step = self.determine_step(request, *args, **kwargs) self.parse_params(request, *args, **kwargs) - # Sanity check. - if current_step >= self.num_steps(): - raise Http404('Step %s does not exist' % current_step) - # Validate and process all the previous forms before instantiating the # current step's form in case self.process_step makes changes to # self.form_list.